web/drupal/modules/block/block.admin.inc
branchdrupal
changeset 74 0ff3ba646492
equal deleted inserted replaced
73:fcf75e232c5b 74:0ff3ba646492
       
     1 <?php
       
     2 // $Id: block.admin.inc,v 1.14.2.5 2008/11/24 06:00:02 dries Exp $
       
     3 
       
     4 /**
       
     5  * @file
       
     6  * Admin page callbacks for the block module.
       
     7  */
       
     8 
       
     9 /**
       
    10  * Menu callback for admin/build/block.
       
    11  */
       
    12 function block_admin_display($theme = NULL) {
       
    13   global $custom_theme;
       
    14 
       
    15   // If non-default theme configuration has been selected, set the custom theme.
       
    16   $custom_theme = isset($theme) ? $theme : variable_get('theme_default', 'garland');
       
    17 
       
    18   // Fetch and sort blocks
       
    19   $blocks = _block_rehash();
       
    20   usort($blocks, '_block_compare');
       
    21 
       
    22   return drupal_get_form('block_admin_display_form', $blocks, $theme);
       
    23 }
       
    24 
       
    25 /**
       
    26  * Generate main blocks administration form.
       
    27  */
       
    28 function block_admin_display_form(&$form_state, $blocks, $theme = NULL) {
       
    29   global $theme_key, $custom_theme;
       
    30 
       
    31   // Add CSS
       
    32   drupal_add_css(drupal_get_path('module', 'block') .'/block.css', 'module', 'all', FALSE);
       
    33 
       
    34   // If non-default theme configuration has been selected, set the custom theme.
       
    35   $custom_theme = isset($theme) ? $theme : variable_get('theme_default', 'garland');
       
    36   init_theme();
       
    37 
       
    38   $throttle = module_exists('throttle');
       
    39   $block_regions = system_region_list($theme_key) + array(BLOCK_REGION_NONE => '<'. t('none') .'>');
       
    40 
       
    41   // Weights range from -delta to +delta, so delta should be at least half
       
    42   // of the amount of blocks present. This makes sure all blocks in the same
       
    43   // region get an unique weight.
       
    44   $weight_delta = round(count($blocks) / 2);
       
    45 
       
    46   // Build form tree
       
    47   $form = array(
       
    48     '#action' => arg(4) ? url('admin/build/block/list/'. $theme_key) : url('admin/build/block'),
       
    49     '#tree' => TRUE,
       
    50   );
       
    51 
       
    52   foreach ($blocks as $i => $block) {
       
    53     $key = $block['module'] .'_'. $block['delta'];
       
    54     $form[$key]['module'] = array(
       
    55       '#type' => 'value',
       
    56       '#value' => $block['module'],
       
    57     );
       
    58     $form[$key]['delta'] = array(
       
    59       '#type' => 'value',
       
    60       '#value' => $block['delta'],
       
    61     );
       
    62     $form[$key]['info'] = array(
       
    63       '#value' => check_plain($block['info'])
       
    64     );
       
    65     $form[$key]['theme'] = array(
       
    66       '#type' => 'hidden',
       
    67       '#value' => $theme_key
       
    68     );
       
    69     $form[$key]['weight'] = array(
       
    70       '#type' => 'weight',
       
    71       '#default_value' => $block['weight'],
       
    72       '#delta' => $weight_delta,
       
    73     );
       
    74     $form[$key]['region'] = array(
       
    75       '#type' => 'select',
       
    76       '#default_value' => $block['region'],
       
    77       '#options' => $block_regions,
       
    78     );
       
    79 
       
    80     if ($throttle) {
       
    81       $form[$key]['throttle'] = array('#type' => 'checkbox', '#default_value' => isset($block['throttle']) ? $block['throttle'] : FALSE);
       
    82     }
       
    83     $form[$key]['configure'] = array('#value' => l(t('configure'), 'admin/build/block/configure/'. $block['module'] .'/'. $block['delta']));
       
    84     if ($block['module'] == 'block') {
       
    85       $form[$key]['delete'] = array('#value' => l(t('delete'), 'admin/build/block/delete/'. $block['delta']));
       
    86     }
       
    87   }
       
    88 
       
    89   $form['submit'] = array(
       
    90     '#type' => 'submit',
       
    91     '#value' => t('Save blocks'),
       
    92   );
       
    93 
       
    94   return $form;
       
    95 }
       
    96 
       
    97 /**
       
    98  * Process main blocks administration form submission.
       
    99  */
       
   100 function block_admin_display_form_submit($form, &$form_state) {
       
   101   foreach ($form_state['values'] as $block) {
       
   102     $block['status'] = $block['region'] != BLOCK_REGION_NONE;
       
   103     $block['region'] = $block['status'] ? $block['region'] : '';
       
   104     db_query("UPDATE {blocks} SET status = %d, weight = %d, region = '%s', throttle = %d WHERE module = '%s' AND delta = '%s' AND theme = '%s'", $block['status'], $block['weight'], $block['region'], isset($block['throttle']) ? $block['throttle'] : 0, $block['module'], $block['delta'], $block['theme']);
       
   105   }
       
   106   drupal_set_message(t('The block settings have been updated.'));
       
   107   cache_clear_all();
       
   108 }
       
   109 
       
   110 /**
       
   111  * Helper function for sorting blocks on admin/build/block.
       
   112  *
       
   113  * Active blocks are sorted by region, then by weight.
       
   114  * Disabled blocks are sorted by name.
       
   115  */
       
   116 function _block_compare($a, $b) {
       
   117   global $theme_key;
       
   118   static $regions;
       
   119 
       
   120   // We need the region list to correctly order by region.
       
   121   if (!isset($regions)) {
       
   122     $regions = array_flip(array_keys(system_region_list($theme_key)));
       
   123     $regions[BLOCK_REGION_NONE] = count($regions);
       
   124   }
       
   125 
       
   126   // Separate enabled from disabled.
       
   127   $status = $b['status'] - $a['status'];
       
   128   if ($status) {
       
   129     return $status;
       
   130   }
       
   131   // Sort by region (in the order defined by theme .info file).
       
   132   if ((!empty($a['region']) && !empty($b['region'])) && ($place = ($regions[$a['region']] - $regions[$b['region']]))) {
       
   133     return $place;
       
   134   }
       
   135   // Sort by weight.
       
   136   $weight = $a['weight'] - $b['weight'];
       
   137   if ($weight) {
       
   138     return $weight;
       
   139   }
       
   140   // Sort by title.
       
   141   return strcmp($a['info'], $b['info']);
       
   142 }
       
   143 
       
   144 /**
       
   145  * Menu callback; displays the block configuration form.
       
   146  */
       
   147 function block_admin_configure(&$form_state, $module = NULL, $delta = 0) {
       
   148 
       
   149   $form['module'] = array('#type' => 'value', '#value' => $module);
       
   150   $form['delta'] = array('#type' => 'value', '#value' => $delta);
       
   151 
       
   152   $edit = db_fetch_array(db_query("SELECT pages, visibility, custom, title FROM {blocks} WHERE module = '%s' AND delta = '%s'", $module, $delta));
       
   153 
       
   154   $form['block_settings'] = array(
       
   155     '#type' => 'fieldset',
       
   156     '#title' => t('Block specific settings'),
       
   157     '#collapsible' => TRUE,
       
   158   );
       
   159   $form['block_settings']['title'] = array(
       
   160     '#type' => 'textfield',
       
   161     '#title' => t('Block title'),
       
   162     '#maxlength' => 64,
       
   163     '#description' => $module == 'block' ? t('The title of the block as shown to the user.') : t('Override the default title for the block. Use <em>&lt;none&gt;</em> to display no title, or leave blank to use the default block title.'),
       
   164     '#default_value' => $edit['title'],
       
   165     '#weight' => -18,
       
   166   );
       
   167 
       
   168 
       
   169   // Module-specific block configurations.
       
   170   if ($settings = module_invoke($module, 'block', 'configure', $delta)) {
       
   171     foreach ($settings as $k => $v) {
       
   172       $form['block_settings'][$k] = $v;
       
   173     }
       
   174   }
       
   175 
       
   176   // Get the block subject for the page title.
       
   177   $info = module_invoke($module, 'block', 'list');
       
   178   if (isset($info[$delta])) {
       
   179     drupal_set_title(t("'%name' block", array('%name' => $info[$delta]['info'])));
       
   180   }
       
   181 
       
   182   // Standard block configurations.
       
   183   $form['user_vis_settings'] = array(
       
   184     '#type' => 'fieldset',
       
   185     '#title' => t('User specific visibility settings'),
       
   186     '#collapsible' => TRUE,
       
   187   );
       
   188   $form['user_vis_settings']['custom'] = array(
       
   189     '#type' => 'radios',
       
   190     '#title' => t('Custom visibility settings'),
       
   191     '#options' => array(
       
   192       t('Users cannot control whether or not they see this block.'),
       
   193       t('Show this block by default, but let individual users hide it.'),
       
   194       t('Hide this block by default but let individual users show it.')
       
   195     ),
       
   196     '#description' => t('Allow individual users to customize the visibility of this block in their account settings.'),
       
   197     '#default_value' => $edit['custom'],
       
   198   );
       
   199 
       
   200   // Role-based visibility settings
       
   201   $default_role_options = array();
       
   202   $result = db_query("SELECT rid FROM {blocks_roles} WHERE module = '%s' AND delta = '%s'", $module, $delta);
       
   203   while ($role = db_fetch_object($result)) {
       
   204     $default_role_options[] = $role->rid;
       
   205   }
       
   206   $result = db_query('SELECT rid, name FROM {role} ORDER BY name');
       
   207   $role_options = array();
       
   208   while ($role = db_fetch_object($result)) {
       
   209     $role_options[$role->rid] = $role->name;
       
   210   }
       
   211   $form['role_vis_settings'] = array(
       
   212     '#type' => 'fieldset',
       
   213     '#title' => t('Role specific visibility settings'),
       
   214     '#collapsible' => TRUE,
       
   215   );
       
   216   $form['role_vis_settings']['roles'] = array(
       
   217     '#type' => 'checkboxes',
       
   218     '#title' => t('Show block for specific roles'),
       
   219     '#default_value' => $default_role_options,
       
   220     '#options' => $role_options,
       
   221     '#description' => t('Show this block only for the selected role(s). If you select no roles, the block will be visible to all users.'),
       
   222   );
       
   223 
       
   224   $form['page_vis_settings'] = array(
       
   225     '#type' => 'fieldset',
       
   226     '#title' => t('Page specific visibility settings'),
       
   227     '#collapsible' => TRUE,
       
   228   );
       
   229   $access = user_access('use PHP for block visibility');
       
   230 
       
   231   if ($edit['visibility'] == 2 && !$access) {
       
   232     $form['page_vis_settings'] = array();
       
   233     $form['page_vis_settings']['visibility'] = array('#type' => 'value', '#value' => 2);
       
   234     $form['page_vis_settings']['pages'] = array('#type' => 'value', '#value' => $edit['pages']);
       
   235   }
       
   236   else {
       
   237     $options = array(t('Show on every page except the listed pages.'), t('Show on only the listed pages.'));
       
   238     $description = t("Enter one page per line as Drupal paths. The '*' character is a wildcard. Example paths are %blog for the blog page and %blog-wildcard for every personal blog. %front is the front page.", array('%blog' => 'blog', '%blog-wildcard' => 'blog/*', '%front' => '<front>'));
       
   239 
       
   240     if ($access) {
       
   241       $options[] = t('Show if the following PHP code returns <code>TRUE</code> (PHP-mode, experts only).');
       
   242       $description .= ' '. t('If the PHP-mode is chosen, enter PHP code between %php. Note that executing incorrect PHP-code can break your Drupal site.', array('%php' => '<?php ?>'));
       
   243     }
       
   244     $form['page_vis_settings']['visibility'] = array(
       
   245       '#type' => 'radios',
       
   246       '#title' => t('Show block on specific pages'),
       
   247       '#options' => $options,
       
   248       '#default_value' => $edit['visibility'],
       
   249     );
       
   250     $form['page_vis_settings']['pages'] = array(
       
   251       '#type' => 'textarea',
       
   252       '#title' => t('Pages'),
       
   253       '#default_value' => $edit['pages'],
       
   254       '#description' => $description,
       
   255     );
       
   256   }
       
   257 
       
   258   $form['submit'] = array(
       
   259     '#type' => 'submit',
       
   260     '#value' => t('Save block'),
       
   261   );
       
   262 
       
   263   return $form;
       
   264 }
       
   265 
       
   266 function block_admin_configure_validate($form, &$form_state) {
       
   267   if ($form_state['values']['module'] == 'block') {
       
   268     if (empty($form_state['values']['info']) || db_result(db_query("SELECT COUNT(*) FROM {boxes} WHERE bid != %d AND info = '%s'", $form_state['values']['delta'], $form_state['values']['info']))) {
       
   269       form_set_error('info', t('Please ensure that each block description is unique.'));
       
   270     }
       
   271   }
       
   272 }
       
   273 
       
   274 function block_admin_configure_submit($form, &$form_state) {
       
   275   if (!form_get_errors()) {
       
   276     db_query("UPDATE {blocks} SET visibility = %d, pages = '%s', custom = %d, title = '%s' WHERE module = '%s' AND delta = '%s'", $form_state['values']['visibility'], trim($form_state['values']['pages']), $form_state['values']['custom'], $form_state['values']['title'], $form_state['values']['module'], $form_state['values']['delta']);
       
   277     db_query("DELETE FROM {blocks_roles} WHERE module = '%s' AND delta = '%s'", $form_state['values']['module'], $form_state['values']['delta']);
       
   278     foreach (array_filter($form_state['values']['roles']) as $rid) {
       
   279       db_query("INSERT INTO {blocks_roles} (rid, module, delta) VALUES (%d, '%s', '%s')", $rid, $form_state['values']['module'], $form_state['values']['delta']);
       
   280     }
       
   281     module_invoke($form_state['values']['module'], 'block', 'save', $form_state['values']['delta'], $form_state['values']);
       
   282     drupal_set_message(t('The block configuration has been saved.'));
       
   283     cache_clear_all();
       
   284     $form_state['redirect'] = 'admin/build/block';
       
   285     return;
       
   286   }
       
   287 }
       
   288 
       
   289 /**
       
   290  * Menu callback: display the custom block addition form.
       
   291  */
       
   292 function block_add_block_form(&$form_state) {
       
   293   return block_admin_configure($form_state, 'block', NULL);
       
   294 }
       
   295 
       
   296 function block_add_block_form_validate($form, &$form_state) {
       
   297   if (empty($form_state['values']['info']) || db_result(db_query("SELECT COUNT(*) FROM {boxes} WHERE info = '%s'", $form_state['values']['info']))) {
       
   298     form_set_error('info', t('Please ensure that each block description is unique.'));
       
   299   }
       
   300 }
       
   301 
       
   302 /**
       
   303  * Save the new custom block.
       
   304  */
       
   305 function block_add_block_form_submit($form, &$form_state) {
       
   306   db_query("INSERT INTO {boxes} (body, info, format) VALUES ('%s', '%s', %d)", $form_state['values']['body'], $form_state['values']['info'], $form_state['values']['format']);
       
   307   $delta = db_last_insert_id('boxes', 'bid');
       
   308 
       
   309   foreach (list_themes() as $key => $theme) {
       
   310     if ($theme->status) {
       
   311       db_query("INSERT INTO {blocks} (visibility, pages, custom, title, module, theme, status, weight, delta, cache) VALUES(%d, '%s', %d, '%s', '%s', '%s', %d, %d, '%s', %d)", $form_state['values']['visibility'], trim($form_state['values']['pages']), $form_state['values']['custom'], $form_state['values']['title'], $form_state['values']['module'], $theme->name, 0, 0, $delta, BLOCK_NO_CACHE);
       
   312     }
       
   313   }
       
   314 
       
   315   foreach (array_filter($form_state['values']['roles']) as $rid) {
       
   316     db_query("INSERT INTO {blocks_roles} (rid, module, delta) VALUES (%d, '%s', '%s')", $rid, $form_state['values']['module'], $delta);
       
   317   }
       
   318 
       
   319   drupal_set_message(t('The block has been created.'));
       
   320   cache_clear_all();
       
   321 
       
   322   $form_state['redirect'] = 'admin/build/block';
       
   323   return;
       
   324 }
       
   325 
       
   326 /**
       
   327  * Menu callback; confirm deletion of custom blocks.
       
   328  */
       
   329 function block_box_delete(&$form_state, $bid = 0) {
       
   330   $box = block_box_get($bid);
       
   331   $form['info'] = array('#type' => 'hidden', '#value' => $box['info']);
       
   332   $form['bid'] = array('#type' => 'hidden', '#value' => $bid);
       
   333 
       
   334   return confirm_form($form, t('Are you sure you want to delete the block %name?', array('%name' => $box['info'])), 'admin/build/block', '', t('Delete'), t('Cancel'));
       
   335 }
       
   336 
       
   337 /**
       
   338  * Deletion of custom blocks.
       
   339  */
       
   340 function block_box_delete_submit($form, &$form_state) {
       
   341   db_query('DELETE FROM {boxes} WHERE bid = %d', $form_state['values']['bid']);
       
   342   db_query("DELETE FROM {blocks} WHERE module = 'block' AND delta = '%s'", $form_state['values']['bid']);
       
   343   drupal_set_message(t('The block %name has been removed.', array('%name' => $form_state['values']['info'])));
       
   344   cache_clear_all();
       
   345   $form_state['redirect'] = 'admin/build/block';
       
   346   return;
       
   347 }
       
   348 
       
   349 /**
       
   350  * Process variables for block-admin-display.tpl.php.
       
   351  *
       
   352  * The $variables array contains the following arguments:
       
   353  * - $form
       
   354  *
       
   355  * @see block-admin-display.tpl.php
       
   356  * @see theme_block_admin_display()
       
   357  */
       
   358 function template_preprocess_block_admin_display_form(&$variables) {
       
   359   global $theme_key;
       
   360 
       
   361   $block_regions = system_region_list($theme_key);
       
   362   $variables['throttle'] = module_exists('throttle');
       
   363   $variables['block_regions'] = $block_regions + array(BLOCK_REGION_NONE => t('Disabled'));
       
   364 
       
   365   foreach ($block_regions as $key => $value) {
       
   366     // Highlight regions on page to provide visual reference.
       
   367     drupal_set_content($key, '<div class="block-region">'. $value .'</div>');
       
   368     // Initialize an empty array for the region.
       
   369     $variables['block_listing'][$key] = array();
       
   370   }
       
   371 
       
   372   // Initialize disabled blocks array.
       
   373   $variables['block_listing'][BLOCK_REGION_NONE] = array();
       
   374 
       
   375   // Set up to track previous region in loop.
       
   376   $last_region = '';
       
   377   foreach (element_children($variables['form']) as $i) {
       
   378     $block = &$variables['form'][$i];
       
   379 
       
   380     // Only take form elements that are blocks.
       
   381     if (isset($block['info'])) {
       
   382       // Fetch region for current block.
       
   383       $region = $block['region']['#default_value'];
       
   384 
       
   385       // Set special classes needed for table drag and drop.
       
   386       $variables['form'][$i]['region']['#attributes']['class'] = 'block-region-select block-region-'. $region;
       
   387       $variables['form'][$i]['weight']['#attributes']['class'] = 'block-weight block-weight-'. $region;
       
   388 
       
   389       $variables['block_listing'][$region][$i]->row_class = isset($block['#attributes']['class']) ? $block['#attributes']['class'] : '';
       
   390       $variables['block_listing'][$region][$i]->block_modified = isset($block['#attributes']['class']) && strpos($block['#attributes']['class'], 'block-modified') !== FALSE ? TRUE : FALSE;
       
   391       $variables['block_listing'][$region][$i]->block_title =  drupal_render($block['info']);
       
   392       $variables['block_listing'][$region][$i]->region_select = drupal_render($block['region']) . drupal_render($block['theme']);
       
   393       $variables['block_listing'][$region][$i]->weight_select = drupal_render($block['weight']);
       
   394       $variables['block_listing'][$region][$i]->throttle_check = $variables['throttle'] ? drupal_render($block['throttle']) : '';
       
   395       $variables['block_listing'][$region][$i]->configure_link = drupal_render($block['configure']);
       
   396       $variables['block_listing'][$region][$i]->delete_link = !empty($block['delete']) ? drupal_render($block['delete']) : '';
       
   397       $variables['block_listing'][$region][$i]->printed = FALSE;
       
   398 
       
   399       $last_region = $region;
       
   400     }
       
   401   }
       
   402 
       
   403   $variables['form_submit'] = drupal_render($variables['form']);
       
   404 }