cms/drupal/modules/dashboard/dashboard.module
changeset 541 e756a8c72c3d
equal deleted inserted replaced
540:07239de796bb 541:e756a8c72c3d
       
     1 <?php
       
     2 /**
       
     3  * @file
       
     4  * Provides a dashboard page in the administrative interface.
       
     5  */
       
     6 
       
     7 /**
       
     8  * Implements hook_help().
       
     9  */
       
    10 function dashboard_help($path, $arg) {
       
    11   switch ($path) {
       
    12     case 'admin/help#dashboard':
       
    13       $output = '';
       
    14       $output .= '<h3>' . t('About') . '</h3>';
       
    15       $output .= '<p>' . t('The Dashboard module provides a <a href="@dashboard">Dashboard page</a> in the administrative interface for organizing administrative tasks and navigation, and tracking information within your site. The Dashboard page contains blocks, which you can add to and arrange using the drag-and-drop interface that appears when you click on the <em>Customize dashboard</em> link. Within this interface, blocks that are not primarily used for site administration do not appear by default, but can be added via the <em>Add other blocks</em> link. For more information, see the online handbook entry for <a href="@handbook">Dashboard module</a>.', array('@handbook' => 'http://drupal.org/documentation/modules/dashboard', '@dashboard' => url('admin/dashboard'))) . '</p>';
       
    16       $output .= '<h3>' . t('Uses') . '</h3>';
       
    17       $output .= '<dl>';
       
    18       $output .= '<dt>' . t('Tracking user activity') . '</dt>';
       
    19       $output .= '<dd>' . t("By enabling blocks such as <em>Who's online</em> and <em>Who's new</em>, site users can track who is logged in and new user signups at a centralized location.") . '</dd>';
       
    20       $output .= '<dt>' . t('Tracking content activity') . '</dt>';
       
    21       $output .= '<dd>' . t('By enabling blocks such as <em>Recent blog posts</em>, <em>New forum topics</em> and <em>Recent comments</em>, site users can view newly added site content at a glance.') . '</dd>';
       
    22       $output .= '</dl>';
       
    23       return $output;
       
    24 
       
    25     case 'admin/dashboard/configure':
       
    26       // @todo This assumes the current page is being displayed using the same
       
    27       //   theme that the dashboard is displayed in.
       
    28       $output = '<p>' . t('Rearrange blocks for display on the <a href="@dashboard-url">Dashboard page</a>. Blocks placed in the <em>Dashboard (inactive)</em> region are not displayed when viewing the Dashboard page, but are available within its <em>Customize dashboard</em> interface. Removing a block from active dashboard display makes it available on the main <a href="@blocks-url">blocks administration page</a>.', array('@dashboard-url' => url('admin/dashboard'), '@blocks-url' => url("admin/structure/block/list/{$GLOBALS['theme_key']}"))) . '</p>';
       
    29       return $output;
       
    30   }
       
    31 }
       
    32 
       
    33 /**
       
    34  * Implements hook_menu().
       
    35  */
       
    36 function dashboard_menu() {
       
    37   $items['admin/dashboard'] = array(
       
    38     'title' => 'Dashboard',
       
    39     'description' => 'View and customize your dashboard.',
       
    40     'page callback' => 'dashboard_admin',
       
    41     'access arguments' => array('access dashboard'),
       
    42     // Make this appear first, so for example, in admin menus, it shows up on
       
    43     // the top corner of the window as a convenient "home link".
       
    44     'weight' => -15,
       
    45   );
       
    46   $items['admin/dashboard/configure'] = array(
       
    47     'title' => 'Configure available dashboard blocks',
       
    48     'description' => 'Configure which blocks can be shown on the dashboard.',
       
    49     'page callback' => 'dashboard_admin_blocks',
       
    50     'access arguments' => array('administer blocks'),
       
    51     'type' => MENU_VISIBLE_IN_BREADCRUMB,
       
    52   );
       
    53   $items['admin/dashboard/customize'] = array(
       
    54     'title' => 'Customize dashboard',
       
    55     'description' => 'Customize your dashboard.',
       
    56     'page callback' => 'dashboard_admin',
       
    57     'page arguments' => array(TRUE),
       
    58     'access arguments' => array('access dashboard'),
       
    59     'type' => MENU_VISIBLE_IN_BREADCRUMB,
       
    60   );
       
    61   $items['admin/dashboard/drawer'] = array(
       
    62     'page callback' => 'dashboard_show_disabled',
       
    63     'access arguments' => array('administer blocks'),
       
    64     'type' => MENU_CALLBACK,
       
    65   );
       
    66   $items['admin/dashboard/block-content/%/%'] = array(
       
    67     'page callback' => 'dashboard_show_block_content',
       
    68     'page arguments' => array(3, 4),
       
    69     'access arguments' => array('administer blocks'),
       
    70     'type' => MENU_CALLBACK,
       
    71   );
       
    72   $items['admin/dashboard/update'] = array(
       
    73     'page callback' => 'dashboard_update',
       
    74     'access arguments' => array('administer blocks'),
       
    75     'type' => MENU_CALLBACK,
       
    76   );
       
    77 
       
    78   return $items;
       
    79 }
       
    80 
       
    81 /**
       
    82  * Implements hook_permission().
       
    83  */
       
    84 function dashboard_permission() {
       
    85   return array(
       
    86     'access dashboard' => array(
       
    87       'title' => t('View the administrative dashboard'),
       
    88       // Note: We translate the 'Administer blocks' permission string here with
       
    89       // a separate t() call, to make sure it gets the same translation as when
       
    90       // it's in block_permission().
       
    91       'description' => t('Customizing the dashboard requires the !permission-name permission.', array(
       
    92         '!permission-name' => l(t('Administer blocks'), 'admin/people/permissions', array('fragment' => 'module-block')),
       
    93       )),
       
    94     ),
       
    95   );
       
    96 }
       
    97 
       
    98 /**
       
    99  * Implements hook_block_info_alter().
       
   100  */
       
   101 function dashboard_block_info_alter(&$blocks, $theme, $code_blocks) {
       
   102   $admin_theme = variable_get('admin_theme');
       
   103   if (($admin_theme && $theme == $admin_theme) || (!$admin_theme && $theme == variable_get('theme_default', 'bartik'))) {
       
   104     foreach ($blocks as $module => &$module_blocks) {
       
   105       foreach ($module_blocks as $delta => &$block) {
       
   106         // Make administrative blocks that are not already in use elsewhere
       
   107         // available for the dashboard.
       
   108         if (empty($block['status']) && (empty($block['region']) || $block['region'] == BLOCK_REGION_NONE) && !empty($code_blocks[$module][$delta]['properties']['administrative'])) {
       
   109           $block['status'] = 1;
       
   110           $block['region'] = 'dashboard_inactive';
       
   111         }
       
   112       }
       
   113     }
       
   114   }
       
   115 }
       
   116 
       
   117 /**
       
   118  * Implements hook_block_list_alter().
       
   119  *
       
   120  * Skip rendering dashboard blocks when not on the dashboard page itself. This
       
   121  * prevents expensive dashboard blocks from causing performance issues on pages
       
   122  * where they will never be displayed.
       
   123  */
       
   124 function dashboard_block_list_alter(&$blocks) {
       
   125   if (!dashboard_is_visible()) {
       
   126     foreach ($blocks as $key => $block) {
       
   127       if (in_array($block->region, dashboard_regions())) {
       
   128         unset($blocks[$key]);
       
   129       }
       
   130     }
       
   131   }
       
   132 }
       
   133 
       
   134 /**
       
   135  * Implements hook_page_build().
       
   136  *
       
   137  * Display dashboard blocks in the main content region.
       
   138  */
       
   139 function dashboard_page_build(&$page) {
       
   140   global $theme_key;
       
   141 
       
   142   if (dashboard_is_visible()) {
       
   143     $block_info = array();
       
   144 
       
   145     // Create a wrapper for the dashboard itself, then insert each dashboard
       
   146     // region into it.
       
   147     $page['content']['dashboard'] = array('#theme_wrappers' => array('dashboard'));
       
   148     foreach (dashboard_regions() as $region) {
       
   149       // Do not show dashboard blocks that are disabled.
       
   150       if ($region == 'dashboard_inactive') {
       
   151         continue;
       
   152       }
       
   153       // Insert regions even when they are empty, so that they will be
       
   154       // displayed when the dashboard is being configured.
       
   155       $page['content']['dashboard'][$region] = !empty($page[$region]) ? $page[$region] : array();
       
   156       $page['content']['dashboard'][$region]['#dashboard_region'] = $region;
       
   157       // Allow each dashboard region to be themed differently, or fall back on
       
   158       // the generic theme wrapper function for dashboard regions.
       
   159       $page['content']['dashboard'][$region]['#theme_wrappers'][] = array($region, 'dashboard_region');
       
   160       unset($page[$region]);
       
   161       $blocks_found = array();
       
   162       foreach ($page['content']['dashboard'][$region] as $item) {
       
   163         if (isset($item['#theme_wrappers']) && is_array($item['#theme_wrappers']) && in_array('block', $item['#theme_wrappers'])) {
       
   164           // If this item is a block, ensure it has a subject.
       
   165           if (empty($item['#block']->subject)) {
       
   166             // Locally cache info data for the object for all blocks, in case
       
   167             // we find a block similarly missing title from the same module.
       
   168             if (!isset($block_info[$item['#block']->module])) {
       
   169               $block_info[$item['#block']->module] = module_invoke($item['#block']->module, 'block_info');
       
   170             }
       
   171             $item['#block']->subject = $block_info[$item['#block']->module][$item['#block']->delta]['info'];
       
   172           }
       
   173           $blocks_found[$item['#block']->module . '_' . $item['#block']->delta] = TRUE;
       
   174         }
       
   175       }
       
   176 
       
   177       // Find blocks which were not yet displayed on the page (were empty), and
       
   178       // add placeholder items in their place for rendering.
       
   179       $block_list = db_select('block')
       
   180         ->condition('theme', $theme_key)
       
   181         ->condition('status', 1)
       
   182         ->condition('region', $region)
       
   183         ->fields('block')
       
   184         ->execute();
       
   185       foreach ($block_list as $block) {
       
   186         if (!isset($blocks_found[$block->module . '_' . $block->delta])) {
       
   187           $block->enabled = $block->page_match = TRUE;
       
   188           $block->content = array('#markup' => '<div class="dashboard-block-empty">(empty)</div>');
       
   189           if (!isset($block_info[$block->module])) {
       
   190             $block_info[$block->module] = module_invoke($block->module, 'block_info');
       
   191           }
       
   192           $block->subject = t('@title', array('@title' => $block_info[$block->module][$block->delta]['info']));
       
   193           $block_render = array($block->module . '_' . $block->delta => $block);
       
   194           $build = _block_get_renderable_array($block_render);
       
   195           $page['content']['dashboard'][$block->region][] = $build;
       
   196         }
       
   197       }
       
   198     }
       
   199   }
       
   200 }
       
   201 
       
   202 /**
       
   203  * Implements hook_system_info_alter().
       
   204  *
       
   205  * Add regions to each theme to store the dashboard blocks.
       
   206  */
       
   207 function dashboard_system_info_alter(&$info, $file, $type) {
       
   208   if ($type == 'theme') {
       
   209     // Add the dashboard regions (the "inactive" region should always appear
       
   210     // last in the list, for usability reasons).
       
   211     $dashboard_regions = dashboard_region_descriptions();
       
   212     if (isset($dashboard_regions['dashboard_inactive'])) {
       
   213       $inactive_region = $dashboard_regions['dashboard_inactive'];
       
   214       unset($dashboard_regions['dashboard_inactive']);
       
   215       $dashboard_regions['dashboard_inactive'] = $inactive_region;
       
   216     }
       
   217     $info['regions'] += $dashboard_regions;
       
   218     // Indicate that these regions are intended to be displayed whenever the
       
   219     // dashboard is displayed in an overlay. This information is provided for
       
   220     // any module that might need to use it, not just the core Overlay module.
       
   221     $info['overlay_regions'] = !empty($info['overlay_regions']) ? array_merge($info['overlay_regions'], dashboard_regions()) : dashboard_regions();
       
   222   }
       
   223 }
       
   224 
       
   225 /**
       
   226  * Implements hook_theme().
       
   227  */
       
   228 function dashboard_theme() {
       
   229   return array(
       
   230     'dashboard' => array(
       
   231       'render element' => 'element',
       
   232     ),
       
   233     'dashboard_admin' => array(
       
   234       'render element' => 'element',
       
   235     ),
       
   236     'dashboard_region' => array(
       
   237       'render element' => 'element',
       
   238     ),
       
   239     'dashboard_disabled_blocks' => array(
       
   240       'variables' => array('blocks' => NULL),
       
   241     ),
       
   242     'dashboard_disabled_block' => array(
       
   243       'variables' => array('block' => NULL),
       
   244     ),
       
   245     'dashboard_admin_display_form' => array(
       
   246       // When building the form for configuring dashboard blocks, reuse the
       
   247       // Block module's template for the main block configuration form.
       
   248       'template' => 'block-admin-display-form',
       
   249       'path' => drupal_get_path('module', 'block'),
       
   250       'file' => 'block.admin.inc',
       
   251       'render element' => 'form',
       
   252     ),
       
   253   );
       
   254 }
       
   255 
       
   256 /**
       
   257  * Implements hook_forms().
       
   258  */
       
   259 function dashboard_forms() {
       
   260   // Reroute the dashboard configuration form to the main blocks administration
       
   261   // form. This allows us to distinguish them by form ID in hook_form_alter().
       
   262   $forms['dashboard_admin_display_form'] = array(
       
   263     'callback' => 'block_admin_display_form',
       
   264   );
       
   265 
       
   266   return $forms;
       
   267 }
       
   268 
       
   269 /**
       
   270  * Page callback: Displays the dashboard.
       
   271  *
       
   272  * @param $launch_customize
       
   273  *   Whether to launch in customization mode right away. TRUE or FALSE.
       
   274  */
       
   275 function dashboard_admin($launch_customize = FALSE) {
       
   276   $js_settings = array(
       
   277     'dashboard' => array(
       
   278       'drawer' => url('admin/dashboard/drawer'),
       
   279       'blockContent' => url('admin/dashboard/block-content'),
       
   280       'updatePath' => url('admin/dashboard/update'),
       
   281       'formToken' => drupal_get_token('dashboard-update'),
       
   282       'launchCustomize' => $launch_customize,
       
   283       'dashboard' => url('admin/dashboard'),
       
   284       'emptyBlockText' => t('(empty)'),
       
   285       'emptyRegionTextInactive' => t('This dashboard region is empty. Click <em>Customize dashboard</em> to add blocks to it.'),
       
   286       'emptyRegionTextActive' => t('DRAG HERE'),
       
   287     ),
       
   288   );
       
   289   $build = array(
       
   290     '#theme' => 'dashboard_admin',
       
   291     '#message' => t('To customize the dashboard page, move blocks to the dashboard regions on the <a href="@dashboard">Dashboard administration page</a>, or enable JavaScript on this page to use the drag-and-drop interface.', array('@dashboard' => url('admin/dashboard/configure'))),
       
   292     '#access' => user_access('administer blocks'),
       
   293     '#attached' => array(
       
   294       'js' => array(
       
   295         drupal_get_path('module', 'dashboard') . '/dashboard.js',
       
   296         array('data' => $js_settings, 'type' => 'setting'),
       
   297       ),
       
   298       'library' => array(array('system', 'ui.sortable')),
       
   299     ),
       
   300   );
       
   301   return $build;
       
   302 }
       
   303 
       
   304 /**
       
   305  * Page callback: Builds the page for administering dashboard blocks.
       
   306  *
       
   307  * This page reuses the Block module's administration form but limits editing
       
   308  * to blocks that are available to appear on the dashboard.
       
   309  *
       
   310  * @see block_admin_display()
       
   311  * @see block_admin_display_form()
       
   312  * @see dashboard_form_dashboard_admin_display_form_alter()
       
   313  * @see template_preprocess_dashboard_admin_display_form()
       
   314  */
       
   315 function dashboard_admin_blocks() {
       
   316   global $theme_key;
       
   317   drupal_theme_initialize();
       
   318   module_load_include('inc', 'block', 'block.admin');
       
   319 
       
   320   // Prepare the blocks for the current theme, and remove those that are
       
   321   // currently displayed in non-dashboard regions.
       
   322   // @todo This assumes the current page is being displayed using the same
       
   323   //   theme that the dashboard is displayed in.
       
   324   $blocks = block_admin_display_prepare_blocks($theme_key);
       
   325   $dashboard_regions = dashboard_region_descriptions();
       
   326   $regions_to_remove = array_diff_key(system_region_list($theme_key, REGIONS_VISIBLE), $dashboard_regions);
       
   327   foreach ($blocks as $id => $block) {
       
   328     if (isset($regions_to_remove[$block['region']])) {
       
   329       unset($blocks[$id]);
       
   330     }
       
   331   }
       
   332 
       
   333   // Pass in the above blocks and dashboard regions to the form, so that only
       
   334   // dashboard-related regions will be displayed.
       
   335   return drupal_get_form('dashboard_admin_display_form', $blocks, $theme_key, $dashboard_regions);
       
   336 }
       
   337 
       
   338 /**
       
   339  * Implements hook_form_FORM_ID_alter().
       
   340  */
       
   341 function dashboard_form_block_admin_display_form_alter(&$form, &$form_state, $form_id) {
       
   342   // Hide dashboard regions (and any blocks placed within them) from the block
       
   343   // administration form and from the options list on that form. This
       
   344   // function is called for both the dashboard block configuration form and the
       
   345   // standard block configuration form so that both forms can share the same
       
   346   // constructor. As a result the form_id must be checked.
       
   347   if ($form_id != 'dashboard_admin_display_form') {
       
   348     $dashboard_regions = dashboard_region_descriptions();
       
   349     $form['block_regions']['#value'] = array_diff_key($form['block_regions']['#value'], $dashboard_regions);
       
   350     foreach (element_children($form['blocks']) as $i) {
       
   351       $block = &$form['blocks'][$i];
       
   352       if (isset($block['region']['#default_value']) && isset($dashboard_regions[$block['region']['#default_value']]) && $block['region']['#default_value'] != 'dashboard_inactive') {
       
   353         $block['#access'] = FALSE;
       
   354       }
       
   355       elseif (isset($block['region']['#options'])) {
       
   356         $block['region']['#options'] = array_diff_key($block['region']['#options'], $dashboard_regions);
       
   357       }
       
   358       // Show inactive dashboard blocks as disabled on the main block
       
   359       // administration form, so that they are available to place in other
       
   360       // regions of the theme. Note that when the form is submitted, any such
       
   361       // blocks which still remain disabled will immediately be put back in the
       
   362       // 'dashboard_inactive' region, because dashboard_block_info_alter() is
       
   363       // called when the blocks are rehashed. Fortunately, this is the exact
       
   364       // behavior we want.
       
   365       if ($block['region']['#default_value'] == 'dashboard_inactive') {
       
   366         // @todo These do not wind up in correct alphabetical order.
       
   367         $block['region']['#default_value'] = NULL;
       
   368       }
       
   369     }
       
   370   }
       
   371 }
       
   372 
       
   373 /**
       
   374  * Implements hook_form_FORM_ID_alter().
       
   375  */
       
   376 function dashboard_form_dashboard_admin_display_form_alter(&$form, &$form_state) {
       
   377   // Redirect the 'configure' and 'delete' links on each block back to the
       
   378   // dashboard blocks administration page.
       
   379   foreach ($form['blocks'] as &$block) {
       
   380     if (isset($block['configure']['#href'])) {
       
   381       $block['configure']['#options']['query']['destination'] = 'admin/dashboard/configure';
       
   382     }
       
   383     if (isset($block['delete']['#href'])) {
       
   384       $block['delete']['#options']['query']['destination'] = 'admin/dashboard/configure';
       
   385     }
       
   386   }
       
   387 }
       
   388 
       
   389 /**
       
   390  * Implements hook_form_FORM_ID_alter().
       
   391  */
       
   392 function dashboard_form_block_admin_configure_alter(&$form, &$form_state) {
       
   393   global $theme_key;
       
   394   drupal_theme_initialize();
       
   395   // Hide the dashboard regions from the region select list on the block
       
   396   // configuration form, for all themes except the current theme (since the
       
   397   // other themes do not display the dashboard).
       
   398   // @todo This assumes the current page is being displayed using the same
       
   399   //   theme that the dashboard is displayed in.
       
   400   $dashboard_regions = dashboard_region_descriptions();
       
   401   foreach (element_children($form['regions']) as $region_name) {
       
   402     $region = &$form['regions'][$region_name];
       
   403     if ($region_name != $theme_key && isset($region['#options'])) {
       
   404       $region['#options'] = array_diff_key($region['#options'], $dashboard_regions);
       
   405     }
       
   406   }
       
   407 }
       
   408 
       
   409 /**
       
   410  * Implements hook_form_FORM_ID_alter().
       
   411  */
       
   412 function dashboard_form_block_add_block_form_alter(&$form, &$form_state) {
       
   413   dashboard_form_block_admin_configure_alter($form, $form_state);
       
   414 }
       
   415 
       
   416 /**
       
   417  * Preprocesses variables for block-admin-display-form.tpl.php.
       
   418  */
       
   419 function template_preprocess_dashboard_admin_display_form(&$variables) {
       
   420   template_preprocess_block_admin_display_form($variables);
       
   421   if (isset($variables['block_regions'][BLOCK_REGION_NONE])) {
       
   422     $variables['block_regions'][BLOCK_REGION_NONE] = t('Other blocks');
       
   423   }
       
   424 }
       
   425 
       
   426 /**
       
   427  * Determines if the dashboard should be displayed on the current page.
       
   428  *
       
   429  * This function checks if the user is currently viewing the dashboard and has
       
   430  * access to see it. It is used by other functions in the dashboard module to
       
   431  * decide whether or not the dashboard content should be displayed to the
       
   432  * current user.
       
   433  *
       
   434  * Although the menu system normally handles the above tasks, it only does so
       
   435  * for the main page content. However, the dashboard is not part of the main
       
   436  * page content, but rather is displayed in special regions of the page (so it
       
   437  * can interface with the Block module's method of managing page regions). We
       
   438  * therefore need to maintain this separate function to check the menu item for
       
   439  * us.
       
   440  *
       
   441  * @return
       
   442  *   TRUE if the dashboard should be visible on the current page, FALSE
       
   443  *   otherwise.
       
   444  *
       
   445  * @see dashboard_block_list_alter()
       
   446  * @see dashboard_page_build()
       
   447  */
       
   448 function dashboard_is_visible() {
       
   449   static $is_visible;
       
   450   if (!isset($is_visible)) {
       
   451     // If the current menu item represents the page on which we want to display
       
   452     // the dashboard, and if the current user has access to see it, return
       
   453     // TRUE.
       
   454     $menu_item = menu_get_item();
       
   455     $is_visible = isset($menu_item['page_callback']) && $menu_item['page_callback'] == 'dashboard_admin' && !empty($menu_item['access']);
       
   456   }
       
   457   return $is_visible;
       
   458 }
       
   459 
       
   460 /**
       
   461  * Returns an array of dashboard region descriptions, keyed by region name.
       
   462  */
       
   463 function dashboard_region_descriptions() {
       
   464   $regions = module_invoke_all('dashboard_regions');
       
   465   drupal_alter('dashboard_regions', $regions);
       
   466   return $regions;
       
   467 }
       
   468 
       
   469 /**
       
   470  * Returns an array of dashboard region names.
       
   471  */
       
   472 function dashboard_regions() {
       
   473   $regions = &drupal_static(__FUNCTION__);
       
   474   if (!isset($regions)) {
       
   475     $regions = array_keys(dashboard_region_descriptions());
       
   476   }
       
   477   return $regions;
       
   478 }
       
   479 
       
   480 /**
       
   481  * Implements hook_dashboard_regions().
       
   482  */
       
   483 function dashboard_dashboard_regions() {
       
   484   return array(
       
   485     'dashboard_main' => 'Dashboard (main)',
       
   486     'dashboard_sidebar' => 'Dashboard (sidebar)',
       
   487     'dashboard_inactive' => 'Dashboard (inactive)',
       
   488   );
       
   489 }
       
   490 
       
   491 /**
       
   492  * Ajax callback: Shows disabled blocks in the dashboard customization mode.
       
   493  */
       
   494 function dashboard_show_disabled() {
       
   495   global $theme_key;
       
   496 
       
   497   // Blocks are not necessarily initialized at this point.
       
   498   $blocks = _block_rehash();
       
   499 
       
   500   // Limit the list to blocks that are marked as disabled for the dashboard.
       
   501   foreach ($blocks as $key => $block) {
       
   502     if ($block['theme'] != $theme_key || $block['region'] != 'dashboard_inactive') {
       
   503       unset($blocks[$key]);
       
   504     }
       
   505   }
       
   506 
       
   507   // Theme the output and end the page request.
       
   508   print theme('dashboard_disabled_blocks', array('blocks' => $blocks));
       
   509   drupal_exit();
       
   510 }
       
   511 
       
   512 /**
       
   513  * Ajax callback: Displays the rendered contents of a specific block.
       
   514  *
       
   515  * @param $module
       
   516  *   The block's module name.
       
   517  * @param $delta
       
   518  *   The block's delta.
       
   519  */
       
   520 function dashboard_show_block_content($module, $delta) {
       
   521   drupal_theme_initialize();
       
   522   global $theme_key;
       
   523 
       
   524   $blocks = array();
       
   525   $block_object = db_query("SELECT * FROM {block} WHERE theme = :theme AND module = :module AND delta = :delta", array(
       
   526     ":theme" => $theme_key,
       
   527     ":module" => $module,
       
   528     ":delta" => $delta,
       
   529     ))
       
   530     ->fetchObject();
       
   531   $block_object->enabled = $block_object->page_match = TRUE;
       
   532   $blocks[$module . "_" . $delta] = $block_object;
       
   533   $block_content = _block_render_blocks($blocks);
       
   534   $build = _block_get_renderable_array($block_content);
       
   535   $rendered_block = drupal_render($build);
       
   536   print $rendered_block;
       
   537   drupal_exit();
       
   538 }
       
   539 
       
   540 /**
       
   541  * Sets the new weight of each region according to the drag-and-drop order.
       
   542  */
       
   543 function dashboard_update() {
       
   544   drupal_theme_initialize();
       
   545   global $theme_key;
       
   546   // Check the form token to make sure we have a valid request.
       
   547   if (!empty($_REQUEST['form_token']) && drupal_valid_token($_REQUEST['form_token'], 'dashboard-update')) {
       
   548     parse_str($_REQUEST['regions'], $regions);
       
   549     foreach ($regions as $region_name => $blocks) {
       
   550       if ($region_name == 'disabled_blocks') {
       
   551         $region_name = 'dashboard_inactive';
       
   552       }
       
   553       foreach ($blocks as $weight => $block_string) {
       
   554         // Parse the query string to determine the block's module and delta.
       
   555         preg_match('/block-([^-]+)-(.+)/', $block_string, $matches);
       
   556         $block = new stdClass();
       
   557         $block->module = $matches[1];
       
   558         $block->delta = $matches[2];
       
   559 
       
   560         $block->region = $region_name;
       
   561         $block->weight = $weight;
       
   562         $block->status = 1;
       
   563 
       
   564         db_merge('block')
       
   565           ->key(array(
       
   566             'module' => $block->module,
       
   567             'delta' => $block->delta,
       
   568             'theme' => $theme_key,
       
   569           ))
       
   570           ->fields(array(
       
   571             'status' => $block->status,
       
   572             'weight' => $block->weight,
       
   573             'region' => $block->region,
       
   574             'pages' => '',
       
   575           ))
       
   576           ->execute();
       
   577       }
       
   578     }
       
   579     drupal_set_message(t('The configuration options have been saved.'), 'status', FALSE);
       
   580   }
       
   581   drupal_exit();
       
   582 }
       
   583 
       
   584 /**
       
   585  * Returns HTML for the entire dashboard.
       
   586  *
       
   587  * @param $variables
       
   588  *   An associative array containing:
       
   589  *   - element: A render element containing the properties of the dashboard
       
   590  *     region element, #dashboard_region and #children.
       
   591  *
       
   592  * @ingroup themeable
       
   593  */
       
   594 function theme_dashboard($variables) {
       
   595   extract($variables);
       
   596   drupal_add_css(drupal_get_path('module', 'dashboard') . '/dashboard.css');
       
   597   return '<div id="dashboard" class="clearfix">' . $element['#children'] . '</div>';
       
   598 }
       
   599 
       
   600 /**
       
   601  * Returns HTML for the non-customizable part of the dashboard page.
       
   602  *
       
   603  * @param $variables
       
   604  *   An associative array containing:
       
   605  *   - element: A render element containing a #message.
       
   606  *
       
   607  * @ingroup themeable
       
   608  */
       
   609 function theme_dashboard_admin($variables) {
       
   610   // We only return a simple help message, since the actual content of the page
       
   611   // will be populated via the dashboard regions in dashboard_page_build().
       
   612   return '<div class="customize-dashboard js-hide">' . $variables['element']['#message'] . '</div>';
       
   613 }
       
   614 
       
   615 /**
       
   616  * Returns HTML for a generic dashboard region.
       
   617  *
       
   618  * @param $variables
       
   619  *   An associative array containing:
       
   620  *   - element: A render element containing the properties of the dashboard
       
   621  *     region element, #dashboard_region and #children.
       
   622  *
       
   623  * @ingroup themeable
       
   624  */
       
   625 function theme_dashboard_region($variables) {
       
   626   extract($variables);
       
   627   $output = '<div id="' . $element['#dashboard_region'] . '" class="dashboard-region">';
       
   628   $output .= '<div class="region clearfix">';
       
   629   $output .= $element['#children'];
       
   630   // Closing div.region
       
   631   $output .= '</div>';
       
   632   // Closing div.dashboard-region
       
   633   $output .= '</div>';
       
   634   return $output;
       
   635 }
       
   636 
       
   637 /**
       
   638  * Returns HTML for disabled blocks, for use in dashboard customization mode.
       
   639  *
       
   640  * @param $variables
       
   641  *   An associative array containing:
       
   642  *   - blocks: An array of block objects from _block_rehash().
       
   643  *
       
   644  * @ingroup themeable
       
   645  */
       
   646 function theme_dashboard_disabled_blocks($variables) {
       
   647   extract($variables);
       
   648   $output = '<div class="canvas-content"><p>' . t('Drag and drop these blocks to the columns below. Changes are automatically saved. More options are available on the <a href="@dashboard-url">configuration page</a>.', array('@dashboard-url' => url('admin/dashboard/configure'))) . '</p>';
       
   649   $output .= '<div id="disabled-blocks"><div class="region disabled-blocks clearfix">';
       
   650   foreach ($blocks as $block) {
       
   651     $output .= theme('dashboard_disabled_block', array('block' => $block));
       
   652   }
       
   653   $output .= '<div class="clearfix"></div>';
       
   654   $output .= '<p class="dashboard-add-other-blocks">' . l(t('Add other blocks'), 'admin/dashboard/configure') . '</p>';
       
   655   $output .= '</div></div></div>';
       
   656   return $output;
       
   657 }
       
   658 
       
   659 /**
       
   660  * Returns HTML for disabled blocks, for use in dashboard customization mode.
       
   661  *
       
   662  * @param $variables
       
   663  *   An associative array containing:
       
   664  *   - block: A block object from _block_rehash().
       
   665  *
       
   666  * @ingroup themeable
       
   667  */
       
   668 function theme_dashboard_disabled_block($variables) {
       
   669   extract($variables);
       
   670   $output = "";
       
   671   if (isset($block)) {
       
   672     $output .= '<div id="block-' . $block['module'] . '-' . $block['delta']
       
   673     . '" class="disabled-block block block-' . $block['module'] . '-' . $block['delta']
       
   674     . ' module-' . $block['module'] . ' delta-' . $block['delta'] . '">'
       
   675     . '<h2>' . (!empty($block['title']) && $block['title'] != '<none>' ? check_plain($block['title']) : check_plain($block['info'])) . '</h2>'
       
   676     . '<div class="content"></div>'
       
   677     . '</div>';
       
   678   }
       
   679   return $output;
       
   680 }
       
   681