upgrade omega again
[indybay:drupal.git] / docs / sites / all / modules / contrib / context / context_ui / export_ui / context_export_ui.class.php
1 <?php
2
3 /**
4  * CTools export UI extending class. Slightly customized for Context.
5  */
6 class context_export_ui extends ctools_export_ui {
7   function list_form(&$form, &$form_state) {
8     parent::list_form($form, $form_state);
9     $form['top row']['submit'] = $form['bottom row']['submit'];
10     $form['top row']['reset'] = $form['bottom row']['reset'];
11     $form['bottom row']['#access'] = FALSE;
12     // Invalidate the context cache.
13     context_invalidate_cache();
14     return;
15   }
16
17   function list_css() {
18     ctools_add_css('export-ui-list');
19     drupal_add_css(drupal_get_path("module", "context_ui") ."/context_ui.css");
20   }
21
22   function list_render(&$form_state) {
23     $table = array(
24       'header' => $this->list_table_header(),
25       'rows' => $this->rows, 
26       'attributes' => array(
27         'class' => array('context-admin'),
28         'id' => 'ctools-export-ui-list-items',
29       ),
30     );
31     return theme('table', $table);
32   }
33
34   function list_build_row($item, &$form_state, $operations) {
35     $name = $item->name;
36
37     // Add a row for tags.
38     $tag = !empty($item->tag) ? $item->tag : t('< Untagged >');
39     if (!isset($this->rows[$tag])) {
40       $this->rows[$tag]['data'] = array();
41       $this->rows[$tag]['data'][] = array('data' => check_plain($tag), 'colspan' => 3, 'class' => array('tag'));
42       $this->sorts["{$tag}"] = $tag;
43     }
44
45     // Build row for each context item.
46     $this->rows["{$tag}:{$name}"]['data'] = array();
47     $this->rows["{$tag}:{$name}"]['class'] = !empty($item->disabled) ? array('ctools-export-ui-disabled') : array('ctools-export-ui-enabled');
48     $this->rows["{$tag}:{$name}"]['data'][] = array(
49       'data' => check_plain($name) . "<div class='description'>" . check_plain($item->description) . "</div>",
50       'class' => array('ctools-export-ui-name')
51     );
52     $this->rows["{$tag}:{$name}"]['data'][] = array(
53       'data' => check_plain($item->type),
54       'class' => array('ctools-export-ui-storage')
55     );
56     $this->rows["{$tag}:{$name}"]['data'][] = array(
57       'data' => theme('links', array(
58         'links' => $operations,
59         'attributes' => array('class' => array('links inline'))
60       )),
61       'class' => array('ctools-export-ui-operations'),
62     );
63
64     // Sort by tag, name.
65     $this->sorts["{$tag}:{$name}"] = $tag . $name;
66   }
67
68   /**
69    * Override of edit_form_submit().
70    * Don't copy values from $form_state['values'].
71    */
72   function edit_form_submit(&$form, &$form_state) {
73     if (!empty($this->plugin['form']['submit'])) {
74       $this->plugin['form']['submit']($form, $form_state);
75     }
76   }
77
78   /**
79    * Override default final validation for ctools. With import wizard
80    * it was possible to get default ctools export ui name validation
81    * rules, this ensures we always get ours.
82    */
83   function edit_finish_validate(&$form, &$form_state) {
84     if ($form_state['op'] != 'edit') {
85       // Validate the name. Fake an element for form_error().
86       $export_key = $this->plugin['export']['key'];
87       $element = array(
88         '#value' => $form_state['item']->{$export_key},
89         '#parents' => array('name'),
90       );
91       $form_state['plugin'] = $this->plugin;
92       context_ui_edit_name_validate($element, $form_state);
93     }
94   }
95 }
96
97
98 /**
99  * Generates the omnibus context definition editing form.
100  *
101  * @param $form
102  *   Form array to populate.
103  * @param $form_state
104  *   Form state array
105  */
106 function context_ui_form(&$form, &$form_state) {  
107   $conditions = array_keys(context_conditions());
108   sort($conditions);
109   $reactions = array_keys(context_reactions());
110   sort($reactions);
111     
112   $context = $form_state['item'];
113   if (!empty($form_state['input'])) {
114     $context = _context_ui_rebuild_from_input($context, $form_state['input'], $conditions, $reactions);
115   }
116   
117   $form['#base'] = 'context_ui_form';
118   $form['#theme'] = 'context_ui_form';
119
120   // Core context definition
121   $form['info']['#type'] = 'fieldset';
122   $form['info']['#tree'] = FALSE;
123
124
125   $form['info']['name']['#element_validate'] = array('context_ui_edit_name_validate');
126
127   $form['info']['tag'] = array(
128     '#title' => t('Tag'),
129     '#type' => 'textfield',
130     '#required' => FALSE,
131     '#maxlength' => 255,
132     '#default_value' => isset($context->tag) ? $context->tag : '',
133     '#description' => t('Example: <code>theme</code>') .'<br/>'. t('A tag to group this context with others.'),
134   );
135
136   $form['info']['description'] = array(
137     '#title' => t('Description'),
138     '#type' => 'textfield',
139     '#required' => FALSE,
140     '#maxlength' => 255,
141     '#default_value' => isset($context->description) ? $context->description: '',
142     '#description' => t('The description of this context definition.'),
143   );
144
145   // Condition mode
146   $form['condition_mode'] = array(
147     '#type' => 'checkbox',
148     '#default_value' => isset($context->condition_mode) ? $context->condition_mode : FALSE,
149     '#title' => t('Require all conditions'),
150     '#description' => t('If checked, all conditions must be met for this context to be active. Otherwise, the first condition that is met will activate this context.')
151   );
152
153   // Condition plugin forms
154   $form['conditions'] = array(
155     '#theme' => 'context_ui_plugins',
156     '#title' => t('Conditions'),
157     '#description' => t('Trigger the activation of this context'),
158     '#tree' => TRUE,
159     'selector' => array(
160       '#type' => 'select',
161       '#options' => array(0 => '<'. t('Add a condition') .'>'),
162       '#default_value' => 0,
163     ),
164     'state' => array(
165       '#attributes' => array('class' => array('context-plugins-state')),
166       '#type' => 'hidden',
167     ),
168     'plugins' => array('#tree' => TRUE),
169   );
170   foreach ($conditions as $condition) {
171     if ($plugin = context_get_plugin('condition', $condition)) {
172       $form['conditions']['plugins'][$condition] = array(
173         '#tree' => TRUE,
174         '#plugin' => $plugin,
175         '#context_enabled' => isset($context->conditions[$condition]), // This flag is used at the theme layer.
176         'values' => $plugin->condition_form($context),
177         'options' => $plugin->options_form($context),
178       );
179       $form['conditions']['selector']['#options'][$condition] = $plugin->title;
180     }
181   }
182
183   // Reaction plugin forms
184   $form['reactions'] = array(
185     '#theme' => 'context_ui_plugins',
186     '#title' => t('Reactions'),
187     '#description' => t('Actions to take when this context is active'),
188     '#tree' => TRUE,
189     'selector' => array(
190       '#type' => 'select',
191       '#options' => array(0 => '<'. t('Add a reaction') .'>'),
192       '#default_value' => 0,
193     ),
194     'state' => array(
195       '#attributes' => array('class' => array('context-plugins-state')),
196       '#type' => 'hidden',
197     ),
198     'plugins' => array('#tree' => TRUE),
199   );
200   foreach ($reactions as $reaction) {
201     if ($plugin = context_get_plugin('reaction', $reaction)) {
202       $form['reactions']['plugins'][$reaction] = $plugin->options_form($context) + array(
203         '#plugin' => $plugin,
204         '#context_enabled' => isset($context->reactions[$reaction]), // This flag is used at the theme layer.
205       );
206       $form['reactions']['selector']['#options'][$reaction] = $plugin->title;
207     }
208   }
209 }
210
211 /**
212  * Handle the complex job of rebuilding a Context from submission data in the case of a validation error.
213  *
214  * @param $context
215  *   The context object to modify.
216  * @param $input
217  *   A form submission values
218  * @param $conditions
219  *   The full list of condition plugins
220  * @param $reactions
221  *   The full list of reaction plugins
222  *
223  * @return
224  *   A context object
225  */
226 function _context_ui_rebuild_from_input($context, $input, $conditions, $reactions) {
227   $condition_defaults = array();  
228   foreach ($conditions as $condition) {
229     if ($plugin = context_get_plugin('condition', $condition)) {
230       $condition_defaults[$condition] = array(
231         'values' => $plugin->condition_form($context),
232         'options' => $plugin->options_form($context),
233       );
234     }
235   }
236   $input['conditions']['plugins'] = array_merge($condition_defaults, $input['conditions']['plugins']);
237   
238   $reaction_defaults = array();
239   foreach ($reactions as $reaction) {
240     if ($plugin = context_get_plugin('reaction', $reaction)) {
241       $reaction_defaults[$reaction] = $plugin->options_form($context);
242     }
243   }
244   $input['reactions']['plugins'] = array_merge($reaction_defaults, $input['reactions']['plugins']);
245
246   return context_ui_form_process($context, $input, FALSE);
247 }
248
249 /**
250  * Modifies a context object from submitted form values.
251  *
252  * @param $context
253  *   The context object to modify.
254  * @param $form
255  *   A form array with submitted values
256  * @param $submit
257  *   A flag indicating if we are building a context on submit. If on
258  *   submit, it will clear out conditions/reactions that are empty.
259  *
260  * @return
261  *   A context object
262  */
263 function context_ui_form_process($context, $form, $submit = TRUE) {
264   $context->name = isset($form['name']) ? $form['name'] : $context->name;
265   $context->description = isset($form['description']) ? $form['description'] : NULL;
266   $context->tag = isset($form['tag']) ? $form['tag'] : NULL;
267   $context->condition_mode = isset($form['condition_mode']) ? $form['condition_mode'] : NULL;
268   $context->conditions = array();
269   $context->reactions = array();
270   if (!empty($form['conditions'])) {
271     $enabled = explode(',', $form['conditions']['state']);
272     foreach ($form['conditions']['plugins'] as $condition => $values) {
273       if (in_array($condition, $enabled, TRUE) && ($plugin = context_get_plugin('condition', $condition))) {
274         if (isset($values['values'])) {
275           $context->conditions[$condition]['values'] = $plugin->condition_form_submit($values['values']);
276         }
277         if (isset($values['options'])) {
278           $context->conditions[$condition]['options'] = $plugin->options_form_submit($values['options']);
279         }
280         if ($submit && context_empty($context->conditions[$condition]['values'])) {
281           unset($context->conditions[$condition]);
282         }
283       }
284     }
285   }
286   if (!empty($form['reactions'])) {
287     $enabled = explode(',', $form['reactions']['state']);
288     foreach ($form['reactions']['plugins'] as $reaction => $values) {
289       if (in_array($reaction, $enabled, TRUE) && ($plugin = context_get_plugin('reaction', $reaction))) {
290         if (isset($values)) {
291           $context->reactions[$reaction] = $plugin->options_form_submit($values);
292         }
293         if ($submit && context_empty($context->reactions[$reaction])) {
294           unset($context->reactions[$reaction]);
295         }
296       }
297     }
298   }
299   return $context;
300 }
301
302 /**
303  * Submit handler for main context_ui form.
304  */
305 function context_ui_form_submit($form, &$form_state) {
306   $form_state['item'] = context_ui_form_process($form_state['item'], $form_state['values']);
307 }
308
309 /**
310  * Replacement for ctools_export_ui_edit_name_validate(). Allow dashes.
311  */
312 function context_ui_edit_name_validate($element, &$form_state) {
313   $plugin = $form_state['plugin'];
314   // Check for string identifier sanity
315   if (!preg_match('!^[a-z0-9_-]+$!', $element['#value'])) {
316     form_error($element, t('The name can only consist of lowercase letters, underscores, dashes, and numbers.'));
317     return;
318   }
319
320   // Check for name collision
321   if ($form_state['op'] != 'edit') {
322     if (empty($form_state['item']->export_ui_allow_overwrite) && $exists = ctools_export_crud_load($plugin['schema'], $element['#value'])) {
323       form_error($element, t('A @plugin with this name already exists. Please choose another name or delete the existing item before creating a new one.', array('@plugin' => $plugin['title singular'])));
324     }
325   }
326 }