context_condition.inc 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. <?php
  2. /**
  3. * Base class for a context condition.
  4. */
  5. class context_condition {
  6. var $plugin;
  7. var $title;
  8. var $description;
  9. var $values = array();
  10. /**
  11. * Clone our references when we're being cloned.
  12. *
  13. * PHP 5.3 performs 'shallow' clones when clone()'ing objects, meaning that
  14. * any objects or arrays referenced by this object will not be copied, the
  15. * cloned object will just reference our objects/arrays instead. By iterating
  16. * over our properties and serializing and unserializing them, we force PHP to
  17. * copy them.
  18. */
  19. function __clone() {
  20. foreach ($this as $key => $val) {
  21. if (is_object($val) || (is_array($val))) {
  22. $this->{$key} = unserialize(serialize($val));
  23. }
  24. }
  25. }
  26. /**
  27. * Constructor. Do not override.
  28. */
  29. function __construct($plugin, $info) {
  30. $this->plugin = $plugin;
  31. $this->title = isset($info['title']) ? $info['title'] : $plugin;
  32. $this->description = isset($info['description']) ? $info['description'] : '';
  33. }
  34. /**
  35. * Condition values.
  36. */
  37. function condition_values() {
  38. return array();
  39. }
  40. /**
  41. * Condition form.
  42. */
  43. function condition_form($context) {
  44. return array(
  45. '#title' => $this->title,
  46. '#description' => $this->description,
  47. '#options' => $this->condition_values(),
  48. '#type' => 'checkboxes',
  49. '#default_value' => $this->fetch_from_context($context, 'values'),
  50. );
  51. }
  52. /**
  53. * Condition form submit handler.
  54. */
  55. function condition_form_submit($values) {
  56. ksort($values);
  57. // Editor forms are generally checkboxes -- do some checkbox processing.
  58. return drupal_map_assoc(array_keys(array_filter($values)));
  59. }
  60. /**
  61. * Options form. Provide additional options for your condition.
  62. */
  63. function options_form($context) {
  64. return array();
  65. }
  66. /**
  67. * Options form submit handler.
  68. */
  69. function options_form_submit($values) {
  70. return $values;
  71. }
  72. /**
  73. * Settings form. Provide variable settings for your condition.
  74. */
  75. function settings_form() {
  76. return array();
  77. }
  78. /**
  79. * Context editor form for conditions.
  80. */
  81. function editor_form($context = NULL) {
  82. $form = array();
  83. if (!empty($this->values)) {
  84. $options = $this->condition_values();
  85. foreach ($this->values as $value => $contexts) {
  86. $label = "{$this->title}: ";
  87. $label .= isset($options[$value]) ? trim($options[$value], ' -') : $value;
  88. $form[$value] = array(
  89. '#type' => 'checkbox',
  90. '#title' => check_plain($label),
  91. '#default_value' => empty($context->name) ? TRUE : in_array($context->name, $contexts, TRUE),
  92. );
  93. }
  94. }
  95. return $form;
  96. }
  97. /**
  98. * Context editor form submit handler.
  99. */
  100. function editor_form_submit(&$context, $values) {
  101. // Merge existing values in from non-active conditions.
  102. $existing = $this->fetch_from_context($context, 'values');
  103. $values += !empty($existing) ? $existing : array();
  104. ksort($values);
  105. // Editor forms are generally checkboxes -- do some checkbox processing.
  106. return drupal_map_assoc(array_keys(array_filter($values)));
  107. }
  108. /**
  109. * Public method that is called from hooks or other integration points with
  110. * Drupal. Note that it is not implemented in the base class, allowing
  111. * extending classes to change the function signature if necessary.
  112. *
  113. * function execute($value) {
  114. * foreach ($this->get_contexts($value) as $context) {
  115. * $this->condition_met($context, $value);
  116. * }
  117. * }
  118. */
  119. /**
  120. * Marks a context as having met this particular condition.
  121. */
  122. function condition_met($context, $value = NULL) {
  123. if (isset($value)) {
  124. $this->values[$value] = isset($this->values[$value]) ? $this->values[$value] : array();
  125. $this->values[$value][] = $context->name;
  126. }
  127. context_condition_met($context, $this->plugin);
  128. }
  129. /**
  130. * Check whether this condition is used by any contexts. Can be used to
  131. * prevent expensive condition checks from being triggered when no contexts
  132. * use this condition.
  133. */
  134. function condition_used() {
  135. $map = context_condition_map();
  136. return !empty($map[$this->plugin]);
  137. }
  138. /**
  139. * Retrieve all contexts with the condition value provided.
  140. */
  141. function get_contexts($value = NULL) {
  142. $map = context_condition_map();
  143. $map = isset($map[$this->plugin]) ? $map[$this->plugin] : array();
  144. $contexts = array();
  145. if (isset($value) && (is_string($value) || is_numeric($value))) {
  146. if (isset($map[$value]) && is_array($map[$value])) {
  147. foreach ($map[$value] as $name) {
  148. if (!isset($contexts[$name])) {
  149. $context = context_load($name);
  150. $contexts[$context->name] = $context;
  151. }
  152. }
  153. }
  154. }
  155. else {
  156. foreach ($map as $submap) {
  157. foreach ($submap as $name) {
  158. if (!isset($contexts[$name])) {
  159. $context = context_load($name);
  160. $contexts[$context->name] = $context;
  161. }
  162. }
  163. }
  164. }
  165. return $contexts;
  166. }
  167. /**
  168. * Retrieve options from the context provided.
  169. */
  170. function fetch_from_context($context, $key = NULL) {
  171. if (isset($key)) {
  172. return isset($context->conditions[$this->plugin][$key]) ? $context->conditions[$this->plugin][$key] : array();
  173. }
  174. return isset($context->conditions[$this->plugin]) ? $context->conditions[$this->plugin] : array();
  175. }
  176. }