Instantly share code, notes, and snippets.
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save olekhy/c47d975cc067bef87b57 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Application\View\Helper; | |
use RuntimeException; | |
use SpiffyNavigation\Page\Page; | |
use SpiffyNavigation\View\Helper\AbstractHelper; | |
class Breadcrumbs extends AbstractHelper | |
{ | |
/** | |
* An array of valid HTML5 attributes. | |
* @var array | |
*/ | |
protected $validAttribs = array( | |
'class', | |
'href', | |
'id', | |
'rel', | |
'target' | |
); | |
/** | |
* Render default breadcrumbs. | |
* | |
* @param string|\SpiffyNavigation\Container|null $container | |
* @param array $options | |
* @return string | |
*/ | |
public function renderBreadcrumbs($container = null, array $options = array()) | |
{ | |
$isActiveRecursion = $this->navigation->getIsActiveRecursion(); | |
$this->navigation->setIsActiveRecursion(false); | |
$breadcrumbs = $this->getBreadcrumbs($container); | |
$html = '<ol class="breadcrumb">'; | |
/** @var Page $page */ | |
foreach ($breadcrumbs as $page) { | |
if (!$this->navigation->isAllowed($page)) { | |
continue; | |
} | |
$activeClass = $this->navigation->isActive($page) ? ' class="active"' : ''; | |
$html .= sprintf('<li%s>', $activeClass); | |
$html .= $this->htmlify($page); | |
$html .= '</li>'; | |
} | |
$html .= '</ol>'; | |
$this->navigation->setIsActiveRecursion($isActiveRecursion); | |
return $html; | |
} | |
/** | |
* Renders the given $container by invoking the partial view helper | |
* | |
* The container will simply be passed on as a model to the view script | |
* as-is, and will be available in the partial script as 'container', e.g. | |
* <code>echo 'Number of pages: ', count($this->container);</code>. | |
* | |
* @param string|\SpiffyNavigation\Container|null $container [optional] container to pass to view script. | |
* @param string $partial [optional] partial view script to use. | |
* @return string | |
* @throws RuntimeException if no partial provided | |
*/ | |
public function renderPartial($container = null, $partial = null) | |
{ | |
$isActiveRecursion = $this->navigation->getIsActiveRecursion(); | |
$this->navigation->setIsActiveRecursion(false); | |
$container = $this->getContainer($container); | |
if (null === $partial) { | |
$partial = $this->getPartial(); | |
} | |
if (empty($partial)) { | |
throw new RuntimeException( | |
'Unable to render menu: No partial view script provided' | |
); | |
} | |
$model = array( | |
'breadcrumbs' => $this->getBreadcrumbs($container), | |
'navigation' => $this->navigation, | |
); | |
$html = $this->view->render($partial, $model); | |
$this->navigation->setIsActiveRecursion($isActiveRecursion); | |
return $html; | |
} | |
/** | |
* Default render. | |
* | |
* @param string|\SpiffyNavigation\Container|null $container | |
* @return string | |
*/ | |
public function render($container = null) | |
{ | |
$container = $this->getContainer($container); | |
if ($this->getPartial()) { | |
return $this->renderPartial($container); | |
} | |
return $this->renderBreadcrumbs($container); | |
} | |
/** | |
* @param \SpiffyNavigation\Container|string|null $container | |
* | |
* @return array | |
* @throws \RuntimeException | |
*/ | |
protected function getBreadcrumbs($container) | |
{ | |
$container = $this->getContainer($container); | |
$routeName = $this->getCurrentRouteName(); | |
$pages = $container->findByOption('route', $routeName); | |
if (!$pages) { | |
return []; | |
} | |
/** @var Page $page */ | |
$page = array_pop($pages); | |
$breadcrumbs = [$page]; | |
while ($page->hasParent()) { | |
$page = $page->getParent(); | |
array_unshift($breadcrumbs, $page); | |
}; | |
return $breadcrumbs; | |
} | |
/** | |
* @return string | |
* @throws \RuntimeException | |
*/ | |
protected function getCurrentRouteName() | |
{ | |
$routeMatch = $this->navigation->getRouteMatch(); | |
if ($routeMatch === null) { | |
throw new RuntimeException('No RouteMatch instance provided'); | |
} | |
$name = $routeMatch->getMatchedRouteName(); | |
if ($name === null) { | |
throw new RuntimeException('RouteMatch does not contain a matched route name'); | |
} | |
return $name; | |
} | |
/** | |
* Convert a page to the html version. | |
* | |
* @param Page $page | |
* @return string | |
*/ | |
protected function htmlify(Page $page) | |
{ | |
if ($page->getOption('label')) { | |
$label = $page->getOption('label'); | |
} else { | |
$label = $page->getName(); | |
} | |
$href = null; | |
try { | |
$href = $this->navigation->getHref($page); | |
} catch (RuntimeException $e) { | |
; // intentionally left blank | |
} | |
$attribs = $page->getAttributes(); | |
if ($href) { | |
$element = 'a'; | |
$attribs['href'] = $href; | |
} else { | |
$element = 'span'; | |
} | |
return sprintf('<%s%s>%s</%s>', $element, $this->htmlAttribs($attribs), $label, $element); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment