Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- /**
- * file : /library/App/View/Helper/Navigation/Menu
- */
- class App_View_Helper_Navigation_Menu extends Zend_View_Helper_Navigation_Menu
- {
- protected $_renderParentSiblings = false;
- /**
- * Returns flag indicating whether parent's siblings should be rendered when rendering
- * only the active branch
- *
- * By default, this value is false.
- *
- * @return bool whether parent's siblings should be rendered
- */
- public function getRenderParentSiblings()
- {
- return $this->_renderParentSiblings;
- }
- /**
- * Enables/disables rendering of parent's siblings when only rendering active branch
- *
- * See {@link setOnlyActiveBranch()} for more information.
- *
- * @param bool $flag [optional] render parent's siblings when
- * rendering active branch.
- * Default is false.
- * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self
- */
- public function setRenderParents($flag = false)
- {
- $this->_renderParentSiblings = (bool) $flag;
- return $this;
- }
- /**
- * Normalizes given render options
- *
- * @param array $options [optional] options to normalize
- * @return array normalized options
- */
- protected function _normalizeOptions(array $options = array())
- {
- $options = parent::_normalizeOptions($options);
- if (!isset($options['renderParentSiblings'])) {
- $options['renderParentSiblings'] = $this->getRenderParentSiblings();
- }
- return $options;
- }
- /**
- * Renders helper
- *
- * Renders a HTML 'ul' for the given $container. If $container is not given,
- * the container registered in the helper will be used.
- *
- * Available $options:
- *
- *
- * @param Zend_Navigation_Container $container [optional] container to
- * create menu from. Default
- * is to use the container
- * retrieved from
- * {@link getContainer()}.
- * @param array $options [optional] options for
- * controlling rendering
- * @return string rendered menu
- */
- public function renderMenu(Zend_Navigation_Container $container = null,
- array $options = array())
- {
- if (null === $container) {
- $container = $this->getContainer();
- }
- $options = $this->_normalizeOptions($options);
- if($options['renderParentSiblings']) {
- $html = $this->_renderMenuWithParentSiblings($container,
- $options['ulClass'],
- $options['indent'],
- $options['minDepth'],
- $options['maxDepth'],
- $options['onlyActiveBranch'],
- $options['renderParentSiblings']);
- } else if ($options['onlyActiveBranch'] && !$options['renderParents']) {
- $html = $this->_renderDeepestMenu($container,
- $options['ulClass'],
- $options['indent'],
- $options['minDepth'],
- $options['maxDepth']);
- } else {
- $html = $this->_renderMenu($container,
- $options['ulClass'],
- $options['indent'],
- $options['minDepth'],
- $options['maxDepth'],
- $options['onlyActiveBranch']);
- }
- return $html;
- }
- /**
- * Renders a menu with all the siblings
- *
- * @param Zend_Navigation_Container $container container to render
- * @param string $ulClass CSS class for first UL
- * @param string $indent initial indentation
- * @param int|null $minDepth minimum depth
- * @param int|null $maxDepth maximum depth
- * @param bool $onlyActive render only active branch?
- * @param bool $renderParentSiblings render all parent siblings
- * @return string
- */
- protected function _renderMenuWithParentSiblings(Zend_Navigation_Container $container,
- $ulClass,
- $indent,
- $minDepth,
- $maxDepth,
- $onlyActive,
- $renderParentSiblings)
- {
- $html = '';
- // find deepest active
- if ($found = $this->findActive($container, $minDepth, $maxDepth)) {
- $foundPage = $found['page'];
- $foundDepth = $found['depth'];
- } else {
- $foundPage = null;
- }
- // create iterator
- $iterator = new RecursiveIteratorIterator($container,
- RecursiveIteratorIterator::SELF_FIRST);
- if (is_int($maxDepth)) {
- $iterator->setMaxDepth($maxDepth);
- }
- // iterate container
- $prevDepth = -1;
- $siblings = array();
- if($foundPage) {
- foreach ($iterator as $page) {
- $depth = $iterator->getDepth();
- if($depth >= $minDepth) {
- if($page->hasPage($foundPage, true) || $page == $foundPage) {
- if(!is_null($page->getParent())) {
- foreach ($page->getParent()->getPages() as $sibling) {
- $siblings[] = $sibling;
- }
- }
- }
- }
- }
- }
- foreach ($iterator as $page) {
- $depth = $iterator->getDepth();
- /* @var $page Zend_Navigation_Page */
- $isActive = $page->isActive(true);
- if(in_array($page, $siblings) && $this->accept($page, true) && $depth >= $minDepth) {
- $accept = true;
- } else if ($depth < $minDepth || !$this->accept($page, true)) {
- // page is below minDepth or not accepted by acl/visibilty
- continue;
- } else if ($onlyActive && !$isActive) {
- // page is not active itself, but might be in the active branch
- $accept = false;
- if ($foundPage) {
- if ($foundPage->hasPage($page)) {
- // accept if page is a direct child of the active page
- $accept = true;
- } else if (!is_null($foundPage->getParent()) && $foundPage->getParent()->hasPage($page)) {
- // page is a sibling of the active page...
- if (!$foundPage->hasPages() ||
- is_int($maxDepth) && $foundDepth + 1 > $maxDepth) {
- // accept if active page has no children, or the
- // children are too deep to be rendered
- $accept = true;
- }
- }
- }
- if (!$accept) {
- continue;
- }
- }
- // make sure indentation is correct
- $depth -= $minDepth;
- $myIndent = $indent . str_repeat(' ', $depth);
- if ($depth > $prevDepth) {
- // start new ul tag
- if ($ulClass && $depth == 0) {
- $ulClass = ' class="' . $ulClass . '"';
- } else {
- $ulClass = '';
- }
- $html .= $myIndent . '<ul' . $ulClass . '>' . self::EOL;
- } else if ($prevDepth > $depth) {
- // close li/ul tags until we're at current depth
- for ($i = $prevDepth; $i > $depth; $i--) {
- $ind = $indent . str_repeat(' ', $i);
- $html .= $ind . ' </li>' . self::EOL;
- $html .= $ind . '</ul>' . self::EOL;
- }
- // close previous li tag
- $html .= $myIndent . ' </li>' . self::EOL;
- } else {
- // close previous li tag
- $html .= $myIndent . ' </li>' . self::EOL;
- }
- // render li tag and page
- $liClass = $isActive ? ' class="active"' : '';
- $html .= $myIndent . ' <li' . $liClass . '>' . self::EOL
- . $myIndent . ' ' . $this->htmlify($page) . self::EOL;
- // store as previous depth for next iteration
- $prevDepth = $depth;
- }
- if ($html) {
- // done iterating container; close open ul/li tags
- for ($i = $prevDepth+1; $i > 0; $i--) {
- $myIndent = $indent . str_repeat(' ', $i-1);
- $html .= $myIndent . ' </li>' . self::EOL
- . $myIndent . '</ul>' . self::EOL;
- }
- $html = rtrim($html, self::EOL);
- }
- return $html;
- }
- /**
- * OVERLOAD - invisible pages should be found back !!
- *
- * Finds the deepest active page in the given container
- *
- * @param Zend_Navigation_Container $container container to search
- * @param int|null $minDepth [optional] minimum depth
- * required for page to be
- * valid. Default is to use
- * {@link getMinDepth()}. A
- * null value means no minimum
- * depth required.
- * @param int|null $minDepth [optional] maximum depth
- * a page can have to be
- * valid. Default is to use
- * {@link getMaxDepth()}. A
- * null value means no maximum
- * depth required.
- * @return array an associative array with
- * the values 'depth' and
- * 'page', or an empty array
- * if not found
- */
- public function findActive(Zend_Navigation_Container $container,
- $minDepth = null,
- $maxDepth = -1)
- {
- if (!is_int($minDepth)) {
- $minDepth = $this->getMinDepth();
- }
- if ((!is_int($maxDepth) || $maxDepth < 0) && null !== $maxDepth) {
- $maxDepth = $this->getMaxDepth();
- }
- $found = null;
- $foundDepth = -1;
- $iterator = new RecursiveIteratorIterator($container,
- RecursiveIteratorIterator::CHILD_FIRST);
- foreach ($iterator as $page) {
- $currDepth = $iterator->getDepth();
- // if ($currDepth < $minDepth || !$this->accept($page)) {
- // hidden pages should be found
- if ($currDepth < $minDepth) {
- // page is not accepted
- continue;
- }
- if ($page->isActive(false) && $currDepth > $foundDepth) {
- // found an active page at a deeper level than before
- $found = $page;
- $foundDepth = $currDepth;
- }
- }
- if (is_int($maxDepth) && $foundDepth > $maxDepth) {
- while ($foundDepth > $maxDepth) {
- if (--$foundDepth < $minDepth) {
- $found = null;
- break;
- }
- $found = $found->getParent();
- if (!$found instanceof Zend_Navigation_Page) {
- $found = null;
- break;
- }
- }
- }
- if ($found) {
- return array('page' => $found, 'depth' => $foundDepth);
- } else {
- return array();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement