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;
- }
- }
|