| <?php |
|
|
| |
| |
| |
| |
| |
| |
|
|
| namespace Piwik\Menu; |
|
|
| use Piwik\Cache; |
| use Piwik\Container\StaticContainer; |
| use Piwik\Plugins\SitesManager\API; |
| use Piwik\Singleton; |
| use Piwik\Plugin\Manager as PluginManager; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| abstract class MenuAbstract extends Singleton |
| { |
| |
| |
| |
| protected $menu = null; |
| |
| |
| |
| protected $menuEntries = []; |
| |
| |
| |
| protected $menuEntriesToRemove = []; |
| |
| |
| |
| protected $edits = []; |
| |
| |
| |
| protected $renames = []; |
| |
| |
| |
| protected $orderingApplied = false; |
| |
| |
| |
| protected $menuIcons = []; |
|
|
| |
| |
| |
| |
| |
| |
| public function getMenu() |
| { |
| $this->buildMenu(); |
| $this->applyEdits(); |
| $this->applyRemoves(); |
| $this->applyRenames(); |
| $this->applyOrdering(); |
| return $this->menu; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| public function registerMenuIcon($menuName, $iconCssClass) |
| { |
| $this->menuIcons[$menuName] = $iconCssClass; |
| } |
|
|
| |
| |
| |
| |
| |
| 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; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| 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 = '' |
| ) { |
| |
| 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, |
| ]; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| public function remove($menuName, $subMenuName = false) |
| { |
| $this->menuEntriesToRemove[] = array( |
| $menuName, |
| $subMenuName, |
| ); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| 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; |
| } |
| } |
| } |
|
|
| |
| |
| |
| private function buildMenu(): void |
| { |
| foreach ($this->menuEntries as $menuEntry) { |
| $this->buildMenuItem(...$menuEntry); |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public function rename($mainMenuOriginal, $subMenuOriginal, $mainMenuRenamed, $subMenuRenamed) |
| { |
| $this->renames[] = [ |
| $mainMenuOriginal, |
| $subMenuOriginal, |
| $mainMenuRenamed, |
| $subMenuRenamed, |
| ]; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public function editUrl($mainMenuToEdit, $subMenuToEdit, $newUrl) |
| { |
| $this->edits[] = [$mainMenuToEdit, $subMenuToEdit, $newUrl]; |
| } |
|
|
| |
| |
| |
| 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])) { |
| |
| if (isset($this->menu[$menuToDelete[0]])) { |
| unset($this->menu[$menuToDelete[0]]); |
| } |
| } else { |
| |
| if (isset($this->menu[$menuToDelete[0]][$menuToDelete[1]])) { |
| unset($this->menu[$menuToDelete[0]][$menuToDelete[1]]); |
| } |
| } |
| } |
| } |
| |
| |
| |
| private function applyRenames(): void |
| { |
| foreach ($this->renames as $rename) { |
| $mainMenuOriginal = $rename[0]; |
| $subMenuOriginal = $rename[1]; |
| $mainMenuRenamed = $rename[2]; |
| $subMenuRenamed = $rename[3]; |
|
|
| |
| 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])) { |
| |
| $save = $this->menu[$mainMenuOriginal]; |
| $save['_name'] = $mainMenuRenamed; |
| unset($this->menu[$mainMenuOriginal]); |
| $this->menu[$mainMenuRenamed] = $save; |
| } |
| } |
| } |
|
|
| |
| |
| |
| 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; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| 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; |
| } |
| } |
|
|