/** * Traverse the config object * * @param array $tree * @param int $depth * @param string $parentHref * @throws Exception * @return \Pop\Dom\Child */ protected function traverse(array $tree, $depth = 1, $parentHref = null) { // Create overriding top level parent, if set if ($depth == 1 && isset($this->config['top'])) { $parent = isset($this->config['top']) && isset($this->config['top']['node']) ? $this->config['top']['node'] : 'ul'; $child = null; if (isset($this->config['child']) && isset($this->config['child']['node'])) { $child = $this->config['child']['node']; } else { if ($parent == 'ul') { $child = 'li'; } } // Create parent node $nav = new Child($parent); // Set top attributes if they exist if (isset($this->config['top']) && isset($this->config['top']['id'])) { $nav->setAttributes('id', $this->config['top']['id']); } if (isset($this->config['top']) && isset($this->config['top']['class'])) { $nav->setAttributes('class', $this->config['top']['class']); } if (isset($this->config['top']['attributes'])) { foreach ($this->config['top']['attributes'] as $attrib => $value) { $nav->setAttributes($attrib, $value); } } } else { // Set up parent/child node names $parent = isset($this->config['parent']) && isset($this->config['parent']['node']) ? $this->config['parent']['node'] : 'ul'; $child = null; if (isset($this->config['child']) && isset($this->config['child']['node'])) { $child = $this->config['child']['node']; } else { if ($parent == 'ul') { $child = 'li'; } } // Create parent node $nav = new Child($parent); // Set parent attributes if they exist if (isset($this->config['parent']) && isset($this->config['parent']['id'])) { $nav->setAttributes('id', $this->config['parent']['id'] . '-' . $this->parentLevel); } if (isset($this->config['parent']) && isset($this->config['parent']['class'])) { $nav->setAttributes('class', $this->config['parent']['class'] . '-' . $depth); } if (isset($this->config['parent']['attributes'])) { foreach ($this->config['parent']['attributes'] as $attrib => $value) { $nav->setAttributes($attrib, $value); } } } $this->parentLevel++; $depth++; // Recursively loop through the nodes foreach ($tree as $node) { $allowed = true; if (isset($node['acl'])) { if (null === $this->acl) { throw new Exception('The access control object is not set.'); } if (null === $this->role) { throw new Exception('The current role is not set.'); } $resource = isset($node['acl']['resource']) ? $node['acl']['resource'] : null; $permission = isset($node['acl']['permission']) ? $node['acl']['permission'] : null; $allowed = $this->acl->isAllowed($this->role, $resource, $permission); } if ($allowed && isset($node['name']) && isset($node['href'])) { // Create child node and child link node $a = new Child('a', $node['name']); if (substr($node['href'], 0, 1) == '/' || substr($node['href'], 0, 1) == '#' || substr($node['href'], -1) == '#' || substr($node['href'], 0, 4) == 'http') { $href = $node['href']; } else { if (substr($parentHref, -1) == '/') { $href = $parentHref . $node['href']; } else { $href = $parentHref . '/' . $node['href']; } } $a->setAttributes('href', $href); if ($this->returnFalse && ($href == '#' || substr($href, -1) == '#')) { $a->setAttributes('onclick', 'return false;'); } $url = $_SERVER['REQUEST_URI']; if (strpos($url, '?') !== false) { $url = substr($url, strpos($url, '?')); } $linkClass = null; if ($href == $url) { if (isset($this->config['on'])) { $linkClass = $this->config['on']; } } else { if (isset($this->config['off'])) { $linkClass = $this->config['off']; } } // If the node has any attributes if (isset($node['attributes'])) { foreach ($node['attributes'] as $attrib => $value) { $value = $attrib == 'class' && null !== $linkClass ? $value . ' ' . $linkClass : $value; $a->setAttributes($attrib, $value); } } else { if (null !== $linkClass) { $a->setAttributes('class', $linkClass); } } if (null !== $child) { $navChild = new Child($child); // Set child attributes if they exist if (isset($this->config['child']) && isset($this->config['child']['id'])) { $navChild->setAttributes('id', $this->config['child']['id'] . '-' . $this->childLevel); } if (isset($this->config['child']) && isset($this->config['child']['class'])) { $navChild->setAttributes('class', $this->config['child']['class'] . '-' . ($depth - 1)); } if (isset($this->config['child']['attributes'])) { foreach ($this->config['child']['attributes'] as $attrib => $value) { $navChild->setAttributes($attrib, $value); } } // Add link node $navChild->addChild($a); $this->childLevel++; // If there are children, loop through and add them if (isset($node['children']) && is_array($node['children']) && count($node['children']) > 0) { $childrenAllowed = true; // Check if the children are allowed if (isset($node['acl'])) { $i = 0; foreach ($node['children'] as $nodeChild) { if (null === $this->acl) { throw new Exception('The access control object is not set.'); } if (null === $this->role) { throw new Exception('The current role is not set.'); } $resource = isset($nodeChild['acl']['resource']) ? $nodeChild['acl']['resource'] : null; $permission = isset($nodeChild['acl']['permission']) ? $nodeChild['acl']['permission'] : null; if (!$this->acl->isAllowed($this->role, $resource, $permission)) { $i++; } } if ($i == count($node['children'])) { $childrenAllowed = false; } } if ($childrenAllowed) { $navChild->addChild($this->traverse($node['children'], $depth, $href)); } } // Add child node $nav->addChild($navChild); } else { $nav->addChild($a); } } } return $nav; }
<?php require_once '../../bootstrap.php'; use Pop\Auth\Acl; use Pop\Auth\Role; use Pop\Auth\Resource; try { // Create some resources $page = new Resource('page'); $template = new Resource('template'); // Create some roles with permissions $reader = Role::factory('reader')->addPermission('read'); $editor = Role::factory('editor')->addPermission('edit'); $publisher = Role::factory('publisher')->addPermission('publish'); $admin = Role::factory('admin')->addPermission('admin'); // Add roles as child roles to demonstrate inheritance $reader->addChild($editor->addChild($publisher->addChild($admin))); $acl = new Acl(); $acl->addRoles(array($reader, $editor, $publisher, $admin)); $acl->addResources(array($page, $template)); $acl->allow('reader', 'page', 'read')->allow('editor', 'page', array('read', 'edit'))->allow('publisher', 'page')->allow('publisher', 'template', 'read')->allow('admin'); $acl->deny('editor', 'page', 'read'); $user = $editor; if ($acl->isAllowed($user, 'page', 'edit')) { echo 'Yes.<br /><br />'; } else { echo 'No.<br /><br />'; } } catch (\Exception $e) { echo $e->getMessage() . PHP_EOL . PHP_EOL; }