root / drupal7 / sites / all / modules / webform / webform.api.php @ 4cfd8be6
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 |
* Alter a Webform submission's header when exported.
|
306 |
*/
|
307 |
function hook_webform_csv_header_alter(&$header, $component) { |
308 |
// Use the machine name for component headers, but only for the webform
|
309 |
// with node 5 and components that are text fields.
|
310 |
if ($component['nid'] == 5 && $component['type'] == 'textfield') { |
311 |
$header[2] = $component['form_key']; |
312 |
} |
313 |
} |
314 |
|
315 |
/**
|
316 |
* Alter a Webform submission's data when exported.
|
317 |
*/
|
318 |
function hook_webform_csv_data_alter(&$data, $component, $submission) { |
319 |
// If a value of a field was left blank, use the value from another
|
320 |
// field.
|
321 |
if ($component['cid'] == 1 && empty($data)) { |
322 |
$data = $submission->data[2]['value'][0]; |
323 |
} |
324 |
} |
325 |
|
326 |
/**
|
327 |
* Define components to Webform.
|
328 |
*
|
329 |
* @return
|
330 |
* An array of components, keyed by machine name. Required properties are
|
331 |
* "label" and "description". The "features" array defines which capabilities
|
332 |
* the component has, such as being displayed in e-mails or csv downloads.
|
333 |
* A component like "markup" for example would not show in these locations.
|
334 |
* The possible features of a component include:
|
335 |
*
|
336 |
* - csv
|
337 |
* - email
|
338 |
* - email_address
|
339 |
* - email_name
|
340 |
* - required
|
341 |
* - conditional
|
342 |
* - spam_analysis
|
343 |
* - group
|
344 |
*
|
345 |
* Note that most of these features do not indicate the default state, but
|
346 |
* determine if the component can have this property at all. Setting
|
347 |
* "required" to TRUE does not mean that a component's fields will always be
|
348 |
* required, but instead give the option to the administrator to choose the
|
349 |
* requiredness. See the example implementation for details on how these
|
350 |
* features may be set.
|
351 |
*
|
352 |
* An optional "file" may be specified to be loaded when the component is
|
353 |
* needed. A set of callbacks will be established based on the name of the
|
354 |
* component. All components follow the pattern:
|
355 |
*
|
356 |
* _webform_[callback]_[component]
|
357 |
*
|
358 |
* Where [component] is the name of the key of the component and [callback] is
|
359 |
* any of the following:
|
360 |
*
|
361 |
* - defaults
|
362 |
* - edit
|
363 |
* - render
|
364 |
* - display
|
365 |
* - submit
|
366 |
* - delete
|
367 |
* - help
|
368 |
* - theme
|
369 |
* - analysis
|
370 |
* - table
|
371 |
* - csv_headers
|
372 |
* - csv_data
|
373 |
*
|
374 |
* See the sample component implementation for details on each one of these
|
375 |
* callbacks.
|
376 |
*
|
377 |
* @see webform_components()
|
378 |
*/
|
379 |
function hook_webform_component_info() { |
380 |
$components = array(); |
381 |
|
382 |
$components['textfield'] = array( |
383 |
'label' => t('Textfield'), |
384 |
'description' => t('Basic textfield type.'), |
385 |
'features' => array( |
386 |
// Add content to CSV downloads. Defaults to TRUE.
|
387 |
'csv' => TRUE, |
388 |
|
389 |
// This component supports default values. Defaults to TRUE.
|
390 |
'default_value' => FALSE, |
391 |
|
392 |
// This component supports a description field. Defaults to TRUE.
|
393 |
'description' => FALSE, |
394 |
|
395 |
// Show this component in e-mailed submissions. Defaults to TRUE.
|
396 |
'email' => TRUE, |
397 |
|
398 |
// Allow this component to be used as an e-mail FROM or TO address.
|
399 |
// Defaults to FALSE.
|
400 |
'email_address' => FALSE, |
401 |
|
402 |
// Allow this component to be used as an e-mail SUBJECT or FROM name.
|
403 |
// Defaults to FALSE.
|
404 |
'email_name' => TRUE, |
405 |
|
406 |
// This component may be toggled as required or not. Defaults to TRUE.
|
407 |
'required' => TRUE, |
408 |
|
409 |
// This component supports a title attribute. Defaults to TRUE.
|
410 |
'title' => FALSE, |
411 |
|
412 |
// This component has a title that can be toggled as displayed or not.
|
413 |
'title_display' => TRUE, |
414 |
|
415 |
// This component has a title that can be displayed inline.
|
416 |
'title_inline' => TRUE, |
417 |
|
418 |
// If this component can be used as a conditional SOURCE. All components
|
419 |
// may always be displayed conditionally, regardless of this setting.
|
420 |
// Defaults to TRUE.
|
421 |
'conditional' => TRUE, |
422 |
|
423 |
// If this component allows other components to be grouped within it
|
424 |
// (like a fieldset or tabs). Defaults to FALSE.
|
425 |
'group' => FALSE, |
426 |
|
427 |
// If this component can be used for SPAM analysis, usually with Mollom.
|
428 |
'spam_analysis' => FALSE, |
429 |
|
430 |
// If this component saves a file that can be used as an e-mail
|
431 |
// attachment. Defaults to FALSE.
|
432 |
'attachment' => FALSE, |
433 |
), |
434 |
'file' => 'components/textfield.inc', |
435 |
); |
436 |
|
437 |
return $components; |
438 |
} |
439 |
|
440 |
/**
|
441 |
* Alter the list of available Webform components.
|
442 |
*
|
443 |
* @param $components
|
444 |
* A list of existing components as defined by hook_webform_component_info().
|
445 |
*
|
446 |
* @see hook_webform_component_info()
|
447 |
*/
|
448 |
function hook_webform_component_info_alter(&$components) { |
449 |
// Completely remove a component.
|
450 |
unset($components['grid']); |
451 |
|
452 |
// Change the name of a component.
|
453 |
$components['textarea']['label'] = t('Text box'); |
454 |
} |
455 |
|
456 |
/**
|
457 |
* Alter the list of Webform component default values.
|
458 |
*
|
459 |
* @param $defaults
|
460 |
* A list of component defaults as defined by _webform_defaults_COMPONENT().
|
461 |
* @param $type
|
462 |
* The component type whose defaults are being provided.
|
463 |
*
|
464 |
* @see _webform_defaults_component()
|
465 |
*/
|
466 |
function hook_webform_component_defaults_alter(&$defaults, $type) { |
467 |
// Alter a default for all component types.
|
468 |
$defaults['required'] = 1; |
469 |
|
470 |
// Add a default for a new field added via hook_form_alter() or
|
471 |
// hook_form_FORM_ID_alter() for all component types.
|
472 |
$defaults['extra']['added_field'] = t('Added default value'); |
473 |
|
474 |
// Add or alter defaults for specific component types:
|
475 |
switch ($type) { |
476 |
case 'select': |
477 |
$defaults['extra']['optrand'] = 1; |
478 |
break;
|
479 |
|
480 |
case 'textfield': |
481 |
case 'textarea': |
482 |
$defaults['extra']['another_added_field'] = t('Another added default value'); |
483 |
} |
484 |
} |
485 |
|
486 |
/**
|
487 |
* Alter access to a Webform submission.
|
488 |
*
|
489 |
* @param $node
|
490 |
* The Webform node on which this submission was made.
|
491 |
* @param $submission
|
492 |
* The Webform submission.
|
493 |
* @param $op
|
494 |
* The operation to be performed on the submission. Possible values are:
|
495 |
* - "view"
|
496 |
* - "edit"
|
497 |
* - "delete"
|
498 |
* - "list"
|
499 |
* @param $account
|
500 |
* A user account object.
|
501 |
* @return
|
502 |
* TRUE if the current user has access to submission,
|
503 |
* or FALSE otherwise.
|
504 |
*/
|
505 |
function hook_webform_submission_access($node, $submission, $op = 'view', $account = NULL) { |
506 |
switch ($op) { |
507 |
case 'view': |
508 |
return TRUE; |
509 |
break;
|
510 |
case 'edit': |
511 |
return FALSE; |
512 |
break;
|
513 |
case 'delete': |
514 |
return TRUE; |
515 |
break;
|
516 |
case 'list': |
517 |
return TRUE; |
518 |
break;
|
519 |
} |
520 |
} |
521 |
|
522 |
/**
|
523 |
* Determine if a user has access to see the results of a webform.
|
524 |
*
|
525 |
* Note in addition to the view access to the results granted here, the $account
|
526 |
* must also have view access to the Webform node in order to see results.
|
527 |
*
|
528 |
* @see webform_results_access().
|
529 |
*
|
530 |
* @param $node
|
531 |
* The Webform node to check access on.
|
532 |
* @param $account
|
533 |
* The user account to check access on.
|
534 |
* @return
|
535 |
* TRUE or FALSE if the user can access the webform results.
|
536 |
*/
|
537 |
function hook_webform_results_access($node, $account) { |
538 |
// Let editors view results of unpublished webforms.
|
539 |
if ($node->status == 0 && in_array('editor', $account->roles)) { |
540 |
return TRUE; |
541 |
} |
542 |
else {
|
543 |
return FALSE; |
544 |
} |
545 |
} |
546 |
|
547 |
/**
|
548 |
* Return an array of files associated with the component.
|
549 |
*
|
550 |
* The output of this function will be used to attach files to e-mail messages.
|
551 |
*
|
552 |
* @param $component
|
553 |
* A Webform component array.
|
554 |
* @param $value
|
555 |
* An array of information containing the submission result, directly
|
556 |
* correlating to the webform_submitted_data database schema.
|
557 |
* @return
|
558 |
* An array of files, each file is an array with following keys:
|
559 |
* - filepath: The relative path to the file.
|
560 |
* - filename: The name of the file including the extension.
|
561 |
* - filemime: The mimetype of the file.
|
562 |
* This will result in an array looking something like this:
|
563 |
* @code
|
564 |
* array[0] => array(
|
565 |
* 'filepath' => '/sites/default/files/attachment.txt',
|
566 |
* 'filename' => 'attachment.txt',
|
567 |
* 'filemime' => 'text/plain',
|
568 |
* );
|
569 |
* @endcode
|
570 |
*/
|
571 |
function _webform_attachments_component($component, $value) { |
572 |
$files = array(); |
573 |
$files[] = (array) file_load($value[0]); |
574 |
return $files; |
575 |
} |
576 |
|
577 |
/**
|
578 |
* @}
|
579 |
*/
|
580 |
|
581 |
/**
|
582 |
* @defgroup webform_component Sample Webform Component
|
583 |
* @{
|
584 |
* In each of these examples, the word "component" should be replaced with the,
|
585 |
* name of the component type (such as textfield or select). These are not
|
586 |
* actual hooks, but instead samples of how Webform integrates with its own
|
587 |
* built-in components.
|
588 |
*/
|
589 |
|
590 |
/**
|
591 |
* Specify the default properties of a component.
|
592 |
*
|
593 |
* @return
|
594 |
* An array defining the default structure of a component.
|
595 |
*/
|
596 |
function _webform_defaults_component() { |
597 |
return array( |
598 |
'name' => '', |
599 |
'form_key' => NULL, |
600 |
'mandatory' => 0, |
601 |
'pid' => 0, |
602 |
'weight' => 0, |
603 |
'extra' => array( |
604 |
'options' => '', |
605 |
'questions' => '', |
606 |
'optrand' => 0, |
607 |
'qrand' => 0, |
608 |
'description' => '', |
609 |
), |
610 |
); |
611 |
} |
612 |
|
613 |
/**
|
614 |
* Generate the form for editing a component.
|
615 |
*
|
616 |
* Create a set of form elements to be displayed on the form for editing this
|
617 |
* component. Use care naming the form items, as this correlates directly to the
|
618 |
* database schema. The component "Name" and "Description" fields are added to
|
619 |
* every component type and are not necessary to specify here (although they
|
620 |
* may be overridden if desired).
|
621 |
*
|
622 |
* @param $component
|
623 |
* A Webform component array.
|
624 |
* @return
|
625 |
* An array of form items to be displayed on the edit component page
|
626 |
*/
|
627 |
function _webform_edit_component($component) { |
628 |
$form = array(); |
629 |
|
630 |
// Disabling the description if not wanted.
|
631 |
$form['description'] = array(); |
632 |
|
633 |
// Most options are stored in the "extra" array, which stores any settings
|
634 |
// unique to a particular component type.
|
635 |
$form['extra']['options'] = array( |
636 |
'#type' => 'textarea', |
637 |
'#title' => t('Options'), |
638 |
'#default_value' => $component['extra']['options'], |
639 |
'#description' => t('Key-value pairs may be entered separated by pipes. i.e. safe_key|Some readable option') . theme('webform_token_help'), |
640 |
'#cols' => 60, |
641 |
'#rows' => 5, |
642 |
'#weight' => -3, |
643 |
'#required' => TRUE, |
644 |
); |
645 |
return $form; |
646 |
} |
647 |
|
648 |
/**
|
649 |
* Render a Webform component to be part of a form.
|
650 |
*
|
651 |
* @param $component
|
652 |
* A Webform component array.
|
653 |
* @param $value
|
654 |
* If editing an existing submission or resuming a draft, this will contain
|
655 |
* an array of values to be shown instead of the default in the component
|
656 |
* configuration. This value will always be an array, keyed numerically for
|
657 |
* each value saved in this field.
|
658 |
* @param $filter
|
659 |
* Whether or not to filter the contents of descriptions and values when
|
660 |
* rendering the component. Values need to be unfiltered to be editable by
|
661 |
* Form Builder.
|
662 |
*
|
663 |
* @see _webform_client_form_add_component()
|
664 |
*/
|
665 |
function _webform_render_component($component, $value = NULL, $filter = TRUE) { |
666 |
$form_item = array( |
667 |
'#type' => 'textfield', |
668 |
'#title' => $filter ? _webform_filter_xss($component['name']) : $component['name'], |
669 |
'#required' => $component['mandatory'], |
670 |
'#weight' => $component['weight'], |
671 |
'#description' => $filter ? _webform_filter_descriptions($component['extra']['description']) : $component['extra']['description'], |
672 |
'#default_value' => $filter ? _webform_filter_values($component['value']) : $component['value'], |
673 |
'#prefix' => '<div class="webform-component-textfield" id="webform-component-' . $component['form_key'] . '">', |
674 |
'#suffix' => '</div>', |
675 |
); |
676 |
|
677 |
if (isset($value)) { |
678 |
$form_item['#default_value'] = $value[0]; |
679 |
} |
680 |
|
681 |
return $form_item; |
682 |
} |
683 |
|
684 |
/**
|
685 |
* Display the result of a submission for a component.
|
686 |
*
|
687 |
* The output of this function will be displayed under the "Results" tab then
|
688 |
* "Submissions". This should output the saved data in some reasonable manner.
|
689 |
*
|
690 |
* @param $component
|
691 |
* A Webform component array.
|
692 |
* @param $value
|
693 |
* An array of information containing the submission result, directly
|
694 |
* correlating to the webform_submitted_data database table schema.
|
695 |
* @param $format
|
696 |
* Either 'html' or 'text'. Defines the format that the content should be
|
697 |
* returned as. Make sure that returned content is run through check_plain()
|
698 |
* or other filtering functions when returning HTML.
|
699 |
* @return
|
700 |
* A renderable element containing at the very least these properties:
|
701 |
* - #title
|
702 |
* - #weight
|
703 |
* - #component
|
704 |
* - #format
|
705 |
* - #value
|
706 |
* Webform also uses #theme_wrappers to output the end result to the user,
|
707 |
* which will properly format the label and content for use within an e-mail
|
708 |
* (such as wrapping the text) or as HTML (ensuring consistent output).
|
709 |
*/
|
710 |
function _webform_display_component($component, $value, $format = 'html') { |
711 |
return array( |
712 |
'#title' => $component['name'], |
713 |
'#weight' => $component['weight'], |
714 |
'#theme' => 'webform_display_textfield', |
715 |
'#theme_wrappers' => $format == 'html' ? array('webform_element') : array('webform_element_text'), |
716 |
'#post_render' => array('webform_element_wrapper'), |
717 |
'#field_prefix' => $component['extra']['field_prefix'], |
718 |
'#field_suffix' => $component['extra']['field_suffix'], |
719 |
'#component' => $component, |
720 |
'#format' => $format, |
721 |
'#value' => isset($value[0]) ? $value[0] : '', |
722 |
); |
723 |
} |
724 |
|
725 |
/**
|
726 |
* A hook for changing the input values before saving to the database.
|
727 |
*
|
728 |
* Webform expects a component to consist of a single field, or a single array
|
729 |
* of fields. If you have a component that requires a deeper form tree
|
730 |
* you must flatten the data into a single array using this callback
|
731 |
* or by setting #parents on each field to avoid data loss and/or unexpected
|
732 |
* behavior.
|
733 |
*
|
734 |
* Note that Webform will save the result of this function directly into the
|
735 |
* database.
|
736 |
*
|
737 |
* @param $component
|
738 |
* A Webform component array.
|
739 |
* @param $value
|
740 |
* The POST data associated with the user input.
|
741 |
* @return
|
742 |
* An array of values to be saved into the database. Note that this should be
|
743 |
* a numerically keyed array.
|
744 |
*/
|
745 |
function _webform_submit_component($component, $value) { |
746 |
// Clean up a phone number into 123-456-7890 format.
|
747 |
if ($component['extra']['phone_number']) { |
748 |
$matches = array(); |
749 |
$number = preg_replace('[^0-9]', $value[0]); |
750 |
if (strlen($number) == 7) { |
751 |
$number = substr($number, 0, 3) . '-' . substr($number, 3, 4); |
752 |
} |
753 |
else {
|
754 |
$number = substr($number, 0, 3) . '-' . substr($number, 3, 3) . '-' . substr($number, 6, 4); |
755 |
} |
756 |
} |
757 |
|
758 |
$value[0] = $number; |
759 |
return $value; |
760 |
} |
761 |
|
762 |
/**
|
763 |
* Delete operation for a component or submission.
|
764 |
*
|
765 |
* @param $component
|
766 |
* A Webform component array.
|
767 |
* @param $value
|
768 |
* An array of information containing the submission result, directly
|
769 |
* correlating to the webform_submitted_data database schema.
|
770 |
*/
|
771 |
function _webform_delete_component($component, $value) { |
772 |
// Delete corresponding files when a submission is deleted.
|
773 |
if (!empty($value[0]) && ($file = webform_get_file($value[0]))) { |
774 |
file_usage_delete($file, 'webform'); |
775 |
file_delete($file);
|
776 |
} |
777 |
} |
778 |
|
779 |
/**
|
780 |
* Module specific instance of hook_help().
|
781 |
*
|
782 |
* This allows each Webform component to add information into hook_help().
|
783 |
*/
|
784 |
function _webform_help_component($section) { |
785 |
switch ($section) { |
786 |
case 'admin/config/content/webform#grid_description': |
787 |
return t('Allows creation of grid questions, denoted by radio buttons.'); |
788 |
} |
789 |
} |
790 |
|
791 |
/**
|
792 |
* Module specific instance of hook_theme().
|
793 |
*
|
794 |
* This allows each Webform component to add information into hook_theme(). If
|
795 |
* you specify a file to include, you must define the path to the module that
|
796 |
* this file belongs to.
|
797 |
*/
|
798 |
function _webform_theme_component() { |
799 |
return array( |
800 |
'webform_grid' => array( |
801 |
'render element' => 'element', |
802 |
'file' => 'components/grid.inc', |
803 |
'path' => drupal_get_path('module', 'webform'), |
804 |
), |
805 |
'webform_display_grid' => array( |
806 |
'render element' => 'element', |
807 |
'file' => 'components/grid.inc', |
808 |
'path' => drupal_get_path('module', 'webform'), |
809 |
), |
810 |
); |
811 |
} |
812 |
|
813 |
/**
|
814 |
* Calculate and returns statistics about results for this component.
|
815 |
*
|
816 |
* This takes into account all submissions to this webform. The output of this
|
817 |
* function will be displayed under the "Results" tab then "Analysis".
|
818 |
*
|
819 |
* @param $component
|
820 |
* An array of information describing the component, directly correlating to
|
821 |
* the webform_component database schema.
|
822 |
* @param $sids
|
823 |
* An optional array of submission IDs (sid). If supplied, the analysis will
|
824 |
* be limited to these sids.
|
825 |
* @param $single
|
826 |
* Boolean flag determining if the details about a single component are being
|
827 |
* shown. May be used to provided detailed information about a single
|
828 |
* component's analysis, such as showing "Other" options within a select list.
|
829 |
* @return
|
830 |
* An array of data rows, each containing a statistic for this component's
|
831 |
* submissions.
|
832 |
*/
|
833 |
function _webform_analysis_component($component, $sids = array(), $single = FALSE) { |
834 |
// Generate the list of options and questions.
|
835 |
$options = _webform_select_options_from_text($component['extra']['options'], TRUE); |
836 |
$questions = _webform_select_options_from_text($component['extra']['questions'], TRUE); |
837 |
|
838 |
// Generate a lookup table of results.
|
839 |
$query = db_select('webform_submitted_data', 'wsd') |
840 |
->fields('wsd', array('no', 'data')) |
841 |
->condition('nid', $component['nid']) |
842 |
->condition('cid', $component['cid']) |
843 |
->condition('data', '', '<>') |
844 |
->groupBy('no')
|
845 |
->groupBy('data');
|
846 |
$query->addExpression('COUNT(sid)', 'datacount'); |
847 |
|
848 |
if (count($sids)) { |
849 |
$query->condition('sid', $sids, 'IN'); |
850 |
} |
851 |
|
852 |
$result = $query->execute(); |
853 |
$counts = array(); |
854 |
foreach ($result as $data) { |
855 |
$counts[$data->no][$data->data] = $data->datacount; |
856 |
} |
857 |
|
858 |
// Create an entire table to be put into the returned row.
|
859 |
$rows = array(); |
860 |
$header = array(''); |
861 |
|
862 |
// Add options as a header row.
|
863 |
foreach ($options as $option) { |
864 |
$header[] = $option; |
865 |
} |
866 |
|
867 |
// Add questions as each row.
|
868 |
foreach ($questions as $qkey => $question) { |
869 |
$row = array($question); |
870 |
foreach ($options as $okey => $option) { |
871 |
$row[] = !empty($counts[$qkey][$okey]) ? $counts[$qkey][$okey] : 0; |
872 |
} |
873 |
$rows[] = $row; |
874 |
} |
875 |
$output = theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('class' => array('webform-grid')))); |
876 |
|
877 |
return array(array(array('data' => $output, 'colspan' => 2))); |
878 |
} |
879 |
|
880 |
/**
|
881 |
* Return the result of a component value for display in a table.
|
882 |
*
|
883 |
* The output of this function will be displayed under the "Results" tab then
|
884 |
* "Table".
|
885 |
*
|
886 |
* @param $component
|
887 |
* A Webform component array.
|
888 |
* @param $value
|
889 |
* An array of information containing the submission result, directly
|
890 |
* correlating to the webform_submitted_data database schema.
|
891 |
* @return
|
892 |
* Textual output formatted for human reading.
|
893 |
*/
|
894 |
function _webform_table_component($component, $value) { |
895 |
$questions = array_values(_webform_component_options($component['extra']['questions'])); |
896 |
$output = ''; |
897 |
// Set the value as a single string.
|
898 |
if (is_array($value)) { |
899 |
foreach ($value as $item => $value) { |
900 |
if ($value !== '') { |
901 |
$output .= $questions[$item] . ': ' . check_plain($value) . '<br />'; |
902 |
} |
903 |
} |
904 |
} |
905 |
else {
|
906 |
$output = check_plain(!isset($value['0']) ? '' : $value['0']); |
907 |
} |
908 |
return $output; |
909 |
} |
910 |
|
911 |
/**
|
912 |
* Return the header for this component to be displayed in a CSV file.
|
913 |
*
|
914 |
* The output of this function will be displayed under the "Results" tab then
|
915 |
* "Download".
|
916 |
*
|
917 |
* @param $component
|
918 |
* A Webform component array.
|
919 |
* @param $export_options
|
920 |
* An array of options that may configure export of this field.
|
921 |
* @return
|
922 |
* An array of data to be displayed in the first three rows of a CSV file, not
|
923 |
* including either prefixed or trailing commas.
|
924 |
*/
|
925 |
function _webform_csv_headers_component($component, $export_options) { |
926 |
$header = array(); |
927 |
$header[0] = array(''); |
928 |
$header[1] = array($component['name']); |
929 |
$items = _webform_component_options($component['extra']['questions']); |
930 |
$count = 0; |
931 |
foreach ($items as $key => $item) { |
932 |
// Empty column per sub-field in main header.
|
933 |
if ($count != 0) { |
934 |
$header[0][] = ''; |
935 |
$header[1][] = ''; |
936 |
} |
937 |
// The value for this option.
|
938 |
$header[2][] = $item; |
939 |
$count++;
|
940 |
} |
941 |
|
942 |
return $header; |
943 |
} |
944 |
|
945 |
/**
|
946 |
* Format the submitted data of a component for CSV downloading.
|
947 |
*
|
948 |
* The output of this function will be displayed under the "Results" tab then
|
949 |
* "Download".
|
950 |
*
|
951 |
* @param $component
|
952 |
* A Webform component array.
|
953 |
* @param $export_options
|
954 |
* An array of options that may configure export of this field.
|
955 |
* @param $value
|
956 |
* An array of information containing the submission result, directly
|
957 |
* correlating to the webform_submitted_data database schema.
|
958 |
* @return
|
959 |
* An array of items to be added to the CSV file. Each value within the array
|
960 |
* will be another column within the file. This function is called once for
|
961 |
* every row of data.
|
962 |
*/
|
963 |
function _webform_csv_data_component($component, $export_options, $value) { |
964 |
$questions = array_keys(_webform_select_options($component['extra']['questions'])); |
965 |
$return = array(); |
966 |
foreach ($questions as $key => $question) { |
967 |
$return[] = isset($value[$key]) ? $value[$key] : ''; |
968 |
} |
969 |
return $return; |
970 |
} |
971 |
|
972 |
/**
|
973 |
* @}
|
974 |
*/
|