View source
<?php
function context_ui_admin() {
drupal_add_css(drupal_get_path("module", "context_ui") . "/context_ui.css");
_block_rehash();
context_ui_rebuild();
$output = "<h3>" . t('User context definitions') . "</h3>";
$contexts = context_ui_tree('ui');
if ($contexts) {
$output .= theme('context_ui_admin', $contexts);
}
else {
$output .= "<p>" . t('Please !add_context to get started.', array(
'!add_context' => l(t('add a context'), 'admin/build/context/add'),
)) . "</p>";
}
$output .= "<h3>" . t('Module context definitions') . "</h3>";
$contexts = context_ui_tree('system');
if ($contexts) {
$output .= theme('context_ui_admin', $contexts);
}
else {
$output .= "<p>" . t('There are currently no module defined contexts.') . "</p>";
}
return $output;
}
function context_ui_form($op, $cid = NULL, $context = NULL) {
drupal_add_css(drupal_get_path("module", "context_ui") . "/context_ui.css");
drupal_add_js(drupal_get_path("module", "context_ui") . "/context_ui.js");
switch ($op) {
case 'add':
if (is_object($context)) {
$context->system = true;
if ($exists = context_ui_context('load', $context)) {
drupal_set_message(t('A module is already providing a context with this namespace/attribute/value identifier. Your context definition will override its settings.'));
}
$context->system = false;
}
break;
case 'view':
if (is_numeric($cid) && ($context = context_ui_context('load', $cid))) {
drupal_set_title(t('View %title', array(
'%title' => $context->value,
)));
}
else {
drupal_goto('admin/build/context');
return;
}
break;
case 'edit':
if (is_numeric($cid) && ($context = context_ui_context('load', $cid))) {
if (!$context->system) {
drupal_set_title(t('Edit context: %title', array(
'%title' => $context->value,
)));
}
else {
drupal_goto('admin/build/context');
return;
}
}
break;
case 'clone':
if (is_numeric($cid) && ($context = context_ui_context('load', $cid))) {
drupal_set_title(t('Clone context: %title', array(
'%title' => $context->value,
)));
$context->system = 0;
$context->cid = null;
$cid = null;
}
else {
drupal_goto('admin/build/context');
return;
}
break;
}
$form = array(
'#base' => 'context_ui_form',
'#theme' => 'context_ui_form',
);
$form['value'] = $form['attribute'] = $form['namespace'] = array(
'#type' => 'textfield',
'#required' => true,
'#maxlength' => 64,
'#size' => 20,
);
$form['value']['#title'] = t('Value');
$form['value']['#description'] = t('A system name for this context. May only contain lowercase letters, underscores, and numbers. Example: <b>science_blog</b>');
$form['attribute']['#title'] = t('Attribute');
$form['attribute']['#default_value'] = 'section';
$form['attribute']['#description'] = t('The type of context information provided in this namespace. Example: <b>section</b>');
$form['namespace']['#title'] = t('Namespace');
$form['namespace']['#default_value'] = 'context_ui';
$form['namespace']['#description'] = t('The namespace for this context definition. Example: <b>context_ui</b>');
$form['items'] = array(
'#tree' => true,
);
foreach (context_ui_types('full') as $type => $item) {
if (in_array($item['#type'], array(
'select',
'radios',
'checkboxes',
'textfield',
))) {
$form['items'][$type] = $item;
}
}
init_theme();
global $theme_key;
$block_options = $block_defaults = array();
$blocks = _context_ui_get_blocks();
$regions = system_region_list($theme_key);
foreach ($blocks[0] as $block) {
if (!isset($context->block[$block->bid])) {
$block_options[$block->module][$block->bid] = $block->label . " ({$block->bid})";
}
}
ksort($block_options);
$form['block'] = array(
'#tree' => true,
);
$form['block']['selector'] = array(
'#description' => t('Control block visibility using context. Selected blocks will be shown when this context is set provided that custom block visibility settings and/or throttling do not hide them. Grayed out blocks are those provided by Drupal\'s standard block settings. These settings apply to the current theme and any enabled themes with regions in common.'),
'#type' => 'item',
'#tree' => true,
'#prefix' => '<div class="context-ui-block-selector">',
'#suffix' => '</div>',
'blocks' => array(
'#type' => 'select',
'#multiple' => true,
'#size' => 15,
'#title' => t('Blocks'),
'#options' => $block_options,
),
'regions' => array(
'#type' => 'select',
'#title' => t('Regions'),
'#options' => $regions,
),
'add' => array(
'#type' => 'markup',
'#value' => "<input id='edit-block-selector-add' class='form-submit' type='button' value='+ " . t('Add') . "'/>",
),
);
$form['block']['regions'] = array(
'#type' => 'item',
'#tree' => true,
'#prefix' => '<div class="context-ui-block-regions">',
'#suffix' => '</div>',
'#value' => theme('context_ui_block_ui', $regions, $context),
);
foreach (array_keys($regions) as $region) {
$defaults = array();
$midpoint = false;
foreach (_context_ui_get_blocks($region, $context) as $block) {
if ($block->type == 'context_ui') {
$defaults[] = $block->bid;
}
else {
if (!$midpoint) {
$midpoint = true;
$defaults[] = 'system';
}
}
}
if (!$defaults) {
$defaults = array(
'system',
);
}
$defaults = implode(',', $defaults);
$form['block']['regions'][$region] = array(
'#type' => 'hidden',
'#default_value' => $defaults,
);
}
if ($op == 'view') {
$form['back'] = array(
'#type' => 'item',
'#value' => l(t('Back'), 'admin/build/context'),
);
}
if ($op != 'view') {
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
}
if ($op == 'edit') {
$form['delete'] = array(
'#type' => 'submit',
'#value' => t('Delete'),
);
}
if ($op == 'view' || $op == 'edit' || $op == 'clone' || $op == 'add' && $context) {
if ($context) {
$form['value']['#default_value'] = $context->value;
$form['attribute']['#default_value'] = $context->attribute;
$form['namespace']['#default_value'] = $context->namespace;
$form['cid'] = array(
'#type' => 'value',
'#value' => $cid,
);
$form['system'] = array(
'#type' => 'value',
'#value' => $context->system,
);
if ($op == 'view' || $context->system) {
$form['value']['#disabled'] = $form['attribute']['#disabled'] = $form['namespace']['#disabled'] = $form['block']['selector']['blocks']['#disabled'] = $form['block']['selector']['regions']['#disabled'] = true;
}
foreach (context_ui_types('full') as $type => $item) {
if (is_array($context->{$type})) {
if ($item['#type'] == 'checkboxes' || $item['#type'] == 'select' && $item['#multiple'] == true) {
$defaults = array();
foreach ($context->{$type} as $id) {
$defaults[$id] = $id;
}
}
else {
$defaults = current($context->{$type});
}
$form['items'][$type]['#default_value'] = $defaults;
}
$form['items'][$type]['#disabled'] = $op == 'view' ? true : false;
}
if (is_array($context->block)) {
foreach ($regions as $region => $label) {
if (isset($form['block'][$region]) && is_array($form['block'][$region])) {
$defaults = array();
foreach ($form['block'][$region]['#options'] as $block => $label) {
if (array_search($block, $context->block) !== false) {
$defaults[$block] = $block;
}
}
$form['block'][$region]['#default_value'] = $defaults;
}
$form['block'][$region]['#disabled'] = $op == 'view' ? true : false;
}
}
}
else {
return drupal_goto('admin/build/context');
}
}
return $form;
}
function theme_context_ui_form($form) {
$output = '';
foreach (element_children($form) as $element) {
if (isset($form[$element]['#weight']) && $form[$element]['#weight'] < 0) {
$output .= drupal_render($form[$element]);
}
}
$header = array(
t('Namespace'),
t('Attribute'),
t('Value'),
);
unset($form['namespace']['#title']);
unset($form['attribute']['#title']);
unset($form['value']['#title']);
$rows = array(
array(
drupal_render($form['namespace']),
drupal_render($form['attribute']),
drupal_render($form['value']),
),
);
$output .= theme('table', $header, $rows, array(
'class' => 'context-ui-3col',
));
$header = array(
t('Set context'),
t('Respond to context'),
);
$setters = $getters = '';
foreach (context_ui_types('full') as $type => $item) {
if ($item['#context_ui'] == 'getter') {
$getters .= drupal_render($form['items'][$type]);
}
else {
$setters .= drupal_render($form['items'][$type]);
}
}
$rows = array(
array(
array(
'data' => $setters,
'class' => 'setters left',
),
array(
'data' => $getters,
'class' => 'getters right',
),
),
);
$output .= theme('table', $header, $rows, array(
'class' => 'context-ui-2col',
));
$header = array(
t('Blocks'),
t('Regions'),
);
$rows = array(
array(
array(
'data' => drupal_render($form['block']['selector']),
'class' => 'left',
),
array(
'data' => drupal_render($form['block']['regions']),
'class' => 'right',
),
),
);
$output .= theme('table', $header, $rows, array(
'id' => 'context-ui-blocks',
'class' => 'context-ui-2col',
));
$output .= drupal_render($form);
return $output;
}
function context_ui_delete_confirm($cid) {
$context = context_ui_context('load', $cid);
if (!$context) {
return drupal_goto('admin/build/context');
}
$form['cid'] = array(
'#type' => 'value',
'#value' => $cid,
);
$form = confirm_form($form, t('Are you sure you want to delete %title?', array(
'%title' => $context->value,
)), 'admin/build/context', t('This action cannot be undone.'), t('Delete'), t('Cancel'));
return $form;
}
function context_ui_delete_confirm_submit($form_id, $form) {
context_ui_context('delete', $form['cid']);
context_ui_rebuild();
return 'admin/build/context';
}
function context_ui_import_page() {
if (!empty($_POST) && $_POST['form_id'] == 'context_ui_form') {
return drupal_get_form('context_ui_form', 'add');
}
return drupal_get_form('context_ui_import');
}
function context_ui_import() {
drupal_set_title(t('Import context'));
$help = t('You can import a context definition by pasting the exported context object code into the field below.');
$form = array();
$form['help'] = array(
'#type' => 'item',
'#value' => $help,
);
$form['import'] = array(
'#title' => t('Context Object'),
'#type' => 'textarea',
'#rows' => 10,
'#required' => true,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Import'),
);
return $form;
}
function context_ui_import_submit($form_id, $form_values) {
$items = array();
if ($import = $form_values['import']) {
ob_start();
eval($import);
ob_end_clean();
}
if (is_array($items) && count($items)) {
$context = current($items);
}
if (is_array($context)) {
$context = (object) $context;
$context->system = FALSE;
if ($exists = context_ui_context('load', $context)) {
drupal_set_message(t('A user-defined context definition with this space/key/value identifier already exists. Please remove the existing context before importing this definition.'), 'error');
return 'admin/build/context';
}
else {
drupal_set_title(t('Add context'));
$output = drupal_get_form('context_ui_form', 'add', null, (object) $context);
print theme('page', $output);
exit;
}
}
else {
drupal_set_message(t('An error occurred while importing. Please check your context definition.', 'error'));
return 'admin/build/context';
}
}
function context_ui_export($cid = NULL) {
if (is_numeric($cid) && ($context = context_ui_context('load', $cid))) {
drupal_set_title(t('Export %title', array(
'%title' => $context->value,
)));
$help = t('You can use exported contexts in your modules by returning an array of defined contexts in <code>hook_context_define()</code>.');
unset($context->cid);
unset($context->status);
unset($context->system);
$context = (array) $context;
foreach ($context['block'] as $bid => $block) {
unset($block->bid);
$context['block'][$bid] = (array) $block;
}
$export = '$items[] = ' . var_export($context, true) . ';';
$form = array();
$form['help'] = array(
'#type' => 'item',
'#value' => $help,
);
$form['export'] = array(
'#type' => 'textarea',
'#rows' => 24,
'#default_value' => $export,
);
return $form;
}
else {
drupal_goto('admin/build/context');
return;
}
}
function context_ui_tree($op = '') {
static $tree;
if (!$tree) {
$tree = array(
'system' => array(),
'ui' => array(),
);
$result = db_query("\n SELECT *\n FROM {context_ui}\n ORDER BY system ASC, namespace ASC, attribute ASC, value ASC");
while ($context = db_fetch_object($result)) {
$branch = $context->system ? 'system' : 'ui';
$tree[$branch][$context->namespace][$context->attribute][$context->value] = $context;
}
}
switch ($op) {
case 'ui':
return $tree['ui'];
case 'system':
return $tree['system'];
default:
return $tree;
}
}
function context_ui_rebuild() {
$default_contexts = context_ui_defaults();
$types = context_ui_types();
$ui = context_ui_tree('ui');
$system = array();
$result = db_query("SELECT * FROM {context_ui} WHERE system = 1");
while ($existing = db_fetch_object($result)) {
$system[$existing->cid] = true;
}
foreach ($default_contexts as $c) {
if (!empty($c->namespace) && !empty($c->attribute)) {
if (!isset($c->system) && !isset($c->status)) {
$c->system = 1;
$c->status = isset($ui[$c->namespace][$c->attribute][$c->value]) ? 0 : 1;
}
if ($context = context_ui_context('load', $c)) {
$c->cid = $context->cid;
context_ui_context('update', $c);
unset($system[$c->cid]);
}
else {
context_ui_context('insert', $c);
}
}
}
foreach ($system as $c => $dummy) {
context_ui_context('delete', $c);
}
}
function theme_context_ui_admin($context_tree) {
foreach ($context_tree as $namespace => $attributes) {
$rows[] = array(
"<span class='context-namespace'>" . $namespace . "</span>",
null,
);
foreach ($attributes as $attribute => $contexts) {
if (is_array($contexts)) {
$rows[] = array(
"<span class='context-attribute'>" . $attribute . "</span>",
null,
);
foreach ($contexts as $value => $context) {
$links = array();
$class = '';
if ($context->system) {
$links[] = l(t('View'), "admin/build/context/view/{$context->cid}");
$links[] = l(t('Override'), 'admin/build/context/clone/' . $context->cid);
}
else {
$links[] = l(t('Edit'), 'admin/build/context/edit/' . $context->cid);
$links[] = l(t('Clone'), 'admin/build/context/clone/' . $context->cid);
$links[] = l(t('Export'), "admin/build/context/export/{$context->cid}");
$links[] = l(t('Delete'), 'admin/build/context/delete/' . $context->cid);
}
if (!$context->status) {
$class = 'overridden';
$value = "{$value} (" . t('Overridden') . ")";
}
$rows[] = array(
"<span class='context-value {$class}'>" . $value . "</span>",
implode(' | ', $links),
);
}
}
else {
$links = array();
$class = '';
if ($contexts->system) {
$links[] = l(t('View'), "admin/build/context/view/{$contexts->cid}");
}
else {
$links[] = l(t('Edit'), 'admin/build/context/edit/' . $contexts->cid);
$links[] = l(t('Delete'), 'admin/build/context/delete/' . $contexts->cid);
}
if ($contexts->overridden) {
$class = 'overridden';
$key = "{$key} (" . t('Overridden') . ")";
}
$rows[] = array(
"<span class='context-key'>" . $key . "</span>",
implode(' | ', $links),
);
}
}
}
return theme('table', array(
t('Context'),
t('Actions'),
), $rows, array(
'class' => 'context-ui',
));
}
function theme_context_ui_block_ui($regions, $context = null) {
$output = '';
$tools = "<div class='tools'><span class='up'></span><span class='down'></span><span class='remove'></span></div>";
foreach ($regions as $region => $label) {
$items = array();
$system = _context_ui_get_blocks($region);
$system_item = array();
foreach ($system as $block) {
$system_item[] = $block->label . " ({$block->bid})";
}
$system_item = implode("<br/>", $system_item);
$options = _context_ui_get_blocks($region, $context);
$midpoint = false;
if ($options) {
foreach ($options as $block) {
if ($block->type == 'context_ui' && !$context->system) {
$items[] = array(
'data' => $tools . $block->label . " ({$block->bid})",
'title' => $block->bid,
);
}
else {
if ($block->type == 'context_ui' && $context->system) {
$items[] = array(
'data' => $block->label . " ({$block->bid})",
'title' => $block->bid,
'class' => 'default',
);
}
else {
if (!$midpoint) {
$midpoint = true;
$items[] = array(
'data' => $system_item,
'title' => 'system',
'class' => 'disabled',
);
}
}
}
}
}
else {
if ($system_item) {
$items[] = array(
'data' => $system_item,
'title' => 'system',
'class' => 'disabled',
);
}
else {
$items[] = array(
'data' => '',
'class' => 'dummy',
);
}
}
$output .= theme('item_list', $items, $label, 'ul', array(
'class' => form_clean_id($region),
));
}
return $output;
}
function context_ui_form_validate($form_id, $form_values) {
if ($form_values['op'] == t('Save') && $form_values['value']) {
foreach (array(
'value',
'attribute',
'namespace',
) as $elem) {
if (!preg_match('!^[a-z0-9_]+$!', $form_values[$elem])) {
form_set_error($elem, t('The context !elem can only consist of lowercase letters, underscores, and numbers.', array(
'!elem' => $elem,
)));
}
}
if (!isset($form_values['cid'])) {
$context = new StdClass();
$context->namespace = $form_values['namespace'];
$context->attribute = $form_values['attribute'];
$context->value = $form_values['value'];
$context->system = 0;
if ($exists = context_ui_context('load', $context)) {
form_set_error($form_values['value'], t('A user-defined context with this space/key/value identifier already exists. Please delete the existing definition before creating a new one.'));
}
}
}
}
function context_ui_form_process($form) {
$context = new stdClass();
$context->cid = $form['cid'] ? $form['cid'] : null;
$context->system = $form['system'] ? $form['system'] : null;
$context->namespace = $form['namespace'] ? $form['namespace'] : null;
$context->attribute = $form['attribute'] ? $form['attribute'] : null;
$context->value = $form['value'] ? $form['value'] : null;
$context->status = 1;
$item_types = context_ui_types();
foreach ($item_types as $element_id) {
if (is_array($form['items'][$element_id])) {
foreach ($form['items'][$element_id] as $option => $value) {
if ($value) {
$context->{$element_id}[] = $option;
}
}
}
else {
if (isset($form['items'][$element_id]) && !empty($form['items'][$element_id])) {
$context->{$element_id}[] = $form['items'][$element_id];
}
}
}
$context->block = array();
global $theme_key;
$valid = _context_ui_get_blocks();
$valid = $valid[0];
foreach (system_region_list($theme_key) as $region => $label) {
if ($blocks = $form['block']['regions'][$region]) {
$blocks = explode(',', $blocks);
$midpoint = array_search('system', $blocks);
foreach ($blocks as $position => $bid) {
if ($bid != 'system') {
$block = $valid[$bid];
$modifier = $position < $midpoint ? -10 : 10;
$block->weight = $position - $midpoint + $modifier;
$block->region = $region;
$block->type = 'context_ui';
$context->block[$block->bid] = $block;
}
}
}
}
return $context;
}
function context_ui_form_submit($form_id, $form_values) {
switch (t($form_values['op'])) {
case 'Delete':
return 'admin/build/context/delete/' . $form_values['cid'];
case 'Save':
$context = context_ui_form_process($form_values);
if (!$context->cid) {
$result = context_ui_context('insert', $context);
if ($result) {
drupal_set_message(t('The context %title was saved successfully.', array(
'%title' => $context->value,
)));
break;
}
}
else {
if (context_ui_context('load', $context->cid)) {
$result = context_ui_context('update', $context);
if ($result) {
drupal_set_message(t('The context %title was saved successfully.', array(
'%title' => $context->value,
)));
break;
}
}
}
drupal_set_message(t('An error occurred while attempting to save your context information.'), 'error');
break;
}
context_ui_rebuild();
return 'admin/build/context';
}
function _context_ui_get_blocks($region = null, $context = null) {
global $theme_key;
static $block_info, $valid, $system_blocks;
$context_blocks = $blocks = array();
if (!$system_blocks) {
foreach (system_region_list($theme_key) as $r => $l) {
$system_blocks[$r] = array();
}
$result = db_query("SELECT module, delta, weight, region, status FROM {blocks} WHERE theme = '%s' ORDER BY weight, module, delta", $theme_key);
while ($block = db_fetch_object($result)) {
$block_info[$block->module] = isset($block_info[$block->module]) ? $block_info[$block->module] : module_invoke($block->module, 'block', 'list');
$block->label = $block_info[$block->module][$block->delta]['info'];
$block->type = 'system';
$block->bid = $block->module . '_' . $block->delta;
if ($block->region && $block->status) {
$system_blocks[$block->region][$block->bid] = $block;
}
else {
$system_blocks[0][$block->bid] = $block;
}
$valid[$block->module . "_" . $block->delta] = true;
}
}
$blocks = $system_blocks;
if (is_object($context) && is_array($context->block)) {
foreach ($context->block as $block) {
$block = (object) $block;
if ($valid[$block->module . "_" . $block->delta]) {
if (!$region || isset($region) && $block->region == $region) {
$block_info[$block->module] = $block_info[$block->module] ? $block_info[$block->module] : module_invoke($block->module, 'block', 'list');
$block->label = $block_info[$block->module][$block->delta]['info'];
$block->type = 'context_ui';
$block->bid = $block->module . '_' . $block->delta;
if ($block->region) {
$blocks[$block->region][$block->bid] = $block;
}
else {
$blocks[0][$block->bid] = $block;
}
}
}
}
}
foreach ($blocks as $r => $sort_region) {
if ($r !== 0) {
uasort($sort_region, "_context_ui_block_compare");
$blocks[$r] = $sort_region;
}
}
return $region ? $blocks[$region] : $blocks;
}