Initial code using Drupal 6.38

This commit is contained in:
Manuel Cillero 2017-07-24 15:21:05 +02:00
commit 4824608a33
467 changed files with 90887 additions and 0 deletions

View file

@ -0,0 +1,75 @@
<?php
/**
* @file block-admin-display-form.tpl.php
* Default theme implementation to configure blocks.
*
* Available variables:
* - $block_regions: An array of regions. Keyed by name with the title as value.
* - $block_listing: An array of blocks keyed by region and then delta.
* - $form_submit: Form submit button.
* - $throttle: TRUE or FALSE depending on throttle module being enabled.
*
* Each $block_listing[$region] contains an array of blocks for that region.
*
* Each $data in $block_listing[$region] contains:
* - $data->region_title: Region title for the listed block.
* - $data->block_title: Block title.
* - $data->region_select: Drop-down menu for assigning a region.
* - $data->weight_select: Drop-down menu for setting weights.
* - $data->throttle_check: Checkbox to enable throttling.
* - $data->configure_link: Block configuration link.
* - $data->delete_link: For deleting user added blocks.
*
* @see template_preprocess_block_admin_display_form()
* @see theme_block_admin_display()
*/
?>
<?php
// Add table javascript.
drupal_add_js('misc/tableheader.js');
drupal_add_js(drupal_get_path('module', 'block') .'/block.js');
foreach ($block_regions as $region => $title) {
drupal_add_tabledrag('blocks', 'match', 'sibling', 'block-region-select', 'block-region-'. $region, NULL, FALSE);
drupal_add_tabledrag('blocks', 'order', 'sibling', 'block-weight', 'block-weight-'. $region);
}
?>
<table id="blocks" class="sticky-enabled">
<thead>
<tr>
<th><?php print t('Block'); ?></th>
<th><?php print t('Region'); ?></th>
<th><?php print t('Weight'); ?></th>
<?php if ($throttle): ?>
<th><?php print t('Throttle'); ?></th>
<?php endif; ?>
<th colspan="2"><?php print t('Operations'); ?></th>
</tr>
</thead>
<tbody>
<?php $row = 0; ?>
<?php foreach ($block_regions as $region => $title): ?>
<tr class="region region-<?php print $region?>">
<td colspan="<?php print $throttle ? '6' : '5'; ?>" class="region"><?php print $title; ?></td>
</tr>
<tr class="region-message region-<?php print $region?>-message <?php print empty($block_listing[$region]) ? 'region-empty' : 'region-populated'; ?>">
<td colspan="<?php print $throttle ? '6' : '5'; ?>"><em><?php print t('No blocks in this region'); ?></em></td>
</tr>
<?php foreach ($block_listing[$region] as $delta => $data): ?>
<tr class="draggable <?php print $row % 2 == 0 ? 'odd' : 'even'; ?><?php print $data->row_class ? ' '. $data->row_class : ''; ?>">
<td class="block"><?php print $data->block_title; ?></td>
<td><?php print $data->region_select; ?></td>
<td><?php print $data->weight_select; ?></td>
<?php if ($throttle): ?>
<td><?php print $data->throttle_check; ?></td>
<?php endif; ?>
<td><?php print $data->configure_link; ?></td>
<td><?php print $data->delete_link; ?></td>
</tr>
<?php $row++; ?>
<?php endforeach; ?>
<?php endforeach; ?>
</tbody>
</table>
<?php print $form_submit; ?>

View file

