/[drupal]/contributions/modules/dhtml_menu/dhtml_menu.theme.inc
ViewVC logotype

Contents of /contributions/modules/dhtml_menu/dhtml_menu.theme.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.12 - (show annotations) (download) (as text)
Sun Oct 25 14:32:36 2009 UTC (4 weeks, 6 days ago) by arancaytar
Branch: MAIN
Branch point for: DRUPAL-6--4
Changes since 1.11: +2 -2 lines
File MIME type: text/x-php
#473356: Stop truncating the ID element in the cookie - the 'dhtml_menu-' has been trimmed both needlessly and incompletely.
1 <?php
2 // $Id: dhtml_menu.theme.inc,v 1.11 2009/10/25 14:27:48 arancaytar Exp $
3
4
5 /**
6 * @file dhtml_menu.theme.inc
7 * All functions related to generating the menu markup.
8 */
9
10 /**
11 * Preprocessor for menu_item_link.
12 * Adds an ID attribute to menu links and helps the module
13 * follow the recursion of menu_tree_output().
14 */
15 function dhtml_menu_theme_menu_item_link($link) {
16 global $theme;
17 $function = &drupal_static(__FUNCTION__);
18 $settings = variable_get('dhtml_menu_settings');
19 if (!isset($function)) {
20 $registry = variable_get('dhtml_menu_theme', array());
21 if (isset($registry[$theme]) && function_exists($registry[$theme]['menu_item_link'])) {
22 $function = $registry[$theme]['menu_item_link'];
23 }
24 else {
25 $function = 'theme_menu_item_link';
26 }
27 }
28
29 // Do not stack items that have no menu or mlid.
30 if (empty($link['menu_name']) || empty($link['mlid'])) {
31 return $function($link);
32 }
33
34 $extended_link = $link;
35
36 // If the menu is blacklisted or not whitelisted, mark the link as disabled for DHTML.
37 $extended_link['dhtml_disabled'] = ($settings['filter']['type'] == 'blacklist') == !empty($settings['filter']['list'][$link['menu_name']]);
38
39 // Add the ID attribute.
40 $extended_link = array_merge_recursive($extended_link, array('localized_options' => array('attributes' => array())));
41 $extended_link['localized_options']['attributes']['id'] = 'dhtml_menu-' . _dhtml_menu_unique_id($link['mlid']);
42
43 // Each link in series is another level of recursion. Add it to the stack, even if it is disabled.
44 _dhtml_menu_stack($extended_link);
45
46 // Pass the altered variables to the normal menu themer, but only if DHTML should be used.
47 return $function(!$extended_link['dhtml_disabled'] ? $extended_link : $link);
48 }
49
50 /**
51 * Preprocessor for menu_item.
52 * Checks whether the current item has children that
53 * were not rendered, and loads and renders them.
54 */
55 function dhtml_menu_theme_menu_item($link, $has_children, $menu = '', $in_active_trail = FALSE, $extra_class = NULL) {
56 global $theme;
57 $cookie = &drupal_static(__FUNCTION__ . ':cookie', array());
58 $function = &drupal_static(__FUNCTION__ . ':function');
59
60 if (empty($function)) {
61 $settings = variable_get('dhtml_menu_settings');
62 if ($settings['effects']['remember'] && $settings['nav'] != 'open' && $settings['effects']['siblings'] != 'close-all') {
63 $cookie = explode(',', @$_COOKIE['dhtml_menu']);
64 }
65 $registry = variable_get('dhtml_menu_theme', array());
66 if (isset($registry[$theme]) && function_exists($registry[$theme]['menu_item'])) {
67 $function = $registry[$theme]['menu_item'];
68 }
69 else {
70 $function = 'theme_menu_item';
71 }
72 }
73
74 /* When theme('menu_item') is called, the menu tree below it has been
75 * rendered already. Since we are done on this recursion level,
76 * one element must be popped off the stack.
77 */
78 $item = _dhtml_menu_stack();
79
80 // If this item should not have DHTML, then return to the "parent" function.
81 if (!$item || !empty($item['dhtml_disabled'])) {
82 return $function($link, $has_children, $menu, $in_active_trail, $extra_class);
83 }
84
85 $extra_class .= ' dhtml-menu ';
86
87 // If there are children, but they were not loaded...
88 if ($has_children && !$menu) {
89 // Load the tree below the current position.
90 $tree = _dhtml_menu_subtree($item);
91
92 // Render it...
93 $menu = menu_tree_output($tree);
94
95 // Sanitize the tree - uncheck has_children if no children were loaded.
96 if (!$menu) {
97 $has_children = FALSE;
98 }
99 }
100
101 // If the current item can expand, and is neither saved as open nor in the active trail, close it.
102 if ($menu && !($in_active_trail || in_array($item['localized_options']['attributes']['id'], $cookie))) {
103 $extra_class .= ' collapsed start-collapsed ';
104 }
105
106 // Cascade up to the original theming function.
107 return $function($link, $has_children, $menu, $in_active_trail, $extra_class);
108 }
109
110 /**
111 * Helper function for storing recursion levels.
112 *
113 * @param $link
114 * If a menu item link is passed, it will be pushed onto the stack.
115 * Otherwise, one element will be popped off the stack.
116 *
117 * @return
118 * The last element of the stack, if no argument is passed.
119 */
120 function _dhtml_menu_stack($link = FALSE) {
121 static $stack = array();
122 if ($link) {
123 $stack[] = $link;
124 }
125 else {
126 return array_pop($stack);
127 }
128 }
129
130 /**
131 * Traverses the menu tree and returns the sub-tree of the item
132 * indicated by the parameter.
133 *
134 * @param $item
135 * A menu item link that must contain the keys "mlid" and "menu_name".
136 *
137 * @return
138 * The tree below the menu item, or an empty array.
139 */
140 function _dhtml_menu_subtree($item) {
141 static $index = array();
142 static $indexed = array();
143
144 // This looks expensive, but menu_tree_all_data uses static caching.
145 $tree = menu_tree_all_data($item['menu_name']);
146
147 // Index the menu tree to find ancestor paths for each item.
148 if (!isset($indexed[$item['menu_name']])) {
149 $index += _dhtml_menu_index($tree);
150 $indexed[$item['menu_name']] = TRUE;
151 }
152
153 // If the menu tree does not contain this item, stop.
154 if (!isset($index[$item['mlid']])) {
155 return array();
156 }
157
158 // Traverse the tree using the ancestor path.
159 foreach ($index[$item['mlid']]['parents'] as $mlid) {
160 $key = $index[$mlid]['key'];
161 if (isset($tree[$key])) {
162 $tree = $tree[$key]['below'];
163 }
164 else {
165 return array();
166 }
167 }
168
169 // Go one level further to go below the current item.
170 $key = $index[$item['mlid']]['key'];
171 return isset($tree[$key]) ? $tree[$key]['below'] : array();
172 }
173
174 /**
175 * Indexes the menu tree by mlid. This is needed to identify the items
176 * without relying on titles or stacks. This function is recursive.
177 *
178 * @param $tree
179 * A tree of menu items such as the return value of menu_tree_all_data().
180 * @param $ancestors
181 * Optional, used only by internal recursion.
182 * @param $parent
183 * Optional, used only by internal recursion.
184 *
185 * @return
186 * An array associating mlid values with the internal keys of the menu tree,
187 * and all the mlids of the item's ancestors.
188 */
189 function _dhtml_menu_index($tree, $ancestors = array(), $parent = NULL) {
190 $index = array();
191 if ($parent) {
192 $ancestors[] = $parent;
193 }
194
195 foreach ($tree as $key => $item) {
196 $index[$item['link']['mlid']] = array(
197 'key' => $key,
198 'parents' => $ancestors,
199 );
200 if (!empty($item['below'])) {
201 $index += _dhtml_menu_index($item['below'], $ancestors, $item['link']['mlid']);
202 }
203 }
204 return $index;
205 }
206
207 /**
208 * Keeps track of ID attributes and adds a suffix to make it unique-when necessary.
209 */
210 function _dhtml_menu_unique_id($id) {
211 static $ids = array();
212 if (!isset($ids[$id])) {
213 $ids[$id] = 1;
214 return $id;
215 }
216 else {
217 return $id . '-' . $ids[$id]++;
218 }
219 }
220

  ViewVC Help
Powered by ViewVC 1.1.2