Newer
Older
The Great Git Migration
committed
<?php
// $Id$
The Great Git Migration
committed
/**
* Page callback for context_ui admin landing page.
*/
function context_ui_admin() {
// Add css
drupal_add_css(drupal_get_path("module", "context_ui") ."/context_ui.css");
// rebuild blocks
_block_rehash();
context_invalidate_cache();
The Great Git Migration
committed
$output = "<h3>". t('Context definitions') ."</h3>";
$normal = context_contexts();
ksort($normal);
The Great Git Migration
committed
}
else {
$output .= "<p>". t('Please !add_context to get started.', array('!add_context' => l(t('add a context'), 'admin/build/context/add'))) ."</p>";
}
return $output;
}
young hahn
committed
/**
* Recursive function that intelligently populates default values in a
* form from a provided array of data.
*
* @param $form
* A form API element to populate with default values.
* @param $data
* A keyed array of data that matches the tree structure of the
* form API branch it should populate.
*
* @return
* A form API element populated with default values.
*/
young hahn
committed
foreach (element_children($form) as $id) {
if (isset($data[$id])) {
$form[$id] = context_ui_default_values($form[$id], $data[$id]);
young hahn
committed
}
}
}
else {
if (is_array($data) && $form['#type'] == 'checkboxes') {
$form['#default_value'] = array();
foreach ($data as $value) {
$form['#default_value'][$value] = $value;
}
}
else if (is_array($data) && $form['#type'] == 'select' && $form['#multiple'] == true) {
$form['#default_value'] = array();
foreach ($data as $value) {
$form['#default_value'][] = $value;
}
}
else if (is_array($data) && $form['#type'] == 'textarea') {
$form['#default_value'] = implode("\n", $data);
}
else if (is_array($data) && $form['#type'] == 'textfield') {
$form['#default_value'] = implode(",", $data);
}
young hahn
committed
else {
$form['#default_value'] = is_array($data) ? current($data) : $data;
}
}
return $form;
}
The Great Git Migration
committed
/**
* Generates the omnibus context definition editing form.
* Note: submission and validation handlers are in context_ui_admin.inc
*
* @param $op
* The type of form to build. Either "add", "view" or "edit"
* @param $cid
* The db context identifier - required when $op == "edit"
*
* @return
* A Drupal form array.
*/
function context_ui_form(&$form_state, $op, $context = NULL) {
The Great Git Migration
committed
switch ($op) {
case 'add':
The Great Git Migration
committed
break;
case 'edit':
if (!$context->system) {
drupal_set_title(t('Edit context: %title', array('%title' => $context->value)));
The Great Git Migration
committed
}
else {
drupal_set_title(t('View %title', array('%title' => $context->value)));
The Great Git Migration
committed
}
break;
case 'clone':
drupal_set_title(t('Clone context: %title', array('%title' => $context->value)));
$context->system = 0;
$context->cid = null;
$cid = null;
The Great Git Migration
committed
break;
}
young hahn
committed
// Initialize context object if it doesn't already exist
$context = !$context ? new StdClass() : $context;
The Great Git Migration
committed
// Core context definition
$form = array(
'#base' => 'context_ui_form',
'#theme' => 'context_ui_form',
);
young hahn
committed
$form['cid'] = array(
'#type' => 'value',
'#value' => isset($context->cid) ? $context->cid : NULL,
);
$form['system'] = array(
'#type' => 'value',
'#value' => isset($context->system) ? $context->system : 0,
The Great Git Migration
committed
);
foreach (array('value', 'attribute', 'namespace', 'description') as $field) {
young hahn
committed
$form[$field] = array(
'#type' => 'textfield',
'#required' => true,
'#maxlength' => 64,
'#size' => 20,
'#disabled' => !empty($context->system) ? true : false,
young hahn
committed
'#default_value' => isset($context->{$field}) ? $context->{$field} : '',
'#title' => t(ucfirst($field)),
young hahn
committed
);
}
$form['value']['#description'] = t('A system name for this context. May only contain lowercase letters, underscores, and numbers. Example: <strong>science_blog</strong>');
young hahn
committed
$form['attribute']['#default_value'] = empty($form['attribute']['#default_value']) ? 'section' : $form['attribute']['#default_value'];
$form['attribute']['#description'] = t('The type of context information provided in this namespace. Example: <strong>section</strong>');
The Great Git Migration
committed
young hahn
committed
$form['namespace']['#default_value'] = empty($form['namespace']['#default_value']) ? 'context_ui' : $form['namespace']['#default_value'];
$form['namespace']['#description'] = t('The namespace for this context definition. Example: <strong>context_ui</strong>');
$form['description']['#required'] = FALSE;
$form['description']['#size'] = 40;
$form['description']['#maxlength'] = 255;
$form['description']['#description'] = t('The description of this context definition.');
The Great Git Migration
committed
$form['items'] = array('#tree' => true);
The Great Git Migration
committed
young hahn
committed
// We need to initialize theme in order to deal with blocks
// and also let themes integrate against context_ui
init_theme();
$theme_key = variable_get('theme_default', 'garland');
The Great Git Migration
committed
// Generate settings for context item associations
foreach ((context_conditions(TRUE) + context_reactions(TRUE)) as $id => $info) {
young hahn
committed
$form['items'][$id] = $info;
// Disable element
if (isset($context->system) && $context->system) {
$form['items'][$id]['#disabled'] = true;
}
young hahn
committed
// Default values
if (isset($context->{$id})) {
$form['items'][$id] = context_ui_default_values($form['items'][$id], $context->{$id});
The Great Git Migration
committed
}
}
$modules = array();
$query = db_query("SELECT name, info FROM {system} WHERE type = '%s'", 'module');
while ($result = db_fetch_object($query)) {
$info = unserialize($result->info);
$modules[$result->name] = $info['name'];
}
The Great Git Migration
committed
// Control block visibility
$block_options =
$block_defaults = array();
$blocks = _context_ui_get_blocks();
$regions = system_region_list($theme_key);
// $blocks in [0] have not been assigned a region
foreach ($blocks[0] as $block) {
$block_options[$block->module][$block->bid] = $block->label;
The Great Git Migration
committed
}
ksort($block_options);
$form['block'] = array(
'#tree' => true,
);
$form['block']['help'] = array(
'#type' => 'markup',
'#value' => 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.'),
);
The Great Git Migration
committed
$form['block']['selector'] = array(
'#type' => 'item',
'#tree' => true,
'#prefix' => '<div class="context-ui-block-selector">',
'#suffix' => '</div>',
);
foreach ($block_options as $module => $module_blocks) {
if (!empty($module_blocks)) {
$form['block']['selector'][$module] = array(
'#type' => 'checkboxes',
'#title' => $modules[$module],
'#options' => $module_blocks,
'#disabled' => isset($context->system) && $context->system ? true : false,
);
}
}
$form['block']['blocks'] = array(
The Great Git Migration
committed
'#tree' => true,
'#theme' => 'context_ui_block_ui',
young hahn
committed
);
foreach ($regions as $region => $label) {
The Great Git Migration
committed
$defaults = array();
$midpoint = false;
$form['block']['blocks'][$region] = array(
'#type' => 'item',
'#title' => $label,
'#tree' => TRUE,
);
$system = _context_ui_get_blocks($region);
if ($system) {
$system_blocks = array();
foreach ($system as $block) {
$system_blocks[] = $block->label;
}
$system_blocks = "<span class='system-blocks'>". implode(", ", $system_blocks) ."</span";
$form['block']['blocks'][$region]['system'] = array(
'#type' => 'markup',
'#tree' => true,
'#value' => $system_blocks,
'#weight' => 0,
'weight' => array(
'#type' => 'weight',
'#delta' => 20,
'#default_value' => 0,
),
);
}
$i = 0;
The Great Git Migration
committed
foreach (_context_ui_get_blocks($region, $context) as $block) {
if ($block->type == 'context_ui') {
$form['block']['blocks'][$region][$block->bid] = array(
'#type' => 'markup',
'#tree' => true,
'#value' => $block->label,
'#weight' => $block->weight,
'weight' => array(
'#type' => 'weight',
'#delta' => 20,
'#default_value' => $block->weight,
),
);
The Great Git Migration
committed
}
The Great Git Migration
committed
}
uasort($form['block']['blocks'][$region], 'element_sort');
$defaults = implode(',', element_children($form['block']['blocks'][$region]));
The Great Git Migration
committed
$form['block']['regions'][$region] = array(
'#type' => 'hidden',
'#default_value' => $defaults,
);
}
The Great Git Migration
committed
$form['back'] = array(
'#type' => 'item',
'#value' => l(t('Back'), 'admin/build/context'),
);
}
The Great Git Migration
committed
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
}
The Great Git Migration
committed
$form['delete'] = array(
'#type' => 'submit',
'#value' => t('Delete'),
);
}
return $form;
}
young hahn
committed
/**
* Generates an abbreviated list of items for display in the
* setter/getter UI.
*/
function context_ui_item_display($type, $element) {
// We're dealing with an item with options --
// try to grab the display-friendly value
young hahn
committed
$items = array();
$title = l($element['#title'], $_GET['q'], array('fragment' => $type));
if (isset($element['#options'])) {
if (isset($element['#default_value'])) {
if (is_array($element['#default_value'])) {
foreach ($element['#default_value'] as $k) {
$items[] = $element['#options'][$k];
}
}
else if (is_string($element['#default_value']) && $k = $element['#default_value']) {
if (!empty($element['#options'][$k])) {
$items[] = $element['#options'][$k];
}
else {
// Fallback to the actual value
$items[] = $k;
}
}
}
if (empty($items)) {
$items[] = array('data' => '', 'class' => 'empty');
}
}
else if (isset($element['#type']) && in_array($element['#type'], array('textfield', 'textarea'))) {
young hahn
committed
$items[] = !empty($element['#default_value']) ? $element['#default_value'] : array('data' => '', 'class' => 'empty');
}
$output = '';
$output .= theme('item_list', $items, $title, 'ul', array('id' => 'display-'. $type));
return $output;
The Great Git Migration
committed
/**
* Theme function for context_ui_form()
*/
function theme_context_ui_form($form) {
drupal_add_css(drupal_get_path("module", "context_ui") ."/context_ui.css");
drupal_add_js(drupal_get_path("module", "context_ui") ."/context_ui.js");
The Great Git Migration
committed
$output = '';
// Render space / key / value trio in a 3-column table
$rows = array(
'trio' => array('class' => 'trio'),
'description' => array()
The Great Git Migration
committed
);
$rows['trio']['data'][] = array('data' => drupal_render($form['namespace']), 'class' => 'namespace');
$rows['trio']['data'][] = array('data' => drupal_render($form['attribute']), 'class' => 'attribute');
$rows['trio']['data'][] = array('data' => drupal_render($form['value']), 'class' => 'value');
$rows['description'] = array(array('data' => drupal_render($form['description']), 'colspan' => 3));
$output .= theme('table', array(), $rows, array('id' => 'context-ui-trio'));
The Great Git Migration
committed
// Render setters / getters as a two column split
young hahn
committed
$widgets = '';
$display = "<div class='label'>";
$display .= t('Conditions');
$display .= "<span class='description'>". t('trigger the activation of this context') ."</span>";
$display .= "</div>";
foreach (array_keys(context_conditions()) as $id) {
young hahn
committed
$widgets .= "<div id='widget-$id' class='widget'>". drupal_render($form['items'][$id]) ."</div>";
$display .= context_ui_item_display($id, $form['items'][$id]);
}
$display .= "<div class='label'>";
$display .= t('Reactions');
$display .= "<span class='description'>". t('respond when this context is active') ."</span>";
$display .= "</div>";
foreach (array_keys(context_reactions()) as $id) {
young hahn
committed
$widgets .= "<div id='widget-$id' class='widget'>". drupal_render($form['items'][$id]) ."</div>";
$display .= context_ui_item_display($id, $form['items'][$id]);
The Great Git Migration
committed
}
$rows = array(
array(
young hahn
committed
array('data' => $display, 'class' => 'display'),
array('data' => $widgets, 'class' => 'widget'),
The Great Git Migration
committed
),
);
$output .= theme('table', array(), $rows, array('id' => 'context-ui-items'));
The Great Git Migration
committed
// Render block visibility
The Great Git Migration
committed
$rows = array(
array(
array('data' => drupal_render($form['block']['blocks']), 'class' => 'display'),
array('data' => drupal_render($form['block']['selector']) . drupal_render($form['block']['help']), 'class' => 'widget'),
The Great Git Migration
committed
),
);
$output .= theme('table', array(), $rows, array('id' => 'context-ui-blocks'));
The Great Git Migration
committed
$output .= drupal_render($form);
return $output;
}
/**
* Provide a form to confirm one of the provided actions.
The Great Git Migration
committed
*/
function context_ui_confirm(&$form_state, $op = 'delete', $context) {
$form = array();
$form['context'] = array('#type' => 'value', '#value' => $context);
$form['action'] = array('#type' => 'value', '#value' => $op);
switch ($op) {
case 'delete':
$action = t('delete');
$message = t('This action will remove this context permanently from your site.');
break;
case 'disable':
$action = t('disable');
$message = '';
break;
case 'enable':
$action = t('enable');
$message = '';
break;
}
The Great Git Migration
committed
$form = confirm_form($form,
t('Are you sure you want to !action the context %title?', array('%title' => $context->value, '!action' => $action)),
The Great Git Migration
committed
'admin/build/context',
$message,
drupal_ucfirst($action), t('Cancel')
The Great Git Migration
committed
);
return $form;
}
/**
* Submit handler for the context_ui_confirm form.
The Great Git Migration
committed
*/
function context_ui_confirm_submit($form, &$form_state) {
switch ($form_state['values']['action']) {
case 'delete':
context_delete_context($form_state['values']['context']);
break;
case 'disable':
case 'enable':
$status["{$context->namespace}-{$context->attribute}-{$context->value}"] = ($form_state['values']['action'] == 'disable' ? CONTEXT_STATUS_DISABLED : CONTEXT_STATUS_ENABLED);
context_invalidate_cache();
The Great Git Migration
committed
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
$form_state['redirect'] = 'admin/build/context';
}
/**
* Page callback for import form. Switches form output to context form
* if import submission has occurred.
*/
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');
}
/**
* Import form. Provides simple helptext instructions and textarea for
* pasting a context definition.
*/
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;
}
/**
* Import form submit handler. Evaluates import code and transfers to
* context definition form.
*/
function context_ui_import_submit($form, &$form_state) {
The Great Git Migration
committed
$items = array();
if ($import = $form_state['values']['import']) {
if (strpos($import, 'return') !== 0) {
$import = "return {$import}";
}
The Great Git Migration
committed
ob_start();
The Great Git Migration
committed
ob_end_clean();
}
if (is_array($context)) {
$context = (object) $context;
if ($exists = context_load_context($context)) {
The Great Git Migration
committed
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');
$form_state['redirect'] = 'admin/build/context';
}
else {
drupal_set_title(t('Add context'));
$output = drupal_get_form('context_ui_form', 'add', (object) $context);
The Great Git Migration
committed
print theme('page', $output);
exit;
}
}
else {
drupal_set_message(t('An error occurred while importing. Please check your context definition.', 'error'));
$form_state['redirect'] = 'admin/build/context';
}
}
/**
* Provides a form with an exported context definition for use in modules.
*
* @param $cid
* A context id.
*
* @return
* A FormAPI array.
*/
function context_ui_export(&$form_state, $context) {
drupal_set_title(t('Export %title', array('%title' => $context->value)));
The Great Git Migration
committed
// prune system specific information and cast for Drupal's AOP (array oriented programming)
$prune = array('cid', 'status', 'system', 'type');
foreach ($prune as $key) {
if (isset($context->{$key})) {
unset($context->{$key});
}
}
$context = (array) $context;
young hahn
committed
// clear out empty associations
foreach ($context as $key => $item) {
if (context_empty($item)) {
young hahn
committed
unset($context[$key]);
}
}
// clean up blocks
young hahn
committed
if (!empty($context['block'])) {
foreach ($context['block'] as $bid => $block) {
unset($block->bid);
$context['block'][$bid] = (array) $block;
}
The Great Git Migration
committed
}
// build the form
$form = array();
$form['export'] = array(
'#type' => 'textarea',
'#rows' => 24,
'#value' => $context,
'#theme' => 'context_ui_export_form',
);
return $form;
The Great Git Migration
committed
}
/**
* Themes a context value into an export friendly var_export().
*/
function theme_context_ui_export_form($form) {
$form['#value'] = $form['#default_value'] = context_var_export($form['#value'], '', FALSE);
return theme('textarea', $form);
}
/**
* Export multiple contexts
*/
function context_ui_bulk_export(&$form_state) {
$form = array();
$contexts = context_contexts();
if (isset($form_state['storage']['module_name'])) {
$code = "function ". $form_state['storage']['module_name'] ."_context_ui_define() {\n";
foreach ($form_state['storage']['contexts'] as $id) {
$context = (array) $contexts[$id];
unset($context['cid']);
$code .= ' $items[] = '. context_var_export($context, ' ') .";\n\n";
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
}
$code .= " return \$items;\n}";
$form['code'] = array(
'#type' => 'textarea',
'#title' => t('Code'),
'#description' => t('Put this in your module\'s .module file.'),
'#cols' => 60,
'#rows' => 30,
'#value' => $code,
'#default_value' => $code,
);
}
else {
$form['#contexts'] = $contexts;
$form['checkboxes']['#tree'] = TRUE;
foreach ($contexts as $context) {
$form['checkboxes']["$context->namespace-$context->attribute-$context->value"] = array(
'#title' => $context->value,
'#type' => 'checkbox',
);
}
$form['module_name'] = array(
'#type' => 'textfield',
'#title' => t('Module Name'),
'#description' => t('The name of the module for which to generate the hook.'),
'#size' => 40,
'#maxlength' => 255,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Export'),
);
$form['#theme'] = 'context_ui_bulk_export_table';
}
return $form;
}
function context_ui_bulk_export_submit($form, &$form_state) {
$form_state['storage']['module_name'] = $form_state['values']['module_name'];
foreach ($form_state['values']['checkboxes'] as $key => $value) {
if ($value) {
$form_state['storage']['contexts'][] = $key;
}
}
}
function theme_context_ui_bulk_export_table($form) {
// Add css
drupal_add_css(drupal_get_path("module", "context_ui") ."/context_ui.css");
$rows = $headings = array();
foreach (element_children($form['checkboxes']) as $key) {
$context = $form['#contexts'][$key];
$row = array();
$namespace = $context->namespace;
$attribute = $context->attribute;
$value = $context->value;
if (isset($context->cid) && $context->cid) {
$identifier = $context->cid;
}
else {
$identifier = $key;
}
// If no heading has been printed for this n/a pair, do so
if (!isset($rows["$namespace-$attribute"])) {
$row = array('', array('data' => "<span class='context-namespace'>$namespace > $attribute</span>", 'colspan' => 2));
$rows["$namespace-$attribute"] = $row;
}
unset($form['checkboxes'][$key]['#title']);
$rows[$key] = array(
'data' => array(
array(
'data' => drupal_render($form['checkboxes'][$key]),
'class' => 'context-ui-checkbox',
),
array(
'data' => '<strong>'. $value .'</strong>',
'class' => 'context-name',
),
),
'class' => 'context-table-row ' . $class,
);
}
$output = theme('table', array(theme('table_select_header_cell'), t('Context')), $rows, array('class' => 'context-ui-bulk-export context-ui-overview'));
$output .= drupal_render($form);
return $output;
}
The Great Git Migration
committed
/**
* Generates the main context_ui admin page with a tiered context listing.
The Great Git Migration
committed
*/
$rows = $headings = array();
foreach ($contexts as $key => $context) {
$row = array();
$namespace = $context->namespace;
$attribute = $context->attribute;
$value = $context->value;
if (isset($context->cid) && $context->cid) {
$identifier = $context->cid;
The Great Git Migration
committed
}
$identifier = $key;
// If no heading has been printed for this n/a pair, do so
if (!isset($rows["$namespace-$attribute"])) {
$row = array(array('data' => "<span class='context-namespace'>$namespace > $attribute</span>", 'colspan' => 2));
$rows["$namespace-$attribute"] = $row;
The Great Git Migration
committed
}
$links = array();
$icon = theme('advanced_help_topic', 'context_ui', 'type');
switch ($context->type) {
case CONTEXT_STORAGE_DEFAULT:
$type = 'Default';
$links[0] = l(t('Override'), "admin/build/context/$identifier/clone");
$links[2] = l(t('Export'), "admin/build/context/$identifier/export");
$links[3] = l(t('Clone'), "admin/build/context/$identifier/clone");
break;
case CONTEXT_STORAGE_OVERRIDDEN:
$type = 'Overridden';
$links[0] = l(t('Edit'), "admin/build/context/$identifier");
$links[2] = l(t('Export'), "admin/build/context/$identifier/export");
$links[3] = l(t('Clone'), "admin/build/context/$identifier/clone");
$links[4] = l(t('Revert'), "admin/build/context/$identifier/delete");
break;
case CONTEXT_STORAGE_NORMAL:
$type = 'Normal';
$links[0] = l(t('Edit'), "admin/build/context/$identifier");
$links[2] = l(t('Export'), "admin/build/context/$identifier/export");
$links[3] = l(t('Clone'), "admin/build/context/$identifier/clone");
$links[4] = l(t('Delete'), "admin/build/context/$identifier/delete");
case CONTEXT_STATUS_DISABLED:
$class = 'disabled';
$enable = l(t('Enable'), "admin/build/context/$identifier/enable");
break;
case CONTEXT_STATUS_ENABLED:
$class = 'enabled';
$enable = l(t('Disable'), "admin/build/context/$identifier/disable");
}
$links[1] = $enable;
if ($icon) {
// These spans are used to work-around advanced help's default styling of
// floating the help icon left. We would like to display it after the text,
// so we put a series of floats next to each other.
$data = "<strong>$value</strong> <em><span>($type</span> $icon<span>)</span></em>";
}
else {
$data = "<strong>$value</strong> <em>($type)</em>";
}
$description = !empty($context->description) ? '<div class="description">'. filter_xss_admin($context->description) .'</div>' : '';
ksort($links);
'data' => array(
array(
'data' => $data . $description,
'class' => 'context-name '. ($icon? 'icon' : 'no-icon'),
),
implode(' | ', $links),
),
'class' => 'context-table-row ' . $class,
The Great Git Migration
committed
}
return theme('table', array(t('Context'), t('Operations')), $rows, array('class' => 'context-ui-overview'));
The Great Git Migration
committed
}
/**
* Generates the AJAX enabled block administration portion of the context_ui admin form.
*/
function theme_context_ui_block_ui($form) {
// Add draggable weights
drupal_add_js('misc/tableheader.js');
The Great Git Migration
committed
$output = '';
The Great Git Migration
committed
foreach (element_children($form) as $region) {
$table_id = 'context-ui-region-'. str_replace('_', '-', $region);
drupal_add_tabledrag($table_id, 'order', 'sibling', 'block-weight', NULL, NULL, FALSE);
$rows = array();
foreach (element_children($form[$region]) as $id) {
$form[$region][$id]['weight']['#attributes'] = array('class' => 'block-weight');
$label = $form[$region][$id]['#value'];
if ($id == 'system') {
$remove = '';
The Great Git Migration
committed
}
else {
$remove = l(t('X'), $_GET['q'], array('fragment' => 'remove', 'attributes' => array('class' => 'remove')));
}
$rows[] = array(
'data' => array($label . drupal_render($form[$region][$id]['weight']), $remove),
'class' => 'draggable',
'id' => $id,
The Great Git Migration
committed
);
}
$output .= "<div class='label'>";
$output .= l(t('+ Add'), $_GET['q'], array('fragment' => $region, 'attributes' => array('class' => 'add-block')));
$output .= $form[$region]['#title'];
$output .= "</div>";
$output .= theme('table', array(), $rows, array('id' => $table_id));
The Great Git Migration
committed
}
return $output;
}
/**
* hook_validate()
*/
function context_ui_form_validate($form, &$form_state) {
if ($form_state['clicked_button']['#id'] == 'edit-submit' && $form_state['values']['value']) {
// Check for string identifier sanity
foreach (array('value', 'attribute', 'namespace') as $elem) {
if (!preg_match('!^[a-z0-9_]+$!', $form_state['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_state['values']['cid'])) {
// Check that no other user-defined context definition has taken this identifier already
$context = new StdClass();
$context->namespace = $form_state['values']['namespace'];
$context->attribute = $form_state['values']['attribute'];
$context->value = $form_state['values']['value'];
if ($exists = context_load_context($context)) {
The Great Git Migration
committed
form_set_error($form_state['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.'));
}
}
}
}
/**
* Produces a context object from submitted form values.
*
* @param $form
* A form array with submitted values
*
* @return
* A context object
*/
function context_ui_form_process($form) {
$context = new stdClass();
// Context ns/attr/value definition
foreach (array('cid', 'system', 'namespace', 'attribute', 'value', 'description') as $item) {
$context->$item = isset($form[$item]) ? $form[$item] : NULL;
}
The Great Git Migration
committed
$context->status = 1; // all user defined contexts have status 1
// Retrieve values for conditions
foreach (array_keys(context_conditions()) as $id) {
young hahn
committed
if (is_array($form['items'][$id])) {
foreach ($form['items'][$id] as $option => $value) {
young hahn
committed
if (!empty($value)) {
young hahn
committed
$context->{$id}[] = $option;
The Great Git Migration
committed
}
}
}
young hahn
committed
else if (isset($form['items'][$id]) && !empty($form['items'][$id])) {
$context->{$id}[] = $form['items'][$id];
}
}
// Retrieve values for reactions -- preserve key => val associations
foreach (array_keys(context_reactions()) as $id) {
if (isset($form['items'][$id]) && !context_empty($form['items'][$id])) {
young hahn
committed
$context->{$id} = $form['items'][$id];
The Great Git Migration
committed
}
}
// Blocks must be done by region
$theme_key = variable_get('theme_default', 'garland');
The Great Git Migration
committed
// Get list of "valid" available blocks
$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) {
young hahn
committed
// Don't initialize the block array until we're actually sure
// the context contains blocks.
if (!isset($context->block)) {
$context->block = array();
}
The Great Git Migration
committed
if ($bid != 'system') {
$block = $valid[$bid];
$modifier = $position < $midpoint ? -20 : 20;
The Great Git Migration
committed
$block->weight = $position - $midpoint + $modifier;
$block->region = $region;
$block->type = 'context_ui';
$context->block[$block->bid] = $block;
}
}
}
}
The Great Git Migration
committed
return $context;
}
/**
* Submit handler for main context_ui form.
*/
function context_ui_form_submit($form, &$form_state) {
Jeff Miccolis
committed
switch ($form_state['clicked_button']['#id']) {
The Great Git Migration
committed
// Send user to delete confirmation page
Jeff Miccolis
committed
case 'edit-delete':
$form_state['redirect'] = 'admin/build/context/'. $form_state['values']['cid'] .'/delete';
The Great Git Migration
committed
return;
// Process form values and save and/or update the context in the db
Jeff Miccolis
committed
case 'edit-submit':
The Great Git Migration
committed
$context = context_ui_form_process($form_state['values']);
$result = context_save_context($context);
young hahn
committed
if ($result) {
drupal_set_message(t('The context %title was saved successfully.', array('%title' => $context->value)));
The Great Git Migration
committed
}
young hahn
committed
else {
drupal_set_message(t('An error occurred while attempting to save your context information.'), 'error');
The Great Git Migration
committed
}
break;
}
$form_state['redirect'] = 'admin/build/context';
}
/**
* Helper function to generate a list of blocks from a specified region. If provided a context object,
* will generate a full list of blocks for that region distinguishing between system blocks and
* context-provided blocks.
*
* @param $region
* The string identifier for a theme region. e.g. "left"
* @param $context
* A context object.
*
* @return
* A keyed (by "module_delta" convention) array of blocks.
*/
function _context_ui_get_blocks($region = null, $context = null) {
$theme_key = variable_get('theme_default', 'garland');
The Great Git Migration
committed
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
static $block_info, $valid, $system_blocks;
// we don't static cache context blocks
$context_blocks = $blocks = array();
if (!$system_blocks) {
// initialize regions
foreach (system_region_list($theme_key) as $r => $l) {
$system_blocks[$r] = array();
}
// load blocks from database
$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)) {
// load block info
$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;
// add block to region
if ($block->region && $block->status) {
$system_blocks[$block->region][$block->bid] = $block;
}
else {
$system_blocks[0][$block->bid] = $block;
}
// mark block as available in DB
$valid[$block->module ."_". $block->delta] = true;
}
}
// load system blocks into main block array
$blocks = $system_blocks;
// load context blocks if provided
if (is_object($context) && !empty($context->block)) {
The Great Git Migration
committed
// iterate over context-associated blocks
foreach ($context->block as $block) {
$block = (object) $block;
// check that this is a valid block
if ($valid[$block->module ."_". $block->delta]) {
// if region has been specified, ensure that block belongs to it
if (!$region || (isset($region) && $block->region == $region)) {
// load block info
$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;
// add block to region
if ($block->region) {
$blocks[$block->region][$block->bid] = $block;
}
else {
$blocks[0][$block->bid] = $block;
}
}
}
}
}