@ -0,0 +1,404 @@
<?php
/**
* @file
* Admin page callbacks for the block module.
*/
/**
* Menu callback for admin/build/block.
*/
function block_admin_display($theme = NULL) {
global $custom_theme;
// If non-default theme configuration has been selected, set the custom theme.
$custom_theme = isset($theme) ? $theme : variable_get('theme_default', 'garland');
// Fetch and sort blocks
$blocks = _block_rehash();
usort($blocks, '_block_compare');
return drupal_get_form('block_admin_display_form', $blocks, $theme);
}
/**
* Generate main blocks administration form.
*/
function block_admin_display_form(&$form_state, $blocks, $theme = NULL) {
global $theme_key, $custom_theme;
// Add CSS
drupal_add_css(drupal_get_path('module', 'block') .'/block.css', 'module', 'all', FALSE);
// If non-default theme configuration has been selected, set the custom theme.
$custom_theme = isset($theme) ? $theme : variable_get('theme_default', 'garland');
init_theme();
$throttle = module_exists('throttle');
$block_regions = system_region_list($theme_key) + array(BLOCK_REGION_NONE => '<'. t('none') .'>');
// Weights range from -delta to +delta, so delta should be at least half
// of the amount of blocks present. This makes sure all blocks in the same
// region get an unique weight.
$weight_delta = round(count($blocks) / 2);
// Build form tree
$form = array(
'#action' => arg(4) ? url('admin/build/block/list/'. $theme_key) : url('admin/build/block'),
'#tree' => TRUE,
);
foreach ($blocks as $i => $block) {
$key = $block['module'] .'_'. $block['delta'];
$form[$key]['module'] = array(
'#type' => 'value',
'#value' => $block['module'],
);
$form[$key]['delta'] = array(
'#type' => 'value',
'#value' => $block['delta'],
);
$form[$key]['info'] = array(
'#value' => check_plain($block['info'])
);
$form[$key]['theme'] = array(
'#type' => 'hidden',
'#value' => $theme_key
);
$form[$key]['weight'] = array(
'#type' => 'weight',
'#default_value' => $block['weight'],
'#delta' => $weight_delta,
);
$form[$key]['region'] = array(
'#type' => 'select',
'#default_value' => $block['region'],
'#options' => $block_regions,
);
if ($throttle) {
$form[$key]['throttle'] = array('#type' => 'checkbox', '#default_value' => isset($block['throttle']) ? $block['throttle'] : FALSE);
}
$form[$key]['configure'] = array('#value' => l(t('configure'), 'admin/build/block/configure/'. $block['module'] .'/'. $block['delta']));
if ($block['module'] == 'block') {
$form[$key]['delete'] = array('#value' => l(t('delete'), 'admin/build/block/delete/'. $block['delta']));
}
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save blocks'),
);
return $form;
}
/**
* Process main blocks administration form submission.
*/
function block_admin_display_form_submit($form, &$form_state) {
foreach ($form_state['values'] as $block) {
$block['status'] = $block['region'] != BLOCK_REGION_NONE;
$block['region'] = $block['status'] ? $block['region'] : '';
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']);
}
drupal_set_message(t('The block settings have been updated.'));
cache_clear_all();
}
/**
* Helper function for sorting blocks on admin/build/block.
*
* Active blocks are sorted by region, then by weight.
* Disabled blocks are sorted by name.
*/
function _block_compare($a, $b) {
global $theme_key;
static $regions;
// We need the region list to correctly order by region.
if (!isset($regions)) {
$regions = array_flip(array_keys(system_region_list($theme_key)));
$regions[BLOCK_REGION_NONE] = count($regions);
}
// Separate enabled from disabled.
$status = $b['status'] - $a['status'];
if ($status) {
return $status;
}
// Sort by region (in the order defined by theme .info file).
if ((!empty($a['region']) && !empty($b['region'])) && ($place = ($regions[$a['region']] - $regions[$b['region']]))) {
return $place;
}
// Sort by weight.
$weight = $a['weight'] - $b['weight'];
if ($weight) {
return $weight;
}
// Sort by title.
return strcmp($a['info'], $b['info']);
}
/**
* Menu callback; displays the block configuration form.
*/
function block_admin_configure(&$form_state, $module = NULL, $delta = 0) {
$form['module'] = array('#type' => 'value', '#value' => $module);
$form['delta'] = array('#type' => 'value', '#value' => $delta);
$edit = db_fetch_array(db_query("SELECT pages, visibility, custom, title FROM {blocks} WHERE module = '%s' AND delta = '%s'", $module, $delta));
$form['block_settings'] = array(
'#type' => 'fieldset',
'#title' => t('Block specific settings'),
'#collapsible' => TRUE,
);
$form['block_settings']['title'] = array(
'#type' => 'textfield',
'#title' => t('Block title'),
'#maxlength' => 64,
'#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.'),
'#default_value' => $edit['title'],
'#weight' => -18,
);
// Module-specific block configurations.
if ($settings = module_invoke($module, 'block', 'configure', $delta)) {
foreach ($settings as $k => $v) {
$form['block_settings'][$k] = $v;
}
}
// Get the block subject for the page title.
$info = module_invoke($module, 'block', 'list');
if (isset($info[$delta])) {
drupal_set_title(t("'%name' block", array('%name' => $info[$delta]['info'])));
}
// Standard block configurations.
$form['user_vis_settings'] = array(
'#type' => 'fieldset',
'#title' => t('User specific visibility settings'),
'#collapsible' => TRUE,
);
$form['user_vis_settings']['custom'] = array(
'#type' => 'radios',
'#title' => t('Custom visibility settings'),
'#options' => array(
t('Users cannot control whether or not they see this block.'),
t('Show this block by default, but let individual users hide it.'),
t('Hide this block by default but let individual users show it.')
),
'#description' => t('Allow individual users to customize the visibility of this block in their account settings.'),
'#default_value' => $edit['custom'],
);
// Role-based visibility settings
$default_role_options = array();
$result = db_query("SELECT rid FROM {blocks_roles} WHERE module = '%s' AND delta = '%s'", $module, $delta);
while ($role = db_fetch_object($result)) {
$default_role_options[] = $role->rid;
}
$result = db_query('SELECT rid, name FROM {role} ORDER BY name');
$role_options = array();
while ($role = db_fetch_object($result)) {
$role_options[$role->rid] = $role->name;
}
$form['role_vis_settings'] = array(
'#type' => 'fieldset',
'#title' => t('Role specific visibility settings'),
'#collapsible' => TRUE,
);
$form['role_vis_settings']['roles'] = array(
'#type' => 'checkboxes',
'#title' => t('Show block for specific roles'),
'#default_value' => $default_role_options,
'#options' => $role_options,
'#description' => t('Show this block only for the selected role(s). If you select no roles, the block will be visible to all users.'),
);
$form['page_vis_settings'] = array(
'#type' => 'fieldset',
'#title' => t('Page specific visibility settings'),
'#collapsible' => TRUE,
);
$access = user_access('use PHP for block visibility');
if ($edit['visibility'] == 2 && !$access) {
$form['page_vis_settings'] = array();
$form['page_vis_settings']['visibility'] = array('#type' => 'value', '#value' => 2);
$form['page_vis_settings']['pages'] = array('#type' => 'value', '#value' => $edit['pages']);
}
else {
$options = array(t('Show on every page except the listed pages.'), t('Show on only the listed pages.'));
$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>'));
if ($access) {
$options[] = t('Show if the following PHP code returns <code>TRUE</code> (PHP-mode, experts only).');
$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 ?>'));
}
$form['page_vis_settings']['visibility'] = array(
'#type' => 'radios',
'#title' => t('Show block on specific pages'),
'#options' => $options,
'#default_value' => $edit['visibility'],
);
$form['page_vis_settings']['pages'] = array(
'#type' => 'textarea',
'#title' => t('Pages'),
'#default_value' => $edit['pages'],
'#description' => $description,
);
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save block'),
);
return $form;
}
function block_admin_configure_validate($form, &$form_state) {
if ($form_state['values']['module'] == 'block') {
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']))) {
form_set_error('info', t('Please ensure that each block description is unique.'));
}
}
}
function block_admin_configure_submit($form, &$form_state) {
if (!form_get_errors()) {
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']);
db_query("DELETE FROM {blocks_roles} WHERE module = '%s' AND delta = '%s'", $form_state['values']['module'], $form_state['values']['delta']);
foreach (array_filter($form_state['values']['roles']) as $rid) {
db_query("INSERT INTO {blocks_roles} (rid, module, delta) VALUES (%d, '%s', '%s')", $rid, $form_state['values']['module'], $form_state['values']['delta']);
}
module_invoke($form_state['values']['module'], 'block', 'save', $form_state['values']['delta'], $form_state['values']);
drupal_set_message(t('The block configuration has been saved.'));
cache_clear_all();
$form_state['redirect'] = 'admin/build/block';
return;
}
}
/**
* Menu callback: display the custom block addition form.
*/
function block_add_block_form(&$form_state) {
return block_admin_configure($form_state, 'block', NULL);
}
function block_add_block_form_validate($form, &$form_state) {
if (empty($form_state['values']['info']) || db_result(db_query("SELECT COUNT(*) FROM {boxes} WHERE info = '%s'", $form_state['values']['info']))) {
form_set_error('info', t('Please ensure that each block description is unique.'));
}
}
/**
* Save the new custom block.
*/
function block_add_block_form_submit($form, &$form_state) {
db_query("INSERT INTO {boxes} (body, info, format) VALUES ('%s', '%s', %d)", $form_state['values']['body'], $form_state['values']['info'], $form_state['values']['format']);
$delta = db_last_insert_id('boxes', 'bid');
foreach (list_themes() as $key => $theme) {
if ($theme->status) {
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);
}
}
foreach (array_filter($form_state['values']['roles']) as $rid) {
db_query("INSERT INTO {blocks_roles} (rid, module, delta) VALUES (%d, '%s', '%s')", $rid, $form_state['values']['module'], $delta);
}
drupal_set_message(t('The block has been created.'));
cache_clear_all();
$form_state['redirect'] = 'admin/build/block';
return;
}
/**
* Menu callback; confirm deletion of custom blocks.
*/
function block_box_delete(&$form_state, $bid = 0) {
$box = block_box_get($bid);
$form['info'] = array('#type' => 'hidden', '#value' => $box['info']);
$form['bid'] = array('#type' => 'hidden', '#value' => $bid);
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'));
}
/**
* Deletion of custom blocks.
*/
function block_box_delete_submit($form, &$form_state) {
db_query('DELETE FROM {boxes} WHERE bid = %d', $form_state['values']['bid']);
db_query("DELETE FROM {blocks} WHERE module = 'block' AND delta = '%s'", $form_state['values']['bid']);
drupal_set_message(t('The block %name has been removed.', array('%name' => $form_state['values']['info'])));
cache_clear_all();
$form_state['redirect'] = 'admin/build/block';
return;
}
/**
* Process variables for block-admin-display.tpl.php.
*
* The $variables array contains the following arguments:
* - $form
*
* @see block-admin-display.tpl.php
* @see theme_block_admin_display()
*/
function template_preprocess_block_admin_display_form(&$variables) {
global $theme_key;
$block_regions = system_region_list($theme_key);
$variables['throttle'] = module_exists('throttle');
$variables['block_regions'] = $block_regions + array(BLOCK_REGION_NONE => t('Disabled'));
foreach ($block_regions as $key => $value) {
// Highlight regions on page to provide visual reference.
drupal_set_content($key, '<div class="block-region">'. $value .'</div>');
// Initialize an empty array for the region.
$variables['block_listing'][$key] = array();
}
// Initialize disabled blocks array.
$variables['block_listing'][BLOCK_REGION_NONE] = array();
// Set up to track previous region in loop.
$last_region = '';
foreach (element_children($variables['form']) as $i) {
$block = &$variables['form'][$i];
// Only take form elements that are blocks.
if (isset($block['info'])) {
// Fetch region for current block.
$region = $block['region']['#default_value'];
// Set special classes needed for table drag and drop.
$variables['form'][$i]['region']['#attributes']['class'] = 'block-region-select block-region-'. $region;
$variables['form'][$i]['weight']['#attributes']['class'] = 'block-weight block-weight-'. $region;
$variables['block_listing'][$region][$i] = new stdClass();
$variables['block_listing'][$region][$i]->row_class = isset($block['#attributes']['class']) ? $block['#attributes']['class'] : '';
$variables['block_listing'][$region][$i]->block_modified = isset($block['#attributes']['class']) && strpos($block['#attributes']['class'], 'block-modified') !== FALSE ? TRUE : FALSE;
$variables['block_listing'][$region][$i]->block_title = drupal_render($block['info']);
$variables['block_listing'][$region][$i]->region_select = drupal_render($block['region']) . drupal_render($block['theme']);
$variables['block_listing'][$region][$i]->weight_select = drupal_render($block['weight']);
$variables['block_listing'][$region][$i]->throttle_check = $variables['throttle'] ? drupal_render($block['throttle']) : '';
$variables['block_listing'][$region][$i]->configure_link = drupal_render($block['configure']);
$variables['block_listing'][$region][$i]->delete_link = !empty($block['delete']) ? drupal_render($block['delete']) : '';
$variables['block_listing'][$region][$i]->printed = FALSE;
$last_region = $region;
}
}
$variables['form_submit'] = drupal_render($variables['form']);
}

