| Drupal | PHP Cross Reference | Content Management Systems |
1 <?php 2 3 /** 4 * @file 5 * Admin page callbacks for the trigger module. 6 */ 7 8 /** 9 * Builds a form that allows users to assign actions to triggers. 10 * 11 * @param $module_to_display 12 * Which tab of triggers to display. E.g., 'node' for all node-related 13 * triggers. 14 * 15 * @return 16 * HTML form. 17 * 18 * @see trigger_menu() 19 */ 20 function trigger_assign($module_to_display = NULL) { 21 // If no type is specified we default to node actions, since they 22 // are the most common. 23 if (!isset($module_to_display)) { 24 drupal_goto('admin/structure/trigger/node'); 25 } 26 27 $build = array(); 28 $trigger_info = module_invoke_all('trigger_info'); 29 drupal_alter('trigger_info', $trigger_info); 30 foreach ($trigger_info as $module => $hooks) { 31 if ($module == $module_to_display) { 32 foreach ($hooks as $hook => $description) { 33 $form_id = 'trigger_' . $hook . '_assign_form'; 34 $build[$form_id] = drupal_get_form($form_id, $module, $hook, $description['label']); 35 } 36 } 37 } 38 return $build; 39 } 40 41 /** 42 * Form constructor for confirmation page for removal of an assigned action. 43 * 44 * @param $module 45 * The tab of triggers the user will be directed to after successful 46 * removal of the action, or if the confirmation form is cancelled. 47 * @param $hook 48 * The name of the trigger hook, e.g., 'node_insert'. 49 * @param $aid 50 * The action ID. 51 * 52 * @see trigger_unassign_submit() 53 * @ingroup forms 54 */ 55 function trigger_unassign($form, $form_state, $module, $hook = NULL, $aid = NULL) { 56 if (!isset($hook, $aid)) { 57 drupal_goto('admin/structure/trigger'); 58 } 59 60 $form['hook'] = array( 61 '#type' => 'value', 62 '#value' => $hook, 63 ); 64 $form['module'] = array( 65 '#type' => 'value', 66 '#value' => $module, 67 ); 68 $form['aid'] = array( 69 '#type' => 'value', 70 '#value' => $aid, 71 ); 72 73 $action = actions_function_lookup($aid); 74 $actions = actions_get_all_actions(); 75 76 $destination = 'admin/structure/trigger/' . $module; 77 78 return confirm_form($form, 79 t('Are you sure you want to unassign the action %title?', array('%title' => $actions[$action]['label'])), 80 $destination, 81 t('You can assign it again later if you wish.'), 82 t('Unassign'), t('Cancel') 83 ); 84 } 85 86 /** 87 * Form submission handler for trigger_unassign(). 88 */ 89 function trigger_unassign_submit($form, &$form_state) { 90 if ($form_state['values']['confirm'] == 1) { 91 $aid = actions_function_lookup($form_state['values']['aid']); 92 db_delete('trigger_assignments') 93 ->condition('hook', $form_state['values']['hook']) 94 ->condition('aid', $aid) 95 ->execute(); 96 drupal_static_reset('trigger_get_assigned_actions'); 97 $actions = actions_get_all_actions(); 98 watchdog('actions', 'Action %action has been unassigned.', array('%action' => $actions[$aid]['label'])); 99 drupal_set_message(t('Action %action has been unassigned.', array('%action' => $actions[$aid]['label']))); 100 $form_state['redirect'] = 'admin/structure/trigger/' . $form_state['values']['module']; 101 } 102 else { 103 drupal_goto('admin/structure/trigger'); 104 } 105 } 106 107 /** 108 * Returns the form for assigning an action to a trigger. 109 * 110 * @param $module 111 * The name of the trigger group, e.g., 'node'. 112 * @param $hook 113 * The name of the trigger hook, e.g., 'node_insert'. 114 * @param $label 115 * A plain English description of what this trigger does. 116 * 117 * @see trigger_assign_form_validate() 118 * @see trigger_assign_form_submit() 119 * @ingroup forms 120 */ 121 function trigger_assign_form($form, $form_state, $module, $hook, $label) { 122 $form['module'] = array( 123 '#type' => 'hidden', 124 '#value' => $module, 125 ); 126 $form['hook'] = array( 127 '#type' => 'hidden', 128 '#value' => $hook, 129 ); 130 // All of these forms use the same validate and submit functions. 131 $form['#validate'][] = 'trigger_assign_form_validate'; 132 $form['#submit'][] = 'trigger_assign_form_submit'; 133 134 $options = array(); 135 $functions = array(); 136 // Restrict the options list to actions that declare support for this hook. 137 foreach (actions_list() as $func => $metadata) { 138 if (isset($metadata['triggers']) && array_intersect(array($hook, 'any'), $metadata['triggers'])) { 139 $functions[] = $func; 140 } 141 } 142 foreach (actions_actions_map(actions_get_all_actions()) as $aid => $action) { 143 if (in_array($action['callback'], $functions)) { 144 $options[$action['type']][$aid] = $action['label']; 145 } 146 } 147 148 $form[$hook] = array( 149 '#type' => 'fieldset', 150 // !description is correct, since these labels are passed through t() in 151 // hook_trigger_info(). 152 '#title' => t('Trigger: !description', array('!description' => $label)), 153 '#theme' => 'trigger_display', 154 ); 155 156 // Retrieve actions that are already assigned to this hook combination. 157 $actions = trigger_get_assigned_actions($hook); 158 $form[$hook]['assigned']['#type'] = 'value'; 159 $form[$hook]['assigned']['#value'] = array(); 160 foreach ($actions as $aid => $info) { 161 // If action is defined unassign it, otherwise offer to delete all orphaned 162 // actions. 163 $hash = drupal_hash_base64($aid, TRUE); 164 if (actions_function_lookup($hash)) { 165 $form[$hook]['assigned']['#value'][$aid] = array( 166 'label' => $info['label'], 167 'link' => l(t('unassign'), "admin/structure/trigger/unassign/$module/$hook/$hash"), 168 ); 169 } 170 else { 171 // Link to system_actions_remove_orphans() to do the clean up. 172 $form[$hook]['assigned']['#value'][$aid] = array( 173 'label' => $info['label'], 174 'link' => l(t('Remove orphaned actions'), "admin/config/system/actions/orphan"), 175 ); 176 } 177 } 178 179 $form[$hook]['parent'] = array( 180 '#type' => 'container', 181 '#attributes' => array('class' => array('container-inline')), 182 ); 183 // List possible actions that may be assigned. 184 if (count($options) != 0) { 185 $form[$hook]['parent']['aid'] = array( 186 '#type' => 'select', 187 '#title' => t('List of trigger actions when !description', array('!description' => $label)), 188 '#title_display' => 'invisible', 189 '#options' => $options, 190 '#empty_option' => t('Choose an action'), 191 ); 192 $form[$hook]['parent']['submit'] = array( 193 '#type' => 'submit', 194 '#value' => t('Assign') 195 ); 196 } 197 else { 198 $form[$hook]['none'] = array( 199 '#markup' => t('No actions available for this trigger. <a href="@link">Add action</a>.', array('@link' => url('admin/config/system/actions/manage'))) 200 ); 201 } 202 return $form; 203 } 204 205 /** 206 * Form validation handler for trigger_assign_form(). 207 * 208 * Makes sure that the user is not re-assigning an action to an event. 209 * 210 * @see trigger_assign_form_submit() 211 */ 212 function trigger_assign_form_validate($form, $form_state) { 213 $form_values = $form_state['values']; 214 if (!empty($form_values['aid'])) { 215 $aid = actions_function_lookup($form_values['aid']); 216 $aid_exists = db_query("SELECT aid FROM {trigger_assignments} WHERE hook = :hook AND aid = :aid", array( 217 ':hook' => $form_values['hook'], 218 ':aid' => $aid, 219 ))->fetchField(); 220 if ($aid_exists) { 221 form_set_error($form_values['hook'], t('The action you chose is already assigned to that trigger.')); 222 } 223 } 224 } 225 226 /** 227 * Form submission handler for trigger_assign_form(). 228 * 229 * @see trigger_assign_form_validate() 230 */ 231 function trigger_assign_form_submit($form, &$form_state) { 232 if (!empty($form_state['values']['aid'])) { 233 $aid = actions_function_lookup($form_state['values']['aid']); 234 $weight = db_query("SELECT MAX(weight) FROM {trigger_assignments} WHERE hook = :hook", array(':hook' => $form_state['values']['hook']))->fetchField(); 235 236 // Insert the new action. 237 db_insert('trigger_assignments') 238 ->fields(array( 239 'hook' => $form_state['values']['hook'], 240 'aid' => $aid, 241 'weight' => $weight + 1, 242 )) 243 ->execute(); 244 245 // If we are not configuring an action for a "presave" hook and this action 246 // changes an object property, then we need to save the object, so the 247 // property change will persist. 248 $actions = actions_list(); 249 if (strpos($form_state['values']['hook'], 'presave') === FALSE && isset($actions[$aid]['behavior']) && in_array('changes_property', $actions[$aid]['behavior'])) { 250 // Determine the corresponding save action name for this action. 251 $save_action = strtok($aid, '_') . '_save_action'; 252 // If no corresponding save action exists, we need to bail out. 253 if (!isset($actions[$save_action])) { 254 throw new Exception(t('Missing/undefined save action (%save_aid) for %aid action.', array('%save_aid' => $aid, '%aid' => $aid))); 255 } 256 // Delete previous save action if it exists, and re-add it using a higher 257 // weight. 258 $save_action_assigned = db_query("SELECT aid FROM {trigger_assignments} WHERE hook = :hook AND aid = :aid", array(':hook' => $form_state['values']['hook'], ':aid' => $save_action))->fetchField(); 259 260 if ($save_action_assigned) { 261 db_delete('trigger_assignments') 262 ->condition('hook', $form_state['values']['hook']) 263 ->condition('aid', $save_action) 264 ->execute(); 265 } 266 db_insert('trigger_assignments') 267 ->fields(array( 268 'hook' => $form_state['values']['hook'], 269 'aid' => $save_action, 270 'weight' => $weight + 2, 271 )) 272 ->execute(); 273 274 // If no save action existed before, inform the user about it. 275 if (!$save_action_assigned) { 276 drupal_set_message(t('The %label action has been appended, which is required to save the property change.', array('%label' => $actions[$save_action]['label']))); 277 } 278 // Otherwise, just inform about the new weight. 279 else { 280 drupal_set_message(t('The %label action was moved to save the property change.', array('%label' => $actions[$save_action]['label']))); 281 } 282 } 283 } 284 drupal_static_reset('trigger_get_assigned_actions'); 285 } 286 287 /** 288 * Returns HTML for the form showing actions assigned to a trigger. 289 * 290 * @param $variables 291 * An associative array containing: 292 * - element: The fieldset including all assigned actions. 293 * 294 * @ingroup themeable 295 */ 296 function theme_trigger_display($variables) { 297 $element = $variables['element']; 298 299 $header = array(); 300 $rows = array(); 301 if (isset($element['assigned']) && count($element['assigned']['#value'])) { 302 $header = array(array('data' => t('Name')), array('data' => t('Operation'))); 303 $rows = array(); 304 foreach ($element['assigned']['#value'] as $aid => $info) { 305 $rows[] = array( 306 check_plain($info['label']), 307 $info['link'] 308 ); 309 } 310 } 311 312 if (count($rows)) { 313 $output = theme('table', array('header' => $header, 'rows' => $rows)) . drupal_render_children($element); 314 } 315 else { 316 $output = drupal_render_children($element); 317 } 318 return $output; 319 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
title