| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- <?php
- /**
- * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
- * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
- *
- * Licensed under The MIT License
- * For full copyright and license information, please see the LICENSE.txt
- * Redistributions of files must retain the above copyright notice.
- *
- * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
- * @link http://cakephp.org CakePHP(tm) Project
- * @since 3.3.6
- * @license http://www.opensource.org/licenses/mit-license.php MIT License
- */
- namespace Cake\View\Helper;
- use Cake\View\Helper;
- use Cake\View\StringTemplateTrait;
- use LogicException;
- /**
- * BreadcrumbsHelper to register and display a breadcrumb trail for your views
- *
- * @property \Cake\View\Helper\UrlHelper $Url
- */
- class BreadcrumbsHelper extends Helper
- {
- use StringTemplateTrait;
- /**
- * Other helpers used by BreadcrumbsHelper
- *
- * @var array
- */
- public $helpers = ['Url'];
- /**
- * Default config for the helper.
- *
- * @var array
- */
- protected $_defaultConfig = [
- 'templates' => [
- 'wrapper' => '<ul{{attrs}}>{{content}}</ul>',
- 'item' => '<li{{attrs}}><a href="{{link}}"{{innerAttrs}}>{{title}}</a></li>{{separator}}',
- 'itemWithoutLink' => '<li{{attrs}}><span{{innerAttrs}}>{{title}}</span></li>{{separator}}',
- 'separator' => '<li{{attrs}}><span{{innerAttrs}}>{{custom}}{{separator}}</span></li>'
- ]
- ];
- /**
- * The crumbs list.
- *
- * @var array
- */
- protected $crumbs = [];
- /**
- * Add a crumb to the trail.
- *
- * @param string $title Title of the crumb
- * @param string|array|null $link Link of the crumb. Either a string, an array of route params to pass to
- * Url::build() or null / empty if the crumb does not have a link
- * @param array $options Array of options
- * @return $this
- */
- public function add($title, $link = null, array $options = [])
- {
- $this->crumbs[] = ['title' => $title, 'link' => $link, 'options' => $options];
- return $this;
- }
- /**
- * Prepend a crumb to the start of the queue.
- *
- * @param string $title Title of the crumb
- * @param string|array|null $link Link of the crumb. Either a string, an array of route params to pass to
- * Url::build() or null / empty if the crumb does not have a link
- * @param array $options Array of options
- * @return $this
- */
- public function prepend($title, $link = null, array $options = [])
- {
- array_unshift($this->crumbs, ['title' => $title, 'link' => $link, 'options' => $options]);
- return $this;
- }
- /**
- * Insert a crumb at a specific index.
- *
- * If the index already exists, the new crumb will be inserted,
- * and the existing element will be shifted one index greater.
- *
- * @param int $index The index to insert at.
- * @param string $title Title of the crumb
- * @param string|array|null $link Link of the crumb. Either a string, an array of route params to pass to
- * Url::build() or null / empty if the crumb does not have a link
- * @param array $options Array of options
- * @return $this
- */
- public function insertAt($index, $title, $link = null, array $options = [])
- {
- array_splice($this->crumbs, $index, 0, [['title' => $title, 'link' => $link, 'options' => $options]]);
- return $this;
- }
- /**
- * Insert a crumb before the first matching crumb with the specified title.
- *
- * Finds the index of the first middleware that matches the provided class,
- * and inserts the supplied callable before it.
- *
- * @param string $matchingTitle The title of the crumb you want to insert this one before
- * @param string $title Title of the crumb
- * @param string|array|null $link Link of the crumb. Either a string, an array of route params to pass to
- * Url::build() or null / empty if the crumb does not have a link
- * @param array $options Array of options
- * @return $this
- */
- public function insertBefore($matchingTitle, $title, $link = null, array $options = [])
- {
- $key = $this->findCrumb($matchingTitle);
- if ($key !== null) {
- return $this->insertAt($key, $title, $link, $options);
- }
- throw new LogicException(sprintf("No crumb matching '%s' could be found.", $matchingTitle));
- }
- /**
- * Insert a crumb after the first matching crumb with the specified title.
- *
- * Finds the index of the first middleware that matches the provided class,
- * and inserts the supplied callable before it.
- *
- * @param string $matchingTitle The title of the crumb you want to insert this one after
- * @param string $title Title of the crumb
- * @param string|array|null $link Link of the crumb. Either a string, an array of route params to pass to
- * Url::build() or null / empty if the crumb does not have a link
- * @param array $options Array of options
- * @return $this
- */
- public function insertAfter($matchingTitle, $title, $link = null, array $options = [])
- {
- $key = $this->findCrumb($matchingTitle);
- if ($key !== null) {
- return $this->insertAt($key + 1, $title, $link, $options);
- }
- throw new LogicException(sprintf("No crumb matching '%s' could be found.", $matchingTitle));
- }
- /**
- * Returns the crumbs list
- *
- * @return array
- */
- public function getCrumbs()
- {
- return $this->crumbs;
- }
- /**
- * Renders the breadcrumbs trail
- *
- * @param array $attributes Array of attributes applied to the wrapper element
- * @param array $separator Array of attributes for the `separator` template
- * @return string The breadcrumbs trail
- */
- public function render(array $attributes = [], array $separator = [])
- {
- $crumbs = $this->crumbs;
- $crumbsCount = count($crumbs);
- $templater = $this->templater();
- $separatorParams = [];
- if ($separator) {
- if (isset($separator['innerAttrs'])) {
- $separatorParams['innerAttrs'] = $templater->formatAttributes($separator['innerAttrs']);
- unset($separator['innerAttrs']);
- }
- if (isset($separator['separator'])) {
- $separatorParams['separator'] = $separator['separator'];
- unset($separator['separator']);
- }
- if (isset($separator['templateVars'])) {
- $separatorParams['templateVars'] = $separator['templateVars'];
- unset($separator['templateVars']);
- }
- $separatorParams['attrs'] = $templater->formatAttributes($separator);
- }
- $crumbTrail = '';
- foreach ($crumbs as $key => $crumb) {
- $link = $this->prepareLink($crumb['link']);
- $title = $crumb['title'];
- $options = $crumb['options'];
- $optionsLink = [];
- if (isset($options['innerAttrs'])) {
- $optionsLink = $options['innerAttrs'];
- unset($options['innerAttrs']);
- }
- $template = 'item';
- $templateParams = [
- 'attrs' => $templater->formatAttributes($options, ['templateVars']),
- 'innerAttrs' => $templater->formatAttributes($optionsLink),
- 'title' => $title,
- 'link' => $link,
- 'separator' => '',
- 'templateVars' => isset($options['templateVars']) ? $options['templateVars'] : []
- ];
- if (!($link)) {
- $template = 'itemWithoutLink';
- }
- if ($separatorParams && $key !== ($crumbsCount - 1)) {
- $templateParams['separator'] = $this->formatTemplate('separator', $separatorParams);
- }
- $crumbTrail .= $this->formatTemplate($template, $templateParams);
- }
- $crumbTrail = $this->formatTemplate('wrapper', [
- 'content' => $crumbTrail,
- 'attrs' => $templater->formatAttributes($attributes, ['templateVars']),
- 'templateVars' => isset($attributes['templateVars']) ? $attributes['templateVars'] : []
- ]);
- return $crumbTrail;
- }
- /**
- * Search a crumb in the current stack which title matches the one provided as argument.
- * If found, the index of the matching crumb will be returned.
- *
- * @param string $title Title to find
- * @return int|null Index of the crumb found, or null if it can not be found
- */
- protected function findCrumb($title)
- {
- foreach ($this->crumbs as $key => $crumb) {
- if ($crumb['title'] === $title) {
- return $key;
- }
- }
- return null;
- }
- /**
- * Prepare the URL for a specific `link` param of a crumb
- *
- * @param array|string|null $link If array, an array of Router url params
- * If string, will be used as is
- * If empty, will consider that there is no link
- *
- * @return null|string The URL of a crumb
- */
- protected function prepareLink($link = null)
- {
- if (!$link) {
- return null;
- }
- return $this->Url->build($link);
- }
- }
|