17
modules/block/block.css Normal file
View file

@ -0,0 +1,17 @@
#blocks td.region {
font-weight: bold;
}
#blocks tr.region-message {
font-weight: normal;
color: #999;
}
#blocks tr.region-populated {
display: none;
}
.block-region {
background-color: #ff6;
margin-top: 4px;
margin-bottom: 4px;
padding: 3px;
}

11
modules/block/block.info Normal file
View file

@ -0,0 +1,11 @@
name = Block
description = Controls the boxes that are displayed around the main content.
package = Core - required
version = VERSION
core = 6.x
; Information added by Drupal.org packaging script on 2016-02-24
version = "6.38"
project = "drupal"
datestamp = "1456343372"

178
modules/block/block.install Normal file
View file

@ -0,0 +1,178 @@
<?php
/**
* Implementation of hook_schema().
*/
function block_schema() {
$schema['blocks'] = array(
'description' => 'Stores block settings, such as region and visibility settings.',
'fields' => array(
'bid' => array(
'type' => 'serial',
'not null' => TRUE,
'description' => 'Primary Key: Unique block ID.',
),
'module' => array(
'type' => 'varchar',
'length' => 64,
'not null' => TRUE,
'default' => '',
'description' => "The module from which the block originates; for example, 'user' for the Who's Online block, and 'block' for any custom blocks.",
),
'delta' => array(
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
'default' => '0',
'description' => 'Unique ID for block within a module.',
),
'theme' => array(
'type' => 'varchar',
'length' => 64,
'not null' => TRUE,
'default' => '',
'description' => 'The theme under which the block settings apply.',
),
'status' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'size' => 'tiny',
'description' => 'Block enabled status. (1 = enabled, 0 = disabled)',
),
'weight' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'size' => 'tiny',
'description' => 'Block weight within region.',
),
'region' => array(
'type' => 'varchar',
'length' => 64,
'not null' => TRUE,
'default' => '',
'description' => 'Theme region within which the block is set.',
),
'custom' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'size' => 'tiny',
'description' => 'Flag to indicate how users may control visibility of the block. (0 = Users cannot control, 1 = On by default, but can be hidden, 2 = Hidden by default, but can be shown)',
),
'throttle' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'size' => 'tiny',
'description' => 'Flag to indicate whether or not to remove block when website traffic is high. (1 = throttle, 0 = do not throttle)',
),
'visibility' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'size' => 'tiny',
'description' => 'Flag to indicate how to show blocks on pages. (0 = Show on all pages except listed pages, 1 = Show only on listed pages, 2 = Use custom PHP code to determine visibility)',
),
'pages' => array(
'type' => 'text',
'not null' => TRUE,
'description' => 'Contents of the "Pages" block; contains either a list of paths on which to include/exclude the block or PHP code, depending on "visibility" setting.',
),
'title' => array(
'type' => 'varchar',
'length' => 64,
'not null' => TRUE,
'default' => '',
'description' => 'Custom title for the block. (Empty string will use block default title, &lt;none&gt; will remove the title, text will cause block to use specified title.)',
),
'cache' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 1,
'size' => 'tiny',
'description' => 'Binary flag to indicate block cache mode. (-1: Do not cache, 1: Cache per role, 2: Cache per user, 4: Cache per page, 8: Block cache global) See BLOCK_CACHE_* constants in block.module for more detailed information.',
),
),
'primary key' => array('bid'),
'unique keys' => array(
'tmd' => array('theme', 'module', 'delta'),
),
'indexes' => array(
'list' => array('theme', 'status', 'region', 'weight', 'module'),
),
);
$schema['blocks_roles'] = array(
'description' => 'Sets up access permissions for blocks based on user roles',
'fields' => array(
'module' => array(
'type' => 'varchar',
'length' => 64,
'not null' => TRUE,
'description' => "The block's origin module, from {blocks}.module.",
),
'delta' => array(
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
'description' => "The block's unique delta within module, from {blocks}.delta.",
),
'rid' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'description' => "The user's role ID from {users_roles}.rid.",
),
),
'primary key' => array(
'module',
'delta',
'rid'
),
'indexes' => array(
'rid' => array('rid'),
),
);
$schema['boxes'] = array(
'description' => 'Stores contents of custom-made blocks.',
'fields' => array(
'bid' => array(
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
'description' => "The block's {blocks}.bid.",
),
'body' => array(
'type' => 'text',
'not null' => FALSE,
'size' => 'big',
'description' => 'Block contents.',
),
'info' => array(
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
'default' => '',
'description' => 'Block description.',
),
'format' => array(
'type' => 'int',
'size' => 'small',
'not null' => TRUE,
'default' => 0,
'description' => "Block body's {filter_formats}.format; for example, 1 = Filtered HTML.",
)
),
'unique keys' => array('info' => array('info')),
'primary key' => array('bid'),
);
$schema['cache_block'] = drupal_get_schema_unprocessed('system', 'cache');
$schema['cache_block']['description'] = 'Cache table for the Block module to store already built blocks, identified by module, delta, and various contexts which may change the block, such as theme, locale, and caching mode defined for the block.';
return $schema;
}

