|
1 <?php |
|
2 |
|
3 /** |
|
4 * @file |
|
5 * Administration toolbar for quick access to top level administration items. |
|
6 */ |
|
7 |
|
8 /** |
|
9 * Implements hook_help(). |
|
10 */ |
|
11 function toolbar_help($path, $arg) { |
|
12 switch ($path) { |
|
13 case 'admin/help#toolbar': |
|
14 $output = '<h3>' . t('About') . '</h3>'; |
|
15 $output .= '<p>' . t('The Toolbar module displays links to top-level administration menu items and links from other modules at the top of the screen. For more information, see the online handbook entry for <a href="@toolbar">Toolbar module</a>.', array('@toolbar' => 'http://drupal.org/documentation/modules/toolbar/')) . '</p>'; |
|
16 $output .= '<h3>' . t('Uses') . '</h3>'; |
|
17 $output .= '<dl>'; |
|
18 $output .= '<dt>' . t('Displaying administrative links') . '</dt>'; |
|
19 $output .= '<dd>' . t('The Toolbar module displays a bar containing top-level administrative links across the top of the screen. Below that, the Toolbar module has a <em>drawer</em> section where it displays links provided by other modules, such as the core <a href="@shortcuts-help">Shortcut module</a>. The drawer can be hidden/shown by using the show/hide shortcuts link at the end of the toolbar.', array('@shortcuts-help' => url('admin/help/shortcut'))) . '</dd>'; |
|
20 $output .= '</dl>'; |
|
21 return $output; |
|
22 } |
|
23 } |
|
24 |
|
25 /** |
|
26 * Implements hook_permission(). |
|
27 */ |
|
28 function toolbar_permission() { |
|
29 return array( |
|
30 'access toolbar' => array( |
|
31 'title' => t('Use the administration toolbar'), |
|
32 ), |
|
33 ); |
|
34 } |
|
35 |
|
36 /** |
|
37 * Implements hook_theme(). |
|
38 */ |
|
39 function toolbar_theme($existing, $type, $theme, $path) { |
|
40 $items['toolbar'] = array( |
|
41 'render element' => 'toolbar', |
|
42 'template' => 'toolbar', |
|
43 'path' => drupal_get_path('module', 'toolbar'), |
|
44 ); |
|
45 $items['toolbar_toggle'] = array( |
|
46 'variables' => array( |
|
47 'collapsed' => NULL, |
|
48 'attributes' => array(), |
|
49 ), |
|
50 ); |
|
51 return $items; |
|
52 } |
|
53 |
|
54 /** |
|
55 * Implements hook_menu(). |
|
56 */ |
|
57 function toolbar_menu() { |
|
58 $items['toolbar/toggle'] = array( |
|
59 'title' => 'Toggle drawer visibility', |
|
60 'type' => MENU_CALLBACK, |
|
61 'page callback' => 'toolbar_toggle_page', |
|
62 'access arguments' => array('access toolbar'), |
|
63 ); |
|
64 return $items; |
|
65 } |
|
66 |
|
67 /** |
|
68 * Menu callback; toggles the visibility of the toolbar drawer. |
|
69 */ |
|
70 function toolbar_toggle_page() { |
|
71 global $base_path; |
|
72 // Toggle the value in the cookie. |
|
73 setcookie('Drupal.toolbar.collapsed', !_toolbar_is_collapsed(), NULL, $base_path); |
|
74 // Redirect the user from where he used the toggle element. |
|
75 drupal_goto(); |
|
76 } |
|
77 |
|
78 /** |
|
79 * Formats an element used to toggle the toolbar drawer's visibility. |
|
80 * |
|
81 * @param $variables |
|
82 * An associative array containing: |
|
83 * - collapsed: A boolean value representing the toolbar drawer's visibility. |
|
84 * - attributes: An associative array of HTML attributes. |
|
85 * |
|
86 * @return |
|
87 * An HTML string representing the element for toggling. |
|
88 * |
|
89 * @ingroup themable |
|
90 */ |
|
91 function theme_toolbar_toggle($variables) { |
|
92 if ($variables['collapsed']) { |
|
93 $toggle_text = t('Show shortcuts'); |
|
94 } |
|
95 else { |
|
96 $toggle_text = t('Hide shortcuts'); |
|
97 $variables['attributes']['class'][] = 'toggle-active'; |
|
98 } |
|
99 return l($toggle_text, 'toolbar/toggle', array('query' => drupal_get_destination(), 'attributes' => array('title' => $toggle_text) + $variables['attributes'])); |
|
100 } |
|
101 |
|
102 /** |
|
103 * Determines the current state of the toolbar drawer's visibility. |
|
104 * |
|
105 * @return |
|
106 * TRUE when drawer is collapsed, FALSE when it is expanded. |
|
107 */ |
|
108 function _toolbar_is_collapsed() { |
|
109 // PHP converts dots into underscores in cookie names to avoid problems with |
|
110 // its parser, so we use a converted cookie name. |
|
111 return isset($_COOKIE['Drupal_toolbar_collapsed']) ? $_COOKIE['Drupal_toolbar_collapsed'] : 0; |
|
112 } |
|
113 |
|
114 /** |
|
115 * Implements hook_page_build(). |
|
116 * |
|
117 * Add admin toolbar to the page_top region automatically. |
|
118 */ |
|
119 function toolbar_page_build(&$page) { |
|
120 $page['page_top']['toolbar'] = array( |
|
121 '#pre_render' => array('toolbar_pre_render'), |
|
122 '#access' => user_access('access toolbar'), |
|
123 'toolbar_drawer' => array(), |
|
124 ); |
|
125 } |
|
126 |
|
127 /** |
|
128 * Prerender function for the toolbar. |
|
129 * |
|
130 * Since building the toolbar takes some time, it is done just prior to |
|
131 * rendering to ensure that it is built only if it will be displayed. |
|
132 */ |
|
133 function toolbar_pre_render($toolbar) { |
|
134 $toolbar = array_merge($toolbar, toolbar_view()); |
|
135 return $toolbar; |
|
136 } |
|
137 |
|
138 /** |
|
139 * Implements hook_preprocess_html(). |
|
140 * |
|
141 * Add some page classes, so global page theming can adjust to the toolbar. |
|
142 */ |
|
143 function toolbar_preprocess_html(&$vars) { |
|
144 if (isset($vars['page']['page_top']['toolbar']) && user_access('access toolbar')) { |
|
145 $vars['classes_array'][] = 'toolbar'; |
|
146 if (!_toolbar_is_collapsed()) { |
|
147 $vars['classes_array'][] = 'toolbar-drawer'; |
|
148 } |
|
149 } |
|
150 } |
|
151 |
|
152 /** |
|
153 * Implements hook_preprocess_toolbar(). |
|
154 * |
|
155 * Adding the 'overlay-displace-top' class to the toolbar pushes the overlay |
|
156 * down, so it appears below the toolbar. |
|
157 */ |
|
158 function toolbar_preprocess_toolbar(&$variables) { |
|
159 $variables['classes_array'][] = "overlay-displace-top"; |
|
160 } |
|
161 |
|
162 /** |
|
163 * Implements hook_system_info_alter(). |
|
164 * |
|
165 * Indicate that the 'page_top' region (in which the toolbar will be displayed) |
|
166 * is an overlay supplemental region that should be refreshed whenever its |
|
167 * content is updated. |
|
168 * |
|
169 * This information is provided for any module that might need to use it, not |
|
170 * just the core Overlay module. |
|
171 */ |
|
172 function toolbar_system_info_alter(&$info, $file, $type) { |
|
173 if ($type == 'theme') { |
|
174 $info['overlay_supplemental_regions'][] = 'page_top'; |
|
175 } |
|
176 } |
|
177 |
|
178 /** |
|
179 * Builds the admin menu as a structured array ready for drupal_render(). |
|
180 * |
|
181 * @return |
|
182 * Array of links and settings relating to the admin menu. |
|
183 */ |
|
184 function toolbar_view() { |
|
185 global $user; |
|
186 |
|
187 $module_path = drupal_get_path('module', 'toolbar'); |
|
188 $build = array( |
|
189 '#theme' => 'toolbar', |
|
190 '#attached'=> array( |
|
191 'js' => array( |
|
192 $module_path . '/toolbar.js', |
|
193 array( |
|
194 'data' => array('tableHeaderOffset' => 'Drupal.toolbar.height'), |
|
195 'type' => 'setting' |
|
196 ), |
|
197 ), |
|
198 'css' => array( |
|
199 $module_path . '/toolbar.css', |
|
200 ), |
|
201 'library' => array(array('system', 'jquery.cookie')), |
|
202 ), |
|
203 ); |
|
204 |
|
205 // Retrieve the admin menu from the database. |
|
206 $links = toolbar_menu_navigation_links(toolbar_get_menu_tree()); |
|
207 $build['toolbar_menu'] = array( |
|
208 '#theme' => 'links__toolbar_menu', |
|
209 '#links' => $links, |
|
210 '#attributes' => array('id' => 'toolbar-menu'), |
|
211 '#heading' => array('text' => t('Administrative toolbar'), 'level' => 'h2', 'class' => 'element-invisible'), |
|
212 ); |
|
213 |
|
214 // Add logout & user account links or login link. |
|
215 if ($user->uid) { |
|
216 $links = array( |
|
217 'account' => array( |
|
218 'title' => t('Hello <strong>@username</strong>', array('@username' => format_username($user))), |
|
219 'href' => 'user', |
|
220 'html' => TRUE, |
|
221 'attributes' => array('title' => t('User account')), |
|
222 ), |
|
223 'logout' => array( |
|
224 'title' => t('Log out'), |
|
225 'href' => 'user/logout', |
|
226 ), |
|
227 ); |
|
228 } |
|
229 else { |
|
230 $links = array( |
|
231 'login' => array( |
|
232 'title' => t('Log in'), |
|
233 'href' => 'user', |
|
234 ), |
|
235 ); |
|
236 } |
|
237 $build['toolbar_user'] = array( |
|
238 '#theme' => 'links__toolbar_user', |
|
239 '#links' => $links, |
|
240 '#attributes' => array('id' => 'toolbar-user'), |
|
241 ); |
|
242 |
|
243 // Add a "home" link. |
|
244 $link = array( |
|
245 'home' => array( |
|
246 'title' => '<span class="home-link">Home</span>', |
|
247 'href' => '<front>', |
|
248 'html' => TRUE, |
|
249 'attributes' => array('title' => t('Home')), |
|
250 ), |
|
251 ); |
|
252 $build['toolbar_home'] = array( |
|
253 '#theme' => 'links', |
|
254 '#links' => $link, |
|
255 '#attributes' => array('id' => 'toolbar-home'), |
|
256 ); |
|
257 |
|
258 // Add an anchor to be able to toggle the visibility of the drawer. |
|
259 $build['toolbar_toggle'] = array( |
|
260 '#theme' => 'toolbar_toggle', |
|
261 '#collapsed' => _toolbar_is_collapsed(), |
|
262 '#attributes' => array('class' => array('toggle')), |
|
263 ); |
|
264 |
|
265 // Prepare the drawer links CSS classes. |
|
266 $toolbar_drawer_classes = array( |
|
267 'toolbar-drawer', |
|
268 'clearfix', |
|
269 ); |
|
270 if(_toolbar_is_collapsed()) { |
|
271 $toolbar_drawer_classes[] = 'collapsed'; |
|
272 } |
|
273 $build['toolbar_drawer_classes'] = implode(' ', $toolbar_drawer_classes); |
|
274 |
|
275 return $build; |
|
276 } |
|
277 |
|
278 /** |
|
279 * Gets only the top level items below the 'admin' path. |
|
280 * |
|
281 * @return |
|
282 * An array containing a menu tree of top level items below the 'admin' path. |
|
283 */ |
|
284 function toolbar_get_menu_tree() { |
|
285 $tree = array(); |
|
286 $admin_link = db_query('SELECT * FROM {menu_links} WHERE menu_name = :menu_name AND module = :module AND link_path = :path', array(':menu_name' => 'management', ':module' => 'system', ':path' => 'admin'))->fetchAssoc(); |
|
287 if ($admin_link) { |
|
288 $tree = menu_build_tree('management', array( |
|
289 'expanded' => array($admin_link['mlid']), |
|
290 'min_depth' => $admin_link['depth'] + 1, |
|
291 'max_depth' => $admin_link['depth'] + 1, |
|
292 )); |
|
293 } |
|
294 |
|
295 return $tree; |
|
296 } |
|
297 |
|
298 /** |
|
299 * Generates a links array from a menu tree array. |
|
300 * |
|
301 * Based on menu_navigation_links(). Adds path based IDs and icon placeholders |
|
302 * to the links. |
|
303 * |
|
304 * @return |
|
305 * An array of links as defined above. |
|
306 */ |
|
307 function toolbar_menu_navigation_links($tree) { |
|
308 $links = array(); |
|
309 foreach ($tree as $item) { |
|
310 if (!$item['link']['hidden'] && $item['link']['access']) { |
|
311 // Make sure we have a path specific ID in place, so we can attach icons |
|
312 // and behaviors to the items. |
|
313 $id = str_replace(array('/', '<', '>'), array('-', '', ''), $item['link']['href']); |
|
314 |
|
315 $link = $item['link']['localized_options']; |
|
316 $link['href'] = $item['link']['href']; |
|
317 // Add icon placeholder. |
|
318 $link['title'] = '<span class="icon"></span>' . check_plain($item['link']['title']); |
|
319 // Add admin link ID. |
|
320 $link['attributes'] = array('id' => 'toolbar-link-' . $id); |
|
321 if (!empty($item['link']['description'])) { |
|
322 $link['title'] .= ' <span class="element-invisible">(' . $item['link']['description'] . ')</span>'; |
|
323 $link['attributes']['title'] = $item['link']['description']; |
|
324 } |
|
325 $link['html'] = TRUE; |
|
326 |
|
327 $class = ' path-' . $id; |
|
328 if (toolbar_in_active_trail($item['link']['href'])) { |
|
329 $class .= ' active-trail'; |
|
330 } |
|
331 $links['menu-' . $item['link']['mlid'] . $class] = $link; |
|
332 } |
|
333 } |
|
334 return $links; |
|
335 } |
|
336 |
|
337 /** |
|
338 * Checks whether an item is in the active trail. |
|
339 * |
|
340 * Useful when using a menu generated by menu_tree_all_data() which does |
|
341 * not set the 'in_active_trail' flag on items. |
|
342 * |
|
343 * @return |
|
344 * TRUE when path is in the active trail, FALSE if not. |
|
345 * |
|
346 * @todo |
|
347 * Look at migrating to a menu system level function. |
|
348 */ |
|
349 function toolbar_in_active_trail($path) { |
|
350 $active_paths = &drupal_static(__FUNCTION__); |
|
351 |
|
352 // Gather active paths. |
|
353 if (!isset($active_paths)) { |
|
354 $active_paths = array(); |
|
355 $trail = menu_get_active_trail(); |
|
356 foreach ($trail as $item) { |
|
357 if (!empty($item['href'])) { |
|
358 $active_paths[] = $item['href']; |
|
359 } |
|
360 } |
|
361 } |
|
362 return in_array($path, $active_paths); |
|
363 } |