cms/drupal/modules/toolbar/toolbar.module
changeset 541 e756a8c72c3d
equal deleted inserted replaced
540:07239de796bb 541:e756a8c72c3d
       
     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 }