Files
cheese-cake/src/View/Helper/ActiveLinkHelper.php
Brandon Shipley bced090f36
All checks were successful
CI / testsuite (mysql, 8.2, ) (push) Successful in 5m47s
CI / testsuite (pgsql, 8.2, ) (push) Successful in 5m51s
CI / testsuite (sqlite, 8.2, ) (push) Successful in 5m7s
CI / testsuite (mysql, 8.4, ) (push) Successful in 11m31s
CI / testsuite (sqlite, 8.2, prefer-lowest) (push) Successful in 5m13s
CI / testsuite (pgsql, 8.4, ) (push) Successful in 10m46s
CI / testsuite (sqlite, 8.4, ) (push) Successful in 7m40s
CI / Coding Standard & Static Analysis (push) Successful in 3m10s
fix isset
2026-04-11 20:08:46 -07:00

170 lines
4.3 KiB
PHP

<?php
declare(strict_types=1);
namespace CheeseCake\View\Helper;
use Cake\Routing\Router;
use Cake\View\Helper;
/**
* ActiveLink helper
*
* @property \Cake\View\Helper\HtmlHelper $Html
*/
class ActiveLinkHelper extends Helper {
/**
* Default configuration.
*
* @var array<string, mixed>
*/
protected array $_defaultConfig = [
'activeClass' => 'active',
];
/**
* List of helpers used by this helper
*
* @var string[]
*/
protected array $helpers = [
'Html',
'Url',
];
/**
* @param array|string $title
* @param array|string|null $url
* @param array $options
*
* @return string
*/
public function link(array|string $title, array|string|null $url = null, array $options = []): string {
$currentUrl = $options['current'] ?? Router::parseRequest($this->getView()->getRequest());
if (!array_key_exists('target', $options) || !$currentUrl) {
return $this->Html->link($title, $url, $options);
}
$target = $options['target'];
$activeClass = $options['activeClass'] ?? $this->getConfig('activeClass');
unset($options['target']);
unset($options['activeClass']);
if (is_string($target)) {
return $this->_linkFromStringTarget($currentUrl, $target, $title, $url, $activeClass, $options);
}
if (!is_array($target)) {
return $this->Html->link($title, $url, $options);
}
if (!array_key_exists('plugin', $currentUrl)) {
$currentUrl['plugin'] = false;
}
if (!array_key_exists('prefix', $currentUrl)) {
$currentUrl['prefix'] = false;
}
if (isset($target['or']) && $target['or']) {
foreach ($target['or'] as $singleTargetToMatch) {
if ($this->_matchesUrlFromArrayTarget($currentUrl, $singleTargetToMatch)) {
$options['class'] = $this->_addClass($options, $activeClass);
return $this->Html->link($title, $url, $options);
}
}
return $this->Html->link($title, $url, $options);
}
if (!$this->doesUrlMatchTarget($target, $currentUrl)) {
return $this->Html->link($title, $url, $options);
}
$options['class'] = $this->_addClass($options, $activeClass);
return $this->Html->link($title, $url, $options);
}
/**
* @param array|string $targetUrl
* @param array|null $current |null current url
*
* @return bool
*/
public function doesUrlMatchTarget(array|string $targetUrl, array|null $current = null) {
if (!isset($current)) {
$current = Router::parseRequest($this->getView()->getRequest());
}
if (is_string($targetUrl) && Router::normalize($current) == Router::normalize($targetUrl)) {
return true;
}
if (is_array($targetUrl)) {
if (isset($targetUrl['or']) && $targetUrl['or']) {
foreach ($targetUrl['or'] as $singleTargetToMatch) {
$matched = $this->_matchesUrlFromArrayTarget($current, $singleTargetToMatch);
if ($matched) {
return true;
}
}
}
return $this->_matchesUrlFromArrayTarget($current, $targetUrl);
}
return false;
}
/**
* @param array $providedOptions
* @param string $toAdd
*
* @return string
*/
protected function _addClass(array $providedOptions, string $toAdd): string {
return array_key_exists('class', $providedOptions) ? $providedOptions['class'] . ' ' . $toAdd : $toAdd;
}
/**
* @param array $current
* @param string $targetString
* @param string $title
* @param array|string|null $url
* @param string $activeClass
* @param array $options
*
* @return string
*/
protected function _linkFromStringTarget(array $current, string $targetString, string $title, array|string|null $url, string $activeClass, array $options) {
if (Router::normalize($current) == Router::normalize($targetString)) {
$options['class'] = $this->_addClass($options, $activeClass);
return $this->Html->link($title, $url, $options);
}
return $this->Html->link($title, $url, $options);
}
/**
* @param array $current
* @param array $targetUrl
*
* @return bool
*/
protected function _matchesUrlFromArrayTarget(array $current, array $targetUrl) {
foreach ($targetUrl as $targetKey => $targetValue) {
if (is_array($targetValue)) {
if (!isset($current[$targetKey]) || !in_array($current[$targetKey], $targetValue)) {
return false;
}
continue;
}
if (!isset($current[$targetKey]) || $targetValue != $current[$targetKey]) {
return false;
}
}
return true;
}
}