94
modules/block/block.js Normal file
View file

@ -0,0 +1,94 @@
/**
* Move a block in the blocks table from one region to another via select list.
*
* This behavior is dependent on the tableDrag behavior, since it uses the
* objects initialized in that behavior to update the row.
*/
Drupal.behaviors.blockDrag = function(context) {
var table = $('table#blocks');
var tableDrag = Drupal.tableDrag.blocks; // Get the blocks tableDrag object.
// Add a handler for when a row is swapped, update empty regions.
tableDrag.row.prototype.onSwap = function(swappedRow) {
checkEmptyRegions(table, this);
};
// A custom message for the blocks page specifically.
Drupal.theme.tableDragChangedWarning = function () {
return '<div class="warning">' + Drupal.theme('tableDragChangedMarker') + ' ' + Drupal.t("The changes to these blocks will not be saved until the <em>Save blocks</em> button is clicked.") + '</div>';
};
// Add a handler so when a row is dropped, update fields dropped into new regions.
tableDrag.onDrop = function() {
dragObject = this;
if ($(dragObject.rowObject.element).prev('tr').is('.region-message')) {
var regionRow = $(dragObject.rowObject.element).prev('tr').get(0);
var regionName = regionRow.className.replace(/([^ ]+[ ]+)*region-([^ ]+)-message([ ]+[^ ]+)*/, '$2');
var regionField = $('select.block-region-select', dragObject.rowObject.element);
var weightField = $('select.block-weight', dragObject.rowObject.element);
var oldRegionName = weightField[0].className.replace(/([^ ]+[ ]+)*block-weight-([^ ]+)([ ]+[^ ]+)*/, '$2');
if (!regionField.is('.block-region-'+ regionName)) {
regionField.removeClass('block-region-' + oldRegionName).addClass('block-region-' + regionName);
weightField.removeClass('block-weight-' + oldRegionName).addClass('block-weight-' + regionName);
regionField.val(regionName);
}
}
};
// Add the behavior to each region select list.
$('select.block-region-select:not(.blockregionselect-processed)', context).each(function() {
$(this).change(function(event) {
// Make our new row and select field.
var row = $(this).parents('tr:first');
var select = $(this);
tableDrag.rowObject = new tableDrag.row(row);
// Find the correct region and insert the row as the first in the region.
$('tr.region-message', table).each(function() {
if ($(this).is('.region-' + select[0].value + '-message')) {
// Add the new row and remove the old one.
$(this).after(row);
// Manually update weights and restripe.
tableDrag.updateFields(row.get(0));
tableDrag.rowObject.changed = true;
if (tableDrag.oldRowElement) {
$(tableDrag.oldRowElement).removeClass('drag-previous');
}
tableDrag.oldRowElement = row.get(0);
tableDrag.restripeTable();
tableDrag.rowObject.markChanged();
tableDrag.oldRowElement = row;
$(row).addClass('drag-previous');
}
});
// Modify empty regions with added or removed fields.
checkEmptyRegions(table, row);
// Remove focus from selectbox.
select.get(0).blur();
});
$(this).addClass('blockregionselect-processed');
});
var checkEmptyRegions = function(table, rowObject) {
$('tr.region-message', table).each(function() {
// If the dragged row is in this region, but above the message row, swap it down one space.
if ($(this).prev('tr').get(0) == rowObject.element) {
// Prevent a recursion problem when using the keyboard to move rows up.
if ((rowObject.method != 'keyboard' || rowObject.direction == 'down')) {
rowObject.swap('after', this);
}
}
// This region has become empty
if ($(this).next('tr').is(':not(.draggable)') || $(this).next('tr').size() == 0) {
$(this).removeClass('region-populated').addClass('region-empty');
}
// This region has become populated.
else if ($(this).is('.region-empty')) {
$(this).removeClass('region-empty').addClass('region-populated');
}
});
};
};

