context_export_ui.class.php

Go to the documentation of this file.
00001 <?php
00002 
00003 /**
00004  * CTools export UI extending class. Slightly customized for Context.
00005  */
00006 class context_export_ui extends ctools_export_ui {
00007   function list_form(&$form, &$form_state) {
00008     parent::list_form($form, $form_state);
00009     $form['top row']['submit'] = $form['bottom row']['submit'];
00010     $form['top row']['reset'] = $form['bottom row']['reset'];
00011     $form['bottom row']['#access'] = FALSE;
00012     // Invalidate the context cache.
00013     context_invalidate_cache();
00014     return;
00015   }
00016 
00017   function list_css() {
00018     ctools_add_css('export-ui-list');
00019     drupal_add_css(drupal_get_path("module", "context_ui") ."/context_ui.css");
00020   }
00021 
00022   function list_render(&$form_state) {
00023     $table = array(
00024       'header' => $this->list_table_header(),
00025       'rows' => $this->rows, 
00026       'attributes' => array(
00027         'class' => array('context-admin'),
00028         'id' => 'ctools-export-ui-list-items',
00029       ),
00030     );
00031     return theme('table', $table);
00032   }
00033 
00034   function list_build_row($item, &$form_state, $operations) {
00035     $name = $item->name;
00036 
00037     // Add a row for tags.
00038     $tag = !empty($item->tag) ? $item->tag : t('< Untagged >');
00039     if (!isset($this->rows[$tag])) {
00040       $this->rows[$tag]['data'] = array();
00041       $this->rows[$tag]['data'][] = array('data' => check_plain($tag), 'colspan' => 3, 'class' => array('tag'));
00042       $this->sorts["{$tag}"] = $tag;
00043     }
00044 
00045     // Build row for each context item.
00046     $this->rows["{$tag}:{$name}"]['data'] = array();
00047     $this->rows["{$tag}:{$name}"]['class'] = !empty($item->disabled) ? array('ctools-export-ui-disabled') : array('ctools-export-ui-enabled');
00048     $this->rows["{$tag}:{$name}"]['data'][] = array(
00049       'data' => check_plain($name) . "<div class='description'>" . check_plain($item->description) . "</div>",
00050       'class' => array('ctools-export-ui-name')
00051     );
00052     $this->rows["{$tag}:{$name}"]['data'][] = array(
00053       'data' => check_plain($item->type),
00054       'class' => array('ctools-export-ui-storage')
00055     );
00056     $this->rows["{$tag}:{$name}"]['data'][] = array(
00057       'data' => theme('links', array(
00058         'links' => $operations,
00059         'attributes' => array('class' => array('links inline'))
00060       )),
00061       'class' => array('ctools-export-ui-operations'),
00062     );
00063 
00064     // Sort by tag, name.
00065     $this->sorts["{$tag}:{$name}"] = $tag . $name;
00066   }
00067 
00068   /**
00069    * Override of edit_form_submit().
00070    * Don't copy values from $form_state['values'].
00071    */
00072   function edit_form_submit(&$form, &$form_state) {
00073     if (!empty($this->plugin['form']['submit'])) {
00074       $this->plugin['form']['submit']($form, $form_state);
00075     }
00076   }
00077 
00078   /**
00079    * Override default final validation for ctools. With import wizard
00080    * it was possible to get default ctools export ui name validation
00081    * rules, this ensures we always get ours.
00082    */
00083   function edit_finish_validate(&$form, &$form_state) {
00084     if ($form_state['op'] != 'edit') {
00085       // Validate the name. Fake an element for form_error().
00086       $export_key = $this->plugin['export']['key'];
00087       $element = array(
00088         '#value' => $form_state['item']->{$export_key},
00089         '#parents' => array('name'),
00090       );
00091       $form_state['plugin'] = $this->plugin;
00092       context_ui_edit_name_validate($element, $form_state);
00093     }
00094   }
00095 }
00096 
00097 
00098 /**
00099  * Generates the omnibus context definition editing form.
00100  *
00101  * @param $form
00102  *   Form array to populate.
00103  * @param $form_state
00104  *   Form state array
00105  */
00106 function context_ui_form(&$form, &$form_state) {  
00107   $conditions = array_keys(context_conditions());
00108   sort($conditions);
00109   $reactions = array_keys(context_reactions());
00110   sort($reactions);
00111     
00112   $context = $form_state['item'];
00113   if (!empty($form_state['input'])) {
00114     $context = _context_ui_rebuild_from_input($context, $form_state['input'], $conditions, $reactions);
00115   }
00116   
00117   $form['#base'] = 'context_ui_form';
00118   $form['#theme'] = 'context_ui_form';
00119 
00120   // Core context definition
00121   $form['info']['#type'] = 'fieldset';
00122   $form['info']['#tree'] = FALSE;
00123 
00124 
00125   $form['info']['name']['#element_validate'] = array('context_ui_edit_name_validate');
00126 
00127   $form['info']['tag'] = array(
00128     '#title' => t('Tag'),
00129     '#type' => 'textfield',
00130     '#required' => FALSE,
00131     '#maxlength' => 255,
00132     '#default_value' => isset($context->tag) ? $context->tag : '',
00133     '#description' => t('Example: <code>theme</code>') .'<br/>'. t('A tag to group this context with others.'),
00134   );
00135 
00136   $form['info']['description'] = array(
00137     '#title' => t('Description'),
00138     '#type' => 'textfield',
00139     '#required' => FALSE,
00140     '#maxlength' => 255,
00141     '#default_value' => isset($context->description) ? $context->description: '',
00142     '#description' => t('The description of this context definition.'),
00143   );
00144 
00145   // Condition mode
00146   $form['condition_mode'] = array(
00147     '#type' => 'checkbox',
00148     '#default_value' => isset($context->condition_mode) ? $context->condition_mode : FALSE,
00149     '#title' => t('Require all conditions'),
00150     '#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.')
00151   );
00152 
00153   // Condition plugin forms
00154   $form['conditions'] = array(
00155     '#theme' => 'context_ui_plugins',
00156     '#title' => t('Conditions'),
00157     '#description' => t('Trigger the activation of this context'),
00158     '#tree' => TRUE,
00159     'selector' => array(
00160       '#type' => 'select',
00161       '#options' => array(0 => '<'. t('Add a condition') .'>'),
00162       '#default_value' => 0,
00163     ),
00164     'state' => array(
00165       '#attributes' => array('class' => array('context-plugins-state')),
00166       '#type' => 'hidden',
00167     ),
00168     'plugins' => array('#tree' => TRUE),
00169   );
00170   foreach ($conditions as $condition) {
00171     if ($plugin = context_get_plugin('condition', $condition)) {
00172       $form['conditions']['plugins'][$condition] = array(
00173         '#tree' => TRUE,
00174         '#plugin' => $plugin,
00175         '#context_enabled' => isset($context->conditions[$condition]), // This flag is used at the theme layer.
00176         'values' => $plugin->condition_form($context),
00177         'options' => $plugin->options_form($context),
00178       );
00179       $form['conditions']['selector']['#options'][$condition] = $plugin->title;
00180     }
00181   }
00182 
00183   // Reaction plugin forms
00184   $form['reactions'] = array(
00185     '#theme' => 'context_ui_plugins',
00186     '#title' => t('Reactions'),
00187     '#description' => t('Actions to take when this context is active'),
00188     '#tree' => TRUE,
00189     'selector' => array(
00190       '#type' => 'select',
00191       '#options' => array(0 => '<'. t('Add a reaction') .'>'),
00192       '#default_value' => 0,
00193     ),
00194     'state' => array(
00195       '#attributes' => array('class' => array('context-plugins-state')),
00196       '#type' => 'hidden',
00197     ),
00198     'plugins' => array('#tree' => TRUE),
00199   );
00200   foreach ($reactions as $reaction) {
00201     if ($plugin = context_get_plugin('reaction', $reaction)) {
00202       $form['reactions']['plugins'][$reaction] = $plugin->options_form($context) + array(
00203         '#plugin' => $plugin,
00204         '#context_enabled' => isset($context->reactions[$reaction]), // This flag is used at the theme layer.
00205       );
00206       $form['reactions']['selector']['#options'][$reaction] = $plugin->title;
00207     }
00208   }
00209 }
00210 
00211 /**
00212  * Handle the complex job of rebuilding a Context from submission data in the case of a validation error.
00213  *
00214  * @param $context
00215  *   The context object to modify.
00216  * @param $input
00217  *   A form submission values
00218  * @param $conditions
00219  *   The full list of condition plugins
00220  * @param $reactions
00221  *   The full list of reaction plugins
00222  *
00223  * @return
00224  *   A context object
00225  */
00226 function _context_ui_rebuild_from_input($context, $input, $conditions, $reactions) {
00227   $condition_defaults = array();  
00228   foreach ($conditions as $condition) {
00229     if ($plugin = context_get_plugin('condition', $condition)) {
00230       $condition_defaults[$condition] = array(
00231         'values' => $plugin->condition_form($context),
00232         'options' => $plugin->options_form($context),
00233       );
00234     }
00235   }
00236   $input['conditions']['plugins'] = array_merge($condition_defaults, $input['conditions']['plugins']);
00237   
00238   $reaction_defaults = array();
00239   foreach ($reactions as $reaction) {
00240     if ($plugin = context_get_plugin('reaction', $reaction)) {
00241       $reaction_defaults[$reaction] = $plugin->options_form($context);
00242     }
00243   }
00244   $input['reactions']['plugins'] = array_merge($reaction_defaults, $input['reactions']['plugins']);
00245 
00246   return context_ui_form_process($context, $input, FALSE);
00247 }
00248 
00249 /**
00250  * Modifies a context object from submitted form values.
00251  *
00252  * @param $context
00253  *   The context object to modify.
00254  * @param $form
00255  *   A form array with submitted values
00256  * @param $submit
00257  *   A flag indicating if we are building a context on submit. If on
00258  *   submit, it will clear out conditions/reactions that are empty.
00259  *
00260  * @return
00261  *   A context object
00262  */
00263 function context_ui_form_process($context, $form, $submit = TRUE) {
00264   $context->name = isset($form['name']) ? $form['name'] : $context->name;
00265   $context->description = isset($form['description']) ? $form['description'] : NULL;
00266   $context->tag = isset($form['tag']) ? $form['tag'] : NULL;
00267   $context->condition_mode = isset($form['condition_mode']) ? $form['condition_mode'] : NULL;
00268   $context->conditions = array();
00269   $context->reactions = array();
00270   if (!empty($form['conditions'])) {
00271     $enabled = explode(',', $form['conditions']['state']);
00272     foreach ($form['conditions']['plugins'] as $condition => $values) {
00273       if (in_array($condition, $enabled, TRUE) && ($plugin = context_get_plugin('condition', $condition))) {
00274         if (isset($values['values'])) {
00275           $context->conditions[$condition]['values'] = $plugin->condition_form_submit($values['values']);
00276         }
00277         if (isset($values['options'])) {
00278           $context->conditions[$condition]['options'] = $plugin->options_form_submit($values['options']);
00279         }
00280         if ($submit && context_empty($context->conditions[$condition]['values'])) {
00281           unset($context->conditions[$condition]);
00282         }
00283       }
00284     }
00285   }
00286   if (!empty($form['reactions'])) {
00287     $enabled = explode(',', $form['reactions']['state']);
00288     foreach ($form['reactions']['plugins'] as $reaction => $values) {
00289       if (in_array($reaction, $enabled, TRUE) && ($plugin = context_get_plugin('reaction', $reaction))) {
00290         if (isset($values)) {
00291           $context->reactions[$reaction] = $plugin->options_form_submit($values);
00292         }
00293         if ($submit && context_empty($context->reactions[$reaction])) {
00294           unset($context->reactions[$reaction]);
00295         }
00296       }
00297     }
00298   }
00299   return $context;
00300 }
00301 
00302 /**
00303  * Submit handler for main context_ui form.
00304  */
00305 function context_ui_form_submit($form, &$form_state) {
00306   $form_state['item'] = context_ui_form_process($form_state['item'], $form_state['values']);
00307 }
00308 
00309 /**
00310  * Replacement for ctools_export_ui_edit_name_validate(). Allow dashes.
00311  */
00312 function context_ui_edit_name_validate($element, &$form_state) {
00313   $plugin = $form_state['plugin'];
00314   // Check for string identifier sanity
00315   if (!preg_match('!^[a-z0-9_-]+$!', $element['#value'])) {
00316     form_error($element, t('The name can only consist of lowercase letters, underscores, dashes, and numbers.'));
00317     return;
00318   }
00319 
00320   // Check for name collision
00321   if ($form_state['op'] != 'edit') {
00322     if (empty($form_state['item']->export_ui_allow_overwrite) && $exists = ctools_export_crud_load($plugin['schema'], $element['#value'])) {
00323       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'])));
00324     }
00325   }
00326 }

Generated on Fri May 24 02:23:53 2013 for Context by  doxygen 1.4.7