| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529 | <?php/** * * Cube Framework $Id$ g+9aR/HEfb0V/s3OWo8wHeJZf6sGDt6ooiPHFmHzoYk= * * @link        http://codecu.be/framework * @copyright   Copyright (c) 2015 CodeCube SRL * @license     http://codecu.be/framework/license Commercial License * * @version     1.4 *//** * navigation view helper */namespace Cube\View\Helper;use Cube\Navigation\AbstractContainer,    Cube\Navigation\Page\AbstractPage,    Cube\Permissions;class Navigation extends AbstractHelper{    /**     *     * initial navigation object (should not modified)     *     * @var \Cube\Navigation\Page\AbstractPage     */    protected $_initialContainer;    /**     *     * navigation object     *     * @var \Cube\Navigation\Page\AbstractPage     */    protected $_container;    /**     *     * path where to search for navigation view partials     *     * @var string     */    protected $_path;    /**     *     * the minimum depth from which the rendering will start     * default = 0 - from first page     *     * @var integer     */    protected $_minDepth = 0;    /**     *     * the maximum depth where the rendering will stop     * default = 0 - until last page     *     * @var integer     */    protected $_maxDepth = 0;    /**     *     * ACL object to use     *     * @var \Cube\Permissions\Acl     */    protected $_acl;    /**     *     * ACL role to use     *     * @var string|\Cube\Permissions\RoleInterface     */    protected $_role;    /**     *     * get the initial navigation object     *     * @return \Cube\Navigation\Page\AbstractPage     * @throws \InvalidArgumentException     */    public function getInitialContainer()    {        if (!$this->_initialContainer instanceof AbstractContainer) {            throw new \InvalidArgumentException(                sprintf("'%s' must be of type \Cube\Navigation\AbstractContainer.", $this->_container));        }        return $this->_initialContainer;    }    /**     *     * set the initial navigation container     *     * @param \Cube\Navigation\Page\AbstractPage $container     *     * @throws \InvalidArgumentException     * @return $this     */    public function setInitialContainer($container)    {        if ($container instanceof AbstractContainer) {            $this->_initialContainer = $container;            $this->setContainer($this->_initialContainer);        }        else {            throw new \InvalidArgumentException(                sprintf("'%s' must be of type \Cube\Navigation\AbstractContainer.", $this->_container));        }        return $this;    }    /**     *     * get the navigation object     *     * @return \Cube\Navigation\Page\AbstractPage     * @throws \InvalidArgumentException     */    public function getContainer()    {        if (!$this->_container instanceof AbstractContainer) {            throw new \InvalidArgumentException(                sprintf("'%s' must be of type \Cube\Navigation\AbstractContainer.", $this->_container));        }        return $this->_container;    }    /**     *     * set the navigation container     *     * @param \Cube\Navigation\Page\AbstractPage $container     *     * @throws \InvalidArgumentException     * @return $this     */    public function setContainer($container)    {        if ($container instanceof AbstractContainer) {            $this->_container = $container;        }        else if ($container !== null) {            throw new \InvalidArgumentException(                sprintf("'%s' must be of type \Cube\Navigation\AbstractContainer.", $this->_container));        }        return $this;    }    /**     *     * reset container     *     * @param bool $initialContainer     *     * @return $this     */    public function resetContainer($initialContainer = true)    {        if ($initialContainer === true) {            $this->_container = $this->getInitialContainer();        }        else {            $this->_container = null;        }        return $this;    }    /**     *     * get navigation partials path     *     * @return string     */    public function getPath()    {        return $this->_path;    }    /**     *     * set navigation partials path     *     * @param string $path     *     * @return $this     */    public function setPath($path)    {//        if (!is_dir($path)) {//            throw new \InvalidArgumentException(//                sprintf("The navigation files path (%s) does not exist.", $path));//        }        if (is_dir($path)) {            $this->_path = $path;        }        return $this;    }    /**     *     * get the minimum depth of the container     *     * @return integer     */    public function getMinDepth()    {        return $this->_minDepth;    }    /**     *     * set the minimum depth of the container     *     * @param int $minDepth     *     * @return $this     */    public function setMinDepth($minDepth)    {        $this->_minDepth = (int)$minDepth;        return $this;    }    /**     *     * get the maximum depth of the container     *     * @return int     */    public function getMaxDepth()    {        return $this->_maxDepth;    }    /**     *     * set the maximum depth of the container     *     * @param int $maxDepth     *     * @return $this     */    public function setMaxDepth($maxDepth)    {        $this->_maxDepth = (int)$maxDepth;        return $this;    }    /**     *     * get ACL     *     * @return \Cube\Permissions\Acl     * @throws \InvalidArgumentException     */    public function getAcl()    {        if (!$this->_acl instanceof Permissions\Acl) {            throw new \InvalidArgumentException(                sprintf("'%s' must be of type \Cube\Permissions\Acl.", $this->_acl));        }        return $this->_acl;    }    /**     *     * set ACL     *     * @param \Cube\Permissions\Acl $acl     *     * @throws \InvalidArgumentException     * @return $this     */    public function setAcl($acl)    {        if ($acl instanceof Permissions\Acl) {            $this->_acl = $acl;        }        else {            throw new \InvalidArgumentException(                sprintf("'%s' must be of type \Cube\Permissions\Acl.", $this->_acl));        }        return $this;    }    /**     *     * get ACL role     *     * @return string|\Cube\Permissions\RoleInterface     */    public function getRole()    {        return $this->_role;    }    /**     *     * set ACL role     *     * @param string|\Cube\Permissions\RoleInterface $role     *     * @return $this     * @throws \InvalidArgumentException     */    public function setRole($role)    {        if ($role === null || is_string($role) || $role instanceof Permissions\RoleInterface) {            $this->_role = $role;        }        else {            throw new \InvalidArgumentException(                sprintf("'%s' must be null, a string, or an instance of type \Cube\Permissions\RoleInterface.",                    $this->_role));        }        return $this;    }    /**     *     * function called by the reflection class when creating the helper     * we will always check if the navigation object and view file are set correctly when calling the navigation proxy class     *     * @param \Cube\Navigation\AbstractContainer $container the navigation object     * @param string                             $partial   the name of the view partial used for rendering the navigation object     *     * @return $this     */    public function navigation($container = null, $partial = null)    {        if ($container !== null) {            $this->setContainer($container);            $this->setPartial($partial);        }        return $this;    }    /**     *     * create a navigation menu from a navigation container and a view partial     *     * @return string       the rendered menu     */    public function menu()    {        $view = $this->getView();        $view->set('menu', $this->getContainer());        return $view->process(            $this->getPartial(), true);    }    /**     *     * find the active page in the container set in the helper     *     * @return \Cube\Navigation\Page\AbstractPage|null      return the page object if found or null otherwise     */    public function findActive()    {        $container = $this->getContainer();        if ($container->isActive()) {            return $container;        }        $iterator = new \RecursiveIteratorIterator($container,            \RecursiveIteratorIterator::CHILD_FIRST);        /** @var \Cube\Navigation\Page\AbstractPage $page */        foreach ($iterator as $page) {            if ($page->isActive()) {                return $page;            }        }        return null;    }    /**     *     * checks if a page is accepted in the iteration     * the method is to be called from the navigation view helper     *     * @param \Cube\Navigation\Page\AbstractPage $page     * @param bool                               $recursive default true     *     * @return bool     */    public function accept(AbstractPage $page, $recursive = true)    {        $accept = true;        if (!$this->_acceptAcl($page)) {            $accept = false;        }        if ($accept && $recursive) {            $parent = $page->getParent();            if ($parent instanceof AbstractPage) {                $accept = $this->accept($parent, true);            }        }        return $accept;    }    /**     *     * check if a page is allowed by ACL     *     * rules:     * - helper has no ACL, page is accepted     * - page has a resource or privilege defined:     *   => the ACL allows access to it using the helper's role,     *   => [OBSOLETE] the ACL doesn't have the resource called in the page     *   => if the resource isn't in the ACL - page isn't accepted     *     * - if page has no resource or privilege, page is accepted     *     * @param \Cube\Navigation\Page\AbstractPage $page     *     * @return bool     */    protected function _acceptAcl(AbstractPage $page)    {        if (!$acl = $this->getAcl()) {            return true;        }        $role = $this->getRole();        $resource = $page->getResource();        $privilege = $page->getPrivilege();        if ($resource || $privilege) {            if ($acl->hasResource($resource)) {                return $acl->isAllowed($role, $resource, $privilege);            }            return false;        }        return true;    }    /**     *     * get active page breadcrumbs array     *     * @return array     */    public function getBreadcrumbs()    {        $breadcrumbs = array();        $depth = 0;        $page = $this->findActive();        if ($page instanceof AbstractPage) {            array_push($breadcrumbs, $page);            while (($parent = $page->getParent()) instanceof AbstractPage) {                array_push($breadcrumbs, $parent);                $page = $parent;            }            $breadcrumbs = array_reverse($breadcrumbs);            foreach ($breadcrumbs as $key => $page) {                if ($depth < $this->_minDepth ||                    ($depth > $this->_maxDepth && $this->_maxDepth > 0)                ) {                    unset($breadcrumbs[$key]);                }                $depth++;            }        }        return $breadcrumbs;    }    /**     *     * create a breadcrumbs helper by getting the active page from the navigation container     * and applying it to a breadcrumbs view partial     * if no active page is found, return an empty display output     *     * @return string|null     */    public function breadcrumbs()    {        $breadcrumbs = $this->getBreadcrumbs();        if (count($breadcrumbs) > 0) {            $view = $this->getView();            $view->set('breadcrumbs', $breadcrumbs);            return $view->process(                $this->getPartial(), true);        }        return null;    }}
 |