diff options
Diffstat (limited to 'library/Icinga/Web/Navigation/Renderer/NavigationItemRenderer.php')
-rw-r--r-- | library/Icinga/Web/Navigation/Renderer/NavigationItemRenderer.php | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/library/Icinga/Web/Navigation/Renderer/NavigationItemRenderer.php b/library/Icinga/Web/Navigation/Renderer/NavigationItemRenderer.php new file mode 100644 index 0000000..74de8f6 --- /dev/null +++ b/library/Icinga/Web/Navigation/Renderer/NavigationItemRenderer.php @@ -0,0 +1,233 @@ +<?php +/* Icinga Web 2 | (c) 2015 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Web\Navigation\Renderer; + +use Icinga\Application\Icinga; +use Icinga\Exception\ProgrammingError; +use Icinga\Util\StringHelper; +use Icinga\Web\Navigation\NavigationItem; +use Icinga\Web\Url; +use Icinga\Web\View; + +/** + * NavigationItemRenderer + */ +class NavigationItemRenderer +{ + /** + * View + * + * @var View + */ + protected $view; + + /** + * The item being rendered + * + * @var NavigationItem + */ + protected $item; + + /** + * Internal link targets provided by Icinga Web 2 + * + * @var array + */ + protected $internalLinkTargets; + + /** + * Whether to escape the label + * + * @var bool + */ + protected $escapeLabel; + + /** + * Create a new NavigationItemRenderer + * + * @param array $options + */ + public function __construct(array $options = null) + { + if (! empty($options)) { + $this->setOptions($options); + } + + $this->internalLinkTargets = array('_main', '_self', '_next'); + $this->init(); + } + + /** + * Initialize this renderer + */ + public function init() + { + } + + /** + * Set the given options + * + * @param array $options + * + * @return $this + */ + public function setOptions(array $options) + { + foreach ($options as $name => $value) { + $setter = 'set' . StringHelper::cname($name); + if (method_exists($this, $setter)) { + $this->$setter($value); + } + } + } + + /** + * Set the view + * + * @param View $view + * + * @return $this + */ + public function setView(View $view) + { + $this->view = $view; + return $this; + } + + /** + * Return the view + * + * @return View + */ + public function view() + { + if ($this->view === null) { + $this->setView(Icinga::app()->getViewRenderer()->view); + } + + return $this->view; + } + + /** + * Set the navigation item to render + * + * @param NavigationItem $item + * + * @return $this + */ + public function setItem(NavigationItem $item) + { + $this->item = $item; + return $this; + } + + /** + * Return the navigation item being rendered + * + * @return NavigationItem + */ + public function getItem() + { + return $this->item; + } + + /** + * Set whether to escape the label + * + * @param bool $state + * + * @return $this + */ + public function setEscapeLabel($state = true) + { + $this->escapeLabel = (bool) $state; + return $this; + } + + /** + * Return whether to escape the label + * + * @return bool + */ + public function getEscapeLabel() + { + return $this->escapeLabel !== null ? $this->escapeLabel : true; + } + + /** + * Render the given navigation item as HTML anchor + * + * @param NavigationItem $item + * + * @return string + */ + public function render(NavigationItem $item = null) + { + if ($item !== null) { + $this->setItem($item); + } elseif (($item = $this->getItem()) === null) { + throw new ProgrammingError( + 'Cannot render nothing. Pass the item to render as part' + . ' of the call to render() or set it with setItem()' + ); + } + + $label = $this->getEscapeLabel() + ? $this->view()->escape($item->getLabel()) + : $item->getLabel(); + if (($icon = $item->getIcon()) !== null) { + $label = $this->view()->icon($icon) . $label; + } elseif ($item->getName()) { + $firstLetter = $item->getName()[0]; + $label = $this->view()->icon('letter', null, ['data-letter' => strtolower($firstLetter)]) . $label; + } + + if (($url = $item->getUrl()) !== null) { + $url->overwriteParams($item->getUrlParameters()); + + $target = $item->getTarget(); + if ($url->isExternal() && (!$target || in_array($target, $this->internalLinkTargets, true))) { + $url = Url::fromPath('iframe', array('url' => $url)); + } + + $content = sprintf( + '<a%s href="%s"%s>%s</a>', + $this->view()->propertiesToString($item->getAttributes()), + $this->view()->escape($url->getAbsoluteUrl('&')), + $this->renderTargetAttribute(), + $label + ); + } elseif ($label) { + $content = sprintf( + '<%1$s%2$s>%3$s</%1$s>', + $item::LINK_ALTERNATIVE, + $this->view()->propertiesToString($item->getAttributes()), + $label + ); + } else { + $content = ''; + } + + return $content; + } + + /** + * Render and return the attribute to provide a non-default target for the url + * + * @return string + */ + protected function renderTargetAttribute() + { + $target = $this->getItem()->getTarget(); + if ($target === null || $this->getItem()->getUrl()->getAbsoluteUrl() == '#') { + return ''; + } + + if (! in_array($target, $this->internalLinkTargets, true)) { + return ' target="' . $this->view()->escape($target) . '"'; + } + + return ' data-base-target="' . $target . '"'; + } +} |