Download core/Menu/MenuAbstract.php from Leon4gr45/matomo: direct link, hf CLI and curl.
- Browser
- Download file 13.6 kB
-
https://huggingface.co/spaces/Leon4gr45/matomo/resolve/main/core/Menu/MenuAbstract.php
- Command line
-
hf download hf://spaces/Leon4gr45/matomo/core/Menu/MenuAbstract.php
-
curl -L -o MenuAbstract.php https://huggingface.co/spaces/Leon4gr45/matomo/resolve/main/core/Menu/MenuAbstract.php
13.6 kB
| /** | |
| * Matomo - free/libre analytics platform | |
| * | |
| * @link https://matomo.org | |
| * @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later | |
| */ | |
| namespace Piwik\Menu; | |
| use Piwik\Cache; | |
| use Piwik\Container\StaticContainer; | |
| use Piwik\Plugins\SitesManager\API; | |
| use Piwik\Singleton; | |
| use Piwik\Plugin\Manager as PluginManager; | |
| /** | |
| * Base class for classes that manage one of Piwik's menus. | |
| * | |
| * There are three menus in Piwik, the main menu, the top menu and the admin menu. | |
| * Each menu has a class that manages the menu's content. Each class invokes | |
| * a different event to allow plugins to add new menu items. | |
| * | |
| * @static \Piwik\Menu\MenuAbstract getInstance() | |
| */ | |
| abstract class MenuAbstract extends Singleton | |
| { | |
| /** | |
| * @var array | |
| */ | |
| protected $menu = null; | |
| /** | |
| * @var array | |
| */ | |
| protected $menuEntries = []; | |
| /** | |
| * @var array | |
| */ | |
| protected $menuEntriesToRemove = []; | |
| /** | |
| * @var array | |
| */ | |
| protected $edits = []; | |
| /** | |
| * @var array | |
| */ | |
| protected $renames = []; | |
| /** | |
| * @var bool | |
| */ | |
| protected $orderingApplied = false; | |
| /** | |
| * @var array<string, string> | |
| */ | |
| protected $menuIcons = []; | |
| /** | |
| * Builds the menu, applies edits, renames | |
| * and orders the entries. | |
| * | |
| * @return array | |
| */ | |
| public function getMenu() | |
| { | |
| $this->buildMenu(); | |
| $this->applyEdits(); | |
| $this->applyRemoves(); | |
| $this->applyRenames(); | |
| $this->applyOrdering(); | |
| return $this->menu; | |
| } | |
| /** | |
| * lets you register a menu icon for a certain menu category to replace the default arrow icon. | |
| * | |
| * @param string $menuName The translation key of a main menu category, eg 'Dashboard_Dashboard' | |
| * @param string $iconCssClass The css class name of an icon, eg 'icon-user' | |
| * @return void | |
| */ | |
| public function registerMenuIcon($menuName, $iconCssClass) | |
| { | |
| $this->menuIcons[$menuName] = $iconCssClass; | |
| } | |
| /** | |
| * Returns a list of available plugin menu instances. | |
| * | |
| * @return \Piwik\Plugin\Menu[] | |
| */ | |
| protected function getAllMenus() | |
| { | |
| $cacheId = 'Menus.all'; | |
| $cache = Cache::getTransientCache(); | |
| if ($cache->contains($cacheId)) { | |
| return $cache->fetch($cacheId); | |
| } | |
| $components = PluginManager::getInstance()->findComponents('Menu', 'Piwik\\Plugin\\Menu'); | |
| $menus = []; | |
| foreach ($components as $component) { | |
| $menus[] = StaticContainer::get($component); | |
| } | |
| $cache->save($cacheId, $menus); | |
| return $menus; | |
| } | |
| /** | |
| * Adds a new entry to the menu. | |
| * | |
| * @param string $menuName The menu's category name. Can be a translation token. | |
| * @param null|string $subMenuName The menu item's name. Can be a translation token. | |
| * @param string|array<string, scalar> $url The URL the admin menu entry should link to, or an array of query parameters | |
| * that can be used to build the URL. | |
| * @param int $order The order hint. | |
| * @param string|null|false $tooltip An optional tooltip to display or false to display the tooltip. | |
| * @param string|null|false $icon An icon classname, such as "icon-add". Only supported by admin menu | |
| * @param string|null|false $onclick Will execute the on click handler instead of executing the link. Only supported by admin menu. | |
| * @param string|null|false $attribute Will add this string as a link attribute. | |
| * @param string|null|false $help Will display a help icon that will pop a notification with help information. | |
| * @param int $badgeCount If non-zero then a badge will be overlaid on the icon showing the provided count | |
| * @param string $cssClass If a string is provided, it will be added as an extra CSS class to the menu item | |
| * @return void | |
| * @since 2.7.0 | |
| * @api | |
| */ | |
| public function addItem( | |
| string $menuName, | |
| ?string $subMenuName, | |
| $url, | |
| int $order = 50, | |
| $tooltip = false, | |
| $icon = false, | |
| $onclick = false, | |
| $attribute = false, | |
| $help = false, | |
| int $badgeCount = 0, | |
| string $cssClass = '' | |
| ) { | |
| // make sure the idSite value used is numeric (hack-y fix for #3426) | |
| if (isset($url['idSite']) && !is_numeric($url['idSite'])) { | |
| $idSites = API::getInstance()->getSitesIdWithAtLeastViewAccess(); | |
| $url['idSite'] = reset($idSites); | |
| } | |
| $this->menuEntries[] = [ | |
| $menuName, | |
| $subMenuName, | |
| $url, | |
| $order, | |
| $tooltip, | |
| $icon, | |
| $onclick, | |
| $attribute, | |
| $help, | |
| $badgeCount, | |
| $cssClass, | |
| ]; | |
| } | |
| /** | |
| * Removes an existing entry from the menu. | |
| * | |
| * @param string $menuName The menu's category name. Can be a translation token. | |
| * @param string|null|false $subMenuName The menu item's name. Can be a translation token. | |
| * @return void | |
| * @api | |
| */ | |
| public function remove($menuName, $subMenuName = false) | |
| { | |
| $this->menuEntriesToRemove[] = array( | |
| $menuName, | |
| $subMenuName, | |
| ); | |
| } | |
| /** | |
| * Builds a single menu item | |
| * | |
| * @param string|array $url | |
| * @param string|null|false $tooltip Tooltip to display. | |
| * @param string|null|false $icon | |
| * @param string|null|false $onclick | |
| * @param string|null|false $attribute | |
| * @param string|null|false $help | |
| */ | |
| private function buildMenuItem( | |
| string $menuName, | |
| ?string $subMenuName, | |
| $url, | |
| int $order = 50, | |
| $tooltip = false, | |
| $icon = false, | |
| $onclick = false, | |
| $attribute = false, | |
| $help = false, | |
| int $badgeCount = 0, | |
| string $cssClass = '' | |
| ): void { | |
| if (!isset($this->menu[$menuName])) { | |
| $this->menu[$menuName] = [ | |
| '_hasSubmenu' => false, | |
| '_order' => $order, | |
| ]; | |
| } | |
| if (empty($subMenuName)) { | |
| $this->menu[$menuName]['_url'] = $url; | |
| $this->menu[$menuName]['_order'] = $order; | |
| $this->menu[$menuName]['_name'] = $menuName; | |
| $this->menu[$menuName]['_tooltip'] = $tooltip; | |
| $this->menu[$menuName]['_attribute'] = $attribute; | |
| if (!empty($this->menuIcons[$menuName])) { | |
| $this->menu[$menuName]['_icon'] = $this->menuIcons[$menuName]; | |
| } else { | |
| $this->menu[$menuName]['_icon'] = ''; | |
| } | |
| if (!empty($onclick)) { | |
| $this->menu[$menuName]['_onclick'] = $onclick; | |
| } | |
| $this->menu[$menuName]['_help'] = $help ?: ''; | |
| $this->menu[$menuName]['_badgecount'] = $badgeCount; | |
| $this->menu[$menuName]['_cssClass'] = $cssClass; | |
| } | |
| if (!empty($subMenuName)) { | |
| $this->menu[$menuName][$subMenuName]['_url'] = $url; | |
| $this->menu[$menuName][$subMenuName]['_order'] = $order; | |
| $this->menu[$menuName][$subMenuName]['_name'] = $subMenuName; | |
| $this->menu[$menuName][$subMenuName]['_tooltip'] = $tooltip; | |
| $this->menu[$menuName][$subMenuName]['_attribute'] = $attribute; | |
| $this->menu[$menuName][$subMenuName]['_icon'] = $icon; | |
| $this->menu[$menuName][$subMenuName]['_onclick'] = $onclick; | |
| $this->menu[$menuName][$subMenuName]['_help'] = $help ?: ''; | |
| $this->menu[$menuName][$subMenuName]['_badgecount'] = $badgeCount; | |
| $this->menu[$menuName][$subMenuName]['_cssClass'] = $cssClass; | |
| $this->menu[$menuName]['_hasSubmenu'] = true; | |
| if (!array_key_exists('_tooltip', $this->menu[$menuName])) { | |
| $this->menu[$menuName]['_tooltip'] = $tooltip; | |
| } | |
| } | |
| } | |
| /** | |
| * Builds the menu from the $this->menuEntries variable. | |
| */ | |
| private function buildMenu(): void | |
| { | |
| foreach ($this->menuEntries as $menuEntry) { | |
| $this->buildMenuItem(...$menuEntry); | |
| } | |
| } | |
| /** | |
| * Renames a single menu entry. | |
| * | |
| * @param string $mainMenuOriginal | |
| * @param string|null $subMenuOriginal | |
| * @param string $mainMenuRenamed | |
| * @param string|null $subMenuRenamed | |
| * @phpstan-param ($subMenuOriginal is null ? null : string) $subMenuRenamed | |
| * @return void | |
| * @api | |
| */ | |
| public function rename($mainMenuOriginal, $subMenuOriginal, $mainMenuRenamed, $subMenuRenamed) | |
| { | |
| $this->renames[] = [ | |
| $mainMenuOriginal, | |
| $subMenuOriginal, | |
| $mainMenuRenamed, | |
| $subMenuRenamed, | |
| ]; | |
| } | |
| /** | |
| * Edits a URL of an existing menu entry. | |
| * | |
| * @param string $mainMenuToEdit | |
| * @param string|null $subMenuToEdit | |
| * @param string|array<string, scalar> $newUrl | |
| * @return void | |
| * @api | |
| */ | |
| public function editUrl($mainMenuToEdit, $subMenuToEdit, $newUrl) | |
| { | |
| $this->edits[] = [$mainMenuToEdit, $subMenuToEdit, $newUrl]; | |
| } | |
| /** | |
| * Applies all edits to the menu. | |
| */ | |
| private function applyEdits(): void | |
| { | |
| foreach ($this->edits as $edit) { | |
| $mainMenuToEdit = $edit[0]; | |
| $subMenuToEdit = $edit[1]; | |
| $newUrl = $edit[2]; | |
| if ($subMenuToEdit === null) { | |
| if (isset($this->menu[$mainMenuToEdit])) { | |
| $menuDataToEdit = &$this->menu[$mainMenuToEdit]; | |
| } else { | |
| $menuDataToEdit = null; | |
| } | |
| } else { | |
| if (isset($this->menu[$mainMenuToEdit][$subMenuToEdit])) { | |
| $menuDataToEdit = &$this->menu[$mainMenuToEdit][$subMenuToEdit]; | |
| } else { | |
| $menuDataToEdit = null; | |
| } | |
| } | |
| if (empty($menuDataToEdit)) { | |
| $this->buildMenuItem($mainMenuToEdit, $subMenuToEdit, $newUrl); | |
| } else { | |
| $menuDataToEdit['_url'] = $newUrl; | |
| } | |
| } | |
| } | |
| private function applyRemoves(): void | |
| { | |
| foreach ($this->menuEntriesToRemove as $menuToDelete) { | |
| if (empty($menuToDelete[1])) { | |
| // Delete Main Menu | |
| if (isset($this->menu[$menuToDelete[0]])) { | |
| unset($this->menu[$menuToDelete[0]]); | |
| } | |
| } else { | |
| // Delete Sub Menu | |
| if (isset($this->menu[$menuToDelete[0]][$menuToDelete[1]])) { | |
| unset($this->menu[$menuToDelete[0]][$menuToDelete[1]]); | |
| } | |
| } | |
| } | |
| } | |
| /** | |
| * Applies renames to the menu. | |
| */ | |
| private function applyRenames(): void | |
| { | |
| foreach ($this->renames as $rename) { | |
| $mainMenuOriginal = $rename[0]; | |
| $subMenuOriginal = $rename[1]; | |
| $mainMenuRenamed = $rename[2]; | |
| $subMenuRenamed = $rename[3]; | |
| // Are we changing a submenu? | |
| if (!empty($subMenuOriginal)) { | |
| if (isset($this->menu[$mainMenuOriginal][$subMenuOriginal])) { | |
| $save = $this->menu[$mainMenuOriginal][$subMenuOriginal]; | |
| $save['_name'] = $subMenuRenamed; | |
| unset($this->menu[$mainMenuOriginal][$subMenuOriginal]); | |
| $this->menu[$mainMenuRenamed][$subMenuRenamed] = $save; | |
| } | |
| } elseif (isset($this->menu[$mainMenuOriginal])) { | |
| // Changing a first-level element | |
| $save = $this->menu[$mainMenuOriginal]; | |
| $save['_name'] = $mainMenuRenamed; | |
| unset($this->menu[$mainMenuOriginal]); | |
| $this->menu[$mainMenuRenamed] = $save; | |
| } | |
| } | |
| } | |
| /** | |
| * Orders the menu according to their order. | |
| */ | |
| private function applyOrdering(): void | |
| { | |
| if ( | |
| empty($this->menu) | |
| || $this->orderingApplied | |
| ) { | |
| return; | |
| } | |
| uasort($this->menu, [$this, 'menuCompare']); | |
| foreach ($this->menu as $key => &$element) { | |
| if (is_null($element)) { | |
| unset($this->menu[$key]); | |
| } elseif ($element['_hasSubmenu']) { | |
| uasort($element, [$this, 'menuCompare']); | |
| } | |
| } | |
| $this->orderingApplied = true; | |
| } | |
| /** | |
| * Compares two menu entries. Used for ordering. | |
| * | |
| * @param array|string $itemOne | |
| * @param array|string $itemTwo | |
| * @return int | |
| */ | |
| protected function menuCompare($itemOne, $itemTwo) | |
| { | |
| if (!is_array($itemOne) && !is_array($itemTwo)) { | |
| return 0; | |
| } | |
| if (!is_array($itemOne) && is_array($itemTwo)) { | |
| return -1; | |
| } | |
| if (is_array($itemOne) && !is_array($itemTwo)) { | |
| return 1; | |
| } | |
| if (!isset($itemOne['_order']) && !isset($itemTwo['_order'])) { | |
| return 0; | |
| } | |
| if (!isset($itemOne['_order']) && isset($itemTwo['_order'])) { | |
| return -1; | |
| } | |
| if (isset($itemOne['_order']) && !isset($itemTwo['_order'])) { | |
| return 1; | |
| } | |
| if ($itemOne['_order'] == $itemTwo['_order']) { | |
| return strcmp( | |
| $itemOne['_name'] ?? '', | |
| $itemTwo['_name'] ?? '' | |
| ); | |
| } | |
| return ($itemOne['_order'] < $itemTwo['_order']) ? -1 : 1; | |
| } | |
| } | |