|
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 } |