modmenu.class.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. <?php
  2. /*
  3. * This file is part of MODX Revolution.
  4. *
  5. * Copyright (c) MODX, LLC. All Rights Reserved.
  6. *
  7. * For complete copyright and license information, see the COPYRIGHT and LICENSE
  8. * files found in the top-level directory of this distribution.
  9. */
  10. /**
  11. * Represents a menu item at the top of the MODX manager.
  12. *
  13. * @property string $text The text of the menu item. Can be a lexicon key.
  14. * @property int $action The modAction ID this menu item maps to.
  15. * @property string $description The description text for the menu item. Can be a lexicon key.
  16. * @property string $icon The icon for the menu item (not used)
  17. * @property int $menuindex The index, or rank, of the menu in its level
  18. * @property string $params Any REQUEST params to be attached to the link
  19. * @property string $handler If specified, instead of a link, this JS will be used to handle the menu item
  20. * @property string $permissions A comma-separated list of required permissions to view this menu item
  21. *
  22. * @see modAction
  23. * @package modx
  24. */
  25. class modMenu extends modAccessibleObject {
  26. /**
  27. * Overrides xPDOObject::save to cache the menus.
  28. *
  29. * {@inheritdoc}
  30. */
  31. public function save($cacheFlag = null) {
  32. $saved = parent::save($cacheFlag);
  33. if ($saved && empty($this->xpdo->config[xPDO::OPT_SETUP])) {
  34. $this->rebuildCache();
  35. }
  36. return $saved;
  37. }
  38. /**
  39. * Overrides xPDOObject::remove to cache the menus.
  40. *
  41. * {@inheritdoc}
  42. */
  43. public function remove(array $ancestors = array()) {
  44. $removed = parent::remove($ancestors);
  45. if ($removed && empty($this->xpdo->config[xPDO::OPT_SETUP])) {
  46. $this->rebuildCache();
  47. }
  48. return $removed;
  49. }
  50. /**
  51. * Rebuilds the menu map cache.
  52. *
  53. * @param string $start The start menu to build from recursively.
  54. * @return array An array of modMenu objects, in tree form.
  55. */
  56. public function rebuildCache($start = '') {
  57. $cacheKey = 'menus/';
  58. if ($start !== '') {
  59. $cacheKey .= "{$start}/";
  60. }
  61. $cacheKey .= $this->xpdo->getOption('manager_language',null,$this->xpdo->getOption('cultureKey',null,'en'));
  62. $menus = $this->getSubMenus($start);
  63. $cached = $this->xpdo->cacheManager->set($cacheKey, $menus, 0, array(
  64. xPDO::OPT_CACHE_KEY => $this->xpdo->cacheManager->getOption('cache_menu_key', null, 'menu'),
  65. xPDO::OPT_CACHE_HANDLER => $this->xpdo->cacheManager->getOption('cache_menu_handler', null, $this->xpdo->getOption(xPDO::OPT_CACHE_HANDLER)),
  66. xPDO::OPT_CACHE_FORMAT => (integer) $this->xpdo->getOption('cache_menu_format', null, $this->xpdo->getOption(xPDO::OPT_CACHE_FORMAT, null, xPDOCacheManager::CACHE_PHP)),
  67. ));
  68. if ($cached === false) {
  69. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "The menu cache key {$cacheKey} could not be written.");
  70. }
  71. return $menus;
  72. }
  73. /**
  74. * Gets all submenus from a start menu.
  75. *
  76. * @param string $start The top menu to load from.
  77. * @return array An array of modMenu objects, in tree form.
  78. */
  79. public function getSubMenus($start = '') {
  80. if (!$this->xpdo->lexicon) {
  81. $this->xpdo->getService('lexicon','modLexicon');
  82. }
  83. $this->xpdo->lexicon->load('menu','topmenu');
  84. $c = $this->xpdo->newQuery('modMenu');
  85. $c->select($this->xpdo->getSelectColumns('modMenu', 'modMenu'));
  86. /* 2.2 and earlier support */
  87. $c->leftJoin('modAction','Action');
  88. $c->select(array(
  89. 'action_controller' => 'Action.controller',
  90. 'action_namespace' => 'Action.namespace',
  91. ));
  92. $c->where(array(
  93. 'modMenu.parent' => $start,
  94. ));
  95. $c->sortby($this->xpdo->getSelectColumns('modMenu','modMenu','',array('menuindex')),'ASC');
  96. $menus = $this->xpdo->getCollection('modMenu',$c);
  97. if (count($menus) < 1) return array();
  98. $list = array();
  99. /** @var modMenu $menu */
  100. foreach ($menus as $menu) {
  101. $ma = $menu->toArray();
  102. $ma['id'] = $menu->get('text');
  103. $action = $menu->get('action');
  104. $namespace = $menu->get('namespace');
  105. // allow 2.2 and earlier actions
  106. $deprecatedNamespace = $menu->get('action_namespace');
  107. if (!empty($deprecatedNamespace)) {
  108. $this->xpdo->deprecated('2.3.0', 'Support for modAction has been replaced with routing based on a namespace and action name. Please update the extra with the namespace ' . $deprecatedNamespace . ' to the routing based system.', 'modAction support');
  109. $namespace = $deprecatedNamespace;
  110. }
  111. if ($namespace != 'core') {
  112. $this->xpdo->lexicon->load($namespace.':default');
  113. }
  114. /* if 3rd party menu item, load proper text */
  115. if (!empty($action)) {
  116. if (!empty($namespace) && $namespace != 'core') {
  117. $ma['text'] = $menu->get('text') === 'user'
  118. ? $this->xpdo->lexicon($menu->get('text'), array('username' => $this->xpdo->getLoginUserName()))
  119. : $this->xpdo->lexicon($menu->get('text'));
  120. } else {
  121. $ma['text'] = $menu->get('text') === 'user'
  122. ? $this->xpdo->lexicon($menu->get('text'), array('username' => $this->xpdo->getLoginUserName()))
  123. : $this->xpdo->lexicon($menu->get('text'));
  124. }
  125. } else {
  126. $ma['text'] = $menu->get('text') === 'user'
  127. ? $this->xpdo->lexicon($menu->get('text'), array('username' => $this->xpdo->getLoginUserName()))
  128. : $this->xpdo->lexicon($menu->get('text'));
  129. }
  130. $desc = $menu->get('description');
  131. $ma['description'] = !empty($desc) ? $this->xpdo->lexicon($desc) : '';
  132. $ma['children'] = $menu->get('text') != '' ? $this->getSubMenus($menu->get('text')) : array();
  133. if ($menu->get('controller')) {
  134. $ma['controller'] = $menu->get('controller');
  135. } else {
  136. $ma['controller'] = '';
  137. }
  138. $list[] = $ma;
  139. }
  140. unset($menu,$desc,$namespace,$ma);
  141. return $list;
  142. }
  143. }