View source
<?php
function context_ui_block($op = 'list', $delta = 0, $edit = array()) {
switch ($op) {
case 'list':
$blocks = array();
$blocks['devel']['info'] = t('Context Devel');
return $blocks;
case 'view':
switch ($delta) {
case 'devel':
$block = array();
$block['subject'] = t('Context Devel');
if ($context = context_get()) {
$output = theme('context_devel', $context);
$block['content'] = $output;
}
else {
$block['content'] = "<p>" . t('No context information is set.') . "</p>";
}
return $block;
}
break;
}
}
function context_ui_context_items() {
$items = array();
$nodetypes = array();
foreach (node_get_types() as $type) {
$nodetypes[$type->type] = t($type->name);
}
$items['node'] = array(
'#title' => t('Content Types'),
'#description' => t('Set this context when viewing a node page or using the add/edit form of one of these content types.'),
'#options' => $nodetypes,
'#type' => 'checkboxes',
'#context_ui' => 'setter',
);
if (module_exists('menu')) {
global $_menu;
$menus = array();
$errors = array();
foreach (array_reverse(menu_get_root_menus(), true) as $root_mid => $root_menu) {
$menu = array();
$options = menu_parent_options(0, $root_mid, 0);
unset($options[key($options)]);
foreach ($options as $mid => $title) {
$item = menu_get_item($mid);
$path = $item['path'];
if (!isset($menu[$path])) {
$menu[$path] = $title;
}
else {
$errors[] = t('!item at !path', array(
'!item' => str_replace('-', '', $menu[$path]),
'!path' => $path,
));
$errors[] = t('!item at !path', array(
'!item' => str_replace('-', '', $title),
'!path' => $path,
));
}
}
$path = $_menu['items'][$root_mid]['path'];
$menus[$root_mid] = "<strong>" . $root_menu . "</strong>";
$menus = $menus + $menu;
}
$items['menu'] = array(
'#title' => t('Menus'),
'#description' => t('Display the selected menu item as active when this context is set.'),
'#options' => $menus,
'#type' => 'radios',
'#context_ui' => 'getter',
);
if (count($errors)) {
$items['menu']['#description'] .= '<p>' . t('<strong>Note:</strong> context_ui will not work properly with menu items that share the same path. You can work around this issue by pointing custom menu items at !alias. The following duplicates were found:', array(
'!alias' => l(t('path aliases'), 'admin/build/path'),
)) . '</p>';
$items['menu']['#description'] .= theme('item_list', $errors);
}
}
$items['user'] = array(
'#title' => t('User Pages'),
'#description' => t('Set this context when a user with selected role(s) is viewed'),
'#options' => user_roles(true),
'#type' => 'checkboxes',
'#context_ui' => 'setter',
);
if (module_exists('book')) {
$result = db_query("SELECT b.nid, nr.title FROM {book} b JOIN {node} n ON n.nid = b.nid AND n.vid = b.vid JOIN {node_revisions} nr ON nr.vid = n.vid WHERE n.status = 1 AND b.parent = 0");
$options = array();
while ($book = db_fetch_object($result)) {
$options[$book->nid] = $book->title;
}
$items['book'] = array(
'#title' => t('Book'),
'#description' => t('Set this context when a node in the selected book is viewed.'),
'#options' => $options,
'#type' => 'checkboxes',
'#context_ui' => 'setter',
);
}
return $items;
}
function context_ui_menu($may_cache) {
$items = array();
if ($may_cache) {
$items[] = array(
'path' => 'admin/build/context',
'callback' => 'context_ui_admin',
'access' => user_access('administer site configuration'),
'type' => MENU_NORMAL_ITEM,
'title' => t('Context'),
'description' => t('Associate menus, views, blocks, etc. with different contexts to structure your site.'),
);
$items[] = array(
'path' => 'admin/build/context/list',
'title' => t('List'),
'callback' => 'context_ui_admin',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 0,
);
$items[] = array(
'path' => 'admin/build/context/add',
'callback' => 'drupal_get_form',
'callback arguments' => array(
'context_ui_form',
'add',
),
'access' => user_access('administer site configuration'),
'type' => MENU_LOCAL_TASK,
'title' => t('Add Context'),
'description' => t('Add a context to your site.'),
'weight' => 1,
);
$items[] = array(
'title' => t('Import'),
'path' => 'admin/build/context/import',
'callback' => 'context_ui_import_page',
'access' => user_access('administer site configuration'),
'type' => MENU_LOCAL_TASK,
'description' => t('Import a context definition into your site.'),
'weight' => 2,
);
$items[] = array(
'path' => 'admin/build/context/edit',
'callback' => 'drupal_get_form',
'callback arguments' => array(
'context_ui_form',
'edit',
),
'access' => user_access('administer site configuration'),
'type' => MENU_CALLBACK,
);
$items[] = array(
'path' => 'admin/build/context/clone',
'callback' => 'drupal_get_form',
'callback arguments' => array(
'context_ui_form',
'clone',
),
'access' => user_access('administer site configuration'),
'type' => MENU_CALLBACK,
'title' => t('Clone Context'),
'description' => t('Duplicate an existing context.'),
'weight' => 1,
);
$items[] = array(
'path' => 'admin/build/context/view',
'callback' => 'drupal_get_form',
'callback arguments' => array(
'context_ui_form',
'view',
),
'access' => user_access('administer site configuration'),
'type' => MENU_CALLBACK,
);
$items[] = array(
'path' => 'admin/build/context/export',
'callback' => 'drupal_get_form',
'callback arguments' => array(
'context_ui_export',
),
'access' => user_access('administer site configuration'),
'type' => MENU_CALLBACK,
);
$items[] = array(
'path' => 'admin/build/context/delete',
'callback' => 'drupal_get_form',
'callback arguments' => array(
'context_ui_delete_confirm',
),
'access' => user_access('administer site configuration'),
'type' => MENU_CALLBACK,
);
return $items;
}
else {
if (arg(0) . '/' . arg(1) . '/' . arg(2) == 'admin/build/context') {
include_once drupal_get_path("module", "context_ui") . "/context_ui_admin.inc";
}
else {
if ($_GET['q'] == 'admin/build/modules') {
include_once drupal_get_path("module", "context_ui") . "/context_ui_admin.inc";
context_ui_rebuild();
}
}
}
}
function context_ui_help($section) {
switch ($section) {
case 'admin/build/context':
return "<p>" . t('Contexts provide you with a way to organize your site using terms familiar to real human beings. You can create a set of sections like <b>"News"</b>, <b>"Projects"</b>, <b>"Staff"</b>, and associate different technical aspects of Drupal to each section. For example, the <b>"News"</b> section may be a collection of <b>Nodes</b>, <b>Views</b>, <b>Menus</b> and <b>Blocks</b>.') . "</p>";
break;
}
}
function context_ui_nodeapi(&$node, $op, $teaser, $page) {
if ($op == 'view' && $page && arg(0) == 'node') {
context_ui_set('node', $node->type);
if (module_exists('book') && isset($node->parent)) {
if ($node->parent == 0) {
context_ui_set('book', $node->nid);
}
else {
$location = book_location($node);
if ($location[0]->parent == 0) {
context_ui_set('book', $location[0]->nid);
}
}
}
}
}
function context_ui_form_alter($form_id, &$form) {
if ($form['#node'] && arg(0) != 'admin') {
context_ui_set('node', $form['#node']->type);
}
else {
if ($form_id == 'comment_form' && ($nid = $form['nid']['#value'])) {
$node = node_load($nid);
context_ui_set('node', $node->type);
}
else {
if ($form_id == 'block_admin_configure') {
$module = $form['module']['#value'];
$delta = $form['delta']['#value'];
$result = db_query("SELECT cb.cid, cb.region, c.namespace, c.attribute, c.value FROM {context_ui_block} cb JOIN {context_ui} c ON cb.cid = c.cid WHERE cb.module = '%s' AND cb.delta = '%s' AND c.status = %d", $module, $delta, 1);
$rows = array();
while ($row = db_fetch_object($result)) {
$rows[] = array(
$row->namespace,
$row->attribute,
$row->value,
$row->region,
l(t('Edit visibility'), 'admin/build/context/edit/' . $row->cid, array(), null, 'context-ui-blocks'),
);
}
if ($rows) {
$content = theme('table', array(
t('Namespace'),
t('Attribute'),
t('Value'),
t('Region'),
'',
), $rows);
}
else {
$content = "<p>" . t('No visibility rules have been set for this block using context_ui.') . "</p>";
}
$form['context_ui'] = array(
'#type' => 'fieldset',
'#title' => t('Context UI visibility'),
'#weight' => -1,
'#collapsible' => true,
);
$form['context_ui']['contexts'] = array(
'#type' => 'item',
'#value' => $content,
'#description' => t('To add or remove block visibility rules based on context, use the !context_admin.', array(
'!context_admin' => l(t('context administration page'), 'admin/build/context'),
)),
);
$form['block_settings']['#weight'] = -5;
}
}
}
}
function context_ui_user($op, &$edit, &$account, $category = NULL) {
if ($op == 'view') {
context_ui_set('user', array_keys($account->roles));
}
}
function context_ui_defaults($namespace = null) {
static $contexts, $namespaces;
if (!$contexts) {
$contexts = array();
foreach (module_implements('context_define') as $module) {
$function = $module . '_context_define';
$contexts = array_merge($contexts, $function());
}
foreach ($contexts as $key => $context) {
$context = (object) $context;
$contexts[$key] = $context;
$namespaces[$context->namespace][] = $context;
}
}
if ($namespace) {
if (isset($namespaces[$namespace])) {
return $namespaces[$namespace];
}
else {
return array();
}
}
return $contexts;
}
function context_ui_types($op = 'list') {
static $types;
if (!$types) {
$types = array();
foreach (module_implements('context_items') as $module) {
$function = $module . '_context_items';
$types = array_merge($types, $function());
}
}
switch ($op) {
case 'list':
return array_keys($types);
break;
case 'full':
return $types;
break;
}
}
function context_ui_set($type, $id) {
if (!is_array($id)) {
$id = array(
$id,
);
}
$set = false;
$result = db_query("\n SELECT c.namespace, c.attribute, c.value, c.cid FROM {context_ui_item} ci\n JOIN {context_ui} c ON ci.cid = c.cid\n WHERE ci.type = '%s' AND ci.id IN (" . substr(str_repeat("'%s',", count($id)), 0, -1) . ") AND c.status = 1", array_merge(array(
$type,
), $id));
while ($context = db_fetch_object($result)) {
if (!context_isset($context->namespace, $context->attribute)) {
context_set($context->namespace, $context->attribute, $context->value);
$context = context_ui_context('load', $context);
module_invoke_all('context_getter', $context);
$cid = context_get('context_ui', 'cid');
$cid = $cid ? $cid : array();
$cid[] = $context->cid;
context_set('context_ui', 'cid', $cid);
$set = true;
}
}
return $set;
}
function context_ui_context_getter($context) {
context_ui_menu_set_location($context);
}
function theme_context_devel($context) {
drupal_add_css(drupal_get_path("module", "context_ui") . "/context_ui.css");
$output = '';
foreach ($context as $space => $a) {
$output .= "<div class='context-devel-space'>{$space}</div>";
$output .= "<div class='context-devel-tree'>" . theme_context_devel_recurse($a) . "</div>";
}
return $output;
}
function theme_context_devel_recurse($value) {
$output = '';
if (is_array($value) || is_object($value)) {
if (is_array($value)) {
$type = 'array';
}
else {
if (is_object($value)) {
$type = 'object';
}
}
foreach ((array) $value as $key => $a) {
$output .= "<div class='context-devel-wrapper'><label><small>{$type}</small>{$key}</label>" . theme('context_devel_recurse', $a) . "</div>";
}
}
else {
if (is_string($value)) {
$type = 'string';
}
else {
if (is_int($value)) {
$type = 'int';
}
else {
if (is_bool($value)) {
$type = 'bool';
}
}
}
$output .= "<div class='context-devel-wrapper'><label><small>{$type}</small>{$value}</label></div>";
}
return $output;
}
function context_ui_menu_set_location($context) {
if ($context->cid) {
$result = db_query("\n SELECT ci.id\n FROM {context_ui_item} ci\n WHERE ci.type = '%s' AND ci.cid = %d", 'menu', $context->cid);
if ($path = db_result($result)) {
global $_menu;
$context_menu = menu_get_item(null, $path);
$items[] = $context_menu;
$mid = $context_menu['pid'];
while ($mid && ($item = menu_get_item($mid))) {
$items[] = $item;
$mid = $item['pid'];
}
$items = array_reverse($items);
$active_mid = menu_get_active_item();
if ($active_mid != $_menu['path index'][$path] && !$items[$active_mid]) {
$active_menu = menu_get_item($active_mid);
if (isset($_menu['visible'][$active_mid])) {
unset($_menu['visible'][$active_mid]);
}
if ($active_menu['type'] & MENU_IS_LOCAL_TASK) {
$parent_menu = menu_get_item($active_menu['pid']);
$items[] = $parent_menu;
if ($parent_menu['type'] & MENU_IS_LOCAL_TASK) {
$items[] = menu_get_item($parent_menu['pid']);
}
}
if ($active_menu['type'] & MENU_IS_LOCAL_TASK & MENU_LINKS_TO_PARENT) {
$real_q = end($items);
$real_q = $real_q['path'];
}
$items[] = $active_menu;
}
menu_set_location($items);
if ($real_q) {
$_GET['q'] = $real_q;
}
}
}
}
function phptemplate_blocks($region) {
$output = "";
if ($list = context_ui_block_list($region)) {
foreach ($list as $key => $block) {
$output .= theme("block", $block);
}
}
$output .= drupal_get_content($region);
return $output;
}
function context_ui_block_list($region) {
global $user, $theme_key;
static $cids = array();
static $blocks = array();
$defaults = array();
if (!count($blocks)) {
$result = db_query("SELECT * FROM {context_ui} WHERE status = 1", 'context_ui');
while ($context = db_fetch_object($result)) {
if (context_get($context->namespace, $context->attribute) == $context->value) {
$cids[$context->cid] = $context->cid;
}
}
$rids = array_keys($user->roles);
$placeholders = implode(',', array_fill(0, count($rids), '%d'));
$result = db_query("\n SELECT DISTINCT b.*, c.weight AS context_weight, c.region AS context_region, c.cid\n FROM {blocks} b\n LEFT JOIN {blocks_roles} r ON b.module = r.module AND b.delta = r.delta\n LEFT JOIN {context_ui_block} c ON b.module = c.module AND b.delta = c.delta\n WHERE b.theme = '%s' AND (r.rid IN ({$placeholders}) OR r.rid IS NULL)\n ORDER BY b.region, b.weight, b.module", array_merge(array(
$theme_key,
), $rids));
while ($block = db_fetch_object($result)) {
$status = FALSE;
if (isset($block->cid) && in_array($block->cid, $cids)) {
$block->context_ui = TRUE;
$block->region = $block->context_region ? $block->context_region : $block->region;
$block->weight = $block->context_weight ? $block->context_weight : $block->weight;
$status = TRUE;
}
else {
$status = $block->status;
}
if ($status) {
if (!isset($blocks[$block->region])) {
$blocks[$block->region] = array();
}
$enabled = _context_ui_block_visibility('user', $block);
$page_match = _context_ui_block_visibility('page', $block);
$throttle = _context_ui_block_visibility('throttle', $block);
if ($enabled && $page_match && $throttle) {
$array = module_invoke($block->module, 'block', 'view', $block->delta);
if (isset($array) && is_array($array) && $array['content'] && !empty($array['content'])) {
foreach ($array as $k => $v) {
$block->{$k} = $v;
}
if ($block->title) {
$block->subject = $block->title == '<none>' ? '' : check_plain($block->title);
}
$blocks[$block->region]["{$block->module}_{$block->delta}"] = $block;
}
}
}
}
foreach ($blocks as $key => $region_blocks) {
uasort($region_blocks, '_context_ui_block_compare');
$blocks[$key] = $region_blocks;
}
}
if (!isset($blocks[$region])) {
$blocks[$region] = array();
}
return $blocks[$region];
}
function _context_ui_block_visibility($op, $block) {
switch ($op) {
case 'user':
global $user;
if ($block->custom != 0) {
if ($user->uid && isset($user->block[$block->module][$block->delta])) {
return $user->block[$block->module][$block->delta];
}
else {
return $block->custom == 1;
}
}
return true;
case 'page':
if ($block->pages) {
if ($block->visibility < 2) {
$path = drupal_get_path_alias($_GET['q']);
$regexp = '/^(' . preg_replace(array(
'/(\\r\\n?|\\n)/',
'/\\\\\\*/',
'/(^|\\|)\\\\<front\\\\>($|\\|)/',
), array(
'|',
'.*',
'\\1' . preg_quote(variable_get('site_frontpage', 'node'), '/') . '\\2',
), preg_quote($block->pages, '/')) . ')$/';
$page_match = preg_match($regexp, $path);
if ($path != $_GET['q']) {
$page_match = $page_match || preg_match($regexp, $_GET['q']);
}
return !($block->visibility xor $page_match);
}
else {
return drupal_eval($block->pages);
}
}
return true;
case 'throttle':
if (!($block->throttle && module_invoke('throttle', 'status') > 0)) {
return true;
}
return false;
}
}
function _context_ui_block_compare($a, $b) {
return $a->weight - $b->weight;
}
function context_ui_context($op, $context) {
switch ($op) {
case 'load':
static $cache = array();
if (is_numeric($context)) {
if (!isset($cache[$context])) {
$context = db_fetch_object(db_query("SELECT * FROM {context_ui} WHERE cid = %d", $context));
}
else {
return $cache[$context];
}
}
else {
if (is_object($context) && isset($context->cid)) {
if (!$cache[$context->cid]) {
$context = db_fetch_object(db_query("SELECT * FROM {context_ui} WHERE cid = %d", $context->cid));
}
else {
return $cache[$context->cid];
}
}
else {
if (is_object($context) && $context->namespace && $context->attribute && $context->value) {
$args = array(
$context->namespace,
$context->attribute,
$context->value,
);
$system = '';
$status = '';
if (isset($context->system)) {
$args[] = $context->system;
$system = "AND system = '%s'";
}
if (isset($context->status)) {
$args[] = $context->status;
$status = "AND status = %d";
}
$context = db_fetch_object(db_query("SELECT * FROM {context_ui} WHERE namespace = '%s' AND attribute = '%s' AND value = '%s' {$system} {$status}", $args));
}
}
}
if ($context) {
$context = context_ui_item('load', $context);
$context = context_ui_item_block('load', $context);
$cache[$context->cid] = $context;
return $context;
}
return false;
case 'insert':
$existing = context_ui_context('load', $context);
if (!$existing || $existing->system != $context->system) {
$context->cid = db_next_id('{context_ui}_cid');
$values = array(
'cid' => $context->cid,
'system' => $context->system,
'status' => $context->status,
'namespace' => $context->namespace,
'attribute' => $context->attribute,
'value' => $context->value,
);
$keys = implode(', ', array_keys($values));
$args = array_merge(array(
$keys,
), $values);
$result = db_query("INSERT INTO {context_ui} (%s) VALUES(%d, %d, %d, '%s', '%s', '%s')", $args);
$result = $result && context_ui_item('save', $context);
$result = $result && context_ui_item_block('save', $context);
return $result ? true : false;
}
return false;
break;
case 'update':
if ($context->cid) {
$values = array(
'system' => $context->system,
'status' => $context->status,
'namespace' => $context->namespace,
'attribute' => $context->attribute,
'value' => $context->value,
'cid' => $context->cid,
);
$result = db_query("UPDATE {context_ui} SET system = %d, status = %d, namespace = '%s', attribute = '%s', value = '%s'WHERE cid = %d", $values);
$result = $result && context_ui_item('save', $context);
$result = $result && context_ui_item_block('save', $context);
return $result ? true : false;
}
break;
case 'delete':
if ($context = context_ui_context('load', $context)) {
db_query("DELETE FROM {context_ui} WHERE cid = %d", $context->cid);
db_query("DELETE FROM {context_ui_item} WHERE cid = %d", $context->cid);
db_query("DELETE FROM {context_ui_block} WHERE cid = %d", $context->cid);
return true;
}
return false;
}
}
function context_ui_item($op = 'load', $context) {
if ($context->cid) {
switch ($op) {
case 'load':
$result = db_query("SELECT * FROM {context_ui_item} WHERE cid = %d", $context->cid);
while ($row = db_fetch_object($result)) {
$context->{$row->type}[$row->id] = $row->id;
}
return $context;
case 'save':
$current = new stdClass();
$current->cid = $context->cid;
$current = context_ui_item('load', $current);
foreach (context_ui_types() as $type) {
if (isset($current->{$type}) && is_array($current->{$type})) {
foreach ($current->{$type} as $id) {
$delete = false;
if (!is_array($context->{$type})) {
$delete = true;
}
else {
if (array_search($id, $context->{$type}) === false) {
$delete = true;
}
}
if ($delete) {
$result = db_query("DELETE FROM {context_ui_item} WHERE cid = %d AND type = '%s' AND id = '%s'", $context->cid, $type, $id);
}
}
}
if (isset($context->{$type}) && is_array($context->{$type})) {
foreach ($context->{$type} as $id) {
$update = false;
if (!(isset($current->{$type}) && is_array($current->{$type}))) {
$update = true;
}
else {
if (array_search($id, $current->{$type}) === false) {
$update = true;
}
}
if ($update) {
$result = db_query("REPLACE INTO {context_ui_item} (cid, type, id) VALUES(%d, '%s', '%s')", $context->cid, $type, $id);
}
}
}
}
return true;
break;
}
}
return false;
}
function context_ui_item_block($op = 'load', $context) {
if ($context->cid) {
switch ($op) {
case 'load':
$result = db_query("SELECT module, delta, region, weight FROM {context_ui_block} WHERE cid = %d", $context->cid);
$context->block = array();
while ($block = db_fetch_object($result)) {
$bid = $block->module . "_" . $block->delta;
$block->bid = $bid;
$context->block[$bid] = $block;
}
return $context;
break;
case 'save':
$current = (object) array(
'cid' => $context->cid,
);
$current = context_ui_item_block('load', $current);
if (is_array($current->block)) {
foreach ($current->block as $block) {
if (!isset($context->block[$block->bid]) || $current->block[$block->bid] != $context->block[$block->bid]) {
$result = db_query("DELETE FROM {context_ui_block WHERE cid = %d AND module = '%s' AND delta = '%s'", $context->cid, $block->module, $block->delta);
}
}
}
if (is_array($context->block)) {
foreach ($context->block as $block) {
$block = (object) $block;
if (!isset($current->block[$block->bid]) || $current->block[$block->bid] != $context->block[$block->bid]) {
$args = array(
'module' => $block->module,
'delta' => $block->delta,
'region' => $block->region,
'weight' => $block->weight,
'cid' => $context->cid,
);
$result = db_query("REPLACE INTO {context_ui_block} (module, delta, region, weight, cid) VALUES ('%s', '%s', '%s', %d, %d)", $args);
}
}
}
return true;
break;
}
}
return false;
}
function theme_context_ui_node_links() {
$output = '';
$links = _context_ui_node_links();
foreach ($links as $link) {
$output .= l('+ ' . t('Add !type', array(
'!type' => $link['title'],
)), $link['href'], array(
'class' => 'button',
));
}
return $output;
}
function _context_ui_node_links($resest = false) {
static $links;
if (!$links || $reset) {
$links = array();
if ($cids = context_get('context_ui', 'cid')) {
$types = node_get_types();
foreach ($cids as $cid) {
$context = context_ui_context('load', $cid);
if (is_array($context->node)) {
foreach ($context->node as $type) {
if (isset($types[$type]) && node_access('create', $type)) {
$links[$type] = array(
'title' => $types[$type]->name,
'href' => 'node/add/' . $type,
);
}
}
}
}
}
}
return $links;
}