mirror of
https://github.com/bdnugget/magento2.git
synced 2026-11-07 09:17:35 +00:00
322 lines
8.0 KiB
PHP
322 lines
8.0 KiB
PHP
<?php
|
|
/**
|
|
* Copyright © Magento, Inc. All rights reserved.
|
|
* See COPYING.txt for license details.
|
|
*/
|
|
namespace Magento\Backend\Model;
|
|
|
|
use Magento\Backend\Model\Menu\Item;
|
|
use Magento\Backend\Model\Menu\Item\Factory;
|
|
use Magento\Framework\App\ObjectManager;
|
|
use Magento\Framework\Serialize\SerializerInterface;
|
|
use Psr\Log\LoggerInterface;
|
|
|
|
/**
|
|
* Backend menu model
|
|
*
|
|
* @api
|
|
* @since 100.0.2
|
|
*/
|
|
class Menu extends \ArrayObject
|
|
{
|
|
/**
|
|
* Path in tree structure
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $_path = '';
|
|
|
|
/**
|
|
* @var LoggerInterface
|
|
*/
|
|
protected $_logger;
|
|
|
|
/**
|
|
* @var Factory
|
|
*/
|
|
private $menuItemFactory;
|
|
|
|
/**
|
|
* @var SerializerInterface
|
|
*/
|
|
private $serializer;
|
|
|
|
/**
|
|
* Menu constructor
|
|
*
|
|
* @param LoggerInterface $logger
|
|
* @param string $pathInMenuStructure
|
|
* @param Factory|null $menuItemFactory
|
|
* @param SerializerInterface|null $serializer
|
|
*/
|
|
public function __construct(
|
|
LoggerInterface $logger,
|
|
$pathInMenuStructure = '',
|
|
Factory $menuItemFactory = null,
|
|
SerializerInterface $serializer = null
|
|
) {
|
|
if ($pathInMenuStructure) {
|
|
$this->_path = $pathInMenuStructure . '/';
|
|
}
|
|
$this->_logger = $logger;
|
|
$this->setIteratorClass(\Magento\Backend\Model\Menu\Iterator::class);
|
|
$this->menuItemFactory = $menuItemFactory ?: ObjectManager::getInstance()
|
|
->create(Factory::class);
|
|
$this->serializer = $serializer ?: ObjectManager::getInstance()->create(SerializerInterface::class);
|
|
}
|
|
|
|
/**
|
|
* Add child to menu item
|
|
*
|
|
* @param Item $item
|
|
* @param string $parentId
|
|
* @param int $index
|
|
* @return void
|
|
* @throws \InvalidArgumentException
|
|
*/
|
|
public function add(Item $item, $parentId = null, $index = null)
|
|
{
|
|
if ($parentId !== null) {
|
|
$parentItem = $this->get($parentId);
|
|
if ($parentItem === null) {
|
|
throw new \InvalidArgumentException("Item with identifier {$parentId} does not exist");
|
|
}
|
|
$parentItem->getChildren()->add($item, null, $index);
|
|
} else {
|
|
$index = (int) $index;
|
|
if (!isset($this[$index])) {
|
|
$this->offsetSet($index, $item);
|
|
$this->_logger->debug(
|
|
sprintf('Add of item with id %s was processed', $item->getId())
|
|
);
|
|
} else {
|
|
$this->add($item, $parentId, $index + 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retrieve menu item by id
|
|
*
|
|
* @param string $itemId
|
|
* @return Item|null
|
|
*/
|
|
public function get($itemId)
|
|
{
|
|
$result = null;
|
|
/** @var Item $item */
|
|
foreach ($this as $item) {
|
|
if ($item->getId() == $itemId) {
|
|
$result = $item;
|
|
break;
|
|
}
|
|
|
|
if ($item->hasChildren() && ($result = $item->getChildren()->get($itemId))) {
|
|
break;
|
|
}
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Move menu item
|
|
*
|
|
* @param string $itemId
|
|
* @param string $toItemId
|
|
* @param int $sortIndex
|
|
* @return void
|
|
* @throws \InvalidArgumentException
|
|
*/
|
|
public function move($itemId, $toItemId, $sortIndex = null)
|
|
{
|
|
$item = $this->get($itemId);
|
|
if ($item === null) {
|
|
throw new \InvalidArgumentException("Item with identifier {$itemId} does not exist");
|
|
}
|
|
$this->remove($itemId);
|
|
$this->add($item, $toItemId, $sortIndex);
|
|
}
|
|
|
|
/**
|
|
* Remove menu item by id
|
|
*
|
|
* @param string $itemId
|
|
* @return bool
|
|
*/
|
|
public function remove($itemId)
|
|
{
|
|
$result = false;
|
|
/** @var Item $item */
|
|
foreach ($this as $key => $item) {
|
|
if ($item->getId() == $itemId) {
|
|
unset($this[$key]);
|
|
$result = true;
|
|
$this->_logger->debug(
|
|
sprintf('Remove on item with id %s was processed', $item->getId())
|
|
);
|
|
break;
|
|
}
|
|
|
|
if ($item->hasChildren() && ($result = $item->getChildren()->remove($itemId))) {
|
|
break;
|
|
}
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Change order of an item in its parent menu
|
|
*
|
|
* @param string $itemId
|
|
* @param int $position
|
|
* @return bool
|
|
*/
|
|
public function reorder($itemId, $position)
|
|
{
|
|
$result = false;
|
|
/** @var Item $item */
|
|
foreach ($this as $key => $item) {
|
|
if ($item->getId() == $itemId) {
|
|
unset($this[$key]);
|
|
$this->add($item, null, $position);
|
|
$result = true;
|
|
break;
|
|
} elseif ($item->hasChildren() && $result = $item->getChildren()->reorder($itemId, $position)) {
|
|
break;
|
|
}
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Check whether provided item is last in list
|
|
*
|
|
* @param Item $item
|
|
* @return bool
|
|
*/
|
|
public function isLast(Item $item)
|
|
{
|
|
return $this->offsetGet(max(array_keys($this->getArrayCopy())))->getId() == $item->getId();
|
|
}
|
|
|
|
/**
|
|
* Find first menu item that user is able to access
|
|
*
|
|
* @return Item|null
|
|
*/
|
|
public function getFirstAvailable()
|
|
{
|
|
$result = null;
|
|
/** @var Item $item */
|
|
foreach ($this as $item) {
|
|
if ($item->isAllowed() && !$item->isDisabled()) {
|
|
if ($item->hasChildren()) {
|
|
$result = $item->getChildren()->getFirstAvailable();
|
|
if (false == ($result === null)) {
|
|
break;
|
|
}
|
|
} else {
|
|
$result = $item;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Get parent items by item id
|
|
*
|
|
* @param string $itemId
|
|
* @return Item[]
|
|
*/
|
|
public function getParentItems($itemId)
|
|
{
|
|
$parents = [];
|
|
$this->_findParentItems($this, $itemId, $parents);
|
|
return array_reverse($parents);
|
|
}
|
|
|
|
/**
|
|
* Find parent items
|
|
*
|
|
* @param \Magento\Backend\Model\Menu $menu
|
|
* @param string $itemId
|
|
* @param array $parents
|
|
* @return bool
|
|
*/
|
|
protected function _findParentItems($menu, $itemId, &$parents)
|
|
{
|
|
/** @var Item $item */
|
|
foreach ($menu as $item) {
|
|
if ($item->getId() == $itemId) {
|
|
return true;
|
|
}
|
|
if ($item->hasChildren()) {
|
|
if ($this->_findParentItems($item->getChildren(), $itemId, $parents)) {
|
|
$parents[] = $item;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Serialize menu
|
|
*
|
|
* @return string
|
|
*/
|
|
#[\ReturnTypeWillChange]
|
|
public function serialize()
|
|
{
|
|
return $this->serializer->serialize($this->toArray());
|
|
}
|
|
|
|
/**
|
|
* Get menu data represented as an array
|
|
*
|
|
* @return array
|
|
* @since 100.2.0
|
|
*/
|
|
public function toArray()
|
|
{
|
|
$data = [];
|
|
foreach ($this as $item) {
|
|
$data[] = $item->toArray();
|
|
}
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Unserialize menu
|
|
*
|
|
* @param string $serialized
|
|
* @return void
|
|
* @since 100.2.0
|
|
*/
|
|
#[\ReturnTypeWillChange]
|
|
public function unserialize($serialized)
|
|
{
|
|
$data = $this->serializer->unserialize($serialized);
|
|
$this->populateFromArray($data);
|
|
}
|
|
|
|
/**
|
|
* Populate the menu with data from array
|
|
*
|
|
* @param array $data
|
|
* @return void
|
|
* @since 100.2.0
|
|
*/
|
|
public function populateFromArray(array $data)
|
|
{
|
|
$items = [];
|
|
foreach ($data as $itemData) {
|
|
$item = $this->menuItemFactory->create($itemData);
|
|
$items[] = $item;
|
|
}
|
|
$this->exchangeArray($items);
|
|
}
|
|
}
|