Instantly share code, notes, and snippets.
Last active
August 29, 2015 14:06
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(1)
1
You must be signed in to fork a gist
-
Save veewee/9fa72438953a5ad98dbe to your computer and use it in GitHub Desktop.
Spiffy Navigation - Breadcrumbs view helper
This file contains 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