Item.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Backend\Model\Menu;
  7. use Magento\Backend\Model\Menu;
  8. use Magento\Store\Model\ScopeInterface;
  9. /**
  10. * Menu item. Should be used to create nested menu structures with \Magento\Backend\Model\Menu
  11. *
  12. * @api
  13. * @SuppressWarnings(PHPMD.TooManyFields)
  14. * @since 100.0.2
  15. */
  16. class Item
  17. {
  18. /**
  19. * Menu item id
  20. *
  21. * @var string
  22. */
  23. protected $_id;
  24. /**
  25. * Menu item title
  26. *
  27. * @var string
  28. */
  29. protected $_title;
  30. /**
  31. * Module of menu item
  32. *
  33. * @var string
  34. */
  35. protected $_moduleName;
  36. /**
  37. * Menu item sort index in list
  38. *
  39. * @var string
  40. */
  41. protected $_sortIndex = null;
  42. /**
  43. * Menu item action
  44. *
  45. * @var string
  46. */
  47. protected $_action = null;
  48. /**
  49. * Parent menu item id
  50. *
  51. * @var string
  52. */
  53. protected $_parentId = null;
  54. /**
  55. * Acl resource of menu item
  56. *
  57. * @var string
  58. */
  59. protected $_resource;
  60. /**
  61. * Item tooltip text
  62. *
  63. * @var string
  64. */
  65. protected $_tooltip;
  66. /**
  67. * Path from root element in tree
  68. *
  69. * @var string
  70. */
  71. protected $_path = '';
  72. /**
  73. * Acl
  74. *
  75. * @var \Magento\Framework\AuthorizationInterface
  76. */
  77. protected $_acl;
  78. /**
  79. * Module that item is dependent on
  80. *
  81. * @var string|null
  82. */
  83. protected $_dependsOnModule;
  84. /**
  85. * Global config option that item is dependent on
  86. *
  87. * @var string|null
  88. */
  89. protected $_dependsOnConfig;
  90. /**
  91. * Submenu item list
  92. *
  93. * @var Menu
  94. */
  95. protected $_submenu;
  96. /**
  97. * @var \Magento\Backend\Model\MenuFactory
  98. */
  99. protected $_menuFactory;
  100. /**
  101. * @var \Magento\Backend\Model\UrlInterface
  102. */
  103. protected $_urlModel;
  104. /**
  105. * @var \Magento\Framework\App\Config\ScopeConfigInterface
  106. */
  107. protected $_scopeConfig;
  108. /**
  109. * @var \Magento\Backend\Model\Menu\Item\Validator
  110. */
  111. protected $_validator;
  112. /**
  113. * Serialized submenu string
  114. *
  115. * @var string
  116. * @deprecated 100.2.0
  117. */
  118. protected $_serializedSubmenu;
  119. /**
  120. * Module list
  121. *
  122. * @var \Magento\Framework\Module\ModuleListInterface
  123. */
  124. protected $_moduleList;
  125. /**
  126. * @var \Magento\Framework\Module\Manager
  127. */
  128. private $_moduleManager;
  129. /**
  130. * Menu item target
  131. *
  132. * @var string|null
  133. */
  134. private $target;
  135. /**
  136. * @param Item\Validator $validator
  137. * @param \Magento\Framework\AuthorizationInterface $authorization
  138. * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
  139. * @param \Magento\Backend\Model\MenuFactory $menuFactory
  140. * @param \Magento\Backend\Model\UrlInterface $urlModel
  141. * @param \Magento\Framework\Module\ModuleListInterface $moduleList
  142. * @param \Magento\Framework\Module\Manager $moduleManager
  143. * @param array $data
  144. */
  145. public function __construct(
  146. \Magento\Backend\Model\Menu\Item\Validator $validator,
  147. \Magento\Framework\AuthorizationInterface $authorization,
  148. \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
  149. \Magento\Backend\Model\MenuFactory $menuFactory,
  150. \Magento\Backend\Model\UrlInterface $urlModel,
  151. \Magento\Framework\Module\ModuleListInterface $moduleList,
  152. \Magento\Framework\Module\Manager $moduleManager,
  153. array $data = []
  154. ) {
  155. $this->_validator = $validator;
  156. $this->_validator->validate($data);
  157. $this->_moduleManager = $moduleManager;
  158. $this->_acl = $authorization;
  159. $this->_scopeConfig = $scopeConfig;
  160. $this->_menuFactory = $menuFactory;
  161. $this->_urlModel = $urlModel;
  162. $this->_moduleList = $moduleList;
  163. $this->populateFromArray($data);
  164. }
  165. /**
  166. * Retrieve argument element, or default value
  167. *
  168. * @param array $array
  169. * @param string $key
  170. * @param mixed $defaultValue
  171. * @return mixed
  172. */
  173. protected function _getArgument(array $array, $key, $defaultValue = null)
  174. {
  175. return isset($array[$key]) ? $array[$key] : $defaultValue;
  176. }
  177. /**
  178. * Retrieve item id
  179. *
  180. * @return string
  181. */
  182. public function getId()
  183. {
  184. return $this->_id;
  185. }
  186. /**
  187. * Retrieve item target
  188. *
  189. * @return string|null
  190. * @since 100.2.0
  191. */
  192. public function getTarget()
  193. {
  194. return $this->target;
  195. }
  196. /**
  197. * Check whether item has subnodes
  198. *
  199. * @return bool
  200. */
  201. public function hasChildren()
  202. {
  203. return (null !== $this->_submenu) && (bool)$this->_submenu->count();
  204. }
  205. /**
  206. * Retrieve submenu
  207. *
  208. * @return Menu
  209. */
  210. public function getChildren()
  211. {
  212. if (!$this->_submenu) {
  213. $this->_submenu = $this->_menuFactory->create();
  214. }
  215. return $this->_submenu;
  216. }
  217. /**
  218. * Retrieve menu item url
  219. *
  220. * @return string
  221. */
  222. public function getUrl()
  223. {
  224. if ((bool)$this->_action) {
  225. return $this->_urlModel->getUrl((string)$this->_action, ['_cache_secret_key' => true]);
  226. }
  227. return '#';
  228. }
  229. /**
  230. * Retrieve menu item action
  231. *
  232. * @return string
  233. */
  234. public function getAction()
  235. {
  236. return $this->_action;
  237. }
  238. /**
  239. * Set Item action
  240. *
  241. * @param string $action
  242. * @return $this
  243. * @throws \InvalidArgumentException
  244. */
  245. public function setAction($action)
  246. {
  247. $this->_validator->validateParam('action', $action);
  248. $this->_action = $action;
  249. return $this;
  250. }
  251. /**
  252. * Check whether item has javascript callback on click
  253. *
  254. * @return bool
  255. */
  256. public function hasClickCallback()
  257. {
  258. return $this->getUrl() == '#';
  259. }
  260. /**
  261. * Retrieve item click callback
  262. *
  263. * @return string
  264. */
  265. public function getClickCallback()
  266. {
  267. if ($this->getUrl() == '#') {
  268. return 'return false;';
  269. }
  270. return '';
  271. }
  272. /**
  273. * Retrieve tooltip text title
  274. *
  275. * @return string
  276. */
  277. public function getTitle()
  278. {
  279. return $this->_title;
  280. }
  281. /**
  282. * Set Item title
  283. *
  284. * @param string $title
  285. * @return $this
  286. * @throws \InvalidArgumentException
  287. */
  288. public function setTitle($title)
  289. {
  290. $this->_validator->validateParam('title', $title);
  291. $this->_title = $title;
  292. return $this;
  293. }
  294. /**
  295. * Check whether item has tooltip text
  296. *
  297. * @return bool
  298. */
  299. public function hasTooltip()
  300. {
  301. return (bool)$this->_tooltip;
  302. }
  303. /**
  304. * Retrieve item tooltip text
  305. *
  306. * @return string
  307. */
  308. public function getTooltip()
  309. {
  310. return $this->_tooltip;
  311. }
  312. /**
  313. * Set Item tooltip
  314. *
  315. * @param string $tooltip
  316. * @return $this
  317. * @throws \InvalidArgumentException
  318. */
  319. public function setTooltip($tooltip)
  320. {
  321. $this->_validator->validateParam('toolTip', $tooltip);
  322. $this->_tooltip = $tooltip;
  323. return $this;
  324. }
  325. /**
  326. * Set Item module
  327. *
  328. * @param string $module
  329. * @return $this
  330. * @throws \InvalidArgumentException
  331. */
  332. public function setModule($module)
  333. {
  334. $this->_validator->validateParam('module', $module);
  335. $this->_moduleName = $module;
  336. return $this;
  337. }
  338. /**
  339. * Set Item module dependency
  340. *
  341. * @param string $moduleName
  342. * @return $this
  343. * @throws \InvalidArgumentException
  344. */
  345. public function setModuleDependency($moduleName)
  346. {
  347. $this->_validator->validateParam('dependsOnModule', $moduleName);
  348. $this->_dependsOnModule = $moduleName;
  349. return $this;
  350. }
  351. /**
  352. * Set Item config dependency
  353. *
  354. * @param string $configPath
  355. * @return $this
  356. * @throws \InvalidArgumentException
  357. */
  358. public function setConfigDependency($configPath)
  359. {
  360. $this->_validator->validateParam('dependsOnConfig', $configPath);
  361. $this->_dependsOnConfig = $configPath;
  362. return $this;
  363. }
  364. /**
  365. * Check whether item is disabled. Disabled items are not shown to user
  366. *
  367. * @return bool
  368. */
  369. public function isDisabled()
  370. {
  371. return !$this->_moduleManager->isOutputEnabled(
  372. $this->_moduleName
  373. ) || !$this->_isModuleDependenciesAvailable() || !$this->_isConfigDependenciesAvailable();
  374. }
  375. /**
  376. * Check whether module that item depends on is active
  377. *
  378. * @return bool
  379. */
  380. protected function _isModuleDependenciesAvailable()
  381. {
  382. if ($this->_dependsOnModule) {
  383. $module = $this->_dependsOnModule;
  384. return $this->_moduleList->has($module);
  385. }
  386. return true;
  387. }
  388. /**
  389. * Check whether config dependency is available
  390. *
  391. * @return bool
  392. */
  393. protected function _isConfigDependenciesAvailable()
  394. {
  395. if ($this->_dependsOnConfig) {
  396. return $this->_scopeConfig->isSetFlag((string)$this->_dependsOnConfig, ScopeInterface::SCOPE_STORE);
  397. }
  398. return true;
  399. }
  400. /**
  401. * Check whether item is allowed to the user
  402. *
  403. * @return bool
  404. */
  405. public function isAllowed()
  406. {
  407. try {
  408. return $this->_acl->isAllowed((string)$this->_resource);
  409. } catch (\Exception $e) {
  410. return false;
  411. }
  412. }
  413. /**
  414. * Get menu item data represented as an array
  415. *
  416. * @return array
  417. * @since 100.2.0
  418. */
  419. public function toArray()
  420. {
  421. return [
  422. 'parent_id' => $this->_parentId,
  423. 'module' => $this->_moduleName,
  424. 'sort_index' => $this->_sortIndex,
  425. 'dependsOnConfig' => $this->_dependsOnConfig,
  426. 'id' => $this->_id,
  427. 'resource' => $this->_resource,
  428. 'path' => $this->_path,
  429. 'action' => $this->_action,
  430. 'dependsOnModule' => $this->_dependsOnModule,
  431. 'toolTip' => $this->_tooltip,
  432. 'title' => $this->_title,
  433. 'target' => $this->target,
  434. 'sub_menu' => isset($this->_submenu) ? $this->_submenu->toArray() : null
  435. ];
  436. }
  437. /**
  438. * Populate the menu item with data from array
  439. *
  440. * @param array $data
  441. * @return void
  442. * @since 100.2.0
  443. */
  444. public function populateFromArray(array $data)
  445. {
  446. $this->_parentId = $this->_getArgument($data, 'parent_id');
  447. $this->_moduleName = $this->_getArgument($data, 'module', 'Magento_Backend');
  448. $this->_sortIndex = $this->_getArgument($data, 'sort_index');
  449. $this->_dependsOnConfig = $this->_getArgument($data, 'dependsOnConfig');
  450. $this->_id = $this->_getArgument($data, 'id');
  451. $this->_resource = $this->_getArgument($data, 'resource');
  452. $this->_path = $this->_getArgument($data, 'path', '');
  453. $this->_action = $this->_getArgument($data, 'action');
  454. $this->_dependsOnModule = $this->_getArgument($data, 'dependsOnModule');
  455. $this->_tooltip = $this->_getArgument($data, 'toolTip');
  456. $this->_title = $this->_getArgument($data, 'title');
  457. $this->target = $this->_getArgument($data, 'target');
  458. $this->_submenu = null;
  459. if (isset($data['sub_menu'])) {
  460. $menu = $this->_menuFactory->create();
  461. $menu->populateFromArray($data['sub_menu']);
  462. $this->_submenu = $menu;
  463. }
  464. }
  465. }