Mercurial > hg > rr-repo
comparison sites/all/modules/webform/webform.api.php @ 0:ff03f76ab3fe
initial version
author | danieleb <danielebarchiesi@me.com> |
---|---|
date | Wed, 21 Aug 2013 18:51:11 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:ff03f76ab3fe |
---|---|
1 <?php | |
2 | |
3 /** | |
4 * @file | |
5 * Sample hooks demonstrating usage in Webform. | |
6 */ | |
7 | |
8 /** | |
9 * @defgroup webform_hooks Webform Module Hooks | |
10 * @{ | |
11 * Webform's hooks enable other modules to intercept events within Webform, such | |
12 * as the completion of a submission or adding validation. Webform's hooks also | |
13 * allow other modules to provide additional components for use within forms. | |
14 */ | |
15 | |
16 /** | |
17 * Define callbacks that can be used as select list options. | |
18 * | |
19 * When users create a select component, they may select a pre-built list of | |
20 * certain options. Webform core provides a few of these lists such as the | |
21 * United States, countries of the world, and days of the week. This hook | |
22 * provides additional lists that may be utilized. | |
23 * | |
24 * @see webform_options_example() | |
25 * @see hook_webform_select_options_info_alter() | |
26 * | |
27 * @return | |
28 * An array of callbacks that can be used for select list options. This array | |
29 * should be keyed by the "name" of the pre-defined list. The values should | |
30 * be an array with the following additional keys: | |
31 * - title: The translated title for this list. | |
32 * - options callback: The name of the function that will return the list. | |
33 * - options arguments: Any additional arguments to send to the callback. | |
34 * - file: Optional. The file containing the options callback, relative to | |
35 * the module root. | |
36 */ | |
37 function hook_webform_select_options_info() { | |
38 $items = array(); | |
39 | |
40 $items['days'] = array( | |
41 'title' => t('Days of the week'), | |
42 'options callback' => 'webform_options_days', | |
43 'file' => 'includes/webform.options.inc', | |
44 ); | |
45 | |
46 return $items; | |
47 } | |
48 | |
49 /** | |
50 * Alter the list of select list options provided by Webform and other modules. | |
51 * | |
52 * @see hook_webform_select_options_info(). | |
53 */ | |
54 function hook_webform_select_options_info_alter(&$items) { | |
55 // Remove the days of the week options. | |
56 unset($items['days']); | |
57 } | |
58 | |
59 /** | |
60 * This is an example function to demonstrate a webform options callback. | |
61 * | |
62 * This function returns a list of options that Webform may use in a select | |
63 * component. In order to be called, the function name | |
64 * ("webform_options_example" in this case), needs to be specified as a callback | |
65 * in hook_webform_select_options_info(). | |
66 * | |
67 * @param $component | |
68 * The Webform component array for the select component being displayed. | |
69 * @param $flat | |
70 * Boolean value indicating whether the returned list needs to be a flat array | |
71 * of key => value pairs. Select components support up to one level of | |
72 * nesting, but when results are displayed, the list needs to be returned | |
73 * without the nesting. | |
74 * @param $filter | |
75 * Boolean value indicating whether the included options should be passed | |
76 * through the _webform_filter_values() function for token replacement (only) | |
77 * needed if your list contains tokens). | |
78 * @param $arguments | |
79 * The "options arguments" specified in hook_webform_select_options_info(). | |
80 * @return | |
81 * An array of key => value pairs suitable for a select list's #options | |
82 * FormAPI property. | |
83 */ | |
84 function webform_options_example($component, $flat, $filter, $arguments) { | |
85 $options = array( | |
86 'one' => t('Pre-built option one'), | |
87 'two' => t('Pre-built option two'), | |
88 'three' => t('Pre-built option three'), | |
89 ); | |
90 | |
91 return $options; | |
92 } | |
93 | |
94 /** | |
95 * Respond to the loading of Webform submissions. | |
96 * | |
97 * @param $submissions | |
98 * An array of Webform submissions that are being loaded, keyed by the | |
99 * submission ID. Modifications to the submissions are done by reference. | |
100 */ | |
101 function hook_webform_submission_load(&$submissions) { | |
102 foreach ($submissions as $sid => $submission) { | |
103 $submissions[$sid]->new_property = 'foo'; | |
104 } | |
105 } | |
106 | |
107 /** | |
108 * Modify a Webform submission, prior to saving it in the database. | |
109 * | |
110 * @param $node | |
111 * The Webform node on which this submission was made. | |
112 * @param $submission | |
113 * The Webform submission that is about to be saved to the database. | |
114 */ | |
115 function hook_webform_submission_presave($node, &$submission) { | |
116 // Update some component's value before it is saved. | |
117 $component_id = 4; | |
118 $submission->data[$component_id]['value'][0] = 'foo'; | |
119 } | |
120 | |
121 /** | |
122 * Respond to a Webform submission being inserted. | |
123 * | |
124 * Note that this hook is called after a submission has already been saved to | |
125 * the database. If needing to modify the submission prior to insertion, use | |
126 * hook_webform_submission_presave(). | |
127 * | |
128 * @param $node | |
129 * The Webform node on which this submission was made. | |
130 * @param $submission | |
131 * The Webform submission that was just inserted into the database. | |
132 */ | |
133 function hook_webform_submission_insert($node, $submission) { | |
134 // Insert a record into a 3rd-party module table when a submission is added. | |
135 db_insert('mymodule_table') | |
136 ->fields(array( | |
137 'nid' => $node->nid, | |
138 'sid' => $submission->sid, | |
139 'foo' => 'foo_data', | |
140 )) | |
141 ->execute(); | |
142 } | |
143 | |
144 /** | |
145 * Respond to a Webform submission being updated. | |
146 * | |
147 * Note that this hook is called after a submission has already been saved to | |
148 * the database. If needing to modify the submission prior to updating, use | |
149 * hook_webform_submission_presave(). | |
150 * | |
151 * @param $node | |
152 * The Webform node on which this submission was made. | |
153 * @param $submission | |
154 * The Webform submission that was just updated in the database. | |
155 */ | |
156 function hook_webform_submission_update($node, $submission) { | |
157 // Update a record in a 3rd-party module table when a submission is updated. | |
158 db_update('mymodule_table') | |
159 ->fields(array( | |
160 'foo' => 'foo_data', | |
161 )) | |
162 ->condition('nid', $node->nid) | |
163 ->condition('sid', $submission->sid) | |
164 ->execute(); | |
165 } | |
166 | |
167 /** | |
168 * Respond to a Webform submission being deleted. | |
169 * | |
170 * @param $node | |
171 * The Webform node on which this submission was made. | |
172 * @param $submission | |
173 * The Webform submission that was just deleted from the database. | |
174 */ | |
175 function hook_webform_submission_delete($node, $submission) { | |
176 // Delete a record from a 3rd-party module table when a submission is deleted. | |
177 db_delete('mymodule_table') | |
178 ->condition('nid', $node->nid) | |
179 ->condition('sid', $submission->sid) | |
180 ->execute(); | |
181 } | |
182 | |
183 /** | |
184 * Provide a list of actions that can be executed on a submission. | |
185 * | |
186 * Some actions are displayed in the list of submissions such as edit, view, and | |
187 * delete. All other actions are displayed only when viewing the submission. | |
188 * These additional actions may be specified in this hook. Examples included | |
189 * directly in the Webform module include PDF, print, and resend e-mails. Other | |
190 * modules may extend this list by using this hook. | |
191 * | |
192 * @param $node | |
193 * The Webform node on which this submission was made. | |
194 * @param $submission | |
195 * The Webform submission on which the actions may be performed. | |
196 */ | |
197 function hook_webform_submission_actions($node, $submission) { | |
198 if (webform_results_access($node)) { | |
199 $actions['myaction'] = array( | |
200 'title' => t('Do my action'), | |
201 'href' => 'node/' . $node->nid . '/submission/' . $submission->sid . '/myaction', | |
202 'query' => drupal_get_destination(), | |
203 ); | |
204 } | |
205 | |
206 return $actions; | |
207 } | |
208 | |
209 /** | |
210 * Alter the display of a Webform submission. | |
211 * | |
212 * This function applies to both e-mails sent by Webform and normal display of | |
213 * submissions when viewing through the adminsitrative interface. | |
214 * | |
215 * @param $renderable | |
216 * The Webform submission in a renderable array, similar to FormAPI's | |
217 * structure. This variable must be passed in by-reference. Important | |
218 * properties of this array include #node, #submission, #email, and #format, | |
219 * which can be used to find the context of the submission that is being | |
220 * rendered. | |
221 */ | |
222 function hook_webform_submission_render_alter(&$renderable) { | |
223 // Remove page breaks from sent e-mails. | |
224 if (isset($renderable['#email'])) { | |
225 foreach (element_children($renderable) as $key) { | |
226 if ($renderable[$key]['#component']['type'] == 'pagebreak') { | |
227 unset($renderable[$key]); | |
228 } | |
229 } | |
230 } | |
231 } | |
232 | |
233 /** | |
234 * Modify a loaded Webform component. | |
235 * | |
236 * IMPORTANT: This hook does not actually exist because components are loaded | |
237 * in bulk as part of webform_node_load(). Use hook_node_load() to modify loaded | |
238 * components when the node is loaded. This example is provided merely to point | |
239 * to hook_node_load(). | |
240 * | |
241 * @see hook_nodeapi() | |
242 * @see webform_node_load() | |
243 */ | |
244 function hook_webform_component_load() { | |
245 // This hook does not exist. Instead use hook_node_load(). | |
246 } | |
247 | |
248 /** | |
249 * Modify a Webform component before it is saved to the database. | |
250 * | |
251 * Note that most of the time this hook is not necessary, because Webform will | |
252 * automatically add data to the component based on the component form. Using | |
253 * hook_form_alter() will be sufficient in most cases. | |
254 * | |
255 * @see hook_form_alter() | |
256 * @see webform_component_edit_form() | |
257 * | |
258 * @param $component | |
259 * The Webform component being saved. | |
260 */ | |
261 function hook_webform_component_presave(&$component) { | |
262 $component['extra']['new_option'] = 'foo'; | |
263 } | |
264 | |
265 /** | |
266 * Respond to a Webform component being inserted into the database. | |
267 */ | |
268 function hook_webform_component_insert($component) { | |
269 // Insert a record into a 3rd-party module table when a component is inserted. | |
270 db_insert('mymodule_table') | |
271 ->fields(array( | |
272 'nid' => $component['nid'], | |
273 'cid' => $component['cid'], | |
274 'foo' => 'foo_data', | |
275 )) | |
276 ->execute(); | |
277 } | |
278 | |
279 /** | |
280 * Respond to a Webform component being updated in the database. | |
281 */ | |
282 function hook_webform_component_update($component) { | |
283 // Update a record in a 3rd-party module table when a component is updated. | |
284 db_update('mymodule_table') | |
285 ->fields(array( | |
286 'foo' => 'foo_data', | |
287 )) | |
288 ->condition('nid', $component['nid']) | |
289 ->condition('cid', $component['cid']) | |
290 ->execute(); | |
291 } | |
292 | |
293 /** | |
294 * Respond to a Webform component being deleted. | |
295 */ | |
296 function hook_webform_component_delete($component) { | |
297 // Delete a record in a 3rd-party module table when a component is deleted. | |
298 db_delete('mymodule_table') | |
299 ->condition('nid', $component['nid']) | |
300 ->condition('cid', $component['cid']) | |
301 ->execute(); | |
302 } | |
303 | |
304 /** | |
305 * Define components to Webform. | |
306 * | |
307 * @return | |
308 * An array of components, keyed by machine name. Required properties are | |
309 * "label" and "description". The "features" array defines which capabilities | |
310 * the component has, such as being displayed in e-mails or csv downloads. | |
311 * A component like "markup" for example would not show in these locations. | |
312 * The possible features of a component include: | |
313 * | |
314 * - csv | |
315 * - email | |
316 * - email_address | |
317 * - email_name | |
318 * - required | |
319 * - conditional | |
320 * - spam_analysis | |
321 * - group | |
322 * | |
323 * Note that most of these features do not indicate the default state, but | |
324 * determine if the component can have this property at all. Setting | |
325 * "required" to TRUE does not mean that a component's fields will always be | |
326 * required, but instead give the option to the administrator to choose the | |
327 * requiredness. See the example implementation for details on how these | |
328 * features may be set. | |
329 * | |
330 * An optional "file" may be specified to be loaded when the component is | |
331 * needed. A set of callbacks will be established based on the name of the | |
332 * component. All components follow the pattern: | |
333 * | |
334 * _webform_[callback]_[component] | |
335 * | |
336 * Where [component] is the name of the key of the component and [callback] is | |
337 * any of the following: | |
338 * | |
339 * - defaults | |
340 * - edit | |
341 * - render | |
342 * - display | |
343 * - submit | |
344 * - delete | |
345 * - help | |
346 * - theme | |
347 * - analysis | |
348 * - table | |
349 * - csv_headers | |
350 * - csv_data | |
351 * | |
352 * See the sample component implementation for details on each one of these | |
353 * callbacks. | |
354 * | |
355 * @see webform_components() | |
356 */ | |
357 function hook_webform_component_info() { | |
358 $components = array(); | |
359 | |
360 $components['textfield'] = array( | |
361 'label' => t('Textfield'), | |
362 'description' => t('Basic textfield type.'), | |
363 'features' => array( | |
364 // Add content to CSV downloads. Defaults to TRUE. | |
365 'csv' => TRUE, | |
366 | |
367 // This component supports default values. Defaults to TRUE. | |
368 'default_value' => FALSE, | |
369 | |
370 // This component supports a description field. Defaults to TRUE. | |
371 'description' => FALSE, | |
372 | |
373 // Show this component in e-mailed submissions. Defaults to TRUE. | |
374 'email' => TRUE, | |
375 | |
376 // Allow this component to be used as an e-mail FROM or TO address. | |
377 // Defaults to FALSE. | |
378 'email_address' => FALSE, | |
379 | |
380 // Allow this component to be used as an e-mail SUBJECT or FROM name. | |
381 // Defaults to FALSE. | |
382 'email_name' => TRUE, | |
383 | |
384 // This component may be toggled as required or not. Defaults to TRUE. | |
385 'required' => TRUE, | |
386 | |
387 // This component supports a title attribute. Defaults to TRUE. | |
388 'title' => FALSE, | |
389 | |
390 // This component has a title that can be toggled as displayed or not. | |
391 'title_display' => TRUE, | |
392 | |
393 // This component has a title that can be displayed inline. | |
394 'title_inline' => TRUE, | |
395 | |
396 // If this component can be used as a conditional SOURCE. All components | |
397 // may always be displayed conditionally, regardless of this setting. | |
398 // Defaults to TRUE. | |
399 'conditional' => TRUE, | |
400 | |
401 // If this component allows other components to be grouped within it | |
402 // (like a fieldset or tabs). Defaults to FALSE. | |
403 'group' => FALSE, | |
404 | |
405 // If this component can be used for SPAM analysis, usually with Mollom. | |
406 'spam_analysis' => FALSE, | |
407 | |
408 // If this component saves a file that can be used as an e-mail | |
409 // attachment. Defaults to FALSE. | |
410 'attachment' => FALSE, | |
411 ), | |
412 'file' => 'components/textfield.inc', | |
413 ); | |
414 | |
415 return $components; | |
416 } | |
417 | |
418 /** | |
419 * Alter the list of available Webform components. | |
420 * | |
421 * @param $components | |
422 * A list of existing components as defined by hook_webform_component_info(). | |
423 * | |
424 * @see hook_webform_component_info() | |
425 */ | |
426 function hook_webform_component_info_alter(&$components) { | |
427 // Completely remove a component. | |
428 unset($components['grid']); | |
429 | |
430 // Change the name of a component. | |
431 $components['textarea']['label'] = t('Text box'); | |
432 } | |
433 | |
434 /** | |
435 * Alter access to a Webform submission. | |
436 * | |
437 * @param $node | |
438 * The Webform node on which this submission was made. | |
439 * @param $submission | |
440 * The Webform submission. | |
441 * @param $op | |
442 * The operation to be performed on the submission. Possible values are: | |
443 * - "view" | |
444 * - "edit" | |
445 * - "delete" | |
446 * - "list" | |
447 * @param $account | |
448 * A user account object. | |
449 * @return | |
450 * TRUE if the current user has access to submission, | |
451 * or FALSE otherwise. | |
452 */ | |
453 function hook_webform_submission_access($node, $submission, $op = 'view', $account = NULL) { | |
454 switch ($op) { | |
455 case 'view': | |
456 return TRUE; | |
457 break; | |
458 case 'edit': | |
459 return FALSE; | |
460 break; | |
461 case 'delete': | |
462 return TRUE; | |
463 break; | |
464 case 'list': | |
465 return TRUE; | |
466 break; | |
467 } | |
468 } | |
469 | |
470 /** | |
471 * Determine if a user has access to see the results of a webform. | |
472 * | |
473 * Note in addition to the view access to the results granted here, the $account | |
474 * must also have view access to the Webform node in order to see results. | |
475 * | |
476 * @see webform_results_access(). | |
477 * | |
478 * @param $node | |
479 * The Webform node to check access on. | |
480 * @param $account | |
481 * The user account to check access on. | |
482 * @return | |
483 * TRUE or FALSE if the user can access the webform results. | |
484 */ | |
485 function hook_webform_results_access($node, $account) { | |
486 // Let editors view results of unpublished webforms. | |
487 if ($node->status == 0 && in_array('editor', $account->roles)) { | |
488 return TRUE; | |
489 } | |
490 else { | |
491 return FALSE; | |
492 } | |
493 } | |
494 | |
495 /** | |
496 * Return an array of files associated with the component. | |
497 * | |
498 * The output of this function will be used to attach files to e-mail messages. | |
499 * | |
500 * @param $component | |
501 * A Webform component array. | |
502 * @param $value | |
503 * An array of information containing the submission result, directly | |
504 * correlating to the webform_submitted_data database schema. | |
505 * @return | |
506 * An array of files, each file is an array with following keys: | |
507 * - filepath: The relative path to the file. | |
508 * - filename: The name of the file including the extension. | |
509 * - filemime: The mimetype of the file. | |
510 * This will result in an array looking something like this: | |
511 * @code | |
512 * array[0] => array( | |
513 * 'filepath' => '/sites/default/files/attachment.txt', | |
514 * 'filename' => 'attachment.txt', | |
515 * 'filemime' => 'text/plain', | |
516 * ); | |
517 * @endcode | |
518 */ | |
519 function _webform_attachments_component($component, $value) { | |
520 $files = array(); | |
521 $files[] = (array) file_load($value[0]); | |
522 return $files; | |
523 } | |
524 | |
525 /** | |
526 * @} | |
527 */ | |
528 | |
529 /** | |
530 * @defgroup webform_component Sample Webform Component | |
531 * @{ | |
532 * In each of these examples, the word "component" should be replaced with the, | |
533 * name of the component type (such as textfield or select). These are not | |
534 * actual hooks, but instead samples of how Webform integrates with its own | |
535 * built-in components. | |
536 */ | |
537 | |
538 /** | |
539 * Specify the default properties of a component. | |
540 * | |
541 * @return | |
542 * An array defining the default structure of a component. | |
543 */ | |
544 function _webform_defaults_component() { | |
545 return array( | |
546 'name' => '', | |
547 'form_key' => NULL, | |
548 'mandatory' => 0, | |
549 'pid' => 0, | |
550 'weight' => 0, | |
551 'extra' => array( | |
552 'options' => '', | |
553 'questions' => '', | |
554 'optrand' => 0, | |
555 'qrand' => 0, | |
556 'description' => '', | |
557 ), | |
558 ); | |
559 } | |
560 | |
561 /** | |
562 * Generate the form for editing a component. | |
563 * | |
564 * Create a set of form elements to be displayed on the form for editing this | |
565 * component. Use care naming the form items, as this correlates directly to the | |
566 * database schema. The component "Name" and "Description" fields are added to | |
567 * every component type and are not necessary to specify here (although they | |
568 * may be overridden if desired). | |
569 * | |
570 * @param $component | |
571 * A Webform component array. | |
572 * @return | |
573 * An array of form items to be displayed on the edit component page | |
574 */ | |
575 function _webform_edit_component($component) { | |
576 $form = array(); | |
577 | |
578 // Disabling the description if not wanted. | |
579 $form['description'] = array(); | |
580 | |
581 // Most options are stored in the "extra" array, which stores any settings | |
582 // unique to a particular component type. | |
583 $form['extra']['options'] = array( | |
584 '#type' => 'textarea', | |
585 '#title' => t('Options'), | |
586 '#default_value' => $component['extra']['options'], | |
587 '#description' => t('Key-value pairs may be entered separated by pipes. i.e. safe_key|Some readable option') . theme('webform_token_help'), | |
588 '#cols' => 60, | |
589 '#rows' => 5, | |
590 '#weight' => -3, | |
591 '#required' => TRUE, | |
592 ); | |
593 return $form; | |
594 } | |
595 | |
596 /** | |
597 * Render a Webform component to be part of a form. | |
598 * | |
599 * @param $component | |
600 * A Webform component array. | |
601 * @param $value | |
602 * If editing an existing submission or resuming a draft, this will contain | |
603 * an array of values to be shown instead of the default in the component | |
604 * configuration. This value will always be an array, keyed numerically for | |
605 * each value saved in this field. | |
606 * @param $filter | |
607 * Whether or not to filter the contents of descriptions and values when | |
608 * rendering the component. Values need to be unfiltered to be editable by | |
609 * Form Builder. | |
610 * | |
611 * @see _webform_client_form_add_component() | |
612 */ | |
613 function _webform_render_component($component, $value = NULL, $filter = TRUE) { | |
614 $form_item = array( | |
615 '#type' => 'textfield', | |
616 '#title' => $filter ? _webform_filter_xss($component['name']) : $component['name'], | |
617 '#required' => $component['mandatory'], | |
618 '#weight' => $component['weight'], | |
619 '#description' => $filter ? _webform_filter_descriptions($component['extra']['description']) : $component['extra']['description'], | |
620 '#default_value' => $filter ? _webform_filter_values($component['value']) : $component['value'], | |
621 '#prefix' => '<div class="webform-component-textfield" id="webform-component-' . $component['form_key'] . '">', | |
622 '#suffix' => '</div>', | |
623 ); | |
624 | |
625 if (isset($value)) { | |
626 $form_item['#default_value'] = $value[0]; | |
627 } | |
628 | |
629 return $form_item; | |
630 } | |
631 | |
632 /** | |
633 * Display the result of a submission for a component. | |
634 * | |
635 * The output of this function will be displayed under the "Results" tab then | |
636 * "Submissions". This should output the saved data in some reasonable manner. | |
637 * | |
638 * @param $component | |
639 * A Webform component array. | |
640 * @param $value | |
641 * An array of information containing the submission result, directly | |
642 * correlating to the webform_submitted_data database table schema. | |
643 * @param $format | |
644 * Either 'html' or 'text'. Defines the format that the content should be | |
645 * returned as. Make sure that returned content is run through check_plain() | |
646 * or other filtering functions when returning HTML. | |
647 * @return | |
648 * A renderable element containing at the very least these properties: | |
649 * - #title | |
650 * - #weight | |
651 * - #component | |
652 * - #format | |
653 * - #value | |
654 * Webform also uses #theme_wrappers to output the end result to the user, | |
655 * which will properly format the label and content for use within an e-mail | |
656 * (such as wrapping the text) or as HTML (ensuring consistent output). | |
657 */ | |
658 function _webform_display_component($component, $value, $format = 'html') { | |
659 return array( | |
660 '#title' => $component['name'], | |
661 '#weight' => $component['weight'], | |
662 '#theme' => 'webform_display_textfield', | |
663 '#theme_wrappers' => $format == 'html' ? array('webform_element') : array('webform_element_text'), | |
664 '#post_render' => array('webform_element_wrapper'), | |
665 '#field_prefix' => $component['extra']['field_prefix'], | |
666 '#field_suffix' => $component['extra']['field_suffix'], | |
667 '#component' => $component, | |
668 '#format' => $format, | |
669 '#value' => isset($value[0]) ? $value[0] : '', | |
670 ); | |
671 } | |
672 | |
673 /** | |
674 * A hook for changing the input values before saving to the database. | |
675 * | |
676 * Webform expects a component to consist of a single field, or a single array | |
677 * of fields. If you have a component that requires a deeper form tree | |
678 * you must flatten the data into a single array using this callback | |
679 * or by setting #parents on each field to avoid data loss and/or unexpected | |
680 * behavior. | |
681 * | |
682 * Note that Webform will save the result of this function directly into the | |
683 * database. | |
684 * | |
685 * @param $component | |
686 * A Webform component array. | |
687 * @param $value | |
688 * The POST data associated with the user input. | |
689 * @return | |
690 * An array of values to be saved into the database. Note that this should be | |
691 * a numerically keyed array. | |
692 */ | |
693 function _webform_submit_component($component, $value) { | |
694 // Clean up a phone number into 123-456-7890 format. | |
695 if ($component['extra']['phone_number']) { | |
696 $matches = array(); | |
697 $number = preg_replace('[^0-9]', $value[0]); | |
698 if (strlen($number) == 7) { | |
699 $number = substr($number, 0, 3) . '-' . substr($number, 3, 4); | |
700 } | |
701 else { | |
702 $number = substr($number, 0, 3) . '-' . substr($number, 3, 3) . '-' . substr($number, 6, 4); | |
703 } | |
704 } | |
705 | |
706 $value[0] = $number; | |
707 return $value; | |
708 } | |
709 | |
710 /** | |
711 * Delete operation for a component or submission. | |
712 * | |
713 * @param $component | |
714 * A Webform component array. | |
715 * @param $value | |
716 * An array of information containing the submission result, directly | |
717 * correlating to the webform_submitted_data database schema. | |
718 */ | |
719 function _webform_delete_component($component, $value) { | |
720 // Delete corresponding files when a submission is deleted. | |
721 $filedata = unserialize($value['0']); | |
722 if (isset($filedata['filepath']) && is_file($filedata['filepath'])) { | |
723 unlink($filedata['filepath']); | |
724 db_query("DELETE FROM {files} WHERE filepath = '%s'", $filedata['filepath']); | |
725 } | |
726 } | |
727 | |
728 /** | |
729 * Module specific instance of hook_help(). | |
730 * | |
731 * This allows each Webform component to add information into hook_help(). | |
732 */ | |
733 function _webform_help_component($section) { | |
734 switch ($section) { | |
735 case 'admin/config/content/webform#grid_description': | |
736 return t('Allows creation of grid questions, denoted by radio buttons.'); | |
737 } | |
738 } | |
739 | |
740 /** | |
741 * Module specific instance of hook_theme(). | |
742 * | |
743 * This allows each Webform component to add information into hook_theme(). If | |
744 * you specify a file to include, you must define the path to the module that | |
745 * this file belongs to. | |
746 */ | |
747 function _webform_theme_component() { | |
748 return array( | |
749 'webform_grid' => array( | |
750 'render element' => 'element', | |
751 'file' => 'components/grid.inc', | |
752 'path' => drupal_get_path('module', 'webform'), | |
753 ), | |
754 'webform_display_grid' => array( | |
755 'render element' => 'element', | |
756 'file' => 'components/grid.inc', | |
757 'path' => drupal_get_path('module', 'webform'), | |
758 ), | |
759 ); | |
760 } | |
761 | |
762 /** | |
763 * Calculate and returns statistics about results for this component. | |
764 * | |
765 * This takes into account all submissions to this webform. The output of this | |
766 * function will be displayed under the "Results" tab then "Analysis". | |
767 * | |
768 * @param $component | |
769 * An array of information describing the component, directly correlating to | |
770 * the webform_component database schema. | |
771 * @param $sids | |
772 * An optional array of submission IDs (sid). If supplied, the analysis will | |
773 * be limited to these sids. | |
774 * @param $single | |
775 * Boolean flag determining if the details about a single component are being | |
776 * shown. May be used to provided detailed information about a single | |
777 * component's analysis, such as showing "Other" options within a select list. | |
778 * @return | |
779 * An array of data rows, each containing a statistic for this component's | |
780 * submissions. | |
781 */ | |
782 function _webform_analysis_component($component, $sids = array(), $single = FALSE) { | |
783 // Generate the list of options and questions. | |
784 $options = _webform_select_options_from_text($component['extra']['options'], TRUE); | |
785 $questions = _webform_select_options_from_text($component['extra']['questions'], TRUE); | |
786 | |
787 // Generate a lookup table of results. | |
788 $query = db_select('webform_submitted_data', 'wsd') | |
789 ->fields('wsd', array('no', 'data')) | |
790 ->condition('nid', $component['nid']) | |
791 ->condition('cid', $component['cid']) | |
792 ->condition('data', '', '<>') | |
793 ->groupBy('no') | |
794 ->groupBy('data'); | |
795 $query->addExpression('COUNT(sid)', 'datacount'); | |
796 | |
797 if (count($sids)) { | |
798 $query->condition('sid', $sids, 'IN'); | |
799 } | |
800 | |
801 $result = $query->execute(); | |
802 $counts = array(); | |
803 foreach ($result as $data) { | |
804 $counts[$data->no][$data->data] = $data->datacount; | |
805 } | |
806 | |
807 // Create an entire table to be put into the returned row. | |
808 $rows = array(); | |
809 $header = array(''); | |
810 | |
811 // Add options as a header row. | |
812 foreach ($options as $option) { | |
813 $header[] = $option; | |
814 } | |
815 | |
816 // Add questions as each row. | |
817 foreach ($questions as $qkey => $question) { | |
818 $row = array($question); | |
819 foreach ($options as $okey => $option) { | |
820 $row[] = !empty($counts[$qkey][$okey]) ? $counts[$qkey][$okey] : 0; | |
821 } | |
822 $rows[] = $row; | |
823 } | |
824 $output = theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('class' => array('webform-grid')))); | |
825 | |
826 return array(array(array('data' => $output, 'colspan' => 2))); | |
827 } | |
828 | |
829 /** | |
830 * Return the result of a component value for display in a table. | |
831 * | |
832 * The output of this function will be displayed under the "Results" tab then | |
833 * "Table". | |
834 * | |
835 * @param $component | |
836 * A Webform component array. | |
837 * @param $value | |
838 * An array of information containing the submission result, directly | |
839 * correlating to the webform_submitted_data database schema. | |
840 * @return | |
841 * Textual output formatted for human reading. | |
842 */ | |
843 function _webform_table_component($component, $value) { | |
844 $questions = array_values(_webform_component_options($component['extra']['questions'])); | |
845 $output = ''; | |
846 // Set the value as a single string. | |
847 if (is_array($value)) { | |
848 foreach ($value as $item => $value) { | |
849 if ($value !== '') { | |
850 $output .= $questions[$item] . ': ' . check_plain($value) . '<br />'; | |
851 } | |
852 } | |
853 } | |
854 else { | |
855 $output = check_plain(!isset($value['0']) ? '' : $value['0']); | |
856 } | |
857 return $output; | |
858 } | |
859 | |
860 /** | |
861 * Return the header for this component to be displayed in a CSV file. | |
862 * | |
863 * The output of this function will be displayed under the "Results" tab then | |
864 * "Download". | |
865 * | |
866 * @param $component | |
867 * A Webform component array. | |
868 * @param $export_options | |
869 * An array of options that may configure export of this field. | |
870 * @return | |
871 * An array of data to be displayed in the first three rows of a CSV file, not | |
872 * including either prefixed or trailing commas. | |
873 */ | |
874 function _webform_csv_headers_component($component, $export_options) { | |
875 $header = array(); | |
876 $header[0] = array(''); | |
877 $header[1] = array($component['name']); | |
878 $items = _webform_component_options($component['extra']['questions']); | |
879 $count = 0; | |
880 foreach ($items as $key => $item) { | |
881 // Empty column per sub-field in main header. | |
882 if ($count != 0) { | |
883 $header[0][] = ''; | |
884 $header[1][] = ''; | |
885 } | |
886 // The value for this option. | |
887 $header[2][] = $item; | |
888 $count++; | |
889 } | |
890 | |
891 return $header; | |
892 } | |
893 | |
894 /** | |
895 * Format the submitted data of a component for CSV downloading. | |
896 * | |
897 * The output of this function will be displayed under the "Results" tab then | |
898 * "Download". | |
899 * | |
900 * @param $component | |
901 * A Webform component array. | |
902 * @param $export_options | |
903 * An array of options that may configure export of this field. | |
904 * @param $value | |
905 * An array of information containing the submission result, directly | |
906 * correlating to the webform_submitted_data database schema. | |
907 * @return | |
908 * An array of items to be added to the CSV file. Each value within the array | |
909 * will be another column within the file. This function is called once for | |
910 * every row of data. | |
911 */ | |
912 function _webform_csv_data_component($component, $export_options, $value) { | |
913 $questions = array_keys(_webform_select_options($component['extra']['questions'])); | |
914 $return = array(); | |
915 foreach ($questions as $key => $question) { | |
916 $return[] = isset($value[$key]) ? $value[$key] : ''; | |
917 } | |
918 return $return; | |
919 } | |
920 | |
921 /** | |
922 * @} | |
923 */ |