mirror of
				https://github.com/Icinga/icingaweb2.git
				synced 2025-10-31 03:14:31 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			381 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			381 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /* Icinga Web 2 | (c) 2015 Icinga Development Team | GPLv2+ */
 | |
| 
 | |
| namespace Icinga\Web\Navigation\Renderer;
 | |
| 
 | |
| use ArrayIterator;
 | |
| use Exception;
 | |
| use RecursiveIterator;
 | |
| use Icinga\Application\Icinga;
 | |
| use Icinga\Exception\IcingaException;
 | |
| use Icinga\Web\Navigation\Navigation;
 | |
| use Icinga\Web\Navigation\NavigationItem;
 | |
| use Icinga\Web\View;
 | |
| 
 | |
| /**
 | |
|  * Renderer for single level navigation
 | |
|  */
 | |
| class NavigationRenderer implements RecursiveIterator, NavigationRendererInterface
 | |
| {
 | |
|     /**
 | |
|      * The tag used for the outer element
 | |
|      *
 | |
|      * @var string
 | |
|      */
 | |
|     protected $elementTag;
 | |
| 
 | |
|     /**
 | |
|      * The CSS class used for the outer element
 | |
|      *
 | |
|      * @var string
 | |
|      */
 | |
|     protected $cssClass;
 | |
| 
 | |
|     /**
 | |
|      * The navigation's heading text
 | |
|      *
 | |
|      * @var string
 | |
|      */
 | |
|     protected $heading;
 | |
| 
 | |
|     /**
 | |
|      * The content rendered so far
 | |
|      *
 | |
|      * @var array
 | |
|      */
 | |
|     protected $content;
 | |
| 
 | |
|     /**
 | |
|      * Whether to skip rendering the outer element
 | |
|      *
 | |
|      * @var bool
 | |
|      */
 | |
|     protected $skipOuterElement;
 | |
| 
 | |
|     /**
 | |
|      * The navigation's iterator
 | |
|      *
 | |
|      * @var ArrayIterator
 | |
|      */
 | |
|     protected $iterator;
 | |
| 
 | |
|     /**
 | |
|      * The navigation
 | |
|      *
 | |
|      * @var Navigation
 | |
|      */
 | |
|     protected $navigation;
 | |
| 
 | |
|     /**
 | |
|      * View
 | |
|      *
 | |
|      * @var View
 | |
|      */
 | |
|     protected $view;
 | |
| 
 | |
|     /**
 | |
|      * Create a new NavigationRenderer
 | |
|      *
 | |
|      * @param   Navigation  $navigation
 | |
|      * @param   bool        $skipOuterElement
 | |
|      */
 | |
|     public function __construct(Navigation $navigation, $skipOuterElement = false)
 | |
|     {
 | |
|         $this->skipOuterElement = $skipOuterElement;
 | |
|         $this->iterator = $navigation->getIterator();
 | |
|         $this->navigation = $navigation;
 | |
|         $this->content = array();
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * {@inheritdoc}
 | |
|      */
 | |
|     public function setElementTag($tag)
 | |
|     {
 | |
|         $this->elementTag = $tag;
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * {@inheritdoc}
 | |
|      */
 | |
|     public function getElementTag()
 | |
|     {
 | |
|         return $this->elementTag ?: static::OUTER_ELEMENT_TAG;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * {@inheritdoc}
 | |
|      */
 | |
|     public function setCssClass($class)
 | |
|     {
 | |
|         $this->cssClass = $class;
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * {@inheritdoc}
 | |
|      */
 | |
|     public function getCssClass()
 | |
|     {
 | |
|         return $this->cssClass;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * {@inheritdoc}
 | |
|      */
 | |
|     public function setHeading($heading)
 | |
|     {
 | |
|         $this->heading = $heading;
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * {@inheritdoc}
 | |
|      */
 | |
|     public function getHeading()
 | |
|     {
 | |
|         return $this->heading;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Return the view
 | |
|      *
 | |
|      * @return View
 | |
|      */
 | |
|     public function view()
 | |
|     {
 | |
|         if ($this->view === null) {
 | |
|             $this->setView(Icinga::app()->getViewRenderer()->view);
 | |
|         }
 | |
| 
 | |
|         return $this->view;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Set the view
 | |
|      *
 | |
|      * @param   View    $view
 | |
|      *
 | |
|      * @return  $this
 | |
|      */
 | |
|     public function setView(View $view)
 | |
|     {
 | |
|         $this->view = $view;
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * {@inheritdoc}
 | |
|      */
 | |
|     public function getChildren()
 | |
|     {
 | |
|         return new static($this->current()->getChildren(), $this->skipOuterElement);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * {@inheritdoc}
 | |
|      */
 | |
|     public function hasChildren()
 | |
|     {
 | |
|         return $this->current()->hasChildren();
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * {@inheritdoc}
 | |
|      *
 | |
|      * @return  NavigationItem
 | |
|      */
 | |
|     public function current()
 | |
|     {
 | |
|         return $this->iterator->current();
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * {@inheritdoc}
 | |
|      */
 | |
|     public function key()
 | |
|     {
 | |
|         return $this->iterator->key();
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * {@inheritdoc}
 | |
|      */
 | |
|     public function next()
 | |
|     {
 | |
|         $this->iterator->next();
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * {@inheritdoc}
 | |
|      */
 | |
|     public function rewind()
 | |
|     {
 | |
|         $this->iterator->rewind();
 | |
|         if (! $this->skipOuterElement) {
 | |
|             $this->content[] = $this->beginMarkup();
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * {@inheritdoc}
 | |
|      */
 | |
|     public function valid()
 | |
|     {
 | |
|         $valid = $this->iterator->valid();
 | |
|         if (! $this->skipOuterElement && !$valid) {
 | |
|             $this->content[] = $this->endMarkup();
 | |
|         }
 | |
| 
 | |
|         return $valid;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Return the opening markup for the navigation
 | |
|      *
 | |
|      * @return  string
 | |
|      */
 | |
|     public function beginMarkup()
 | |
|     {
 | |
|         $content = array();
 | |
|         $content[] = sprintf(
 | |
|             '<%s%s role="navigation">',
 | |
|             $this->getElementTag(),
 | |
|             $this->getCssClass() !== null ? ' class="' . $this->getCssClass() . '"' : ''
 | |
|         );
 | |
|         if (($heading = $this->getHeading()) !== null) {
 | |
|             $content[] = sprintf(
 | |
|                 '<h%1$d id="navigation" class="sr-only" tabindex="-1">%2$s</h%1$d>',
 | |
|                 static::HEADING_RANK,
 | |
|                 $this->view()->escape($heading)
 | |
|             );
 | |
|         }
 | |
|         $content[] = $this->beginChildrenMarkup();
 | |
|         return join("\n", $content);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Return the closing markup for the navigation
 | |
|      *
 | |
|      * @return  string
 | |
|      */
 | |
|     public function endMarkup()
 | |
|     {
 | |
|         $content = array();
 | |
|         $content[] = $this->endChildrenMarkup();
 | |
|         $content[] = '</' . $this->getElementTag() . '>';
 | |
|         return join("\n", $content);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Return the opening markup for multiple navigation items
 | |
|      *
 | |
|      * @param   int $level
 | |
|      *
 | |
|      * @return  string
 | |
|      */
 | |
|     public function beginChildrenMarkup($level = 1)
 | |
|     {
 | |
|         $cssClass = array(static::CSS_CLASS_NAV);
 | |
|         if ($this->navigation->getLayout() === Navigation::LAYOUT_TABS) {
 | |
|             $cssClass[] = static::CSS_CLASS_NAV_TABS;
 | |
|         } elseif ($this->navigation->getLayout() === Navigation::LAYOUT_DROPDOWN) {
 | |
|             $cssClass[] = static::CSS_CLASS_NAV_DROPDOWN;
 | |
|         }
 | |
| 
 | |
|         $cssClass[] = 'nav-level-' . $level;
 | |
| 
 | |
|         return '<ul class="' . join(' ', $cssClass) . '">';
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Return the closing markup for multiple navigation items
 | |
|      *
 | |
|      * @return  string
 | |
|      */
 | |
|     public function endChildrenMarkup()
 | |
|     {
 | |
|         return '</ul>';
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Return the opening markup for the given navigation item
 | |
|      *
 | |
|      * @param   NavigationItem  $item
 | |
|      *
 | |
|      * @return  string
 | |
|      */
 | |
|     public function beginItemMarkup(NavigationItem $item)
 | |
|     {
 | |
|         $cssClasses = array(static::CSS_CLASS_ITEM);
 | |
| 
 | |
|         if ($item->hasChildren() && $item->getChildren()->getLayout() === Navigation::LAYOUT_DROPDOWN) {
 | |
|             $cssClasses[] = static::CSS_CLASS_DROPDOWN;
 | |
|             $item
 | |
|                 ->setAttribute('class', static::CSS_CLASS_DROPDOWN_TOGGLE)
 | |
|                 ->setIcon(static::DROPDOWN_TOGGLE_ICON)
 | |
|                 ->setUrl('#');
 | |
|         }
 | |
| 
 | |
|         if ($item->getActive()) {
 | |
|             $cssClasses[] = static::CSS_CLASS_ACTIVE;
 | |
|         }
 | |
| 
 | |
|         if ($item->getIcon() === null) {
 | |
|             // @TODO(el): Add constant
 | |
|             $cssClasses[] = 'no-icon';
 | |
|         }
 | |
| 
 | |
|         if ($cssClass = $item->getCssClass()) {
 | |
|             $cssClasses[] = $cssClass;
 | |
|         }
 | |
| 
 | |
|         $content = sprintf(
 | |
|             '<li class="%s">',
 | |
|             join(' ', $cssClasses)
 | |
|         );
 | |
|         return $content;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Return the closing markup for a navigation item
 | |
|      *
 | |
|      * @return  string
 | |
|      */
 | |
|     public function endItemMarkup()
 | |
|     {
 | |
|         return '</li>';
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * {@inheritdoc}
 | |
|      */
 | |
|     public function render()
 | |
|     {
 | |
|         foreach ($this as $item) {
 | |
|             /** @var NavigationItem $item */
 | |
|             if ($item->shouldRender()) {
 | |
|                 $content = $item->render();
 | |
|                 $this->content[] = $this->beginItemMarkup($item);
 | |
|                 $this->content[] = $content;
 | |
|                 $this->content[] = $this->endItemMarkup();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         return join("\n", $this->content);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * {@inheritdoc}
 | |
|      */
 | |
|     public function __toString()
 | |
|     {
 | |
|         try {
 | |
|             return $this->render();
 | |
|         } catch (Exception $e) {
 | |
|             return IcingaException::describe($e);
 | |
|         }
 | |
|     }
 | |
| }
 |