605
modules/block/block.module Normal file
View file

@ -0,0 +1,605 @@
<?php
/**
* @file
* Controls the boxes that are displayed around the main content.
*/
/**
* Denotes that a block is not enabled in any region and should not
* be shown.
*/
define('BLOCK_REGION_NONE', -1);
/**
* Constants defining cache granularity for blocks.
*
* Modules specify the caching patterns for their blocks using binary
* combinations of these constants in their hook_block(op 'list'):
* $block[delta]['cache'] = BLOCK_CACHE_PER_ROLE | BLOCK_CACHE_PER_PAGE;
* BLOCK_CACHE_PER_ROLE is used as a default when no caching pattern is
* specified.
*
* The block cache is cleared in cache_clear_all(), and uses the same clearing
* policy than page cache (node, comment, user, taxonomy added or updated...).
* Blocks requiring more fine-grained clearing might consider disabling the
* built-in block cache (BLOCK_NO_CACHE) and roll their own.
*
* Note that user 1 is excluded from block caching.
*/
/**
* The block should not get cached. This setting should be used:
* - for simple blocks (notably those that do not perform any db query),
* where querying the db cache would be more expensive than directly generating
* the content.
* - for blocks that change too frequently.
*/
define('BLOCK_NO_CACHE', -1);
/**
* The block can change depending on the roles the user viewing the page belongs to.
* This is the default setting, used when the block does not specify anything.
*/
define('BLOCK_CACHE_PER_ROLE', 0x0001);
/**
* The block can change depending on the user viewing the page.
* This setting can be resource-consuming for sites with large number of users,
* and thus should only be used when BLOCK_CACHE_PER_ROLE is not sufficient.
*/
define('BLOCK_CACHE_PER_USER', 0x0002);
/**
* The block can change depending on the page being viewed.
*/
define('BLOCK_CACHE_PER_PAGE', 0x0004);
/**
* The block is the same for every user on every page where it is visible.
*/
define('BLOCK_CACHE_GLOBAL', 0x0008);
/**
* Implementation of hook_help().
*/
function block_help($path, $arg) {
switch ($path) {
case 'admin/help#block':
$output = '<p>'. t('Blocks are boxes of content rendered into an area, or region, of a web page. The default theme Garland, for example, implements the regions "left sidebar", "right sidebar", "content", "header", and "footer", and a block may appear in any one of these areas. The <a href="@blocks">blocks administration page</a> provides a drag-and-drop interface for assigning a block to a region, and for controlling the order of blocks within regions.', array('@blocks' => url('admin/build/block'))) .'</p>';
$output .= '<p>'. t('Although blocks are usually generated automatically by modules (like the <em>User login</em> block, for example), administrators can also define custom blocks. Custom blocks have a title, description, and body. The body of the block can be as long as necessary, and can contain content supported by any available <a href="@input-format">input format</a>.', array('@input-format' => url('admin/settings/filters'))) .'</p>';
$output .= '<p>'. t('When working with blocks, remember that:') .'</p>';
$output .= '<ul><li>'. t('since not all themes implement the same regions, or display regions in the same way, blocks are positioned on a per-theme basis.') .'</li>';
$output .= '<li>'. t('disabled blocks, or blocks not in a region, are never shown.') .'</li>';
$output .= '<li>'. t('when throttle module is enabled, throttled blocks (blocks with the <em>Throttle</em> checkbox selected) are hidden during high server loads.') .'</li>';
$output .= '<li>'. t('blocks can be configured to be visible only on certain pages.') .'</li>';
$output .= '<li>'. t('blocks can be configured to be visible only when specific conditions are true.') .'</li>';
$output .= '<li>'. t('blocks can be configured to be visible only for certain user roles.') .'</li>';
$output .= '<li>'. t('when allowed by an administrator, specific blocks may be enabled or disabled on a per-user basis using the <em>My account</em> page.') .'</li>';
$output .= '<li>'. t('some dynamic blocks, such as those generated by modules, will be displayed only on certain pages.') .'</li></ul>';
$output .= '<p>'. t('For more information, see the online handbook entry for <a href="@block">Block module</a>.', array('@block' => 'http://drupal.org/handbook/modules/block/')) .'</p>';
return $output;
case 'admin/build/block':
$throttle = module_exists('throttle');
$output = '<p>'. t('This page provides a drag-and-drop interface for assigning a block to a region, and for controlling the order of blocks within regions. To change the region or order of a block, grab a drag-and-drop handle under the <em>Block</em> column and drag the block to a new location in the list. (Grab a handle by clicking and holding the mouse while hovering over a handle icon.) Since not all themes implement the same regions, or display regions in the same way, blocks are positioned on a per-theme basis. Remember that your changes will not be saved until you click the <em>Save blocks</em> button at the bottom of the page.') .'</p>';
if ($throttle) {
$output .= '<p>'. t('To reduce CPU usage, database traffic or bandwidth, blocks may be automatically disabled during high server loads by selecting their <em>Throttle</em> checkbox. Adjust throttle thresholds on the <a href="@throttleconfig">throttle configuration page</a>.', array('@throttleconfig' => url('admin/settings/throttle'))) .'</p>';
}
$output .= '<p>'. t('Click the <em>configure</em> link next to each block to configure its specific title and visibility settings. Use the <a href="@add-block">add block page</a> to create a custom block.', array('@add-block' => url('admin/build/block/add'))) .'</p>';
return $output;
case 'admin/build/block/add':
return '<p>'. t('Use this page to create a new custom block. New blocks are disabled by default, and must be moved to a region on the <a href="@blocks">blocks administration page</a> to be visible.', array('@blocks' => url('admin/build/block'))) .'</p>';
}
}
/**
* Implementation of hook_theme()
*/
function block_theme() {
return array(
'block_admin_display_form' => array(
'template' => 'block-admin-display-form',
'file' => 'block.admin.inc',
'arguments' => array('form' => NULL),
),
);
}
/**
* Implementation of hook_perm().
*/
function block_perm() {
return array('administer blocks', 'use PHP for block visibility');
}
/**
* Implementation of hook_menu().
*/
function block_menu() {
$items['admin/build/block'] = array(
'title' => 'Blocks',
'description' => 'Configure what block content appears in your site\'s sidebars and other regions.',
'page callback' => 'block_admin_display',
'access arguments' => array('administer blocks'),
'file' => 'block.admin.inc',
);
$items['admin/build/block/list'] = array(
'title' => 'List',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['admin/build/block/list/js'] = array(
'title' => 'JavaScript List Form',
'page callback' => 'block_admin_display_js',
'access arguments' => array('administer blocks'),
'type' => MENU_CALLBACK,
'file' => 'block.admin.inc',
);
$items['admin/build/block/configure'] = array(
'title' => 'Configure block',
'page callback' => 'drupal_get_form',
'page arguments' => array('block_admin_configure'),
'access arguments' => array('administer blocks'),
'type' => MENU_CALLBACK,
'file' => 'block.admin.inc',
);
$items['admin/build/block/delete'] = array(
'title' => 'Delete block',
'page callback' => 'drupal_get_form',
'page arguments' => array('block_box_delete'),
'access arguments' => array('administer blocks'),
'type' => MENU_CALLBACK,
'file' => 'block.admin.inc',
);
$items['admin/build/block/add'] = array(
'title' => 'Add block',
'page callback' => 'drupal_get_form',
'page arguments' => array('block_add_block_form'),
'access arguments' => array('administer blocks'),
'type' => MENU_LOCAL_TASK,
'file' => 'block.admin.inc',
);
$default = variable_get('theme_default', 'garland');
foreach (list_themes() as $key => $theme) {
$items['admin/build/block/list/'. $key] = array(
'title' => check_plain($theme->info['name']),
'page arguments' => array($key),
'type' => $key == $default ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
'weight' => $key == $default ? -10 : 0,
'file' => 'block.admin.inc',
'access callback' => '_block_themes_access',
'access arguments' => array($theme),
);
}
return $items;
}
/**
* Menu item access callback - only admin or enabled themes can be accessed
*/
function _block_themes_access($theme) {
return user_access('administer blocks') && ($theme->status || $theme->name == variable_get('admin_theme', '0'));
}
/**
* Implementation of hook_block().
*
* Generates the administrator-defined blocks for display.
*/
function block_block($op = 'list', $delta = 0, $edit = array()) {
switch ($op) {
case 'list':
$blocks = array();
$result = db_query('SELECT bid, info FROM {boxes} ORDER BY info');
while ($block = db_fetch_object($result)) {
$blocks[$block->bid]['info'] = $block->info;
// Not worth caching.
$blocks[$block->bid]['cache'] = BLOCK_NO_CACHE;
}
return $blocks;
case 'configure':
$box = array('format' => FILTER_FORMAT_DEFAULT);
if ($delta) {
$box = block_box_get($delta);
}
if (filter_access($box['format'])) {
return block_box_form($box);
}
break;
case 'save':
block_box_save($edit, $delta);
break;
case 'view':
$block = db_fetch_object(db_query('SELECT body, format FROM {boxes} WHERE bid = %d', $delta));
$data['content'] = check_markup($block->body, $block->format, FALSE);
return $data;
}
}
/**
* Update the 'blocks' DB table with the blocks currently exported by modules.
*
* @param $theme
* The theme to rehash blocks for. If not provided, defaults to the currently
* used theme.
*
* @return
* Blocks currently exported by modules.
*/
function _block_rehash($theme = NULL) {
global $theme_key;
init_theme();
if (!isset($theme)) {
$theme = $theme_key;
}
$result = db_query("SELECT * FROM {blocks} WHERE theme = '%s'", $theme);
$old_blocks = array();
while ($old_block = db_fetch_array($result)) {
$old_blocks[$old_block['module']][$old_block['delta']] = $old_block;
}
$blocks = array();
// Valid region names for the theme.
$regions = system_region_list($theme);
foreach (module_list() as $module) {
$module_blocks = module_invoke($module, 'block', 'list');
if ($module_blocks) {
foreach ($module_blocks as $delta => $block) {
if (empty($old_blocks[$module][$delta])) {
// If it's a new block, add identifiers.
$block['module'] = $module;
$block['delta'] = $delta;
$block['theme'] = $theme;
if (!isset($block['pages'])) {
// {block}.pages is type 'text', so it cannot have a
// default value, and not null, so we need to provide
// value if the module did not.
$block['pages'] = '';
}
// Add defaults and save it into the database.
drupal_write_record('blocks', $block);
// Set region to none if not enabled.
$block['region'] = $block['status'] ? $block['region'] : BLOCK_REGION_NONE;
// Add to the list of blocks we return.
$blocks[] = $block;
}
else {
// If it's an existing block, database settings should overwrite
// the code. The only exceptions are 'cache' which is only definable
// and updatable in the code, and 'info' which is not stored in
// the database.
// Update the cache mode only; the other values don't need to change.
if (isset($block['cache']) && $block['cache'] != $old_blocks[$module][$delta]['cache']) {
db_query("UPDATE {blocks} SET cache = %d WHERE bid = %d", $block['cache'], $old_blocks[$module][$delta]['bid']);
}
// Add 'info' to this block.
$old_blocks[$module][$delta]['info'] = $block['info'];
// If the region name does not exist, disable the block and assign it to none.
if (!empty($old_blocks[$module][$delta]['region']) && !isset($regions[$old_blocks[$module][$delta]['region']])) {
drupal_set_message(t('The block %info was assigned to the invalid region %region and has been disabled.', array('%info' => $old_blocks[$module][$delta]['info'], '%region' => $old_blocks[$module][$delta]['region'])), 'warning');
$old_blocks[$module][$delta]['status'] = 0;
$old_blocks[$module][$delta]['region'] = BLOCK_REGION_NONE;
}
else {
$old_blocks[$module][$delta]['region'] = $old_blocks[$module][$delta]['status'] ? $old_blocks[$module][$delta]['region'] : BLOCK_REGION_NONE;
}
// Add this block to the list of blocks we return.
$blocks[] = $old_blocks[$module][$delta];
// Remove this block from the list of blocks to be deleted.
unset($old_blocks[$module][$delta]);
}
}
}
}
// Remove blocks that are no longer defined by the code from the database.
foreach ($old_blocks as $module => $old_module_blocks) {
// This cleanup does not apply to disabled modules, to avoid configuration
// being lost when modules are disabled.
if (module_exists($module)) {
foreach ($old_module_blocks as $delta => $block) {
db_query("DELETE FROM {blocks} WHERE module = '%s' AND delta = '%s' AND theme = '%s'", $module, $delta, $theme);
}
}
}
return $blocks;
}
/**
* Implementation of hook_flush_caches().
*/
function block_flush_caches() {
// Rehash blocks for active themes. We don't use list_themes() here,
// because if MAINTENANCE_MODE is defined it skips reading the database,
// and we can't tell which themes are active.
$result = db_query("SELECT name FROM {system} WHERE type = 'theme' AND status = 1");
while ($theme = db_result($result)) {
_block_rehash($theme);
}
}
/**
* Returns information from database about a user-created (custom) block.
*
* @param $bid
* ID of the block to get information for.
* @return
* Associative array of information stored in the database for this block.
* Array keys:
* - bid: Block ID.
* - info: Block description.
* - body: Block contents.
* - format: Filter ID of the filter format for the body.
*/
function block_box_get($bid) {
return db_fetch_array(db_query("SELECT * FROM {boxes} WHERE bid = %d", $bid));
}
/**
* Define the custom block form.
*/
function block_box_form($edit = array()) {
$edit += array(
'info' => '',
'body' => '',
);
$form['info'] = array(
'#type' => 'textfield',
'#title' => t('Block description'),
'#default_value' => $edit['info'],
'#maxlength' => 64,
'#description' => t('A brief description of your block. Used on the <a href="@overview">block overview page</a>.', array('@overview' => url('admin/build/block'))),
'#required' => TRUE,
'#weight' => -19,
);
$form['body_field']['#weight'] = -17;
$form['body_field']['body'] = array(
'#type' => 'textarea',
'#title' => t('Block body'),
'#default_value' => $edit['body'],
'#rows' => 15,
'#description' => t('The content of the block as shown to the user.'),
'#weight' => -17,
);
if (!isset($edit['format'])) {
$edit['format'] = FILTER_FORMAT_DEFAULT;
}
$form['body_field']['format'] = filter_form($edit['format'], -16);
return $form;
}
/**
* Saves a user-created block in the database.
*
* @param $edit
* Associative array of fields to save. Array keys:
* - info: Block description.
* - body: Block contents.
* - format: Filter ID of the filter format for the body.
* @param $delta
* Block ID of the block to save.
* @return
* Always returns TRUE.
*/
function block_box_save($edit, $delta) {
if (!filter_access($edit['format'])) {
$edit['format'] = FILTER_FORMAT_DEFAULT;
}
db_query("UPDATE {boxes} SET body = '%s', info = '%s', format = %d WHERE bid = %d", $edit['body'], $edit['info'], $edit['format'], $delta);
return TRUE;
}
/**
* Implementation of hook_user().
*
* Allow users to decide which custom blocks to display when they visit
* the site.
*/
function block_user($type, $edit, &$account, $category = NULL) {
switch ($type) {
case 'form':
if ($category == 'account') {
$rids = array_keys($account->roles);
$result = db_query("SELECT DISTINCT b.* FROM {blocks} b LEFT JOIN {blocks_roles} r ON b.module = r.module AND b.delta = r.delta WHERE b.status = 1 AND b.custom != 0 AND (r.rid IN (". db_placeholders($rids) .") OR r.rid IS NULL) ORDER BY b.weight, b.module", $rids);
$form['block'] = array('#type' => 'fieldset', '#title' => t('Block configuration'), '#weight' => 3, '#collapsible' => TRUE, '#tree' => TRUE);
while ($block = db_fetch_object($result)) {
$data = module_invoke($block->module, 'block', 'list');
if ($data[$block->delta]['info']) {
$return = TRUE;
$form['block'][$block->module][$block->delta] = array('#type' => 'checkbox', '#title' => check_plain($data[$block->delta]['info']), '#default_value' => isset($account->block[$block->module][$block->delta]) ? $account->block[$block->module][$block->delta] : ($block->custom == 1));
}
}
if (!empty($return)) {
return $form;
}
}
break;
case 'validate':
if (empty($edit['block'])) {
$edit['block'] = array();
}
return $edit;
}
}
/**
* Return all blocks in the specified region for the current user.
*
* @param $region
* The name of a region.
*
* @return
* An array of block objects, indexed with module name and block delta
* concatenated with an underscore, thus: MODULE_DELTA. If you are displaying
* your blocks in one or two sidebars, you may check whether this array is
* empty to see how many columns are going to be displayed.
*
* @todo
* Now that the blocks table has a primary key, we should use that as the
* array key instead of MODULE_DELTA.
*/
function block_list($region) {
global $user, $theme_key;
static $blocks = array();
if (!count($blocks)) {
$rids = array_keys($user->roles);
$result = db_query(db_rewrite_sql("SELECT DISTINCT b.* FROM {blocks} b LEFT JOIN {blocks_roles} r ON b.module = r.module AND b.delta = r.delta WHERE b.theme = '%s' AND b.status = 1 AND (r.rid IN (". db_placeholders($rids) .") OR r.rid IS NULL) ORDER BY b.region, b.weight, b.module", 'b', 'bid'), array_merge(array($theme_key), $rids));
while ($block = db_fetch_object($result)) {
if (!isset($blocks[$block->region])) {
$blocks[$block->region] = array();
}
// Use the user's block visibility setting, if necessary
if ($block->custom != 0) {
if ($user->uid && isset($user->block[$block->module][$block->delta])) {
$enabled = $user->block[$block->module][$block->delta];
}
else {
$enabled = ($block->custom == 1);
}
}
else {
$enabled = TRUE;
}
// Match path if necessary
if ($block->pages) {
if ($block->visibility < 2) {
$path = drupal_get_path_alias($_GET['q']);
// Compare with the internal and path alias (if any).
$page_match = drupal_match_path($path, $block->pages);
if ($path != $_GET['q']) {
$page_match = $page_match || drupal_match_path($_GET['q'], $block->pages);
}
// When $block->visibility has a value of 0, the block is displayed on
// all pages except those listed in $block->pages. When set to 1, it
// is displayed only on those pages listed in $block->pages.
$page_match = !($block->visibility xor $page_match);
}
else {
$page_match = drupal_eval($block->pages);
}
}
else {
$page_match = TRUE;
}
$block->enabled = $enabled;
$block->page_match = $page_match;
$blocks[$block->region]["{$block->module}_{$block->delta}"] = $block;
}
}
// Create an empty array if there were no entries
if (!isset($blocks[$region])) {
$blocks[$region] = array();
}
foreach ($blocks[$region] as $key => $block) {
// Render the block content if it has not been created already.
if (!isset($block->content)) {
// Erase the block from the static array - we'll put it back if it has content.
unset($blocks[$region][$key]);
if ($block->enabled && $block->page_match) {
// Check the current throttle status and see if block should be displayed
// based on server load.
if (!($block->throttle && (module_invoke('throttle', 'status') > 0))) {
// Try fetching the block from cache. Block caching is not compatible with
// node_access modules. We also preserve the submission of forms in blocks,
// by fetching from cache only if the request method is 'GET'.
if (!count(module_implements('node_grants')) && $_SERVER['REQUEST_METHOD'] == 'GET' && ($cid = _block_get_cache_id($block)) && ($cache = cache_get($cid, 'cache_block'))) {
$array = $cache->data;
}
else {
$array = module_invoke($block->module, 'block', 'view', $block->delta);
if (isset($cid)) {
cache_set($cid, $array, 'cache_block', CACHE_TEMPORARY);
}
}
if (isset($array) && is_array($array)) {
foreach ($array as $k => $v) {
$block->$k = $v;
}
}
}
if (isset($block->content) && $block->content) {
// Override default block title if a custom display title is present.
if ($block->title) {
// Check plain here to allow module generated titles to keep any markup.
$block->subject = $block->title == '<none>' ? '' : check_plain($block->title);
}
if (!isset($block->subject)) {
$block->subject = '';
}
$blocks[$block->region]["{$block->module}_{$block->delta}"] = $block;
}
}
}
}
return $blocks[$region];
}
/**
* Assemble the cache_id to use for a given block.
*
* The cache_id string reflects the viewing context for the current block
* instance, obtained by concatenating the relevant context information
* (user, page, ...) according to the block's cache settings (BLOCK_CACHE_*
* constants). Two block instances can use the same cached content when
* they share the same cache_id.
*
* Theme and language contexts are automatically differenciated.
*
* @param $block
* @return
* The string used as cache_id for the block.
*/
function _block_get_cache_id($block) {
global $theme, $base_root, $user;
// User 1 being out of the regular 'roles define permissions' schema,
// it brings too many chances of having unwanted output get in the cache
// and later be served to other users. We therefore exclude user 1 from
// block caching.
if (variable_get('block_cache', 0) && $block->cache != BLOCK_NO_CACHE && $user->uid != 1) {
$cid_parts = array();
// Start with common sub-patterns: block identification, theme, language.
$cid_parts[] = $block->module;
$cid_parts[] = $block->delta;
$cid_parts[] = $theme;
if (module_exists('locale')) {
global $language;
$cid_parts[] = $language->language;
}
// 'PER_ROLE' and 'PER_USER' are mutually exclusive. 'PER_USER' can be a
// resource drag for sites with many users, so when a module is being
// equivocal, we favor the less expensive 'PER_ROLE' pattern.
if ($block->cache & BLOCK_CACHE_PER_ROLE) {
$cid_parts[] = 'r.'. implode(',', array_keys($user->roles));
}
elseif ($block->cache & BLOCK_CACHE_PER_USER) {
$cid_parts[] = "u.$user->uid";
}
if ($block->cache & BLOCK_CACHE_PER_PAGE) {
$cid_parts[] = $base_root . request_uri();
}
return implode(':', $cid_parts);
}
}