PageRenderTime 26ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/smarty_tiki/function.menu.php

https://gitlab.com/ElvisAns/tiki
PHP | 248 lines | 189 code | 33 blank | 26 comment | 53 complexity | e004a3abc0400941533c7d8f923fff9e MD5 | raw file
  1. <?php
  2. // (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
  3. //
  4. // All Rights Reserved. See copyright.txt for details and a complete list of authors.
  5. // Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
  6. // $Id$
  7. /* params
  8. * - link_on_section
  9. * - css = use suckerfish menu
  10. * - type = vert|horiz
  11. * - id = menu ID (mandatory)
  12. * - translate = y|n , n means no option translation (default y)
  13. * - menu_cookie=y|n (default y) n, it will automatically open the submenu the url is in
  14. * - bs_menu_class='' custom class for the top level bootstrap menu element
  15. * - sectionLevel: displays from this level only
  16. * - toLevel : displays to this level only
  17. * - drilldown ??
  18. * - bootstrap : navbar|basic (equates to horiz or vert in old menus)
  19. * - setSelected=y|n (default=y) processes all menu items to show currently selected item, also sets open states, sectionLevel, toLevel etc
  20. * so menu_cookie, sectionLevel and toLevel will be ignored if this is set to n
  21. */
  22. function smarty_function_menu($params, $smarty)
  23. {
  24. global $prefs;
  25. $default = ['css' => 'y'];
  26. if (isset($params['params'])) {
  27. $params = array_merge($params, $params['params']);
  28. unset($params['params']);
  29. }
  30. $params = array_merge($default, $params);
  31. extract($params, EXTR_SKIP);
  32. if (empty($link_on_section) || $link_on_section == 'y') {
  33. $smarty->assign('link_on_section', 'y');
  34. } else {
  35. $smarty->assign('link_on_section', 'n');
  36. }
  37. if (empty($translate)) {
  38. $translate = 'y';
  39. }
  40. $smarty->assignByRef('translate', $translate);
  41. if (empty($menu_cookie)) {
  42. $menu_cookie = 'y';
  43. }
  44. $smarty->assignByRef('menu_cookie', $menu_cookie);
  45. if (empty($bs_menu_class)) {
  46. $bs_menu_class = '';
  47. }
  48. $smarty->assignByRef('bs_menu_class', $bs_menu_class);
  49. list($menu_info, $channels) = get_menu_with_selections($params);
  50. $smarty->assign('menu_channels', $channels['data']);
  51. $smarty->assign('menu_info', $menu_info);
  52. $objectCategories = TikiLib::lib('categ')->get_current_object_categories();
  53. if ($objectCategories) {
  54. $categGroups = array_values(
  55. array_filter(
  56. array_map(
  57. function ($categId) {
  58. $categ = TikiLib::lib('categ')->get_category($categId);
  59. $parent = TikiLib::lib('categ')->get_category($categ["parentId"]);
  60. if (! $parent || $parent["parentId"] != 0 || ! $parent["tplGroupContainerId"]) {
  61. return null;
  62. }
  63. $templatedgroupid = TikiLib::lib('attribute')->get_attribute("category", $categId, "tiki.category.templatedgroupid");
  64. $tplGroup = TikiLib::lib('user')->get_groupId_info($templatedgroupid);
  65. if (empty($tplGroup['groupName'])) {
  66. return null;
  67. }
  68. return [$parent["tplGroupContainerId"] => $tplGroup['groupName']];
  69. },
  70. $objectCategories
  71. ),
  72. function ($group) {
  73. return $group != null;
  74. }
  75. )
  76. );
  77. } else {
  78. $categGroups = [];
  79. }
  80. if (isset($params['bootstrap']) && $params['bootstrap'] !== 'n' && $prefs['javascript_enabled'] === 'y') {
  81. $structured = [];
  82. // Unification with structure menus - adds sectionLevel
  83. if (empty($menu_info['structure'])) {
  84. $channels['data'] = add_section_levels_to_menu_data($channels['data']);
  85. }
  86. // Builds Menus nested tree of options
  87. foreach ($channels['data'] as $element) {
  88. $attribute = TikiLib::lib('attribute')->get_attribute('menu', $element["optionId"], 'tiki.menu.templatedgroupid');
  89. if ($attribute && $catName = $categGroups[$attribute]) {
  90. $element["name"] = str_replace("--groupname--", $catName, $element["name"]);
  91. $element["url"] = str_replace("--groupname--", $catName, $element["name"]);
  92. $element["sefurl"] = str_replace("--groupname--", $catName, $element["sefurl"]);
  93. $element["canonic"] = str_replace("--groupname--", $catName, $element["canonic"]);
  94. } elseif ($attribute && ! $categGroups[$attribute]) {
  95. continue;
  96. }
  97. if ($element['type'] !== '-') {
  98. $level = $element['sectionLevel'];
  99. // Creates new branch at level 0
  100. if ($level === 0) {
  101. array_push($structured, $element);
  102. continue;
  103. }
  104. // Always selects last branch at level 0
  105. $branch = &$structured[count($structured) - 1];
  106. // Selects nested part of the branch at element level
  107. for ($i = 0; $i < $level - 1; $i++) {
  108. if ($branch['children']) {
  109. $branch = &$branch['children'][count($branch['children']) - 1];
  110. }
  111. }
  112. // Pushes the element at the end of selected element children.
  113. if (! empty($branch['children'])) {
  114. array_push($branch['children'], $element);
  115. } else {
  116. $branch['children'] = [$element];
  117. }
  118. }
  119. }
  120. $smarty->assign('list', $structured);
  121. return $smarty->fetch('bootstrap_menu.tpl');
  122. }
  123. if ($params['css'] !== 'n' && $prefs['feature_cssmenus'] == 'y') {
  124. static $idCssmenu = 0;
  125. if (! isset($css_id)) {//adding $css_id parameter to customize menu id and prevent automatic id renaming when a menu is removed
  126. $smarty->assign('idCssmenu', $idCssmenu++);
  127. } else {
  128. $smarty->assign('idCssmenu', $css_id);
  129. }
  130. if (empty($params['type'])) {
  131. $params['type'] = 'vert';
  132. }
  133. $smarty->assign('menu_type', $params['type']);
  134. if (! empty($drilldown) && $drilldown == 'y') {
  135. $smarty->assign('drilldownmenu', 'y');
  136. }
  137. $tpl = 'tiki-user_cssmenu.tpl';
  138. } else {
  139. $tpl = 'tiki-user_menu.tpl';
  140. }
  141. $data = $smarty->fetch($tpl);
  142. return MenuLib::clean_menu_html($data);
  143. }
  144. function compare_menu_options($a, $b)
  145. {
  146. return strcmp(tra($a['name']), tra($b['name']));
  147. }
  148. function get_menu_with_selections($params)
  149. {
  150. global $user, $prefs;
  151. $tikilib = TikiLib::lib('tiki');
  152. $menulib = TikiLib::lib('menu');
  153. $cachelib = TikiLib::lib('cache');
  154. $cacheName = isset($prefs['mylevel']) ? $prefs['mylevel'] : 0;
  155. $cacheName .= '_' . $prefs['language'] . '_' . md5(implode("\n", $tikilib->get_user_groups($user)));
  156. extract($params, EXTR_SKIP);
  157. if (isset($structureId)) {
  158. $cacheType = 'structure_' . $structureId . '_';
  159. } else {
  160. $cacheType = 'menu_' . $id . '_';
  161. }
  162. if ($cdata = $cachelib->getSerialized($cacheName, $cacheType)) {
  163. list($menu_info, $channels) = $cdata;
  164. } elseif (! empty($structureId)) {
  165. $structlib = TikiLib::lib('struct');
  166. if (! is_numeric($structureId)) {
  167. $structureId = $structlib->get_struct_ref_id($structureId);
  168. }
  169. $channels = $structlib->build_subtree_toc($structureId);
  170. $structure_info = $structlib->s_get_page_info($structureId);
  171. $channels = $structlib->to_menu($channels, $structure_info['pageName'], 0, 0, $params);
  172. $menu_info = ['type' => 'd', 'menuId' => $structureId, 'structure' => 'y'];
  173. } elseif (! empty($id)) {
  174. $menu_info = $menulib->get_menu($id);
  175. $channels = $menulib->list_menu_options($id, 0, -1, 'position_asc', '', '', isset($prefs['mylevel']) ? $prefs['mylevel'] : 0);
  176. $channels = $menulib->sort_menu_options($channels);
  177. } else {
  178. return '<span class="alert-warning">menu function: Menu or Structure ID not set</span>';
  179. }
  180. if (strpos($_SERVER['SCRIPT_NAME'], 'tiki-register') === false) {
  181. $cachelib->cacheItem($cacheName, serialize([$menu_info, $channels]), $cacheType);
  182. }
  183. if (! isset($setSelected) || $setSelected !== 'n') {
  184. $channels = $menulib->setSelected($channels, isset($sectionLevel) ? $sectionLevel : '', isset($toLevel) ? $toLevel : '', $params);
  185. }
  186. foreach ($channels['data'] as & $item) {
  187. if (! empty($menu_info['parse']) && $menu_info['parse'] === 'y') {
  188. $item['block'] = TikiLib::lib('parser')->contains_html_block($item['name']); // Only used for CSS menus
  189. $item['name'] = preg_replace('/(.*)\n$/', '$1', $item['name']); // parser adds a newline to everything
  190. }
  191. }
  192. return [$menu_info, $channels];
  193. }
  194. function add_section_levels_to_menu_data($data)
  195. {
  196. $sectionLevel = 0;
  197. $prev_type = null;
  198. $new_data = array_map(function ($menu_item) use (&$sectionLevel, &$prev_type) {
  199. if ($menu_item['type'] === 's') {
  200. $sectionLevel = 0;
  201. } elseif (($prev_type === 's' || is_numeric($prev_type)) && $menu_item['type'] === 'o') {
  202. $sectionLevel++;
  203. } elseif ($menu_item['type'] === '-') {
  204. if ($sectionLevel - 1 >= 0) {
  205. $sectionLevel--;
  206. }
  207. } elseif (is_numeric($menu_item['type'])) {
  208. $sectionLevel = (int)$menu_item['type'];
  209. }
  210. $prev_type = $menu_item['type'];
  211. $menu_item['sectionLevel'] = $sectionLevel;
  212. return $menu_item;
  213. }, $data);
  214. return $new_data;
  215. }