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 = [];
|
protected $callbacks = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array List of registered items.
|
* @var MainMenuItem[] List of registered items.
|
||||||
*/
|
*/
|
||||||
protected $items;
|
protected $items;
|
||||||
|
|
||||||
|
|
@ -61,7 +61,7 @@ class NavigationManager
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var System\Classes\PluginManager
|
* @var PluginManager
|
||||||
*/
|
*/
|
||||||
protected $pluginManager;
|
protected $pluginManager;
|
||||||
|
|
||||||
|
|
@ -76,6 +76,7 @@ class NavigationManager
|
||||||
/**
|
/**
|
||||||
* Loads the menu items from modules and plugins
|
* Loads the menu items from modules and plugins
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws SystemException
|
||||||
*/
|
*/
|
||||||
protected function loadItems()
|
protected function loadItems()
|
||||||
{
|
{
|
||||||
|
|
@ -118,7 +119,7 @@ class NavigationManager
|
||||||
/*
|
/*
|
||||||
* Sort menu items
|
* Sort menu items
|
||||||
*/
|
*/
|
||||||
uasort($this->items, function ($a, $b) {
|
uasort($this->items, static function ($a, $b) {
|
||||||
return $a->order - $b->order;
|
return $a->order - $b->order;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -147,7 +148,7 @@ class NavigationManager
|
||||||
/*
|
/*
|
||||||
* Sort side menu items
|
* Sort side menu items
|
||||||
*/
|
*/
|
||||||
uasort($item->sideMenu, function ($a, $b) {
|
uasort($item->sideMenu, static function ($a, $b) {
|
||||||
return $a->order - $b->order;
|
return $a->order - $b->order;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -202,6 +203,7 @@ class NavigationManager
|
||||||
* - counterLabel - an optional string value to describe the numeric reference in counter.
|
* - 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 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.
|
* @param array $definitions An array of the menu item definitions.
|
||||||
|
* @throws SystemException
|
||||||
*/
|
*/
|
||||||
public function registerMenuItems($owner, array $definitions)
|
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() . ')';
|
$errorMessage = 'Invalid menu item detected in ' . $owner . '. Contact the plugin author to fix (' . $validator->errors()->first() . ')';
|
||||||
if (Config::get('app.debug', false)) {
|
if (Config::get('app.debug', false)) {
|
||||||
throw new SystemException($errorMessage);
|
throw new SystemException($errorMessage);
|
||||||
} else {
|
|
||||||
Log::error($errorMessage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log::error($errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addMainMenuItems($owner, $definitions);
|
$this->addMainMenuItems($owner, $definitions);
|
||||||
|
|
@ -246,7 +248,7 @@ class NavigationManager
|
||||||
* Dynamically add a single main menu item
|
* Dynamically add a single main menu item
|
||||||
* @param string $owner
|
* @param string $owner
|
||||||
* @param string $code
|
* @param string $code
|
||||||
* @param array $definitions
|
* @param array $definition
|
||||||
*/
|
*/
|
||||||
public function addMainMenuItem($owner, $code, array $definition)
|
public function addMainMenuItem($owner, $code, array $definition)
|
||||||
{
|
{
|
||||||
|
|
@ -256,20 +258,39 @@ class NavigationManager
|
||||||
$definition = array_merge((array) $this->items[$itemKey], $definition);
|
$definition = array_merge((array) $this->items[$itemKey], $definition);
|
||||||
}
|
}
|
||||||
|
|
||||||
$item = (object) array_merge(self::$mainItemDefaults, array_merge($definition, [
|
$item = array_merge($definition, [
|
||||||
'code' => $code,
|
'code' => $code,
|
||||||
'owner' => $owner
|
'owner' => $owner
|
||||||
]));
|
]);
|
||||||
|
|
||||||
$this->items[$itemKey] = $item;
|
$this->items[$itemKey] = MainMenuItem::createFromArray($item);
|
||||||
|
|
||||||
if ($item->sideMenu) {
|
if (array_key_exists('sideMenu', $item)) {
|
||||||
$this->addSideMenuItems($owner, $code, $item->sideMenu);
|
$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
|
* Removes a single main menu item
|
||||||
|
* @param $owner
|
||||||
|
* @param $code
|
||||||
*/
|
*/
|
||||||
public function removeMainMenuItem($owner, $code)
|
public function removeMainMenuItem($owner, $code)
|
||||||
{
|
{
|
||||||
|
|
@ -295,9 +316,10 @@ class NavigationManager
|
||||||
* @param string $owner
|
* @param string $owner
|
||||||
* @param string $code
|
* @param string $code
|
||||||
* @param string $sideCode
|
* @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);
|
$itemKey = $this->makeItemKey($owner, $code);
|
||||||
|
|
||||||
|
|
@ -316,15 +338,20 @@ class NavigationManager
|
||||||
$definition = array_merge((array) $mainItem->sideMenu[$sideCode], $definition);
|
$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
|
* 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);
|
$itemKey = $this->makeItemKey($owner, $code);
|
||||||
if (!isset($this->items[$itemKey])) {
|
if (!isset($this->items[$itemKey])) {
|
||||||
|
|
@ -332,12 +359,14 @@ class NavigationManager
|
||||||
}
|
}
|
||||||
|
|
||||||
$mainItem = $this->items[$itemKey];
|
$mainItem = $this->items[$itemKey];
|
||||||
unset($mainItem->sideMenu[$sideCode]);
|
$mainItem->removeSideMenuItem($sideCode);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of the main menu items.
|
* Returns a list of the main menu items.
|
||||||
* @return array
|
* @return array
|
||||||
|
* @throws SystemException
|
||||||
*/
|
*/
|
||||||
public function listMainMenuItems()
|
public function listMainMenuItems()
|
||||||
{
|
{
|
||||||
|
|
@ -372,8 +401,12 @@ class NavigationManager
|
||||||
/**
|
/**
|
||||||
* Returns a list of side menu items for the currently active main menu item.
|
* 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.
|
* 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;
|
$activeItem = null;
|
||||||
|
|
||||||
|
|
@ -467,17 +500,18 @@ class NavigationManager
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if a main menu item is active.
|
* 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.
|
* @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
|
* 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()
|
public function getActiveMainMenuItem()
|
||||||
{
|
{
|
||||||
|
|
@ -492,17 +526,17 @@ class NavigationManager
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if a side menu item is active.
|
* 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.
|
* @return boolean Returns true if the side item is active.
|
||||||
*/
|
*/
|
||||||
public function isSideMenuItemActive($item)
|
public function isSideMenuItemActive($item): bool
|
||||||
{
|
{
|
||||||
if ($this->contextSideMenuItemCode === true) {
|
if ($this->contextSideMenuItemCode === true) {
|
||||||
$this->contextSideMenuItemCode = null;
|
$this->contextSideMenuItemCode = null;
|
||||||
return true;
|
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.
|
* Removes menu items from an array if the supplied user lacks permission.
|
||||||
* @param User $user A user object
|
* @param \Backend\Models\User $user A user object
|
||||||
* @param array $items A collection of menu items
|
* @param MainMenuItem[]|SideMenuItem[] $items A collection of menu items
|
||||||
* @return array The filtered menu items
|
* @return array The filtered menu items
|
||||||
*/
|
*/
|
||||||
protected function filterItemPermissions($user, array $items)
|
protected function filterItemPermissions($user, array $items): array
|
||||||
{
|
{
|
||||||
if (!$user) {
|
if (!$user) {
|
||||||
return $items;
|
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)) {
|
if (!$item->permissions || !count($item->permissions)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -557,10 +591,11 @@ class NavigationManager
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal method to make a unique key for an item.
|
* Internal method to make a unique key for an item.
|
||||||
* @param object $item
|
* @param string $owner
|
||||||
|
* @param string $code
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function makeItemKey($owner, $code)
|
protected function makeItemKey($owner, $code): string
|
||||||
{
|
{
|
||||||
return strtoupper($owner).'.'.strtoupper($code);
|
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