Modify menu structure to objects (#4929)
* Modify menu structure to objects
This commit is contained in:
parent
56b2864ef5
commit
bf8ab3612e
|
|
@ -0,0 +1,125 @@
|
|||
<?php namespace Backend\Classes;
|
||||
|
||||
use October\Rain\Exception\SystemException;
|
||||
|
||||
/**
|
||||
* Class MainMenuItem
|
||||
*
|
||||
* @package Backend\Classes
|
||||
*/
|
||||
class MainMenuItem
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $code;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $owner;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $label;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
public $icon;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
public $iconSvg;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
public $counter;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
public $counterLabel;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $url;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $permissions = [];
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $order = 500;
|
||||
|
||||
/**
|
||||
* @var SideMenuItem[]
|
||||
*/
|
||||
public $sideMenu = [];
|
||||
|
||||
/**
|
||||
* @param string $permission
|
||||
* @param array $definition
|
||||
*/
|
||||
public function addPermission(string $permission, array $definition)
|
||||
{
|
||||
$this->permissions[$permission] = $definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SideMenuItem $sideMenu
|
||||
*/
|
||||
public function addSideMenuItem(SideMenuItem $sideMenu)
|
||||
{
|
||||
$this->sideMenu[$sideMenu->code] = $sideMenu;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $code
|
||||
* @return SideMenuItem
|
||||
* @throws SystemException
|
||||
*/
|
||||
public function getSideMenuItem(string $code): SideMenuItem
|
||||
{
|
||||
if (!array_key_exists($code, $this->sideMenu)) {
|
||||
throw new SystemException('No sidenavigation item available with code ' . $code);
|
||||
}
|
||||
|
||||
return $this->sideMenu[$code];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $code
|
||||
*/
|
||||
public function removeSideMenuItem(string $code)
|
||||
{
|
||||
unset($this->sideMenu[$code]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return static
|
||||
*/
|
||||
public static function createFromArray(array $data)
|
||||
{
|
||||
$instance = new static();
|
||||
$instance->code = $data['code'];
|
||||
$instance->owner = $data['owner'];
|
||||
$instance->label = $data['label'];
|
||||
$instance->url = $data['url'];
|
||||
$instance->icon = $data['icon'] ?? null;
|
||||
$instance->iconSvg = $data['iconSvg'] ?? null;
|
||||
$instance->counter = $data['counter'] ?? null;
|
||||
$instance->counterLabel = $data['counterLabel'] ?? null;
|
||||
$instance->permissions = $data['permissions'] ?? $instance->permissions;
|
||||
$instance->order = $data['order'] ?? $instance->order;
|
||||
return $instance;
|
||||
}
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ class NavigationManager
|
|||
protected $callbacks = [];
|
||||
|
||||
/**
|
||||
* @var array List of registered items.
|
||||
* @var MainMenuItem[] List of registered items.
|
||||
*/
|
||||
protected $items;
|
||||
|
||||
|
|
@ -61,7 +61,7 @@ class NavigationManager
|
|||
];
|
||||
|
||||
/**
|
||||
* @var System\Classes\PluginManager
|
||||
* @var PluginManager
|
||||
*/
|
||||
protected $pluginManager;
|
||||
|
||||
|
|
@ -76,6 +76,7 @@ class NavigationManager
|
|||
/**
|
||||
* Loads the menu items from modules and plugins
|
||||
* @return void
|
||||
* @throws SystemException
|
||||
*/
|
||||
protected function loadItems()
|
||||
{
|
||||
|
|
@ -118,7 +119,7 @@ class NavigationManager
|
|||
/*
|
||||
* Sort menu items
|
||||
*/
|
||||
uasort($this->items, function ($a, $b) {
|
||||
uasort($this->items, static function ($a, $b) {
|
||||
return $a->order - $b->order;
|
||||
});
|
||||
|
||||
|
|
@ -147,7 +148,7 @@ class NavigationManager
|
|||
/*
|
||||
* Sort side menu items
|
||||
*/
|
||||
uasort($item->sideMenu, function ($a, $b) {
|
||||
uasort($item->sideMenu, static function ($a, $b) {
|
||||
return $a->order - $b->order;
|
||||
});
|
||||
|
||||
|
|
@ -202,6 +203,7 @@ class NavigationManager
|
|||
* - counterLabel - an optional string value to describe the numeric reference in counter.
|
||||
* @param string $owner Specifies the menu items owner plugin or module in the format Author.Plugin.
|
||||
* @param array $definitions An array of the menu item definitions.
|
||||
* @throws SystemException
|
||||
*/
|
||||
public function registerMenuItems($owner, array $definitions)
|
||||
{
|
||||
|
|
@ -222,9 +224,9 @@ class NavigationManager
|
|||
$errorMessage = 'Invalid menu item detected in ' . $owner . '. Contact the plugin author to fix (' . $validator->errors()->first() . ')';
|
||||
if (Config::get('app.debug', false)) {
|
||||
throw new SystemException($errorMessage);
|
||||
} else {
|
||||
Log::error($errorMessage);
|
||||
}
|
||||
|
||||
Log::error($errorMessage);
|
||||
}
|
||||
|
||||
$this->addMainMenuItems($owner, $definitions);
|
||||
|
|
@ -246,7 +248,7 @@ class NavigationManager
|
|||
* Dynamically add a single main menu item
|
||||
* @param string $owner
|
||||
* @param string $code
|
||||
* @param array $definitions
|
||||
* @param array $definition
|
||||
*/
|
||||
public function addMainMenuItem($owner, $code, array $definition)
|
||||
{
|
||||
|
|
@ -256,20 +258,39 @@ class NavigationManager
|
|||
$definition = array_merge((array) $this->items[$itemKey], $definition);
|
||||
}
|
||||
|
||||
$item = (object) array_merge(self::$mainItemDefaults, array_merge($definition, [
|
||||
$item = array_merge($definition, [
|
||||
'code' => $code,
|
||||
'owner' => $owner
|
||||
]));
|
||||
]);
|
||||
|
||||
$this->items[$itemKey] = $item;
|
||||
$this->items[$itemKey] = MainMenuItem::createFromArray($item);
|
||||
|
||||
if ($item->sideMenu) {
|
||||
$this->addSideMenuItems($owner, $code, $item->sideMenu);
|
||||
if (array_key_exists('sideMenu', $item)) {
|
||||
$this->addSideMenuItems($owner, $code, $item['sideMenu']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $owner
|
||||
* @param string $code
|
||||
* @return MainMenuItem
|
||||
* @throws SystemException
|
||||
*/
|
||||
public function getMainMenuItem(string $owner, string $code): MainMenuItem
|
||||
{
|
||||
$itemKey = $this->makeItemKey($owner, $code);
|
||||
|
||||
if (!array_key_exists($itemKey, $this->items)) {
|
||||
throw new SystemException('No main menu item found with key ' . $itemKey);
|
||||
}
|
||||
|
||||
return $this->items[$itemKey];
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a single main menu item
|
||||
* @param $owner
|
||||
* @param $code
|
||||
*/
|
||||
public function removeMainMenuItem($owner, $code)
|
||||
{
|
||||
|
|
@ -295,9 +316,10 @@ class NavigationManager
|
|||
* @param string $owner
|
||||
* @param string $code
|
||||
* @param string $sideCode
|
||||
* @param array $definitions
|
||||
* @param array $definition
|
||||
* @return bool
|
||||
*/
|
||||
public function addSideMenuItem($owner, $code, $sideCode, array $definition)
|
||||
public function addSideMenuItem($owner, $code, $sideCode, array $definition): bool
|
||||
{
|
||||
$itemKey = $this->makeItemKey($owner, $code);
|
||||
|
||||
|
|
@ -316,15 +338,20 @@ class NavigationManager
|
|||
$definition = array_merge((array) $mainItem->sideMenu[$sideCode], $definition);
|
||||
}
|
||||
|
||||
$item = (object) array_merge(self::$sideItemDefaults, $definition);
|
||||
$item = SideMenuItem::createFromArray($definition);
|
||||
|
||||
$this->items[$itemKey]->sideMenu[$sideCode] = $item;
|
||||
$this->items[$itemKey]->addSideMenuItem($item);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a single main menu item
|
||||
* @param string $owner
|
||||
* @param string $code
|
||||
* @param string $sideCode
|
||||
* @return bool
|
||||
*/
|
||||
public function removeSideMenuItem($owner, $code, $sideCode)
|
||||
public function removeSideMenuItem($owner, $code, $sideCode): bool
|
||||
{
|
||||
$itemKey = $this->makeItemKey($owner, $code);
|
||||
if (!isset($this->items[$itemKey])) {
|
||||
|
|
@ -332,12 +359,14 @@ class NavigationManager
|
|||
}
|
||||
|
||||
$mainItem = $this->items[$itemKey];
|
||||
unset($mainItem->sideMenu[$sideCode]);
|
||||
$mainItem->removeSideMenuItem($sideCode);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of the main menu items.
|
||||
* @return array
|
||||
* @throws SystemException
|
||||
*/
|
||||
public function listMainMenuItems()
|
||||
{
|
||||
|
|
@ -372,8 +401,12 @@ class NavigationManager
|
|||
/**
|
||||
* Returns a list of side menu items for the currently active main menu item.
|
||||
* The currently active main menu item is set with the setContext methods.
|
||||
* @param null $owner
|
||||
* @param null $code
|
||||
* @return SideMenuItem[]
|
||||
* @throws SystemException
|
||||
*/
|
||||
public function listSideMenuItems($owner = null, $code = null)
|
||||
public function listSideMenuItems($owner = null, $code = null): array
|
||||
{
|
||||
$activeItem = null;
|
||||
|
||||
|
|
@ -467,17 +500,18 @@ class NavigationManager
|
|||
|
||||
/**
|
||||
* Determines if a main menu item is active.
|
||||
* @param mixed $item Specifies the item object.
|
||||
* @param MainMenuItem $item Specifies the item object.
|
||||
* @return boolean Returns true if the menu item is active.
|
||||
*/
|
||||
public function isMainMenuItemActive($item)
|
||||
public function isMainMenuItemActive($item): bool
|
||||
{
|
||||
return $this->contextOwner == $item->owner && $this->contextMainMenuItemCode == $item->code;
|
||||
return $this->contextOwner === $item->owner && $this->contextMainMenuItemCode === $item->code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently active main menu item
|
||||
* @param mixed $item Returns the item object or null.
|
||||
* @return null|MainMenuItem $item Returns the item object or null.
|
||||
* @throws SystemException
|
||||
*/
|
||||
public function getActiveMainMenuItem()
|
||||
{
|
||||
|
|
@ -492,17 +526,17 @@ class NavigationManager
|
|||
|
||||
/**
|
||||
* Determines if a side menu item is active.
|
||||
* @param mixed $item Specifies the item object.
|
||||
* @param SideMenuItem $item Specifies the item object.
|
||||
* @return boolean Returns true if the side item is active.
|
||||
*/
|
||||
public function isSideMenuItemActive($item)
|
||||
public function isSideMenuItemActive($item): bool
|
||||
{
|
||||
if ($this->contextSideMenuItemCode === true) {
|
||||
$this->contextSideMenuItemCode = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->contextOwner == $item->owner && $this->contextSideMenuItemCode == $item->code;
|
||||
return $this->contextOwner === $item->owner && $this->contextSideMenuItemCode === $item->code;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -534,17 +568,17 @@ class NavigationManager
|
|||
|
||||
/**
|
||||
* Removes menu items from an array if the supplied user lacks permission.
|
||||
* @param User $user A user object
|
||||
* @param array $items A collection of menu items
|
||||
* @param \Backend\Models\User $user A user object
|
||||
* @param MainMenuItem[]|SideMenuItem[] $items A collection of menu items
|
||||
* @return array The filtered menu items
|
||||
*/
|
||||
protected function filterItemPermissions($user, array $items)
|
||||
protected function filterItemPermissions($user, array $items): array
|
||||
{
|
||||
if (!$user) {
|
||||
return $items;
|
||||
}
|
||||
|
||||
$items = array_filter($items, function ($item) use ($user) {
|
||||
$items = array_filter($items, static function ($item) use ($user) {
|
||||
if (!$item->permissions || !count($item->permissions)) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -557,10 +591,11 @@ class NavigationManager
|
|||
|
||||
/**
|
||||
* Internal method to make a unique key for an item.
|
||||
* @param object $item
|
||||
* @param string $owner
|
||||
* @param string $code
|
||||
* @return string
|
||||
*/
|
||||
protected function makeItemKey($owner, $code)
|
||||
protected function makeItemKey($owner, $code): string
|
||||
{
|
||||
return strtoupper($owner).'.'.strtoupper($code);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,117 @@
|
|||
<?php namespace Backend\Classes;
|
||||
|
||||
/**
|
||||
* Class SideMenuItem
|
||||
*
|
||||
* @package Backend\Classes
|
||||
*/
|
||||
class SideMenuItem
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $code;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $owner;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $label;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
public $icon;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
public $iconSvg;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $url;
|
||||
|
||||
/**
|
||||
* @var null|int|callable
|
||||
*/
|
||||
public $counter;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
public $counterLabel;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $order = -1;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $attributes = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $permissions = [];
|
||||
|
||||
/**
|
||||
* @param null|string|int $attribute
|
||||
* @param null|string|array $value
|
||||
*/
|
||||
public function addAttribute($attribute, $value)
|
||||
{
|
||||
$this->attributes[$attribute] = $value;
|
||||
}
|
||||
|
||||
public function removeAttribute($attribute)
|
||||
{
|
||||
unset($this->attributes[$attribute]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $permission
|
||||
* @param array $definition
|
||||
*/
|
||||
public function addPermission(string $permission, array $definition)
|
||||
{
|
||||
$this->permissions[$permission] = $definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $permission
|
||||
* @return void
|
||||
*/
|
||||
public function removePermission(string $permission)
|
||||
{
|
||||
unset($this->permissions[$permission]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return static
|
||||
*/
|
||||
public static function createFromArray(array $data): self
|
||||
{
|
||||
$instance = new static();
|
||||
$instance->code = $data['code'];
|
||||
$instance->owner = $data['owner'];
|
||||
$instance->label = $data['label'];
|
||||
$instance->url = $data['url'];
|
||||
$instance->icon = $data['icon'] ?? null;
|
||||
$instance->iconSvg = $data['iconSvg'] ?? null;
|
||||
$instance->counter = $data['counter'] ?? null;
|
||||
$instance->counterLabel = $data['counterLabel'] ?? null;
|
||||
$instance->attributes = $data['attributes'] ?? $instance->attributes;
|
||||
$instance->permissions = $data['permissions'] ?? $instance->permissions;
|
||||
$instance->order = $data['order'] ?? $instance->order;
|
||||
return $instance;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue