FINAL suepr merge step : added all modules to this super repos
This commit is contained in:
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Base class for a context condition.
|
||||
*/
|
||||
class context_condition {
|
||||
var $plugin;
|
||||
var $title;
|
||||
var $description;
|
||||
var $values = array();
|
||||
|
||||
/**
|
||||
* Clone our references when we're being cloned.
|
||||
*
|
||||
* PHP 5.3 performs 'shallow' clones when clone()'ing objects, meaning that
|
||||
* any objects or arrays referenced by this object will not be copied, the
|
||||
* cloned object will just reference our objects/arrays instead. By iterating
|
||||
* over our properties and serializing and unserializing them, we force PHP to
|
||||
* copy them.
|
||||
*/
|
||||
function __clone() {
|
||||
foreach ($this as $key => $val) {
|
||||
if (is_object($val) || (is_array($val))) {
|
||||
$this->{$key} = unserialize(serialize($val));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor. Do not override.
|
||||
*/
|
||||
function __construct($plugin, $info) {
|
||||
$this->plugin = $plugin;
|
||||
$this->title = isset($info['title']) ? $info['title'] : $plugin;
|
||||
$this->description = isset($info['description']) ? $info['description'] : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Condition values.
|
||||
*/
|
||||
function condition_values() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Condition form.
|
||||
*/
|
||||
function condition_form($context) {
|
||||
return array(
|
||||
'#title' => $this->title,
|
||||
'#description' => $this->description,
|
||||
'#options' => $this->condition_values(),
|
||||
'#type' => 'checkboxes',
|
||||
'#default_value' => $this->fetch_from_context($context, 'values'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Condition form submit handler.
|
||||
*/
|
||||
function condition_form_submit($values) {
|
||||
ksort($values);
|
||||
|
||||
// Editor forms are generally checkboxes -- do some checkbox processing.
|
||||
return drupal_map_assoc(array_keys(array_filter($values)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Options form. Provide additional options for your condition.
|
||||
*/
|
||||
function options_form($context) {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Options form submit handler.
|
||||
*/
|
||||
function options_form_submit($values) {
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Settings form. Provide variable settings for your condition.
|
||||
*/
|
||||
function settings_form() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Context editor form for conditions.
|
||||
*/
|
||||
function editor_form($context = NULL) {
|
||||
$form = array();
|
||||
if (!empty($this->values)) {
|
||||
$options = $this->condition_values();
|
||||
foreach ($this->values as $value => $contexts) {
|
||||
$label = "{$this->title}: ";
|
||||
$label .= isset($options[$value]) ? trim($options[$value], ' -') : $value;
|
||||
$form[$value] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => check_plain($label),
|
||||
'#default_value' => empty($context->name) ? TRUE : in_array($context->name, $contexts, TRUE),
|
||||
);
|
||||
}
|
||||
}
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Context editor form submit handler.
|
||||
*/
|
||||
function editor_form_submit(&$context, $values) {
|
||||
// Merge existing values in from non-active conditions.
|
||||
$existing = $this->fetch_from_context($context, 'values');
|
||||
$values += !empty($existing) ? $existing : array();
|
||||
|
||||
ksort($values);
|
||||
|
||||
// Editor forms are generally checkboxes -- do some checkbox processing.
|
||||
return drupal_map_assoc(array_keys(array_filter($values)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Public method that is called from hooks or other integration points with
|
||||
* Drupal. Note that it is not implemented in the base class, allowing
|
||||
* extending classes to change the function signature if necessary.
|
||||
*
|
||||
* function execute($value) {
|
||||
* foreach ($this->get_contexts($value) as $context) {
|
||||
* $this->condition_met($context, $value);
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
/**
|
||||
* Marks a context as having met this particular condition.
|
||||
*/
|
||||
function condition_met($context, $value = NULL) {
|
||||
if (isset($value)) {
|
||||
$this->values[$value] = isset($this->values[$value]) ? $this->values[$value] : array();
|
||||
$this->values[$value][] = $context->name;
|
||||
}
|
||||
context_condition_met($context, $this->plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this condition is used by any contexts. Can be used to
|
||||
* prevent expensive condition checks from being triggered when no contexts
|
||||
* use this condition.
|
||||
*/
|
||||
function condition_used() {
|
||||
$map = context_condition_map();
|
||||
return !empty($map[$this->plugin]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all contexts with the condition value provided.
|
||||
*/
|
||||
function get_contexts($value = NULL) {
|
||||
$map = context_condition_map();
|
||||
$map = isset($map[$this->plugin]) ? $map[$this->plugin] : array();
|
||||
|
||||
$contexts = array();
|
||||
if (isset($value) && (is_string($value) || is_numeric($value))) {
|
||||
if (isset($map[$value]) && is_array($map[$value])) {
|
||||
foreach ($map[$value] as $name) {
|
||||
if (!isset($contexts[$name])) {
|
||||
$context = context_load($name);
|
||||
$contexts[$context->name] = $context;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
foreach ($map as $submap) {
|
||||
foreach ($submap as $name) {
|
||||
if (!isset($contexts[$name])) {
|
||||
$context = context_load($name);
|
||||
$contexts[$context->name] = $context;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $contexts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve options from the context provided.
|
||||
*/
|
||||
function fetch_from_context($context, $key = NULL) {
|
||||
if (isset($key)) {
|
||||
return isset($context->conditions[$this->plugin][$key]) ? $context->conditions[$this->plugin][$key] : array();
|
||||
}
|
||||
return isset($context->conditions[$this->plugin]) ? $context->conditions[$this->plugin] : array();
|
||||
}
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Expose book properties as a context condition.
|
||||
*/
|
||||
class context_condition_book extends context_condition {
|
||||
function condition_values() {
|
||||
$values = array();
|
||||
foreach (book_get_books() as $book) {
|
||||
$values[$book['menu_name']] = check_plain($book['title']);
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
function execute($node, $op) {
|
||||
if (isset($node->book, $node->book['menu_name'])) {
|
||||
foreach ($this->get_contexts($node->book['menu_name']) as $context) {
|
||||
$this->condition_met($context, $node->book['menu_name']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Set the context on the basis of the node type of page's book root.
|
||||
*/
|
||||
class context_condition_bookroot extends context_condition_node {
|
||||
function execute($node, $op) {
|
||||
if ($this->condition_used() && !empty($node->book['bid'])) {
|
||||
$type = db_select('node')
|
||||
->fields('node', array('type'))
|
||||
->condition('nid', $node->book['nid'])
|
||||
->execute()
|
||||
->fetchField();
|
||||
$book = new stdClass();
|
||||
$book->type = $type;
|
||||
parent::execute($book, $op);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Expose active contexts as a context condition.
|
||||
*/
|
||||
class context_condition_context extends context_condition_path {
|
||||
function execute() {
|
||||
if ($this->condition_used()) {
|
||||
$active_contexts = array_keys(context_active_contexts());
|
||||
foreach ($this->get_contexts() as $context) {
|
||||
if (!in_array($context->name, $active_contexts, TRUE) && $values = $this->fetch_from_context($context, 'values')) {
|
||||
if ($this->match($active_contexts, $values)) {
|
||||
$this->condition_met($context);
|
||||
}
|
||||
}
|
||||
}
|
||||
// If the list of active contexts has changed, we need to recurse.
|
||||
if ($active_contexts != array_keys(context_active_contexts())) {
|
||||
$this->execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Expose current language as a context condition.
|
||||
*/
|
||||
class context_condition_language extends context_condition {
|
||||
function condition_values() {
|
||||
return module_exists('locale') ? locale_language_list() : array();
|
||||
}
|
||||
|
||||
function execute($value) {
|
||||
foreach ($this->get_contexts($value) as $context) {
|
||||
$this->condition_met($context, $value);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Expose menu items as a context condition.
|
||||
*/
|
||||
class context_condition_menu extends context_condition {
|
||||
/**
|
||||
* Override of condition_values().
|
||||
*/
|
||||
function condition_values() {
|
||||
if (module_exists('menu')) {
|
||||
$menus = menu_parent_options(menu_get_menus(), array('mlid' => 0));
|
||||
$root_menus = array();
|
||||
foreach ($menus as $key => $name) {
|
||||
$id = explode(':', $key);
|
||||
if ($id[1] == '0') {
|
||||
$root_menus[$id[0]] = check_plain($name);
|
||||
}
|
||||
else {
|
||||
$link = menu_link_load($id[1]);
|
||||
$identifier = $link['link_path'];
|
||||
$root_menu = $root_menus[$id[0]];
|
||||
while (isset($menus[$root_menu][$identifier])) {
|
||||
$identifier .= "'";
|
||||
}
|
||||
$menus[$root_menu][$identifier] = $name;
|
||||
}
|
||||
unset($menus[$key]);
|
||||
}
|
||||
array_unshift($menus, "-- " . t('None') . " --");
|
||||
}
|
||||
else {
|
||||
$menus = array();
|
||||
}
|
||||
return $menus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override of condition_form().
|
||||
* Use multiselect widget.
|
||||
*/
|
||||
function condition_form($context) {
|
||||
$form = parent::condition_form($context);
|
||||
$menu_count = count($form['#options'], COUNT_RECURSIVE);
|
||||
$form['#type'] = 'select';
|
||||
$form['#multiple'] = TRUE;
|
||||
$form['#attributes'] = array('size' => $menu_count > 20 ? 20 : $menu_count);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override of condition_form_submit().
|
||||
* Trim any identifier padding for non-unique path menu items.
|
||||
*/
|
||||
function condition_form_submit($values) {
|
||||
// Trim any identifier padding for non-unique path menu items.
|
||||
$values = parent::condition_form_submit($values);
|
||||
$trimmed = array();
|
||||
foreach ($values as $key => $value) {
|
||||
$trimmed[trim($key, "'")] = trim($value, "'");
|
||||
}
|
||||
return $trimmed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override of execute().
|
||||
*/
|
||||
function execute() {
|
||||
if ($this->condition_used()) {
|
||||
$trail = menu_get_active_trail();
|
||||
foreach ($trail as $item) {
|
||||
if (!empty($item['href'])) {
|
||||
foreach ($this->get_contexts($item['href']) as $context) {
|
||||
$this->condition_met($context, $item['href']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Trigger context on node view only.
|
||||
*/
|
||||
define('CONTEXT_NODE_VIEW', 0);
|
||||
|
||||
/**
|
||||
* Trigger context on node view and node form.
|
||||
*/
|
||||
define('CONTEXT_NODE_FORM', 1);
|
||||
|
||||
/**
|
||||
* Trigger context on node form only.
|
||||
*/
|
||||
define('CONTEXT_NODE_FORM_ONLY', 2);
|
||||
|
||||
/**
|
||||
* Expose node views/node forms of specific node types as a context condition.
|
||||
*/
|
||||
class context_condition_node extends context_condition {
|
||||
function condition_values() {
|
||||
$values = array();
|
||||
foreach (node_type_get_types() as $type) {
|
||||
$values[$type->type] = check_plain($type->name);
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
function options_form($context) {
|
||||
$defaults = $this->fetch_from_context($context, 'options');
|
||||
return array(
|
||||
'node_form' => array(
|
||||
'#title' => t('Set on node form'),
|
||||
'#type' => 'select',
|
||||
'#options' => array(
|
||||
CONTEXT_NODE_VIEW => t('No'),
|
||||
CONTEXT_NODE_FORM => t('Yes'),
|
||||
CONTEXT_NODE_FORM_ONLY => t('Only on node form')
|
||||
),
|
||||
'#description' => t('Set this context on node forms'),
|
||||
'#default_value' => isset($defaults['node_form']) ? $defaults['node_form'] : TRUE,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
function execute($node, $op) {
|
||||
foreach ($this->get_contexts($node->type) as $context) {
|
||||
// Check the node form option.
|
||||
$options = $this->fetch_from_context($context, 'options');
|
||||
if ($op === 'form') {
|
||||
$options = $this->fetch_from_context($context, 'options');
|
||||
if (!empty($options['node_form']) && in_array($options['node_form'], array(CONTEXT_NODE_FORM, CONTEXT_NODE_FORM_ONLY))) {
|
||||
$this->condition_met($context, $node->type);
|
||||
}
|
||||
}
|
||||
elseif (empty($options['node_form']) || $options['node_form'] != CONTEXT_NODE_FORM_ONLY) {
|
||||
$this->condition_met($context, $node->type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Expose node taxonomy terms as a context condition.
|
||||
*/
|
||||
class context_condition_node_taxonomy extends context_condition_node {
|
||||
function condition_values() {
|
||||
$values = array();
|
||||
if (module_exists('taxonomy')) {
|
||||
foreach (taxonomy_get_vocabularies() as $vocab) {
|
||||
if (empty($vocab->tags)) {
|
||||
foreach (taxonomy_get_tree($vocab->vid) as $term) {
|
||||
$values[$term->tid] = check_plain($term->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
function condition_form($context) {
|
||||
$form = parent::condition_form($context);
|
||||
$form['#type'] = 'select';
|
||||
$form['#size'] = 12;
|
||||
$form['#multiple'] = TRUE;
|
||||
$vocabularies = taxonomy_get_vocabularies();
|
||||
$options = array();
|
||||
foreach ($vocabularies as $vid => $vocabulary) {
|
||||
$tree = taxonomy_get_tree($vid);
|
||||
if ($tree && (count($tree) > 0)) {
|
||||
$options[$vocabulary->name] = array();
|
||||
foreach ($tree as $term) {
|
||||
$options[$vocabulary->name][$term->tid] = str_repeat('-', $term->depth) . $term->name;
|
||||
}
|
||||
}
|
||||
}
|
||||
$form['#options'] = $options;
|
||||
return $form;
|
||||
}
|
||||
|
||||
function execute($node, $op) {
|
||||
// build a list of each taxonomy reference field belonging to the bundle for the current node
|
||||
$fields = field_info_fields();
|
||||
$instance_fields = field_info_instances('node', $node->type);
|
||||
$check_fields = array();
|
||||
foreach ($instance_fields as $key => $field_info) {
|
||||
if ($fields[$key]['type'] == 'taxonomy_term_reference') {
|
||||
$check_fields[] = $key;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->condition_used() && !empty($check_fields)) {
|
||||
foreach ($check_fields as $field) {
|
||||
if ($terms = field_get_items('node', $node, $field)) {
|
||||
foreach ($terms as $term) {
|
||||
foreach ($this->get_contexts($term['tid']) as $context) {
|
||||
// Check the node form option.
|
||||
if ($op === 'form') {
|
||||
$options = $this->fetch_from_context($context, 'options');
|
||||
if (!empty($options['node_form'])) {
|
||||
$this->condition_met($context, $term['tid']);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$this->condition_met($context, $term['tid']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Expose paths as a context condition.
|
||||
*/
|
||||
class context_condition_path extends context_condition {
|
||||
/**
|
||||
* Omit condition values. We will provide a custom input form for our conditions.
|
||||
*/
|
||||
function condition_values() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Condition form.
|
||||
*/
|
||||
function condition_form($context) {
|
||||
$form = parent::condition_form($context);
|
||||
unset($form['#options']);
|
||||
|
||||
$form['#type'] = 'textarea';
|
||||
$form['#default_value'] = implode("\n", $this->fetch_from_context($context, 'values'));
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Condition form submit handler.
|
||||
*/
|
||||
function condition_form_submit($values) {
|
||||
$parsed = array();
|
||||
$items = explode("\n", $values);
|
||||
if (!empty($items)) {
|
||||
foreach ($items as $v) {
|
||||
$v = trim($v);
|
||||
if (!empty($v)) {
|
||||
$parsed[$v] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $parsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute.
|
||||
*/
|
||||
function execute() {
|
||||
if ($this->condition_used()) {
|
||||
// Include both the path alias and normal path for matching.
|
||||
$current_path = array(drupal_get_path_alias($_GET['q']));
|
||||
if ($current_path[0] != $_GET['q']) {
|
||||
$current_path[] = $_GET['q'];
|
||||
}
|
||||
foreach ($this->get_contexts() as $context) {
|
||||
$paths = $this->fetch_from_context($context, 'values');
|
||||
if ($this->match($current_path, $paths, TRUE)) {
|
||||
$this->condition_met($context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Match the subject against a set of regex patterns.
|
||||
* Similar to drupal_match_path() but also handles negation through the use
|
||||
* of the ~ character.
|
||||
*
|
||||
* @param mixed $subject
|
||||
* The subject string or an array of strings to be matched.
|
||||
* @param array $patterns
|
||||
* An array of patterns. Any patterns that begin with ~ are considered
|
||||
* negative or excluded conditions.
|
||||
* @param boolean $path
|
||||
* Whether the given subject should be matched as a Drupal path. If TRUE,
|
||||
* '<front>' will be replaced with the site frontpage when matching against
|
||||
* $patterns.
|
||||
*/
|
||||
protected function match($subject, $patterns, $path = FALSE) {
|
||||
static $regexps;
|
||||
$match = FALSE;
|
||||
$positives = $negatives = 0;
|
||||
$subject = !is_array($subject) ? array($subject) : $subject;
|
||||
foreach ($patterns as $pattern) {
|
||||
if (strpos($pattern, '~') === 0) {
|
||||
$negate = TRUE;
|
||||
$negatives++;
|
||||
}
|
||||
else {
|
||||
$negate = FALSE;
|
||||
$positives++;
|
||||
}
|
||||
$pattern = ltrim($pattern, '~');
|
||||
if (!isset($regexps[$pattern])) {
|
||||
if ($path) {
|
||||
$regexps[$pattern] = '/^(' . preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<front\\\\>($|\|)/'), array('|', '.*', '\1' . preg_quote(variable_get('site_frontpage', 'node'), '/') . '\2'), preg_quote($pattern, '/')) . ')$/';
|
||||
}
|
||||
else {
|
||||
$regexps[$pattern] = '/^(' . preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/'), array('|', '.*'), preg_quote($pattern, '/')) . ')$/';
|
||||
}
|
||||
}
|
||||
foreach ($subject as $value) {
|
||||
if (preg_match($regexps[$pattern], $value)) {
|
||||
if ($negate) {
|
||||
return FALSE;
|
||||
}
|
||||
$match = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If there are **only** negative conditions and we've gotten this far none
|
||||
// we actually have a match.
|
||||
if ($positives === 0 && $negatives) {
|
||||
return TRUE;
|
||||
}
|
||||
return $match;
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Simple sitewide context, always present.
|
||||
*/
|
||||
class context_condition_sitewide extends context_condition {
|
||||
function condition_values() {
|
||||
return array(1 => t('Always active'));
|
||||
}
|
||||
|
||||
function editor_form($context = NULL) {
|
||||
$form = parent::editor_form($context);
|
||||
$form[1]['#title'] = t('Always active');
|
||||
$form['#weight'] = -10;
|
||||
return $form;
|
||||
}
|
||||
|
||||
function execute($value) {
|
||||
foreach ($this->get_contexts($value) as $context) {
|
||||
$this->condition_met($context, $value);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Expose term views/term forms by vocabulary as a context condition.
|
||||
*/
|
||||
class context_condition_taxonomy_term extends context_condition {
|
||||
function condition_values() {
|
||||
$values = array();
|
||||
foreach (taxonomy_get_vocabularies() as $vocab) {
|
||||
$values[$vocab->machine_name] = check_plain($vocab->name);
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
function options_form($context) {
|
||||
$defaults = $this->fetch_from_context($context, 'options');
|
||||
return array(
|
||||
'term_form' => array(
|
||||
'#title' => t('Set on term form'),
|
||||
'#type' => 'select',
|
||||
'#options' => array(
|
||||
0 => t('No'),
|
||||
1 => t('Yes'),
|
||||
2 => t('Only on term form')
|
||||
),
|
||||
'#description' => t('Set this context on term forms'),
|
||||
'#default_value' => isset($defaults['term_form']) ? $defaults['term_form'] : TRUE,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
function execute($term, $op) {
|
||||
foreach ($this->get_contexts($term->vocabulary_machine_name) as $context) {
|
||||
// Check the node form option.
|
||||
$options = $this->fetch_from_context($context, 'options');
|
||||
if ($op === 'form') {
|
||||
$options = $this->fetch_from_context($context, 'options');
|
||||
if (!empty($options['term_form']) && in_array($options['term_form'], array(1, 2))) {
|
||||
$this->condition_met($context, $term->vocabulary_machine_name);
|
||||
}
|
||||
}
|
||||
elseif (empty($options['term_form']) || $options['term_form'] != 2) {
|
||||
$this->condition_met($context, $term->vocabulary_machine_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Expose current user role as a context condition.
|
||||
*/
|
||||
class context_condition_user extends context_condition {
|
||||
function condition_values() {
|
||||
$values = array();
|
||||
foreach (user_roles() as $rid => $role_name) {
|
||||
if ($rid == DRUPAL_ANONYMOUS_RID) {
|
||||
$values['anonymous user'] = check_plain($role_name);
|
||||
}
|
||||
elseif ($rid == DRUPAL_AUTHENTICATED_RID) {
|
||||
$values['authenticated user'] = check_plain($role_name);
|
||||
}
|
||||
else {
|
||||
$values[$role_name] = check_plain($role_name);
|
||||
}
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
function execute($account) {
|
||||
$roles = $account->roles;
|
||||
foreach ($roles as $rid => $role) {
|
||||
foreach ($this->get_contexts($role) as $context) {
|
||||
$this->condition_met($context, $role);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Expose user pages as a context condition.
|
||||
*/
|
||||
class context_condition_user_page extends context_condition {
|
||||
function condition_values() {
|
||||
$values = array();
|
||||
$values['view'] = t('User profile');
|
||||
$values['form'] = t('User account form');
|
||||
$values['register'] = t('Registration form');
|
||||
return $values;
|
||||
}
|
||||
|
||||
function options_form($context) {
|
||||
$defaults = $this->fetch_from_context($context, 'options');
|
||||
return array(
|
||||
'mode' => array(
|
||||
'#title' => t('Active for'),
|
||||
'#type' => 'select',
|
||||
'#options' => array(
|
||||
'all' => t('Any user'),
|
||||
'current' => t('Only the current user'),
|
||||
'other' => t('Only other users'),
|
||||
),
|
||||
'#default_value' => isset($defaults['mode']) ? $defaults['mode'] : 'all',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
function execute($account, $op) {
|
||||
global $user;
|
||||
foreach ($this->get_contexts($op) as $context) {
|
||||
if ($op === 'register') {
|
||||
$this->condition_met($context);
|
||||
}
|
||||
else {
|
||||
$options = $this->fetch_from_context($context, 'options');
|
||||
$mode = !empty($options['mode']) ? $options['mode'] : 'all';
|
||||
switch ($options['mode']) {
|
||||
case 'current':
|
||||
if ($account->uid == $user->uid) {
|
||||
$this->condition_met($context);
|
||||
}
|
||||
break;
|
||||
case 'other':
|
||||
if ($account->uid != $user->uid) {
|
||||
$this->condition_met($context);
|
||||
}
|
||||
break;
|
||||
case 'all':
|
||||
default:
|
||||
$this->condition_met($context);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
class context_condition_views extends context_condition {
|
||||
|
||||
/**
|
||||
* Generate a list of database and module provided views.
|
||||
*/
|
||||
function condition_values() {
|
||||
$enabled_views = array();
|
||||
|
||||
$views = views_get_all_views();
|
||||
ksort($views);
|
||||
|
||||
foreach ($views as $view) {
|
||||
if (!isset($views[$view->name]->disabled) || !$views[$view->name]->disabled) {
|
||||
$enabled_views[$view->name] = check_plain($view->name);
|
||||
|
||||
// Provide more granular options for each page display
|
||||
$displays = array();
|
||||
foreach ($view->display as $id => $display) {
|
||||
if ($display->display_plugin == 'page') {
|
||||
$displays[$view->name . ":" . $id] = check_plain("-- {$display->display_title}");
|
||||
}
|
||||
}
|
||||
$enabled_views += $displays;
|
||||
}
|
||||
}
|
||||
return $enabled_views;
|
||||
}
|
||||
|
||||
function execute($view) {
|
||||
switch ($view->display_handler->display->display_plugin) {
|
||||
case 'page':
|
||||
case 'calendar':
|
||||
// Set contexts for this view.
|
||||
foreach ($this->get_contexts($view->name) as $context) {
|
||||
$this->condition_met($context, $view->name);
|
||||
}
|
||||
// Set any contexts associated with the current display
|
||||
if (!empty($view->current_display)) {
|
||||
foreach ($this->get_contexts("{$view->name}:{$view->current_display}") as $context) {
|
||||
$this->condition_met($context, "{$view->name}:{$view->current_display}");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Base class for a context reaction.
|
||||
*/
|
||||
class context_reaction {
|
||||
var $plugin;
|
||||
var $title;
|
||||
var $description;
|
||||
|
||||
/**
|
||||
* Clone our references when we're being cloned.
|
||||
*
|
||||
* PHP 5.3 performs 'shallow' clones when clone()'ing objects, meaning that
|
||||
* any objects or arrays referenced by this object will not be copied, the
|
||||
* cloned object will just reference our objects/arrays instead. By iterating
|
||||
* over our properties and serializing and unserializing them, we force PHP to
|
||||
* copy them.
|
||||
*/
|
||||
function __clone() {
|
||||
foreach ($this as $key => $val) {
|
||||
if (is_object($val) || (is_array($val))) {
|
||||
$this->{$key} = unserialize(serialize($val));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor. Do not override.
|
||||
*/
|
||||
function __construct($plugin, $info) {
|
||||
$this->plugin = $plugin;
|
||||
$this->title = isset($info['title']) ? $info['title'] : $plugin;
|
||||
$this->description = isset($info['description']) ? $info['description'] : '';
|
||||
}
|
||||
|
||||
function options_form($context) {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Options form submit handler.
|
||||
*/
|
||||
function options_form_submit($values) {
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Settings form. Provide variable settings for your reaction.
|
||||
*/
|
||||
function settings_form() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Public method that is called from hooks or other integration points with
|
||||
* Drupal. Note that it is not implemented in the base class, allowing
|
||||
* extending classes to change the function signature if necessary.
|
||||
*
|
||||
* function execute($value) {
|
||||
* foreach ($this->get_contexts($value) as $context) {
|
||||
* $this->condition_met($context, $value);
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
/**
|
||||
* Retrieve active contexts that have values for this reaction.
|
||||
*/
|
||||
function get_contexts() {
|
||||
$contexts = array();
|
||||
foreach (context_active_contexts() as $context) {
|
||||
if ($this->fetch_from_context($context)) {
|
||||
$contexts[$context->name] = $context;
|
||||
}
|
||||
}
|
||||
return $contexts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve options from the context provided.
|
||||
*/
|
||||
function fetch_from_context($context) {
|
||||
return isset($context->reactions[$this->plugin]) ? $context->reactions[$this->plugin] : array();
|
||||
}
|
||||
}
|
@@ -0,0 +1,262 @@
|
||||
/**
|
||||
* Script placeholder markup.
|
||||
*/
|
||||
.script-placeholder {
|
||||
padding:100px 0px;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
/**
|
||||
* Browser
|
||||
*/
|
||||
.context-block-browser {
|
||||
width: 600px;
|
||||
}
|
||||
|
||||
.context-block-browser .blocks {
|
||||
height:98%;
|
||||
overflow: auto;
|
||||
float: left;
|
||||
width: 320px;
|
||||
}
|
||||
|
||||
.context-block-browser .block-browser-sidebar {
|
||||
float: left;
|
||||
width: 250px;
|
||||
padding: 0 0 0 15px;
|
||||
}
|
||||
|
||||
.context-block-item,
|
||||
.context-block-browser .draggable-placeholder,
|
||||
#admin-toolbar .context-block-browser .context-block-item {
|
||||
font-size:11px;
|
||||
line-height:20px;
|
||||
height:20px;
|
||||
|
||||
color:#333;
|
||||
|
||||
padding:3px 3px 3px 3px;
|
||||
margin:0px 1px 1px 0px;
|
||||
max-width:300px;
|
||||
white-space:nowrap;
|
||||
overflow:hidden;
|
||||
|
||||
background:#efefef;
|
||||
border:1px solid #ddd;
|
||||
position:relative;
|
||||
|
||||
border-radius:5px;
|
||||
-moz-border-radius:5px;
|
||||
-moz-user-select:none;
|
||||
-webkit-user-select:none;
|
||||
}
|
||||
|
||||
|
||||
.context-block-addable { cursor: pointer; }
|
||||
|
||||
.context-block-item span.icon {
|
||||
background:url(context_reaction_block.png) 0px -80px no-repeat;
|
||||
display:block;
|
||||
width:20px;
|
||||
height:20px;
|
||||
float:left;
|
||||
margin-right:5px;
|
||||
}
|
||||
|
||||
.context-block-loading { max-width:none; }
|
||||
|
||||
.context-block-loading span.icon {
|
||||
background-position:-20px -80px;
|
||||
float:none;
|
||||
margin:0px auto;
|
||||
}
|
||||
|
||||
.context-block-browser .draggable-placeholder { padding:2px 1px 1px 2px; }
|
||||
|
||||
#admin-toolbar.horizontal .context-block-browser .draggable-placeholder,
|
||||
#admin-toolbar.horizontal .context-block-browser .context-block-item {
|
||||
width:180px;
|
||||
margin-right:1px;
|
||||
padding-right:9px;
|
||||
float:left;
|
||||
}
|
||||
|
||||
|
||||
.context-block-added { display:none !important; }
|
||||
|
||||
/**
|
||||
* Inline editing elements ============================================
|
||||
*/
|
||||
div.context-block-region {display: none;}
|
||||
a.context-block { display:none !important; }
|
||||
|
||||
body.context-editing div.context-block-region {
|
||||
-moz-border-radius:5px;
|
||||
-webkit-border-radius:5px;
|
||||
background:#666;
|
||||
color:#fff;
|
||||
opacity: 0.5;
|
||||
-moz-opacity: 0.5;
|
||||
filter:alpha(opacity=50);
|
||||
|
||||
display:block;
|
||||
height:40px;
|
||||
line-height:24px;
|
||||
|
||||
text-align:center;
|
||||
font-size:18px;
|
||||
white-space:nowrap;
|
||||
}
|
||||
|
||||
.context-block-region .region-name {
|
||||
width:100%;
|
||||
text-align:center;
|
||||
font-size:18px;
|
||||
color:#fff;
|
||||
white-space:nowrap;
|
||||
display:block;
|
||||
-moz-user-select:none;
|
||||
-webkit-user-select:none;
|
||||
}
|
||||
|
||||
body.context-editing .ui-sortable .block { opacity:.25; }
|
||||
|
||||
body.context-editing .ui-sortable .draggable {
|
||||
position:relative;
|
||||
opacity:1;
|
||||
}
|
||||
|
||||
body.context-editing .draggable-placeholder {
|
||||
-moz-border-radius:5px;
|
||||
-webkit-border-radius:5px;
|
||||
|
||||
background:#fff;
|
||||
border:3px dashed #666;
|
||||
opacity:.2;
|
||||
}
|
||||
|
||||
body.context-editing .draggable:hover a.context-block-remove,
|
||||
body.context-editing .draggable:hover a.context-block-handle {
|
||||
background:url(context_reaction_block.png) no-repeat;
|
||||
cursor:move;
|
||||
display:block;
|
||||
width:40px;
|
||||
height:40px;
|
||||
position:absolute;
|
||||
right:35px;
|
||||
top:-5px;
|
||||
z-index:100;
|
||||
}
|
||||
|
||||
body.context-editing .draggable:hover a.context-block-remove {
|
||||
background-position:-40px 0px;
|
||||
cursor:pointer;
|
||||
right:-5px;
|
||||
}
|
||||
|
||||
.context-block-hidden { display:none !important; }
|
||||
|
||||
.block .context-block-empty-content {
|
||||
text-align:center;
|
||||
padding:10px;
|
||||
opacity:.5;
|
||||
background:#fff;
|
||||
color:#666;
|
||||
}
|
||||
|
||||
/**
|
||||
* Block visibility ===================================================
|
||||
*/
|
||||
#context-blockform .context-blockform-selector {
|
||||
height:20em;
|
||||
overflow:auto;
|
||||
}
|
||||
|
||||
#context-blockform span.system-blocks { color:#999; }
|
||||
|
||||
#context-blockform td.blocks,
|
||||
#context-blockform td.selector {
|
||||
border:1px solid #ddd;
|
||||
padding:10px;
|
||||
width:50%;
|
||||
}
|
||||
|
||||
#context-blockform td.blocks .label,
|
||||
#context-blockform td.blocks td,
|
||||
#context-blockform td.blocks th {
|
||||
background:#fff;
|
||||
padding:5px 5px 4px;
|
||||
border:0px;
|
||||
border-bottom:1px solid #ddd;
|
||||
}
|
||||
|
||||
#context-blockform td.blocks .label { background:#eee; }
|
||||
#context-blockform td.blocks .label a { float:right; }
|
||||
|
||||
#context-ui-items #context-blockform {
|
||||
font-size:11px;
|
||||
line-height:15px;
|
||||
}
|
||||
|
||||
#context-ui-items #context-blockform .form-checkboxes {
|
||||
height:auto;
|
||||
overflow:visible;
|
||||
padding:0px;
|
||||
margin:0px;
|
||||
border:0px;
|
||||
}
|
||||
|
||||
#context-ui-items #context-blockform .form-item { padding:0px; }
|
||||
|
||||
#context-ui-items #context-blockform label {
|
||||
background:#eee;
|
||||
display:block;
|
||||
padding:5px;
|
||||
line-height:15px;
|
||||
}
|
||||
|
||||
#context-ui-items #context-blockform label.option {
|
||||
background:#fff;
|
||||
display:block;
|
||||
border:0px;
|
||||
}
|
||||
|
||||
#context-blockform .tabledrag-toggle-weight-wrapper {
|
||||
margin-bottom:0;
|
||||
}
|
||||
|
||||
a.context-ui-add-link, a:link.context-ui-add-link, a:visited.context-ui-add-link {
|
||||
display:block;
|
||||
width:100%;
|
||||
text-align:center;
|
||||
font-size:12px;
|
||||
color:#fff;
|
||||
cursor: pointer;
|
||||
line-height:14px;
|
||||
}
|
||||
|
||||
.editing-context-label {
|
||||
position: fixed;
|
||||
top:70px;
|
||||
background:#fff;
|
||||
color:#222;
|
||||
padding:10px;
|
||||
font-weight:bold;
|
||||
opacity: 0.5;
|
||||
-moz-opacity: 0.5;
|
||||
filter:alpha(opacity=50);
|
||||
border:1px solid #ddd;
|
||||
border-left:0;
|
||||
border-radius:0 6px 6px 0;
|
||||
}
|
||||
|
||||
.context-help {
|
||||
font-size:12px;
|
||||
font-weight:normal;
|
||||
}
|
||||
|
||||
.context-editor-title {
|
||||
font-size:24px;
|
||||
margin:10px 0px;
|
||||
padding:0;
|
||||
}
|
@@ -0,0 +1,673 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Expose blocks as context reactions.
|
||||
*/
|
||||
class context_reaction_block extends context_reaction {
|
||||
/**
|
||||
* Options form.
|
||||
*/
|
||||
function options_form($context) {
|
||||
// Rebuild the block info cache if necessary.
|
||||
$this->get_blocks(NULL, NULL, $this->rebuild_needed());
|
||||
$this->rebuild_needed(FALSE);
|
||||
|
||||
$theme_key = variable_get('theme_default', 'garland');
|
||||
$weight_delta = $this->max_block_weight();
|
||||
|
||||
$form = array(
|
||||
'#tree' => TRUE,
|
||||
'#theme' => 'context_block_form',
|
||||
'max_block_weight' => array(
|
||||
'#value' => $weight_delta,
|
||||
'#type' => 'value',
|
||||
),
|
||||
'state' => array(
|
||||
'#type' => 'hidden',
|
||||
'#attributes' => array('class' => 'context-blockform-state'),
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* Selector.
|
||||
*/
|
||||
$modules = module_list();
|
||||
$form['selector'] = array(
|
||||
'#type' => 'item',
|
||||
'#tree' => TRUE,
|
||||
'#prefix' => '<div class="context-blockform-selector">',
|
||||
'#suffix' => '</div>',
|
||||
);
|
||||
foreach ($this->get_blocks() as $block) {
|
||||
$group = isset($block->context_group) ? $block->context_group : $block->module;
|
||||
if (!isset($form['selector'][$group])) {
|
||||
$form['selector'][$group] = array(
|
||||
'#type' => 'checkboxes',
|
||||
'#title' => isset($block->context_group) ? $block->context_group : $modules[$block->module],
|
||||
'#options' => array(),
|
||||
);
|
||||
}
|
||||
$form['selector'][$group]['#options'][$block->bid] = check_plain($block->info);
|
||||
}
|
||||
ksort($form['selector']);
|
||||
|
||||
/**
|
||||
* Regions.
|
||||
*/
|
||||
$form['blocks'] = array(
|
||||
'#tree' => TRUE,
|
||||
'#theme' => 'context_block_regions_form',
|
||||
);
|
||||
foreach (system_region_list($theme_key, REGIONS_VISIBLE) as $region => $label) {
|
||||
$form['blocks'][$region] = array(
|
||||
'#type' => 'item',
|
||||
'#title' => $label,
|
||||
'#tree' => TRUE,
|
||||
);
|
||||
foreach ($this->get_blocks($region, $context) as $block) {
|
||||
if (!empty($block->context)) {
|
||||
$form['blocks'][$region][$block->bid] = array(
|
||||
'#value' => check_plain($block->info),
|
||||
'#weight' => $block->weight,
|
||||
'#type' => 'markup',
|
||||
'#tree' => TRUE,
|
||||
'weight' => array('#type' => 'weight', '#delta' => $weight_delta, '#default_value' => $block->weight),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options form submit handler.
|
||||
*/
|
||||
function options_form_submit($values) {
|
||||
$blocks = array();
|
||||
$block_info = $this->get_blocks();
|
||||
|
||||
// Retrieve blocks from submitted JSON string.
|
||||
if (!empty($values['state'])) {
|
||||
$edited = $this->json_decode($values['state']);
|
||||
}
|
||||
else {
|
||||
$edited = array();
|
||||
}
|
||||
|
||||
foreach ($edited as $region => $block_data) {
|
||||
foreach ($block_data as $position => $data) {
|
||||
if (isset($block_info[$data->bid])) {
|
||||
$blocks[$data->bid] = array(
|
||||
'module' => $block_info[$data->bid]->module,
|
||||
'delta' => $block_info[$data->bid]->delta,
|
||||
'region' => $region,
|
||||
'weight' => $data->weight,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return array('blocks' => $blocks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Context editor form for blocks.
|
||||
*/
|
||||
function editor_form($context) {
|
||||
$form = array();
|
||||
drupal_add_library('system', 'ui.droppable');
|
||||
drupal_add_library('system', 'ui.sortable');
|
||||
drupal_add_js(drupal_get_path('module', 'context_ui') . '/json2.js');
|
||||
drupal_add_js(drupal_get_path('module', 'context_ui') . '/theme/filter.js');
|
||||
drupal_add_js(drupal_get_path('module', 'context') . '/plugins/context_reaction_block.js');
|
||||
drupal_add_css(drupal_get_path('module', 'context') . '/plugins/context_reaction_block.css');
|
||||
|
||||
// We might be called multiple times so use a static to ensure this is set just once.
|
||||
static $once;
|
||||
if (!isset($once)) {
|
||||
$settings = array(
|
||||
'path' => drupal_is_front_page() ? base_path() : url($_GET['q']),
|
||||
'params' => (object) array_diff_key($_GET, array('q' => '')),
|
||||
'scriptPlaceholder' => theme('context_block_script_placeholder', array('text' => '')),
|
||||
);
|
||||
drupal_add_js(array('contextBlockEditor' => $settings), 'setting');
|
||||
$once = TRUE;
|
||||
}
|
||||
|
||||
$form['state'] = array(
|
||||
'#type' => 'hidden',
|
||||
'#attributes' => array('class' => array('context-block-editor-state')),
|
||||
);
|
||||
$form['browser'] = array(
|
||||
'#markup' => theme('context_block_browser', array(
|
||||
'blocks' => $this->get_blocks(NULL, NULL, $this->rebuild_needed()),
|
||||
'context' => $context
|
||||
)),
|
||||
);
|
||||
$this->rebuild_needed(FALSE);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit handler context editor form.
|
||||
*/
|
||||
function editor_form_submit(&$context, $values) {
|
||||
$edited = !empty($values['state']) ? (array) $this->json_decode($values['state']) : array();
|
||||
|
||||
$options = array();
|
||||
|
||||
// Take the existing context values and remove blocks that belong affected regions.
|
||||
$affected_regions = array_keys($edited);
|
||||
if (!empty($context->reactions['block']['blocks'])) {
|
||||
$options = $context->reactions['block'];
|
||||
foreach ($options['blocks'] as $key => $block) {
|
||||
if (in_array($block['region'], $affected_regions)) {
|
||||
unset($options['blocks'][$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate through blocks and add in the ones that belong to the context.
|
||||
foreach ($edited as $region => $blocks) {
|
||||
foreach ($blocks as $weight => $block) {
|
||||
if ($block->context === $context->name) {
|
||||
$split = explode('-', $block->bid);
|
||||
$options['blocks'][$block->bid] = array(
|
||||
'module' => array_shift($split),
|
||||
'delta' => implode('-', $split),
|
||||
'region' => $region,
|
||||
'weight' => $weight,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Settings form for variables.
|
||||
*/
|
||||
function settings_form() {
|
||||
$form = array();
|
||||
$form['context_reaction_block_all_regions'] = array(
|
||||
'#title' => t('Show all regions'),
|
||||
'#type' => 'checkbox',
|
||||
'#default_value' => variable_get('context_reaction_block_all_regions', FALSE),
|
||||
'#description' => t('Show all regions including those that are empty. Enable if you are administering your site using the inline editor.')
|
||||
);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute.
|
||||
*/
|
||||
function execute(&$page) {
|
||||
global $theme;
|
||||
|
||||
// The theme system might not yet be initialized. We need $theme.
|
||||
drupal_theme_initialize();
|
||||
|
||||
// If the context_block querystring param is set, switch to AJAX rendering.
|
||||
// Note that we check the output buffer for any content to ensure that we
|
||||
// are not in the middle of a PHP template render.
|
||||
if (isset($_GET['context_block']) && !ob_get_contents()) {
|
||||
return $this->render_ajax($_GET['context_block']);
|
||||
}
|
||||
|
||||
// Populate all block regions
|
||||
$all_regions = system_region_list($theme);
|
||||
|
||||
// Load all region content assigned via blocks.
|
||||
foreach (array_keys($all_regions) as $region) {
|
||||
if ($this->is_enabled_region($region)) {
|
||||
if ($blocks = $this->block_get_blocks_by_region($region)) {
|
||||
|
||||
// Are the blocks already sorted.
|
||||
$blocks_sorted = TRUE;
|
||||
|
||||
// If blocks have already been placed in this region (most likely by
|
||||
// Block module), then merge in blocks from Context.
|
||||
if (isset($page[$region])) {
|
||||
$page[$region] = array_merge($page[$region], $blocks);
|
||||
|
||||
// Restore the weights that Block module manufactured
|
||||
// @see _block_get_renderable_array()
|
||||
foreach ($page[$region] as &$block) {
|
||||
if (isset($block['#block']->weight)) {
|
||||
$block['#weight'] = $block['#block']->weight;
|
||||
$blocks_sorted = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$page[$region] = $blocks;
|
||||
}
|
||||
|
||||
$page[$region]['#sorted'] = $blocks_sorted;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of enabled regions for which blocks should be built.
|
||||
* Split out into a separate method for easy overrides in extending classes.
|
||||
*/
|
||||
protected function is_enabled_region($region) {
|
||||
global $theme;
|
||||
$regions = array_keys(system_region_list($theme));
|
||||
return in_array($region, $regions, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether inline editing requirements are met and that the current
|
||||
* user may edit.
|
||||
*/
|
||||
protected function is_editable_region($region, $reset = FALSE) {
|
||||
// Check requirements.
|
||||
// Generally speaking, it does not make sense to allow anonymous users to
|
||||
// edit a context inline. Though it may be possible to save (and restore)
|
||||
// an edited context to an anonymous user's cookie or session, it's an
|
||||
// edge case and probably not something we want to encourage anyway.
|
||||
static $requirements;
|
||||
if (!isset($requirements) || $reset) {
|
||||
global $user;
|
||||
if ($user->uid && user_access('administer contexts') && variable_get('context_ui_dialog_enabled', FALSE)) {
|
||||
$requirements = TRUE;
|
||||
drupal_add_library('system', 'ui.droppable');
|
||||
drupal_add_library('system', 'ui.sortable');
|
||||
drupal_add_js(drupal_get_path('module', 'context') . '/plugins/context_reaction_block.js');
|
||||
drupal_add_css(drupal_get_path('module', 'context') . '/plugins/context_reaction_block.css');
|
||||
}
|
||||
else {
|
||||
$requirements = FALSE;
|
||||
}
|
||||
}
|
||||
// Check that this region is not locked by the theme.
|
||||
global $theme;
|
||||
$info = system_get_info('theme', $theme);
|
||||
if ($info && isset($info['regions_locked']) && in_array($region, $info['regions_locked'])) {
|
||||
return FALSE;
|
||||
}
|
||||
// Check that this region is not hidden
|
||||
$visible = system_region_list($theme, REGIONS_VISIBLE);
|
||||
return $requirements && $this->is_enabled_region($region) && isset($visible[$region]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add markup for making a block editable.
|
||||
*/
|
||||
protected function editable_block($block) {
|
||||
if (!empty($block->content)) {
|
||||
$block->content = array(
|
||||
'content' => $block->content,
|
||||
'context' => array('#markup' => "<a id='context-block-{$block->module}-{$block->delta}' class='context-block editable edit-{$block->context}'></a>"),
|
||||
);
|
||||
//Contextual links are in the wrong spot in the render array once we've nested them
|
||||
if (isset($block->content['content']['#contextual_links'])) {
|
||||
$block->content['#contextual_links'] = $block->content['content']['#contextual_links'];
|
||||
unset($block->content['content']['#contextual_links']);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// the block alter in context.module should ensure that blocks are never
|
||||
// empty if the inline editor is present but in the case that they are,
|
||||
// warn that editing the context is likely to cause this block to be dropped
|
||||
drupal_set_message(t('The block with delta @delta from module @module is not compatible with the inline editor and will be dropped from the context containing it if you edit contexts here', array('@delta' => $block->delta, '@module' => $block->module)), 'warning');
|
||||
}
|
||||
return $block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add markup for making a region editable.
|
||||
*/
|
||||
protected function editable_region($region, $build) {
|
||||
if ($this->is_editable_region($region) &&
|
||||
(!empty($build) ||
|
||||
variable_get('context_reaction_block_all_regions', FALSE) ||
|
||||
context_isset('context_ui', 'context_ui_editor_present'))
|
||||
) {
|
||||
global $theme;
|
||||
$regions = system_region_list($theme);
|
||||
$name = isset($regions[$region]) ? $regions[$region] : $region;
|
||||
// The negative weight + sorted will push our region marker to the top of the region
|
||||
$build['context'] = array(
|
||||
'#prefix' => "<div class='context-block-region' id='context-block-region-{$region}'>",
|
||||
'#markup' => "<span class='region-name'>{$name}</span>" .
|
||||
"<a class='context-ui-add-link'>" . t('Add a block here.') . '</a>',
|
||||
'#suffix' => '</div>',
|
||||
'#weight' => -100,
|
||||
);
|
||||
$build['#sorted'] = FALSE;
|
||||
}
|
||||
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a renderable array of a region containing all enabled blocks.
|
||||
*/
|
||||
function block_get_blocks_by_region($region) {
|
||||
module_load_include('module', 'block', 'block');
|
||||
|
||||
$build = array();
|
||||
if ($list = $this->block_list($region)) {
|
||||
$build = _block_get_renderable_array($list);
|
||||
}
|
||||
if ($this->is_editable_region($region)) {
|
||||
$build = $this->editable_region($region, $build);
|
||||
}
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* An alternative version of block_list() that provides any context enabled blocks.
|
||||
*/
|
||||
function block_list($region) {
|
||||
module_load_include('module', 'block', 'block');
|
||||
|
||||
$context_blocks = &drupal_static('context_reaction_block_list');;
|
||||
$contexts = context_active_contexts();
|
||||
if (!isset($context_blocks)) {
|
||||
$info = $this->get_blocks();
|
||||
$context_blocks = array();
|
||||
foreach ($contexts as $context) {
|
||||
$options = $this->fetch_from_context($context);
|
||||
if (!empty($options['blocks'])) {
|
||||
foreach ($options['blocks'] as $context_block) {
|
||||
$bid = "{$context_block['module']}-{$context_block['delta']}";
|
||||
if (isset($info[$bid])) {
|
||||
$block = (object) array_merge((array) $info[$bid], $context_block);
|
||||
$block->context = $context->name;
|
||||
$block->title = isset($info[$block->bid]->title) ? $info[$block->bid]->title : NULL;
|
||||
$block->cache = isset($info[$block->bid]->cache) ? $info[$block->bid]->cache : DRUPAL_NO_CACHE;
|
||||
$context_blocks[$block->region][$block->bid] = $block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->is_editable_check($context_blocks);
|
||||
foreach ($context_blocks as $r => $blocks) {
|
||||
$context_blocks[$r] = _block_render_blocks($blocks);
|
||||
|
||||
// Make blocks editable if allowed.
|
||||
if ($this->is_editable_region($r)) {
|
||||
foreach ($context_blocks[$r] as $key => $block) {
|
||||
$context_blocks[$r][$key] = $this->editable_block($block);
|
||||
}
|
||||
}
|
||||
|
||||
// Sort blocks.
|
||||
uasort($context_blocks[$r], array('context_reaction_block', 'block_sort'));
|
||||
}
|
||||
}
|
||||
return isset($context_blocks[$region]) ? $context_blocks[$region] : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if there is an active context editor block, and set a flag. We will set a flag so
|
||||
* that we can make sure that blocks with empty content have some default content. This is
|
||||
* needed so the save of the context inline editor does not remove the blocks with no content.
|
||||
*/
|
||||
function is_editable_check($context_blocks) {
|
||||
foreach ($context_blocks as $r => $blocks) {
|
||||
if (isset($blocks['context_ui-editor'])) {
|
||||
$block = $blocks['context_ui-editor'];
|
||||
// see if the editor is actually enabled, lifted from _block_render_blocks
|
||||
if (!count(module_implements('node_grants')) && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD') && ($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);
|
||||
drupal_alter(array('block_view', "block_view_{$block->module}_{$block->delta}"), $array, $block);
|
||||
}
|
||||
if(!empty($array['content'])) {
|
||||
context_set('context_ui', 'context_ui_editor_present', TRUE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the safe weight range for a block being added to a region such that
|
||||
* there are enough potential unique weights to support all blocks.
|
||||
*/
|
||||
protected function max_block_weight() {
|
||||
$blocks = $this->get_blocks();
|
||||
$block_count = 0;
|
||||
foreach ($blocks as $region => $block_list) {
|
||||
$block_count += count($block_list);
|
||||
}
|
||||
// Add 2 to make sure there's space at either end of the block list
|
||||
return round(($block_count + 2) / 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check or set whether a rebuild of the block info cache is needed.
|
||||
*/
|
||||
function rebuild_needed($set = NULL) {
|
||||
if (isset($set) && $set != variable_get('context_block_rebuild_needed', FALSE)) {
|
||||
variable_set('context_block_rebuild_needed', $set);
|
||||
}
|
||||
return (bool) variable_get('context_block_rebuild_needed', FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 get_blocks($region = NULL, $context = NULL, $reset = FALSE) {
|
||||
static $block_info;
|
||||
$theme_key = variable_get('theme_default', 'garland');
|
||||
|
||||
if (!isset($block_info) || $reset) {
|
||||
$block_info = array();
|
||||
if (!$reset) {
|
||||
$block_info = context_cache_get('block_info');
|
||||
}
|
||||
if (empty($block_info)) {
|
||||
if (module_exists('block')) {
|
||||
$block_blocks = _block_rehash($theme_key);
|
||||
$block_info = array();
|
||||
// Change from numeric keys to module-delta.
|
||||
foreach ($block_blocks as $block) {
|
||||
$block = (object) $block;
|
||||
unset($block->theme, $block->status, $block->weight, $block->region, $block->custom, $block->visibility, $block->pages);
|
||||
$block->bid = "{$block->module}-{$block->delta}";
|
||||
$block_info[$block->bid] = $block;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$block_info = array();
|
||||
foreach (module_implements('block_info') as $module) {
|
||||
$module_blocks = module_invoke($module, 'block_info');
|
||||
if (!empty($module_blocks)) {
|
||||
foreach ($module_blocks as $delta => $block) {
|
||||
$block = (object) $block;
|
||||
$block->module = $module;
|
||||
$block->delta = $delta;
|
||||
$block->bid = "{$block->module}-{$block->delta}";
|
||||
$block_info[$block->bid] = $block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
context_cache_set('block_info', $block_info);
|
||||
}
|
||||
// Allow other modules that may declare blocks dynamically to alter
|
||||
// this list.
|
||||
drupal_alter('context_block_info', $block_info);
|
||||
|
||||
// Gather only region info from the database.
|
||||
if (module_exists('block')) {
|
||||
$result = db_select('block')
|
||||
->fields('block')
|
||||
->condition('theme', $theme_key)
|
||||
->execute();
|
||||
foreach ($result as $row) {
|
||||
if (isset($block_info["{$row->module}-{$row->delta}"])) {
|
||||
$block_info["{$row->module}-{$row->delta}"] = (object) array_merge((array) $row, (array) $block_info["{$row->module}-{$row->delta}"]);
|
||||
unset($block_info["{$row->module}-{$row->delta}"]->status);
|
||||
unset($block_info["{$row->module}-{$row->delta}"]->visibility);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$blocks = array();
|
||||
|
||||
// No region specified, provide all blocks.
|
||||
if (!isset($region)) {
|
||||
$blocks = $block_info;
|
||||
}
|
||||
// Region specified.
|
||||
else {
|
||||
foreach ($block_info as $bid => $block) {
|
||||
if (isset($block->region) && $block->region == $region) {
|
||||
$blocks[$bid] = $block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add context blocks if provided.
|
||||
if (is_object($context) && $options = $this->fetch_from_context($context)) {
|
||||
if (!empty($options['blocks'])) {
|
||||
foreach ($options['blocks'] as $block) {
|
||||
if (
|
||||
isset($block_info["{$block['module']}-{$block['delta']}"]) && // Block is valid.
|
||||
(!isset($region) || (!empty($region) && $block['region'] == $region)) // No region specified or regions match.
|
||||
) {
|
||||
$context_block = $block_info["{$block['module']}-{$block['delta']}"];
|
||||
$context_block->weight = $block['weight'];
|
||||
$context_block->region = $block['region'];
|
||||
$context_block->context = !empty($context->name) ? $context->name : 'tempname';
|
||||
$blocks[$context_block->bid] = $context_block;
|
||||
}
|
||||
}
|
||||
}
|
||||
uasort($blocks, array('context_reaction_block', 'block_sort'));
|
||||
}
|
||||
return $blocks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort callback.
|
||||
*/
|
||||
static function block_sort($a, $b) {
|
||||
return ($a->weight - $b->weight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compatibility wrapper around json_decode().
|
||||
*/
|
||||
protected function json_decode($json, $assoc = FALSE) {
|
||||
// Requires PHP 5.2.
|
||||
if (function_exists('json_decode')) {
|
||||
return json_decode($json, $assoc);
|
||||
}
|
||||
return context_reaction_block::_json_decode($json);
|
||||
}
|
||||
|
||||
/**
|
||||
* From http://www.php.net/manual/en/function.json-decode.php#91216
|
||||
* with modifications for consistency with output of json_decode().
|
||||
*
|
||||
* Original author: walidator.info 2009.
|
||||
*/
|
||||
static function _json_decode($json) {
|
||||
$comment = FALSE;
|
||||
$out = '$x = ';
|
||||
for ($i=0; $i < strlen($json); $i++) {
|
||||
if (!$comment) {
|
||||
switch ($json[$i]) {
|
||||
case '{':
|
||||
$out .= ' (object) array(';
|
||||
break;
|
||||
case '}':
|
||||
$out .= ')';
|
||||
break;
|
||||
case '[':
|
||||
$out .= ' array(';
|
||||
break;
|
||||
case ']':
|
||||
$out .= ')';
|
||||
break;
|
||||
case ':';
|
||||
$out .= '=>';
|
||||
break;
|
||||
default:
|
||||
$out .= $json[$i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$out .= $json[$i];
|
||||
}
|
||||
if ($json[$i] == '"') {
|
||||
$comment = !$comment;
|
||||
}
|
||||
}
|
||||
eval($out . ';');
|
||||
return $x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Block renderer for AJAX requests. Triggered when $_GET['context_block']
|
||||
* is set. See ->execute() for how this is called.
|
||||
*/
|
||||
function render_ajax($param) {
|
||||
// Besure the page isn't a 404 or 403.
|
||||
$headers = drupal_get_http_header();
|
||||
if (array_key_exists('status', $headers) && ($headers['status'] == "404 Not Found" || $headers['status'] == "403 Forbidden")) {
|
||||
return;
|
||||
}
|
||||
// Set the header right away. This will inform any players in the stack
|
||||
// that we are in the middle of responding to an AJAX request.
|
||||
drupal_add_http_header('Content-Type', 'text/javascript; charset=utf-8');
|
||||
|
||||
if (strpos($param, ',') !== FALSE) {
|
||||
list($bid, $context) = explode(',', $param);
|
||||
list($module, $delta) = explode('-', $bid, 2);
|
||||
// Check token to make sure user has access to block.
|
||||
if (empty($_GET['context_token']) || $_GET['context_token'] != drupal_get_token($bid)) {
|
||||
echo drupal_json_encode(array('status' => 0));
|
||||
exit;
|
||||
}
|
||||
|
||||
// Ensure $bid is valid.
|
||||
$info = $this->get_blocks();
|
||||
if (isset($info[$bid])) {
|
||||
module_load_include('module', 'block', 'block');
|
||||
$block = $info[$bid];
|
||||
$block->title = isset($block->title) ? $block->title : '';
|
||||
$block->context = $context;
|
||||
$block->region = '';
|
||||
$rendered_blocks = _block_render_blocks(array($block)); // For E_STRICT warning
|
||||
$block = array_shift($rendered_blocks);
|
||||
if (empty($block->content['#markup'])) {
|
||||
$block->content['#markup'] = "<div class='context-block-empty'>" . t('This block appears empty when displayed on this page.') . "</div>";
|
||||
}
|
||||
$block = $this->editable_block($block);
|
||||
$renderable_block = _block_get_renderable_array(array($block)); // For E_STRICT warning
|
||||
echo drupal_json_encode(array(
|
||||
'status' => 1,
|
||||
'block' => drupal_render($renderable_block),
|
||||
));
|
||||
drupal_exit();
|
||||
}
|
||||
}
|
||||
echo drupal_json_encode(array('status' => 0));
|
||||
drupal_exit();
|
||||
}
|
||||
}
|
@@ -0,0 +1,501 @@
|
||||
(function($){
|
||||
Drupal.behaviors.contextReactionBlock = {attach: function(context) {
|
||||
$('form.context-editor:not(.context-block-processed)')
|
||||
.addClass('context-block-processed')
|
||||
.each(function() {
|
||||
var id = $(this).attr('id');
|
||||
Drupal.contextBlockEditor = Drupal.contextBlockEditor || {};
|
||||
$(this).bind('init.pageEditor', function(event) {
|
||||
Drupal.contextBlockEditor[id] = new DrupalContextBlockEditor($(this));
|
||||
});
|
||||
$(this).bind('start.pageEditor', function(event, context) {
|
||||
// Fallback to first context if param is empty.
|
||||
if (!context) {
|
||||
context = $(this).data('defaultContext');
|
||||
}
|
||||
Drupal.contextBlockEditor[id].editStart($(this), context);
|
||||
});
|
||||
$(this).bind('end.pageEditor', function(event) {
|
||||
Drupal.contextBlockEditor[id].editFinish();
|
||||
});
|
||||
});
|
||||
|
||||
//
|
||||
// Admin Form =======================================================
|
||||
//
|
||||
// ContextBlockForm: Init.
|
||||
$('#context-blockform:not(.processed)').each(function() {
|
||||
$(this).addClass('processed');
|
||||
Drupal.contextBlockForm = new DrupalContextBlockForm($(this));
|
||||
Drupal.contextBlockForm.setState();
|
||||
});
|
||||
|
||||
// ContextBlockForm: Attach block removal handlers.
|
||||
// Lives in behaviors as it may be required for attachment to new DOM elements.
|
||||
$('#context-blockform a.remove:not(.processed)').each(function() {
|
||||
$(this).addClass('processed');
|
||||
$(this).click(function() {
|
||||
$(this).parents('tr').eq(0).remove();
|
||||
Drupal.contextBlockForm.setState();
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
// Conceal Section title, subtitle and class
|
||||
$('div.context-block-browser', context).nextAll('.form-item').hide();
|
||||
}};
|
||||
|
||||
/**
|
||||
* Context block form. Default form for editing context block reactions.
|
||||
*/
|
||||
DrupalContextBlockForm = function(blockForm) {
|
||||
this.state = {};
|
||||
|
||||
this.setState = function() {
|
||||
$('table.context-blockform-region', blockForm).each(function() {
|
||||
var region = $(this).attr('id').split('context-blockform-region-')[1];
|
||||
var blocks = [];
|
||||
$('tr', $(this)).each(function() {
|
||||
var bid = $(this).attr('id');
|
||||
var weight = $(this).find('select,input').first().val();
|
||||
blocks.push({'bid' : bid, 'weight' : weight});
|
||||
});
|
||||
Drupal.contextBlockForm.state[region] = blocks;
|
||||
});
|
||||
|
||||
// Serialize here and set form element value.
|
||||
$('form input.context-blockform-state').val(JSON.stringify(this.state));
|
||||
|
||||
// Hide enabled blocks from selector that are used
|
||||
$('table.context-blockform-region tr').each(function() {
|
||||
var bid = $(this).attr('id');
|
||||
$('div.context-blockform-selector input[value='+bid+']').parents('div.form-item').eq(0).hide();
|
||||
});
|
||||
// Show blocks in selector that are unused
|
||||
$('div.context-blockform-selector input').each(function() {
|
||||
var bid = $(this).val();
|
||||
if ($('table.context-blockform-region tr#'+bid).size() === 0) {
|
||||
$(this).parents('div.form-item').eq(0).show();
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
// make sure we update the state right before submits, this takes care of an
|
||||
// apparent race condition between saving the state and the weights getting set
|
||||
// by tabledrag
|
||||
$('#ctools-export-ui-edit-item-form').submit(function() { Drupal.contextBlockForm.setState(); });
|
||||
|
||||
// Tabledrag
|
||||
// Add additional handlers to update our blocks.
|
||||
$.each(Drupal.settings.tableDrag, function(base) {
|
||||
var table = $('#' + base + ':not(.processed)', blockForm);
|
||||
if (table && table.is('.context-blockform-region')) {
|
||||
table.addClass('processed');
|
||||
table.bind('mouseup', function(event) {
|
||||
Drupal.contextBlockForm.setState();
|
||||
return;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Add blocks to a region
|
||||
$('td.blocks a', blockForm).each(function() {
|
||||
$(this).click(function() {
|
||||
var region = $(this).attr('href').split('#')[1];
|
||||
var base = "context-blockform-region-"+ region;
|
||||
var selected = $("div.context-blockform-selector input:checked");
|
||||
if (selected.size() > 0) {
|
||||
var weight_warn = false;
|
||||
var min_weight_option = -10;
|
||||
var max_weight_option = 10;
|
||||
var max_observed_weight = min_weight_option - 1;
|
||||
$('table#' + base + ' tr').each(function() {
|
||||
var weight_input_val = $(this).find('select,input').first().val();
|
||||
if (+weight_input_val > +max_observed_weight) {
|
||||
max_observed_weight = weight_input_val;
|
||||
}
|
||||
});
|
||||
|
||||
selected.each(function() {
|
||||
// create new block markup
|
||||
var block = document.createElement('tr');
|
||||
var text = $(this).parents('div.form-item').eq(0).hide().children('label').text();
|
||||
var select = '<div class="form-item form-type-select"><select class="tabledrag-hide form-select">';
|
||||
var i;
|
||||
weight_warn = true;
|
||||
var selected_weight = max_weight_option;
|
||||
if (max_weight_option >= (1 + +max_observed_weight)) {
|
||||
selected_weight = ++max_observed_weight;
|
||||
weight_warn = false;
|
||||
}
|
||||
|
||||
for (i = min_weight_option; i <= max_weight_option; ++i) {
|
||||
select += '<option';
|
||||
if (i == selected_weight) {
|
||||
select += ' selected=selected';
|
||||
}
|
||||
select += '>' + i + '</option>';
|
||||
}
|
||||
select += '</select></div>';
|
||||
$(block).attr('id', $(this).attr('value')).addClass('draggable');
|
||||
$(block).html("<td>"+ text + "</td><td>" + select + "</td><td><a href='' class='remove'>X</a></td>");
|
||||
|
||||
// add block item to region
|
||||
//TODO : Fix it so long blocks don't get stuck when added to top regions and dragged towards bottom regions
|
||||
Drupal.tableDrag[base].makeDraggable(block);
|
||||
$('table#'+base).append(block);
|
||||
if ($.cookie('Drupal.tableDrag.showWeight') == 1) {
|
||||
$('table#'+base).find('.tabledrag-hide').css('display', '');
|
||||
$('table#'+base).find('.tabledrag-handle').css('display', 'none');
|
||||
}
|
||||
else {
|
||||
$('table#'+base).find('.tabledrag-hide').css('display', 'none');
|
||||
$('table#'+base).find('.tabledrag-handle').css('display', '');
|
||||
}
|
||||
Drupal.attachBehaviors($('table#'+base));
|
||||
|
||||
Drupal.contextBlockForm.setState();
|
||||
$(this).removeAttr('checked');
|
||||
});
|
||||
if (weight_warn) {
|
||||
alert(Drupal.t('Desired block weight exceeds available weight options, please check weights for blocks before saving'));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Context block editor. AHAH editor for live block reaction editing.
|
||||
*/
|
||||
DrupalContextBlockEditor = function(editor) {
|
||||
this.editor = editor;
|
||||
this.state = {};
|
||||
this.blocks = {};
|
||||
this.regions = {};
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
DrupalContextBlockEditor.prototype = {
|
||||
initBlocks : function(blocks) {
|
||||
var self = this;
|
||||
this.blocks = blocks;
|
||||
blocks.each(function() {
|
||||
if($(this).hasClass('context-block-empty')) {
|
||||
$(this).removeClass('context-block-hidden');
|
||||
}
|
||||
$(this).addClass('draggable');
|
||||
$(this).prepend($('<a class="context-block-handle"></a>'));
|
||||
$(this).prepend($('<a class="context-block-remove"></a>').click(function() {
|
||||
$(this).parent ('.block').eq(0).fadeOut('medium', function() {
|
||||
$(this).remove();
|
||||
self.updateBlocks();
|
||||
});
|
||||
return false;
|
||||
}));
|
||||
});
|
||||
},
|
||||
initRegions : function(regions) {
|
||||
this.regions = regions;
|
||||
var ref = this;
|
||||
|
||||
$(regions).not('.context-ui-processed')
|
||||
.each(function(index, el) {
|
||||
$('.context-ui-add-link', el).click(function(e){
|
||||
ref.showBlockBrowser($(this).parent());
|
||||
}).addClass('context-ui-processed');
|
||||
});
|
||||
$('.context-block-browser').hide();
|
||||
},
|
||||
showBlockBrowser : function(region) {
|
||||
var toggled = false;
|
||||
//figure out the id of the context
|
||||
var activeId = $('.context-editing', this.editor).attr('id').replace('-trigger', ''),
|
||||
context = $('#' + activeId)[0];
|
||||
|
||||
this.browser = $('.context-block-browser', context).addClass('active');
|
||||
|
||||
//add the filter element to the block browser
|
||||
if (!this.browser.has('input.filter').size()) {
|
||||
var parent = $('.block-browser-sidebar .filter', this.browser);
|
||||
var list = $('.blocks', this.browser);
|
||||
new Drupal.Filter (list, false, '.context-block-addable', parent);
|
||||
}
|
||||
//show a dialog for the blocks list
|
||||
this.browser.show().dialog({
|
||||
modal : true,
|
||||
close : function() {
|
||||
$(this).dialog('destroy');
|
||||
//reshow all the categories
|
||||
$('.category', this).show();
|
||||
$(this).hide().appendTo(context).removeClass('active');
|
||||
},
|
||||
height: (.8 * $(window).height()),
|
||||
minHeight:400,
|
||||
minWidth:680,
|
||||
width:680
|
||||
});
|
||||
|
||||
//handle showing / hiding block items when a different category is selected
|
||||
$('.context-block-browser-categories', this.browser).change(function(e) {
|
||||
//if no category is selected we want to show all the items
|
||||
if ($(this).val() == 0) {
|
||||
$('.category', self.browser).show();
|
||||
} else {
|
||||
$('.category', self.browser).hide();
|
||||
$('.category-' + $(this).val(), self.browser).show();
|
||||
}
|
||||
});
|
||||
|
||||
//if we already have the function for a different context, rebind it so we don't get dupes
|
||||
if(this.addToRegion) {
|
||||
$('.context-block-addable', this.browser).unbind('click.addToRegion')
|
||||
}
|
||||
|
||||
//protected function for adding a clicked block to a region
|
||||
var self = this;
|
||||
this.addToRegion = function(e){
|
||||
var ui = {
|
||||
'item' : $(this).clone(),
|
||||
'sender' : $(region)
|
||||
};
|
||||
$(this).parents('.context-block-browser.active').dialog('close');
|
||||
$(region).after(ui.item);
|
||||
self.addBlock(e, ui, this.editor, activeId.replace('context-editable-', ''));
|
||||
};
|
||||
|
||||
$('.context-block-addable', this.browser).bind('click.addToRegion', this.addToRegion);
|
||||
},
|
||||
// Update UI to match the current block states.
|
||||
updateBlocks : function() {
|
||||
var browser = $('div.context-block-browser');
|
||||
|
||||
// For all enabled blocks, mark corresponding addables as having been added.
|
||||
$('.block, .admin-block').each(function() {
|
||||
var bid = $(this).attr('id').split('block-')[1]; // Ugh.
|
||||
});
|
||||
// For all hidden addables with no corresponding blocks, mark as addable.
|
||||
$('.context-block-item', browser).each(function() {
|
||||
var bid = $(this).attr('id').split('context-block-addable-')[1];
|
||||
});
|
||||
|
||||
// Mark empty regions.
|
||||
$(this.regions).each(function() {
|
||||
if ($('.block:has(a.context-block)', this).size() > 0) {
|
||||
$(this).removeClass('context-block-region-empty');
|
||||
}
|
||||
else {
|
||||
$(this).addClass('context-block-region-empty');
|
||||
}
|
||||
});
|
||||
},
|
||||
// Live update a region
|
||||
updateRegion : function(event, ui, region, op) {
|
||||
switch (op) {
|
||||
case 'over':
|
||||
$(region).removeClass('context-block-region-empty');
|
||||
break;
|
||||
case 'out':
|
||||
if (
|
||||
// jQuery UI 1.8
|
||||
$('.draggable-placeholder', region).size() === 1 &&
|
||||
$('.block:has(a.context-block)', region).size() == 0
|
||||
) {
|
||||
$(region).addClass('context-block-region-empty');
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
// Remove script elements while dragging & dropping.
|
||||
scriptFix : function(event, ui, editor, context) {
|
||||
if ($('script', ui.item)) {
|
||||
var placeholder = $(Drupal.settings.contextBlockEditor.scriptPlaceholder);
|
||||
var label = $('div.handle label', ui.item).text();
|
||||
placeholder.children('strong').html(label);
|
||||
$('script', ui.item).parent().empty().append(placeholder);
|
||||
}
|
||||
},
|
||||
// Add a block to a region through an AJAX load of the block contents.
|
||||
addBlock : function(event, ui, editor, context) {
|
||||
var self = this;
|
||||
if (ui.item.is('.context-block-addable')) {
|
||||
var bid = ui.item.attr('id').split('context-block-addable-')[1];
|
||||
|
||||
// Construct query params for our AJAX block request.
|
||||
var params = Drupal.settings.contextBlockEditor.params;
|
||||
params.context_block = bid + ',' + context;
|
||||
if (!Drupal.settings.contextBlockEditor.block_tokens || !Drupal.settings.contextBlockEditor.block_tokens[bid]) {
|
||||
alert(Drupal.t('An error occurred trying to retrieve block content. Please contact a site administer.'));
|
||||
return;
|
||||
}
|
||||
params.context_token = Drupal.settings.contextBlockEditor.block_tokens[bid];
|
||||
|
||||
// Replace item with loading block.
|
||||
//ui.sender.append(ui.item);
|
||||
|
||||
var blockLoading = $('<div class="context-block-item context-block-loading"><span class="icon"></span></div>');
|
||||
ui.item.addClass('context-block-added');
|
||||
ui.item.after(blockLoading);
|
||||
|
||||
|
||||
$.getJSON(Drupal.settings.contextBlockEditor.path, params, function(data) {
|
||||
if (data.status) {
|
||||
var newBlock = $(data.block);
|
||||
if ($('script', newBlock)) {
|
||||
$('script', newBlock).remove();
|
||||
}
|
||||
blockLoading.fadeOut(function() {
|
||||
$(this).replaceWith(newBlock);
|
||||
self.initBlocks(newBlock);
|
||||
self.updateBlocks();
|
||||
Drupal.attachBehaviors(newBlock);
|
||||
});
|
||||
}
|
||||
else {
|
||||
blockLoading.fadeOut(function() { $(this).remove(); });
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (ui.item.is(':has(a.context-block)')) {
|
||||
self.updateBlocks();
|
||||
}
|
||||
},
|
||||
// Update form hidden field with JSON representation of current block visibility states.
|
||||
setState : function() {
|
||||
var self = this;
|
||||
|
||||
$(this.regions).each(function() {
|
||||
var region = $('.context-block-region', this).attr('id').split('context-block-region-')[1];
|
||||
var blocks = [];
|
||||
$('a.context-block', $(this)).each(function() {
|
||||
if ($(this).attr('class').indexOf('edit-') != -1) {
|
||||
var bid = $(this).attr('id').split('context-block-')[1];
|
||||
var context = $(this).attr('class').split('edit-')[1].split(' ')[0];
|
||||
context = context ? context : 0;
|
||||
var block = {'bid': bid, 'context': context};
|
||||
blocks.push(block);
|
||||
}
|
||||
});
|
||||
self.state[region] = blocks;
|
||||
});
|
||||
// Serialize here and set form element value.
|
||||
$('input.context-block-editor-state', this.editor).val(JSON.stringify(this.state));
|
||||
},
|
||||
//Disable text selection.
|
||||
disableTextSelect : function() {
|
||||
if ($.browser.safari) {
|
||||
$('.block:has(a.context-block):not(:has(input,textarea))').css('WebkitUserSelect','none');
|
||||
}
|
||||
else if ($.browser.mozilla) {
|
||||
$('.block:has(a.context-block):not(:has(input,textarea))').css('MozUserSelect','none');
|
||||
}
|
||||
else if ($.browser.msie) {
|
||||
$('.block:has(a.context-block):not(:has(input,textarea))').bind('selectstart.contextBlockEditor', function() { return false; });
|
||||
}
|
||||
else {
|
||||
$(this).bind('mousedown.contextBlockEditor', function() { return false; });
|
||||
}
|
||||
},
|
||||
//Enable text selection.
|
||||
enableTextSelect : function() {
|
||||
if ($.browser.safari) {
|
||||
$('*').css('WebkitUserSelect','');
|
||||
}
|
||||
else if ($.browser.mozilla) {
|
||||
$('*').css('MozUserSelect','');
|
||||
}
|
||||
else if ($.browser.msie) {
|
||||
$('*').unbind('selectstart.contextBlockEditor');
|
||||
}
|
||||
else {
|
||||
$(this).unbind('mousedown.contextBlockEditor');
|
||||
}
|
||||
},
|
||||
// Start editing. Attach handlers, begin draggable/sortables.
|
||||
editStart : function(editor, context) {
|
||||
var self = this;
|
||||
// This is redundant to the start handler found in context_ui.js.
|
||||
// However it's necessary that we trigger this class addition before
|
||||
// we call .sortable() as the empty regions need to be visible.
|
||||
$(document.body).addClass('context-editing');
|
||||
this.editor.addClass('context-editing');
|
||||
this.disableTextSelect();
|
||||
this.initBlocks($('.block:has(a.context-block.edit-'+context+')'));
|
||||
this.initRegions($('.context-block-region').parent());
|
||||
this.updateBlocks();
|
||||
|
||||
$('a.context_ui_dialog-stop').hide();
|
||||
|
||||
$('.editing-context-label').remove();
|
||||
var label = $('#context-editable-trigger-'+context+' .label').text();
|
||||
label = Drupal.t('Now Editing: ') + label;
|
||||
editor.parent().parent()
|
||||
.prepend('<div class="editing-context-label">'+ label + '</div>');
|
||||
|
||||
// First pass, enable sortables on all regions.
|
||||
$(this.regions).each(function() {
|
||||
var region = $(this);
|
||||
var params = {
|
||||
revert: true,
|
||||
dropOnEmpty: true,
|
||||
placeholder: 'draggable-placeholder',
|
||||
forcePlaceholderSize: true,
|
||||
items: '> .block:has(a.context-block.editable)',
|
||||
handle: 'a.context-block-handle',
|
||||
start: function(event, ui) { self.scriptFix(event, ui, editor, context); },
|
||||
stop: function(event, ui) { self.addBlock(event, ui, editor, context); },
|
||||
receive: function(event, ui) { self.addBlock(event, ui, editor, context); },
|
||||
over: function(event, ui) { self.updateRegion(event, ui, region, 'over'); },
|
||||
out: function(event, ui) { self.updateRegion(event, ui, region, 'out'); },
|
||||
cursorAt: {left: 300, top: 0}
|
||||
};
|
||||
region.sortable(params);
|
||||
});
|
||||
|
||||
// Second pass, hook up all regions via connectWith to each other.
|
||||
$(this.regions).each(function() {
|
||||
$(this).sortable('option', 'connectWith', ['.ui-sortable']);
|
||||
});
|
||||
|
||||
// Terrible, terrible workaround for parentoffset issue in Safari.
|
||||
// The proper fix for this issue has been committed to jQuery UI, but was
|
||||
// not included in the 1.6 release. Therefore, we do a browser agent hack
|
||||
// to ensure that Safari users are covered by the offset fix found here:
|
||||
// http://dev.jqueryui.com/changeset/2073.
|
||||
if ($.ui.version === '1.6' && $.browser.safari) {
|
||||
$.browser.mozilla = true;
|
||||
}
|
||||
},
|
||||
// Finish editing. Remove handlers.
|
||||
editFinish : function() {
|
||||
this.editor.removeClass('context-editing');
|
||||
this.enableTextSelect();
|
||||
|
||||
$('.editing-context-label').remove();
|
||||
|
||||
// Remove UI elements.
|
||||
$(this.blocks).each(function() {
|
||||
$('a.context-block-handle, a.context-block-remove', this).remove();
|
||||
if($(this).hasClass('context-block-empty')) {
|
||||
$(this).addClass('context-block-hidden');
|
||||
}
|
||||
$(this).removeClass('draggable');
|
||||
});
|
||||
|
||||
$('a.context_ui_dialog-stop').show();
|
||||
|
||||
this.regions.sortable('destroy');
|
||||
|
||||
this.setState();
|
||||
|
||||
// Unhack the user agent.
|
||||
if ($.ui.version === '1.6' && $.browser.safari) {
|
||||
$.browser.mozilla = false;
|
||||
}
|
||||
}
|
||||
}; //End of DrupalContextBlockEditor prototype
|
||||
|
||||
})(jQuery);
|
Binary file not shown.
After Width: | Height: | Size: 2.6 KiB |
@@ -0,0 +1,256 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="80"
|
||||
height="120"
|
||||
id="svg2"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.46"
|
||||
version="1.0"
|
||||
sodipodi:docname="context_reaction_block.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
inkscape:export-filename="/home/devseed/kitrium/profiles/openatrium/modules/contrib/context/plugins/context_reaction_block.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient3186">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:0.1254902"
|
||||
offset="0"
|
||||
id="stop3188" />
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop3190" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient3191">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3193" />
|
||||
<stop
|
||||
style="stop-color:#c0c0c0;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3195" />
|
||||
</linearGradient>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||
id="perspective10" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3191"
|
||||
id="linearGradient3197"
|
||||
x1="10"
|
||||
y1="10"
|
||||
x2="10"
|
||||
y2="30"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3191"
|
||||
id="linearGradient3199"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="10"
|
||||
y1="10"
|
||||
x2="10"
|
||||
y2="30" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3191"
|
||||
id="linearGradient3176"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="18"
|
||||
y1="81"
|
||||
x2="18"
|
||||
y2="99" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3186"
|
||||
id="linearGradient3192"
|
||||
x1="2"
|
||||
y1="92.5"
|
||||
x2="10"
|
||||
y2="92.5"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3191"
|
||||
id="linearGradient3255"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="18"
|
||||
y1="81"
|
||||
x2="18"
|
||||
y2="99" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3191"
|
||||
id="linearGradient3260"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="18"
|
||||
y1="81"
|
||||
x2="18"
|
||||
y2="99" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3191"
|
||||
id="linearGradient3265"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="18"
|
||||
y1="81"
|
||||
x2="18"
|
||||
y2="99" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3191"
|
||||
id="linearGradient3276"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="18"
|
||||
y1="81"
|
||||
x2="18"
|
||||
y2="99" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3191"
|
||||
id="linearGradient3284"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="18"
|
||||
y1="81"
|
||||
x2="18"
|
||||
y2="99" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
gridtolerance="10000"
|
||||
guidetolerance="10"
|
||||
objecttolerance="10"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="31.144684"
|
||||
inkscape:cy="24.681366"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid2383"
|
||||
visible="true"
|
||||
enabled="true" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<path
|
||||
sodipodi:nodetypes="ccccsccccccccccssccsccc"
|
||||
id="path3287"
|
||||
d="M 30,84.5 C 27.8265,84.5 25.87799,85.506572 24.59375,87.0625 L 24.59375,87.09375 L 26,88.5 C 26.912944,87.291403 28.369734,86.5 30,86.5 C 32.044638,86.5 33.787894,87.740652 34.5625,89.5 L 31.5,89.5 L 35.5,93.5 L 39.5,89.5 L 39,89.5 L 36.6875,89.5 C 35.825628,86.615704 33.164199,84.5 30,84.5 z M 24.5,89.5 L 20.5,93.5 L 23.3125,93.5 C 24.174372,96.384296 26.835801,98.5 30,98.5 C 32.1735,98.5 34.12201,97.493428 35.40625,95.9375 C 35.411546,95.931083 35.400976,95.912686 35.40625,95.90625 L 34,94.5 C 33.087056,95.708597 31.630266,96.5 30,96.5 C 27.955362,96.5 26.212106,95.259348 25.4375,93.5 L 28.5,93.5 L 24.5,89.5 z"
|
||||
style="opacity:1;fill:#000000;fill-opacity:0.50196078000000000;fill-rule:nonzero;stroke:none;stroke-width:1.25000000000000000;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;color:#000000" />
|
||||
<rect
|
||||
style="opacity:1;fill:#404040;fill-opacity:0.75294118;fill-rule:nonzero;stroke:none;stroke-width:1.25;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2385"
|
||||
width="80"
|
||||
height="40"
|
||||
x="0"
|
||||
y="0"
|
||||
rx="10"
|
||||
ry="10" />
|
||||
<path
|
||||
id="path3183"
|
||||
d="M 20,12.5 L 17,15.5 L 19,15.5 L 19,20.5 L 14,20.5 L 14,18.5 L 11,21.5 L 14,24.5 L 14,22.5 L 19,22.5 L 19,27.5 L 17,27.5 L 20,30.5 L 23,27.5 L 21,27.5 L 21,22.5 L 26,22.5 L 26,24.5 L 29,21.5 L 26,18.5 L 26,20.5 L 21,20.5 L 21,15.5 L 23,15.5 L 20,12.5 z"
|
||||
style="opacity:1;fill:#000000;fill-opacity:0.50196078;fill-rule:nonzero;stroke:none;stroke-width:1.25;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
<path
|
||||
style="opacity:1;fill:url(#linearGradient3199);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.25;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M 20,11 L 17,14 L 19,14 L 19,19 L 14,19 L 14,17 L 11,20 L 14,23 L 14,21 L 19,21 L 19,26 L 17,26 L 20,29 L 23,26 L 21,26 L 21,21 L 26,21 L 26,23 L 29,20 L 26,17 L 26,19 L 21,19 L 21,14 L 23,14 L 20,11 z"
|
||||
id="path3161" />
|
||||
<path
|
||||
id="path3185"
|
||||
d="M 55.5,15.21875 C 55.372191,15.21875 55.254184,15.245816 55.15625,15.34375 L 53.84375,16.65625 C 53.647881,16.852119 53.647881,17.147881 53.84375,17.34375 L 58,21.5 L 53.84375,25.65625 C 53.647883,25.852118 53.647881,26.147881 53.84375,26.34375 L 55.15625,27.65625 C 55.352118,27.852119 55.647881,27.852119 55.84375,27.65625 L 60,23.5 L 64.15625,27.65625 C 64.352119,27.852119 64.64788,27.852119 64.84375,27.65625 L 66.15625,26.34375 C 66.352119,26.147881 66.352117,25.852118 66.15625,25.65625 L 62,21.5 L 66.15625,17.34375 C 66.352119,17.147882 66.352119,16.852119 66.15625,16.65625 L 64.84375,15.34375 C 64.64788,15.147881 64.352119,15.147881 64.15625,15.34375 L 60,19.5 L 55.84375,15.34375 C 55.745816,15.245816 55.627809,15.21875 55.5,15.21875 z"
|
||||
style="opacity:1;fill:#000000;fill-opacity:0.50196078;fill-rule:nonzero;stroke:none;stroke-width:1.25;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
<path
|
||||
style="opacity:1;fill:url(#linearGradient3197);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.25;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M 55.5,13.71875 C 55.372191,13.71875 55.254184,13.745816 55.15625,13.84375 L 53.84375,15.15625 C 53.647881,15.352119 53.647881,15.647881 53.84375,15.84375 L 58,20 L 53.84375,24.15625 C 53.647883,24.352118 53.647881,24.647881 53.84375,24.84375 L 55.15625,26.15625 C 55.352118,26.352119 55.647881,26.352119 55.84375,26.15625 L 60,22 L 64.15625,26.15625 C 64.352119,26.352119 64.64788,26.352119 64.84375,26.15625 L 66.15625,24.84375 C 66.352119,24.647881 66.352117,24.352118 66.15625,24.15625 L 62,20 L 66.15625,15.84375 C 66.352119,15.647882 66.352119,15.352119 66.15625,15.15625 L 64.84375,13.84375 C 64.64788,13.647881 64.352119,13.647881 64.15625,13.84375 L 60,18 L 55.84375,13.84375 C 55.745816,13.745816 55.627809,13.71875 55.5,13.71875 z"
|
||||
id="rect3173" />
|
||||
<rect
|
||||
style="opacity:1;fill:#404040;fill-opacity:0.50196078;fill-rule:nonzero;stroke:none;stroke-width:1.25;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect3179"
|
||||
width="1"
|
||||
height="30"
|
||||
x="40"
|
||||
y="5"
|
||||
ry="0.5"
|
||||
rx="0.5" />
|
||||
<rect
|
||||
y="40"
|
||||
x="0"
|
||||
height="40"
|
||||
width="80"
|
||||
id="rect2391"
|
||||
style="opacity:1;fill:#404040;fill-opacity:0.75294118;fill-rule:nonzero;stroke:none;stroke-width:1.25;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
<g
|
||||
id="g3215">
|
||||
<rect
|
||||
style="opacity:1;fill:#000000;fill-opacity:0.50196078000000000;fill-rule:nonzero;stroke:none;stroke-width:1.25000000000000000;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;color:#000000"
|
||||
id="rect3200"
|
||||
width="14"
|
||||
height="14"
|
||||
x="3"
|
||||
y="84.5"
|
||||
rx="2"
|
||||
ry="2" />
|
||||
<path
|
||||
style="fill:url(#linearGradient3176);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.25;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M 5,83 L 15,83 C 16.108,83 17,83.892 17,85 L 17,95 C 17,96.108 16.108,97 15,97 L 5,97 C 3.892,97 3,96.108 3,95 L 3,85 C 3,83.892 3.892,83 5,83 z"
|
||||
id="rect3198" />
|
||||
<rect
|
||||
ry="0.5"
|
||||
rx="0.5"
|
||||
y="87"
|
||||
x="5"
|
||||
height="8"
|
||||
width="10"
|
||||
id="rect3206"
|
||||
style="opacity:1;fill:#000000;fill-opacity:0.1254902;fill-rule:nonzero;stroke:none;stroke-width:1.25000000000000000;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
<path
|
||||
id="rect3208"
|
||||
d="M 5.5 87 C 5.223 87 5 87.223 5 87.5 L 5 94 L 6 88 L 14 88 L 15 94 L 15 87.5 C 15 87.223 14.777 87 14.5 87 L 5.5 87 z "
|
||||
style="opacity:1;fill:#000000;fill-opacity:0.1254902;fill-rule:nonzero;stroke:none;stroke-width:1.25;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
</g>
|
||||
<path
|
||||
style="opacity:1;fill:url(#linearGradient3284);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.25000000000000000;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;color:#000000"
|
||||
d="M 30,83 C 27.8265,83 25.87799,84.006572 24.59375,85.5625 L 24.59375,85.59375 L 26,87 C 26.912944,85.791403 28.369734,85 30,85 C 32.044638,85 33.787894,86.240652 34.5625,88 L 31.5,88 L 35.5,92 L 39.5,88 L 39,88 L 36.6875,88 C 35.825628,85.115704 33.164199,83 30,83 z M 24.5,88 L 20.5,92 L 23.3125,92 C 24.174372,94.884296 26.835801,97 30,97 C 32.1735,97 34.12201,95.993428 35.40625,94.4375 C 35.411546,94.431083 35.400976,94.412686 35.40625,94.40625 L 34,93 C 33.087056,94.208597 31.630266,95 30,95 C 27.955362,95 26.212106,93.759348 25.4375,92 L 28.5,92 L 24.5,88 z"
|
||||
id="path3231"
|
||||
sodipodi:nodetypes="ccccsccccccccccssccsccc" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 14 KiB |
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Set the breadcrumb using a context reaction.
|
||||
*/
|
||||
class context_reaction_breadcrumb extends context_reaction_menu {
|
||||
/**
|
||||
* Override of execute().
|
||||
*/
|
||||
function execute(&$vars = NULL) {
|
||||
if ($active_paths = $this->get_active_paths()) {
|
||||
$breadcrumb = array(l(t('Home'), '<front>', array('purl' => array('disabled' => TRUE))));
|
||||
foreach ($active_paths as $path) {
|
||||
$result = db_select('menu_links')
|
||||
->fields('menu_links', array('p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8'))
|
||||
->condition('hidden', 0)
|
||||
->condition('link_path', $path)
|
||||
->execute();
|
||||
while ($parents = $result->fetchAssoc()) {
|
||||
$set = FALSE;
|
||||
foreach (array_filter($parents) as $plid) {
|
||||
$parent = menu_link_load($plid);
|
||||
if ($parent && $parent['access'] && empty($parent['hidden']) && !empty($parent['title'])) {
|
||||
$set = TRUE;
|
||||
$breadcrumb[] = l($parent['title'], $parent['href']);
|
||||
}
|
||||
}
|
||||
// Only set the breadcrumb if one or more links were added to the
|
||||
// trail. If not, continue iterating through possible menu links.
|
||||
if ($set) {
|
||||
drupal_set_breadcrumb($breadcrumb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
class context_reaction_css_injector extends context_reaction {
|
||||
|
||||
function options_form($context) {
|
||||
$list = array();
|
||||
foreach (_css_injector_load_rule() as $css_rule) {
|
||||
$list[$css_rule['crid']] = $css_rule['title'];
|
||||
}
|
||||
ksort($list);
|
||||
|
||||
return array(
|
||||
'#title' => $this->title,
|
||||
'#description' => $this->description,
|
||||
'#options' => $list,
|
||||
'#type' => 'checkboxes',
|
||||
'#default_value' => $this->fetch_from_context($context),
|
||||
);
|
||||
}
|
||||
|
||||
function execute() {
|
||||
$contexts = $this->get_contexts();
|
||||
foreach ($contexts as $context) {
|
||||
if (!empty($context->reactions[$this->plugin])) {
|
||||
foreach ($context->reactions[$this->plugin] as $crid => $enabled) {
|
||||
if ($enabled && $css_rule = _css_injector_load_rule($crid)) {
|
||||
drupal_add_css(_css_injector_rule_uri($crid), 'module', $css_rule['media'], $css_rule['preprocess']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Output context debug information.
|
||||
*/
|
||||
class context_reaction_debug extends context_reaction {
|
||||
function options_form($context) {
|
||||
return array('debug' => array('#type' => 'value', '#value' => TRUE));
|
||||
}
|
||||
|
||||
function options_form_submit($values) {
|
||||
return array('debug' => 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Output a list of active contexts.
|
||||
*/
|
||||
function execute() {
|
||||
$contexts = context_active_contexts();
|
||||
foreach ($contexts as $context) {
|
||||
if (!empty($context->reactions['debug'])) {
|
||||
if (user_access('administer site configuration') && module_exists('context_ui')) {
|
||||
$name = l($context->name, "admin/structure/context/list/{$context->name}", array('query' => array('destination' => $_GET['q'])));
|
||||
}
|
||||
else {
|
||||
$name = check_plain($context->name);
|
||||
}
|
||||
drupal_set_message(t("Active context: !name", array('!name' => $name)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Expose menu items as context reactions.
|
||||
*/
|
||||
class context_reaction_menu extends context_reaction {
|
||||
/**
|
||||
* Provide a form element that allow the admin to chose a menu item.
|
||||
*/
|
||||
function options_form($context) {
|
||||
if (module_exists('menu')) {
|
||||
$menus = menu_parent_options(menu_get_menus(), array('mlid' => 0));
|
||||
$root_menus = array();
|
||||
foreach ($menus as $key => $name) {
|
||||
$id = explode(':', $key);
|
||||
if ($id[1] == '0') {
|
||||
$root_menus[$id[0]] = check_plain($name);
|
||||
}
|
||||
else {
|
||||
$link = menu_link_load($id[1]);
|
||||
$identifier = $link['link_path'];
|
||||
$root_menu = $root_menus[$id[0]];
|
||||
while (isset($menus[$root_menu][$identifier])) {
|
||||
$identifier .= "'";
|
||||
}
|
||||
$menus[$root_menu][$identifier] = $name;
|
||||
}
|
||||
unset($menus[$key]);
|
||||
}
|
||||
array_unshift($menus, "-- " . t('None') . " --");
|
||||
}
|
||||
else {
|
||||
$menus = array();
|
||||
}
|
||||
return array(
|
||||
'#title' => $this->title,
|
||||
'#description' => $this->description,
|
||||
'#options' => $menus,
|
||||
'#type' => 'select',
|
||||
'#default_value' => $this->fetch_from_context($context),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override of options_form_submit().
|
||||
* Trim any identifier padding for non-unique path menu items.
|
||||
*/
|
||||
function options_form_submit($values) {
|
||||
return trim($values, "'");
|
||||
}
|
||||
|
||||
/**
|
||||
* If primary + secondary links are pointed at the same menu, provide
|
||||
* contextual trailing by default.
|
||||
*/
|
||||
function execute(&$vars = NULL) {
|
||||
if (variable_get('menu_main_links_source', 'main-menu') == variable_get('menu_secondary_links_source', 'user-menu')) {
|
||||
$vars['main_menu'] = theme_get_setting('toggle_main_menu') ? $this->menu_navigation_links(variable_get('menu_main_links_source', 'main-menu')) : $vars['main_menu'];
|
||||
$vars['secondary_menu'] = theme_get_setting('toggle_secondary_menu') ? $this->menu_navigation_links(variable_get('menu_secondary_links_source', 'secondary-links'), 1) : $vars['secondary_menu'];
|
||||
}
|
||||
|
||||
$vars['main_menu'] = $this->menu_set_active($vars['main_menu']);
|
||||
$vars['secondary_menu'] = $this->menu_set_active($vars['secondary_menu']);
|
||||
}
|
||||
|
||||
function get_active_paths() {
|
||||
$active_paths = array();
|
||||
foreach ($this->get_contexts() as $context) {
|
||||
if (isset($context->reactions[$this->plugin])) {
|
||||
$active_paths[] = $context->reactions[$this->plugin];
|
||||
}
|
||||
}
|
||||
return $active_paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through a provided links array for use with theme_links()
|
||||
* (e.g. from menu_primary_links()) and provides an active class for
|
||||
* any items that have a path that matches an active context.
|
||||
*
|
||||
* @param $links
|
||||
* An array of links.
|
||||
* @param $reset
|
||||
* A boolean flag for resetting the static cache.
|
||||
*
|
||||
* @return
|
||||
* A modified links array.
|
||||
*/
|
||||
function menu_set_active($links = array(), $reset = FALSE) {
|
||||
$new_links = array();
|
||||
if (!empty($links)) {
|
||||
$active_paths = $this->get_active_paths();
|
||||
|
||||
// Iterate through the provided links and build a new set of links
|
||||
// that includes active classes
|
||||
foreach ($links as $key => $link) {
|
||||
if (!empty($link['href']) && in_array($link['href'], $active_paths)) {
|
||||
$link['attributes']['class'][] = 'active';
|
||||
|
||||
if (strpos(' active', $key) === FALSE) {
|
||||
$new_links[$key . ' active'] = $link;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$new_links[$key] = $link;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $new_links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around menu_navigation_links() that gives themers the option of
|
||||
* building navigation links based on an active context trail.
|
||||
*/
|
||||
function menu_navigation_links($menu_name, $level = 0) {
|
||||
// Retrieve original path so we can repair it after our hack.
|
||||
$original_path = $_GET['q'];
|
||||
$original_menu_trail = drupal_static('menu_set_active_trail');
|
||||
|
||||
// Retrieve the first active menu path found.
|
||||
if ($active_paths = $this->get_active_paths()) {
|
||||
$path = current($active_paths);
|
||||
if (menu_get_item($path)) {
|
||||
menu_set_active_item($path);
|
||||
}
|
||||
}
|
||||
|
||||
// Build the links requested
|
||||
if (module_exists('i18n_menu')) {
|
||||
$links = i18n_menu_navigation_links($menu_name, $level);
|
||||
} else {
|
||||
$links = menu_navigation_links($menu_name, $level);
|
||||
}
|
||||
|
||||
// Repair and get out
|
||||
menu_set_active_item($original_path);
|
||||
$repair_menu_trail = &drupal_static('menu_set_active_trail');
|
||||
$repair_menu_trail = $original_menu_trail;
|
||||
return $links;
|
||||
}
|
||||
}
|
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
class context_reaction_region extends context_reaction {
|
||||
|
||||
function editor_form($context) {
|
||||
}
|
||||
|
||||
function options_form($context) {
|
||||
$values = $this->fetch_from_context($context);
|
||||
$form = array();
|
||||
foreach (list_themes() as $theme) {
|
||||
if ($theme->status) {
|
||||
$regions = system_region_list($theme->name);
|
||||
$default = isset($values[$theme->name]) ? $values[$theme->name]['disable'] : array();
|
||||
|
||||
$form[$theme->name] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => "Disable Regions in {$theme->name} Theme",
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => !array_reduce($default, create_function('$a, $b', 'return $a || $b;')),
|
||||
);
|
||||
$form[$theme->name]['disable'] = array(
|
||||
'#type' => 'checkboxes',
|
||||
'#title' => t("Disable the following"),
|
||||
'#options' => $regions,
|
||||
'#default_value' => $default,
|
||||
);
|
||||
}
|
||||
}
|
||||
return $form;
|
||||
}
|
||||
|
||||
function execute(&$page) {
|
||||
global $theme;
|
||||
foreach ($this->get_contexts() as $k => $v) {
|
||||
if (isset($v->reactions[$this->plugin][$theme])) {
|
||||
$regions = $v->reactions[$this->plugin][$theme]['disable'];
|
||||
foreach ($regions as $region => $disable) {
|
||||
if ($disable && isset($page[$region])) {
|
||||
unset($page[$region]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Expose themes as context reactions.
|
||||
*/
|
||||
class context_reaction_theme extends context_reaction {
|
||||
/**
|
||||
* Editor form.
|
||||
*/
|
||||
function editor_form($context) {
|
||||
$form = $this->options_form($context);
|
||||
|
||||
// Hide descriptions which take up too much space.
|
||||
unset($form['title']['#description']);
|
||||
unset($form['subtitle']['#description']);
|
||||
unset($form['class']['#description']);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit handler for editor form.
|
||||
*/
|
||||
function editor_form_submit($context, $values) {
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow admins to provide a section title, section subtitle and section class.
|
||||
*/
|
||||
function options_form($context) {
|
||||
$values = $this->fetch_from_context($context);
|
||||
$form = array(
|
||||
'#tree' => TRUE,
|
||||
'#title' => t('Theme variables'),
|
||||
'title' => array(
|
||||
'#title' => t('Section title'),
|
||||
'#description' => t('Provides this text as a <strong>$section_title</strong> variable for display in page.tpl.php when this context is active.'),
|
||||
'#type' => 'textfield',
|
||||
'#maxlength' => 255,
|
||||
'#default_value' => isset($values['title']) ? $values['title'] : '',
|
||||
),
|
||||
'subtitle' => array(
|
||||
'#title' => t('Section subtitle'),
|
||||
'#description' => t('Provides this text as a <strong>$section_subtitle</strong> variable for display in page.tpl.php when this context is active.'),
|
||||
'#type' => 'textfield',
|
||||
'#maxlength' => 255,
|
||||
'#default_value' => isset($values['subtitle']) ? $values['subtitle'] : '',
|
||||
),
|
||||
);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set 'section_title', and 'section_subtitle' if not set
|
||||
*/
|
||||
function execute(&$vars) {
|
||||
$classes = array();
|
||||
foreach ($this->get_contexts() as $k => $v) {
|
||||
if (!empty($v->reactions[$this->plugin]['title']) && !isset($vars['section_title'])) {
|
||||
$vars['section_title'] = check_plain(t($v->reactions[$this->plugin]['title']));
|
||||
}
|
||||
if (!empty($v->reactions[$this->plugin]['subtitle']) && !isset($vars['section_subtitle'])) {
|
||||
$vars['section_subtitle'] = check_plain(t($v->reactions[$this->plugin]['subtitle']));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/**
|
||||
* Expose themes as context reactions.
|
||||
*/
|
||||
class context_reaction_theme_html extends context_reaction_theme {
|
||||
/**
|
||||
* Allow admins to provide additional body classes.
|
||||
*/
|
||||
function options_form($context) {
|
||||
$values = $this->fetch_from_context($context);
|
||||
$form = array(
|
||||
'class' => array(
|
||||
'#title' => t('Section class'),
|
||||
'#description' => t('Provides this text as an additional body class (in <strong>$classes</strong> in html.tpl.php) when this section is active.'),
|
||||
'#type' => 'textfield',
|
||||
'#maxlength' => 64,
|
||||
'#default_value' => isset($values['class']) ? $values['class'] : '',
|
||||
),
|
||||
);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set additional classes onto the 'body_classes'.
|
||||
*/
|
||||
function execute(&$vars) {
|
||||
$classes = array();
|
||||
foreach ($this->get_contexts() as $k => $v) {
|
||||
if (!empty($v->reactions[$this->plugin]['class'])) {
|
||||
$vars['classes_array'][] = $v->reactions[$this->plugin]['class'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user