root / drupal7 / sites / all / modules / webform / webform.api.php @ 76bdcd04
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 array
|
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 a function implementing
|
33 |
* callback_webform_options() that will return the list.
|
34 |
* - options arguments: Any additional arguments to send to the callback.
|
35 |
* - file: Optional. The file containing the options callback, relative to
|
36 |
* the module root.
|
37 |
*/
|
38 |
function hook_webform_select_options_info() { |
39 |
$items = array(); |
40 |
|
41 |
$items['days'] = array( |
42 |
'title' => t('Days of the week'), |
43 |
'options callback' => 'webform_options_days', |
44 |
'file' => 'includes/webform.options.inc', |
45 |
); |
46 |
|
47 |
return $items; |
48 |
} |
49 |
|
50 |
/**
|
51 |
* Alter the list of select list options provided by Webform and other modules.
|
52 |
*
|
53 |
* @see hook_webform_select_options_info()
|
54 |
*/
|
55 |
function hook_webform_select_options_info_alter(&$items) { |
56 |
// Remove the days of the week options.
|
57 |
unset($items['days']); |
58 |
} |
59 |
|
60 |
/**
|
61 |
* Define a list of options that Webform may use in a select component.
|
62 |
*
|
63 |
* Callback for hook_webform_select_options_info().
|
64 |
*
|
65 |
* @param $component
|
66 |
* The Webform component array for the select component being displayed.
|
67 |
* @param $flat
|
68 |
* Boolean value indicating whether the returned list needs to be a flat array
|
69 |
* of key => value pairs. Select components support up to one level of
|
70 |
* nesting, but when results are displayed, the list needs to be returned
|
71 |
* without the nesting.
|
72 |
* @param $arguments
|
73 |
* The "options arguments" specified in hook_webform_select_options_info().
|
74 |
*
|
75 |
* @return array
|
76 |
* An array of key => value pairs suitable for a select list's #options
|
77 |
* FormAPI property.
|
78 |
*/
|
79 |
function callback_webform_options($component, $flat, $arguments) { |
80 |
$options = array( |
81 |
'one' => t('Pre-built option one'), |
82 |
'two' => t('Pre-built option two'), |
83 |
'three' => t('Pre-built option three'), |
84 |
); |
85 |
|
86 |
return $options; |
87 |
} |
88 |
|
89 |
/**
|
90 |
* Respond to the loading of Webform submissions.
|
91 |
*
|
92 |
* @param $submissions
|
93 |
* An array of Webform submissions that are being loaded, keyed by the
|
94 |
* submission ID. Modifications to the submissions are done by reference.
|
95 |
*/
|
96 |
function hook_webform_submission_load(&$submissions) { |
97 |
foreach ($submissions as $sid => $submission) { |
98 |
$submissions[$sid]->new_property = 'foo'; |
99 |
} |
100 |
} |
101 |
|
102 |
/**
|
103 |
* Respond to the creation of a new submission from form values.
|
104 |
*
|
105 |
* This hook is called when a user has completed a submission to initialize the
|
106 |
* submission object. After this object has its values populated, it will be
|
107 |
* saved by webform_submission_insert(). Note that this hook is only called for
|
108 |
* new submissions, not for submissions being edited. If responding to the
|
109 |
* saving of all submissions, it's recommended to use
|
110 |
* hook_webform_submission_presave().
|
111 |
*
|
112 |
* @param $submission
|
113 |
* The submission object that has been created.
|
114 |
* @param $node
|
115 |
* The Webform node for which this submission is being saved.
|
116 |
* @param $account
|
117 |
* The user account that is creating the submission.
|
118 |
* @param $form_state
|
119 |
* The contents of form state that is the basis for this submission.
|
120 |
*
|
121 |
* @see webform_submission_create()
|
122 |
*/
|
123 |
function hook_webform_submission_create_alter(&$submission, &$node, &$account, &$form_state) { |
124 |
$submission->new_property = TRUE; |
125 |
} |
126 |
|
127 |
/**
|
128 |
* Modify a Webform submission, prior to saving it in the database.
|
129 |
*
|
130 |
* @param $node
|
131 |
* The Webform node on which this submission was made.
|
132 |
* @param $submission
|
133 |
* The Webform submission that is about to be saved to the database.
|
134 |
*/
|
135 |
function hook_webform_submission_presave($node, &$submission) { |
136 |
// Update some component's value before it is saved.
|
137 |
$component_id = 4; |
138 |
$submission->data[$component_id][0] = 'foo'; |
139 |
} |
140 |
|
141 |
/**
|
142 |
* Respond to a Webform submission being inserted.
|
143 |
*
|
144 |
* Note that this hook is called after a submission has already been saved to
|
145 |
* the database. If needing to modify the submission prior to insertion, use
|
146 |
* hook_webform_submission_presave().
|
147 |
*
|
148 |
* @param $node
|
149 |
* The Webform node on which this submission was made.
|
150 |
* @param $submission
|
151 |
* The Webform submission that was just inserted into the database.
|
152 |
*/
|
153 |
function hook_webform_submission_insert($node, $submission) { |
154 |
// Insert a record into a 3rd-party module table when a submission is added.
|
155 |
db_insert('mymodule_table')
|
156 |
->fields(array(
|
157 |
'nid' => $node->nid, |
158 |
'sid' => $submission->sid, |
159 |
'foo' => 'foo_data', |
160 |
)) |
161 |
->execute(); |
162 |
} |
163 |
|
164 |
/**
|
165 |
* Respond to a Webform submission being updated.
|
166 |
*
|
167 |
* Note that this hook is called after a submission has already been saved to
|
168 |
* the database. If needing to modify the submission prior to updating, use
|
169 |
* hook_webform_submission_presave().
|
170 |
*
|
171 |
* @param $node
|
172 |
* The Webform node on which this submission was made.
|
173 |
* @param $submission
|
174 |
* The Webform submission that was just updated in the database.
|
175 |
*/
|
176 |
function hook_webform_submission_update($node, $submission) { |
177 |
// Update a record in a 3rd-party module table when a submission is updated.
|
178 |
db_update('mymodule_table')
|
179 |
->fields(array(
|
180 |
'foo' => 'foo_data', |
181 |
)) |
182 |
->condition('nid', $node->nid) |
183 |
->condition('sid', $submission->sid) |
184 |
->execute(); |
185 |
} |
186 |
|
187 |
/**
|
188 |
* Respond to a Webform submission being deleted.
|
189 |
*
|
190 |
* @param $node
|
191 |
* The Webform node on which this submission was made.
|
192 |
* @param $submission
|
193 |
* The Webform submission that was just deleted from the database.
|
194 |
*/
|
195 |
function hook_webform_submission_delete($node, $submission) { |
196 |
// Delete a record from a 3rd-party module table when a submission is deleted.
|
197 |
db_delete('mymodule_table')
|
198 |
->condition('nid', $node->nid) |
199 |
->condition('sid', $submission->sid) |
200 |
->execute(); |
201 |
} |
202 |
|
203 |
/**
|
204 |
* Provide a list of actions that can be executed on a submission.
|
205 |
*
|
206 |
* Some actions are displayed in the list of submissions such as edit, view, and
|
207 |
* delete. All other actions are displayed only when viewing the submission.
|
208 |
* These additional actions may be specified in this hook. Examples included
|
209 |
* directly in the Webform module include PDF, print, and resend e-mails. Other
|
210 |
* modules may extend this list by using this hook.
|
211 |
*
|
212 |
* @param $node
|
213 |
* The Webform node on which this submission was made.
|
214 |
* @param $submission
|
215 |
* The Webform submission on which the actions may be performed.
|
216 |
*
|
217 |
* @return array
|
218 |
* List of action.
|
219 |
*/
|
220 |
function hook_webform_submission_actions($node, $submission) { |
221 |
$actions = array(); |
222 |
|
223 |
if (webform_results_access($node)) { |
224 |
$actions['myaction'] = array( |
225 |
'title' => t('Do my action'), |
226 |
'href' => 'node/' . $node->nid . '/submission/' . $submission->sid . '/myaction', |
227 |
'query' => drupal_get_destination(),
|
228 |
); |
229 |
} |
230 |
|
231 |
return $actions; |
232 |
} |
233 |
|
234 |
/**
|
235 |
* Modify the draft to be presented for editing.
|
236 |
*
|
237 |
* When drafts are enabled for the webform, by default, a pre-existing draft is
|
238 |
* presented when the webform is displayed to that user. To allow multiple
|
239 |
* drafts, implement this alter function to set the $sid to NULL, or use your
|
240 |
* application's business logic to determine whether a new draft or which of
|
241 |
* he pre-existing drafts should be presented.
|
242 |
*
|
243 |
* @param int $sid
|
244 |
* The id of the most recent submission to be presented for editing. Change
|
245 |
* to a different draft's sid or set to NULL for a new draft.
|
246 |
* @param array $context
|
247 |
* Array of context with indices 'nid' and 'uid'.
|
248 |
*/
|
249 |
function hook_webform_draft_alter(&$sid, array $context) { |
250 |
if ($_GET['newdraft']) { |
251 |
$sid = NULL; |
252 |
} |
253 |
} |
254 |
|
255 |
/**
|
256 |
* Alter the display of a Webform submission.
|
257 |
*
|
258 |
* This function applies to both e-mails sent by Webform and normal display of
|
259 |
* submissions when viewing through the administrative interface.
|
260 |
*
|
261 |
* @param $renderable
|
262 |
* The Webform submission in a renderable array, similar to FormAPI's
|
263 |
* structure. This variable must be passed in by-reference. Important
|
264 |
* properties of this array include #node, #submission, #email, and #format,
|
265 |
* which can be used to find the context of the submission that is being
|
266 |
* rendered.
|
267 |
*/
|
268 |
function hook_webform_submission_render_alter(&$renderable) { |
269 |
// Remove page breaks from sent e-mails.
|
270 |
if (isset($renderable['#email'])) { |
271 |
foreach (element_children($renderable) as $key) { |
272 |
if ($renderable[$key]['#component']['type'] == 'pagebreak') { |
273 |
unset($renderable[$key]); |
274 |
} |
275 |
} |
276 |
} |
277 |
} |
278 |
|
279 |
/**
|
280 |
* Modify a loaded Webform component.
|
281 |
*
|
282 |
* IMPORTANT: This hook does not actually exist because components are loaded
|
283 |
* in bulk as part of webform_node_load(). Use hook_node_load() to modify loaded
|
284 |
* components when the node is loaded. This example is provided merely to point
|
285 |
* to hook_node_load().
|
286 |
*
|
287 |
* @see hook_nodeapi()
|
288 |
* @see webform_node_load()
|
289 |
*/
|
290 |
function hook_webform_component_load() { |
291 |
// This hook does not exist. Instead use hook_node_load().
|
292 |
} |
293 |
|
294 |
/**
|
295 |
* Modify a Webform component before it is saved to the database.
|
296 |
*
|
297 |
* Note that most of the time this hook is not necessary, because Webform will
|
298 |
* automatically add data to the component based on the component form. Using
|
299 |
* hook_form_alter() will be sufficient in most cases.
|
300 |
*
|
301 |
* @param $component
|
302 |
* The Webform component being saved.
|
303 |
*
|
304 |
* @see hook_form_alter()
|
305 |
* @see webform_component_edit_form()
|
306 |
*/
|
307 |
function hook_webform_component_presave(&$component) { |
308 |
$component['extra']['new_option'] = 'foo'; |
309 |
} |
310 |
|
311 |
/**
|
312 |
* Respond to a Webform component being inserted into the database.
|
313 |
*/
|
314 |
function hook_webform_component_insert($component) { |
315 |
// Insert a record into a 3rd-party module table when a component is inserted.
|
316 |
db_insert('mymodule_table')
|
317 |
->fields(array(
|
318 |
'nid' => $component['nid'], |
319 |
'cid' => $component['cid'], |
320 |
'foo' => 'foo_data', |
321 |
)) |
322 |
->execute(); |
323 |
} |
324 |
|
325 |
/**
|
326 |
* Respond to a Webform component being updated in the database.
|
327 |
*/
|
328 |
function hook_webform_component_update($component) { |
329 |
// Update a record in a 3rd-party module table when a component is updated.
|
330 |
db_update('mymodule_table')
|
331 |
->fields(array(
|
332 |
'foo' => 'foo_data', |
333 |
)) |
334 |
->condition('nid', $component['nid']) |
335 |
->condition('cid', $component['cid']) |
336 |
->execute(); |
337 |
} |
338 |
|
339 |
/**
|
340 |
* Respond to a Webform component being deleted.
|
341 |
*/
|
342 |
function hook_webform_component_delete($component) { |
343 |
// Delete a record in a 3rd-party module table when a component is deleted.
|
344 |
db_delete('mymodule_table')
|
345 |
->condition('nid', $component['nid']) |
346 |
->condition('cid', $component['cid']) |
347 |
->execute(); |
348 |
} |
349 |
|
350 |
/**
|
351 |
* Alter the entire analysis before rendering to the page on the Analysis tab.
|
352 |
*
|
353 |
* This alter hook allows modification of the entire analysis of a node's
|
354 |
* Webform results. The resulting analysis is displayed on the Results ->
|
355 |
* Analysis tab on the Webform.
|
356 |
*
|
357 |
* @param array $analysis
|
358 |
* A Drupal renderable array, passed by reference, containing the entire
|
359 |
* contents of the analysis page. This typically will contain the following
|
360 |
* two major keys:
|
361 |
* - form: The form for configuring the shown analysis.
|
362 |
* - components: The list of analyses for each analysis-enabled component
|
363 |
* for the node. Each keyed by its component ID.
|
364 |
*/
|
365 |
function hook_webform_analysis_alter(array &$analysis) { |
366 |
$node = $analysis['#node']; |
367 |
|
368 |
// Add an additional piece of information to every component's analysis:
|
369 |
foreach (element_children($analysis['components']) as $cid) { |
370 |
$component = $node->components[$cid]; |
371 |
$analysis['components'][$cid]['chart'] = array( |
372 |
'#markup' => t('Chart for the @name component', array('@name' => $component['name'])), |
373 |
); |
374 |
} |
375 |
} |
376 |
|
377 |
/**
|
378 |
* Alter data when displaying an analysis on that component.
|
379 |
*
|
380 |
* This hook modifies the data from an individual component's analysis results.
|
381 |
* It can be used to add additional analysis, or to modify the existing results.
|
382 |
* If needing to alter the entire set of analyses rather than an individual
|
383 |
* component, hook_webform_analysis_alter() may be used instead.
|
384 |
*
|
385 |
* @param array $data
|
386 |
* An array containing the result of a components analysis hook, passed by
|
387 |
* reference. This is passed directly from a component's
|
388 |
* _webform_analysis_component() function. See that hook for more information
|
389 |
* on this value.
|
390 |
* @param object $node
|
391 |
* The node object that contains the component being analyzed.
|
392 |
* @param array $component
|
393 |
* The Webform component array whose analysis results are being displayed.
|
394 |
*
|
395 |
* @see _webform_analysis_component()
|
396 |
* @see hook_webform_analysis_alter()
|
397 |
*/
|
398 |
function hook_webform_analysis_component_data_alter(array &$data, $node, array $component) { |
399 |
if ($component['type'] === 'textfield') { |
400 |
// Do not display rows that contain a zero value.
|
401 |
foreach ($data as $row_number => $row_data) { |
402 |
if ($row_data[1] === 0) { |
403 |
unset($data[$row_number]); |
404 |
} |
405 |
} |
406 |
} |
407 |
} |
408 |
|
409 |
/**
|
410 |
* Alter a Webform submission's header when exported.
|
411 |
*/
|
412 |
function hook_webform_csv_header_alter(&$header, $component) { |
413 |
// Use the machine name for component headers, but only for the webform
|
414 |
// with node 5 and components that are text fields.
|
415 |
if ($component['nid'] == 5 && $component['type'] == 'textfield') { |
416 |
$header[2] = $component['form_key']; |
417 |
} |
418 |
} |
419 |
|
420 |
/**
|
421 |
* Alter a Webform submission's data when exported.
|
422 |
*/
|
423 |
function hook_webform_csv_data_alter(&$data, $component, $submission) { |
424 |
// If a value of a field was left blank, use the value from another
|
425 |
// field.
|
426 |
if ($component['cid'] == 1 && empty($data)) { |
427 |
$data = $submission->data[2]['value'][0]; |
428 |
} |
429 |
} |
430 |
|
431 |
/**
|
432 |
* Define components to Webform.
|
433 |
*
|
434 |
* @return array
|
435 |
* An array of components, keyed by machine name. Required properties are
|
436 |
* "label" and "description". The "features" array defines which capabilities
|
437 |
* the component has, such as being displayed in e-mails or csv downloads.
|
438 |
* A component like "markup" for example would not show in these locations.
|
439 |
* The possible features of a component include:
|
440 |
*
|
441 |
* - csv
|
442 |
* - email
|
443 |
* - email_address
|
444 |
* - email_name
|
445 |
* - required
|
446 |
* - conditional
|
447 |
* - spam_analysis
|
448 |
* - group
|
449 |
* - private
|
450 |
*
|
451 |
* Note that most of these features do not indicate the default state, but
|
452 |
* determine if the component can have this property at all. Setting
|
453 |
* "required" to TRUE does not mean that a component's fields will always be
|
454 |
* required, but instead give the option to the administrator to choose the
|
455 |
* requiredness. See the example implementation for details on how these
|
456 |
* features may be set.
|
457 |
*
|
458 |
* An optional "file" may be specified to be loaded when the component is
|
459 |
* needed. A set of callbacks will be established based on the name of the
|
460 |
* component. All components follow the pattern:
|
461 |
*
|
462 |
* _webform_[callback]_[component]
|
463 |
*
|
464 |
* Where [component] is the name of the key of the component and [callback] is
|
465 |
* any of the following:
|
466 |
*
|
467 |
* - defaults
|
468 |
* - edit
|
469 |
* - render
|
470 |
* - display
|
471 |
* - submit
|
472 |
* - delete
|
473 |
* - help
|
474 |
* - theme
|
475 |
* - analysis
|
476 |
* - table
|
477 |
* - csv_headers
|
478 |
* - csv_data
|
479 |
*
|
480 |
* See the sample component implementation for details on each one of these
|
481 |
* callbacks.
|
482 |
*
|
483 |
* @see webform_components()
|
484 |
*/
|
485 |
function hook_webform_component_info() { |
486 |
$components = array(); |
487 |
|
488 |
$components['textfield'] = array( |
489 |
'label' => t('Textfield'), |
490 |
'description' => t('Basic textfield type.'), |
491 |
'features' => array( |
492 |
// This component includes an analysis callback. Defaults to TRUE.
|
493 |
'analysis' => TRUE, |
494 |
|
495 |
// Add content to CSV downloads. Defaults to TRUE.
|
496 |
'csv' => TRUE, |
497 |
|
498 |
// This component supports default values. Defaults to TRUE.
|
499 |
'default_value' => FALSE, |
500 |
|
501 |
// This component supports a description field. Defaults to TRUE.
|
502 |
'description' => FALSE, |
503 |
|
504 |
// Show this component in e-mailed submissions. Defaults to TRUE.
|
505 |
'email' => TRUE, |
506 |
|
507 |
// Allow this component to be used as an e-mail FROM or TO address.
|
508 |
// Defaults to FALSE.
|
509 |
'email_address' => FALSE, |
510 |
|
511 |
// Allow this component to be used as an e-mail SUBJECT or FROM name.
|
512 |
// Defaults to FALSE.
|
513 |
'email_name' => TRUE, |
514 |
|
515 |
// This component may be toggled as required or not. Defaults to TRUE.
|
516 |
'required' => TRUE, |
517 |
|
518 |
// This component supports a title attribute. Defaults to TRUE.
|
519 |
'title' => FALSE, |
520 |
|
521 |
// This component has a title that can be toggled as displayed or not.
|
522 |
'title_display' => TRUE, |
523 |
|
524 |
// This component has a title that can be displayed inline.
|
525 |
'title_inline' => TRUE, |
526 |
|
527 |
// If this component can be used as a conditional SOURCE. All components
|
528 |
// may always be displayed conditionally, regardless of this setting.
|
529 |
// Defaults to TRUE.
|
530 |
'conditional' => TRUE, |
531 |
|
532 |
// If this component allows other components to be grouped within it
|
533 |
// (like a fieldset or tabs). Defaults to FALSE.
|
534 |
'group' => FALSE, |
535 |
|
536 |
// If this component can be used for SPAM analysis.
|
537 |
'spam_analysis' => FALSE, |
538 |
|
539 |
// If this component saves a file that can be used as an e-mail
|
540 |
// attachment. Defaults to FALSE.
|
541 |
'attachment' => FALSE, |
542 |
|
543 |
// If this component reflects a time range and should use labels such as
|
544 |
// "Before" and "After" when exposed as filters in Views module.
|
545 |
'views_range' => FALSE, |
546 |
|
547 |
// Set this to FALSE if this component cannot be used as a private
|
548 |
// component. If this is not FALSE, in your implementation of
|
549 |
// _webform_defaults_COMPONENT(), set ['extra']['private'] property to
|
550 |
// TRUE or FALSE.
|
551 |
'private' => FALSE, |
552 |
), |
553 |
|
554 |
// Specify the conditional behaviour of this component.
|
555 |
// Examples are 'string', 'date', 'time', 'numeric', 'select'.
|
556 |
// Defaults to 'string'.
|
557 |
'conditional_type' => 'string', |
558 |
|
559 |
'file' => 'components/textfield.inc', |
560 |
); |
561 |
|
562 |
return $components; |
563 |
} |
564 |
|
565 |
/**
|
566 |
* Alter the list of available Webform components.
|
567 |
*
|
568 |
* @param $components
|
569 |
* A list of existing components as defined by hook_webform_component_info().
|
570 |
*
|
571 |
* @see hook_webform_component_info()
|
572 |
*/
|
573 |
function hook_webform_component_info_alter(&$components) { |
574 |
// Completely remove a component.
|
575 |
unset($components['grid']); |
576 |
|
577 |
// Change the name of a component.
|
578 |
$components['textarea']['label'] = t('Text box'); |
579 |
} |
580 |
|
581 |
/**
|
582 |
* Alter the list of Webform component default values.
|
583 |
*
|
584 |
* @param $defaults
|
585 |
* A list of component defaults as defined by _webform_defaults_COMPONENT().
|
586 |
* @param $type
|
587 |
* The component type whose defaults are being provided.
|
588 |
*
|
589 |
* @see _webform_defaults_component()
|
590 |
*/
|
591 |
function hook_webform_component_defaults_alter(&$defaults, $type) { |
592 |
// Alter a default for all component types.
|
593 |
$defaults['required'] = 1; |
594 |
|
595 |
// Add a default for a new field added via hook_form_alter() or
|
596 |
// hook_form_FORM_ID_alter() for all component types.
|
597 |
$defaults['extra']['added_field'] = t('Added default value'); |
598 |
|
599 |
// Add or alter defaults for specific component types:
|
600 |
switch ($type) { |
601 |
case 'select': |
602 |
$defaults['extra']['optrand'] = 1; |
603 |
break;
|
604 |
|
605 |
case 'textfield': |
606 |
case 'textarea': |
607 |
$defaults['extra']['another_added_field'] = t('Another added default value'); |
608 |
} |
609 |
} |
610 |
|
611 |
/**
|
612 |
* Alter access to a Webform submission.
|
613 |
*
|
614 |
* @param $node
|
615 |
* The Webform node on which this submission was made.
|
616 |
* @param $submission
|
617 |
* The Webform submission.
|
618 |
* @param $op
|
619 |
* The operation to be performed on the submission. Possible values are:
|
620 |
* - "view"
|
621 |
* - "edit"
|
622 |
* - "delete"
|
623 |
* - "list"
|
624 |
* @param $account
|
625 |
* A user account object.
|
626 |
*
|
627 |
* @return bool
|
628 |
* TRUE if the current user has access to submission,
|
629 |
* or FALSE otherwise.
|
630 |
*/
|
631 |
function hook_webform_submission_access($node, $submission, $op = 'view', $account = NULL) { |
632 |
switch ($op) { |
633 |
case 'view': |
634 |
return TRUE; |
635 |
|
636 |
case 'edit': |
637 |
return FALSE; |
638 |
|
639 |
case 'delete': |
640 |
return TRUE; |
641 |
|
642 |
case 'list': |
643 |
return TRUE; |
644 |
} |
645 |
} |
646 |
|
647 |
/**
|
648 |
* Determine if a user has access to see the results of a webform.
|
649 |
*
|
650 |
* Note in addition to the view access to the results granted here, the $account
|
651 |
* must also have view access to the Webform node in order to see results.
|
652 |
* Access via this hook is in addition (adds permission) to the standard
|
653 |
* webform access.
|
654 |
*
|
655 |
* @param $node
|
656 |
* The Webform node to check access on.
|
657 |
* @param $account
|
658 |
* The user account to check access on.
|
659 |
*
|
660 |
* @return bool
|
661 |
* TRUE or FALSE if the user can access the webform results.
|
662 |
*
|
663 |
* @see webform_results_access()
|
664 |
*/
|
665 |
function hook_webform_results_access($node, $account) { |
666 |
// Let editors view results of unpublished webforms.
|
667 |
if ($node->status == 0 && in_array('editor', $account->roles)) { |
668 |
return TRUE; |
669 |
} |
670 |
else {
|
671 |
return FALSE; |
672 |
} |
673 |
} |
674 |
|
675 |
/**
|
676 |
* Determine if a user has access to clear the results of a webform.
|
677 |
*
|
678 |
* Access via this hook is in addition (adds permission) to the standard
|
679 |
* webform access (delete all webform submissions).
|
680 |
*
|
681 |
* @param object $node
|
682 |
* The Webform node to check access on.
|
683 |
* @param object $account
|
684 |
* The user account to check access on.
|
685 |
*
|
686 |
* @return bool
|
687 |
* TRUE or FALSE if the user can access the webform results.
|
688 |
*
|
689 |
* @see webform_results_clear_access()
|
690 |
*/
|
691 |
function hook_webform_results_clear_access($node, $account) { |
692 |
return user_access('my additional access', $account); |
693 |
} |
694 |
|
695 |
/**
|
696 |
* Overrides the node_access and user_access permissions.
|
697 |
*
|
698 |
* Overrides the node_access and user_access permission to access and edit
|
699 |
* webform components, e-mails, conditions, and form settings.
|
700 |
*
|
701 |
* Return NULL to defer to other modules. If all implementations defer, then
|
702 |
* access to the node's EDIT tab plus 'edit webform components' permission
|
703 |
* determines access. To grant access, return TRUE; to deny access, return
|
704 |
* FALSE. If more than one implementation return TRUE/FALSE, all must be TRUE
|
705 |
* to grant access.
|
706 |
*
|
707 |
* In this way, access to the EDIT tab of the node may be decoupled from
|
708 |
* access to the WEBFORM tab. When returning TRUE, consider all aspects of
|
709 |
* access as this will be the only test. For example, 'return TRUE;' would grant
|
710 |
* annonymous access to creating webform components, which seldom be desired.
|
711 |
*
|
712 |
* @param object $node
|
713 |
* The Webform node to check access on.
|
714 |
* @param object $account
|
715 |
* The user account to check access on.
|
716 |
*
|
717 |
* @return bool|null
|
718 |
* TRUE or FALSE if the user can access the webform results, or NULL if
|
719 |
* access should be deferred to other implementations of this hook or
|
720 |
* node_access('update') plus user_access('edit webform components').
|
721 |
*
|
722 |
* @see webform_node_update_access()
|
723 |
*/
|
724 |
function hook_webform_update_access($node, $account) { |
725 |
// Allow anyone who can see webform_editable_by_user nodes and who has
|
726 |
// 'my webform component edit access' permission to see, edit, and delete the
|
727 |
// webform components, e-mails, conditionals, and form settings.
|
728 |
if ($node->type == 'webform_editable_by_user') { |
729 |
return node_access('view', $node, $account) && user_access('my webform component edit access', $account); |
730 |
} |
731 |
} |
732 |
|
733 |
/**
|
734 |
* Return an array of files associated with the component.
|
735 |
*
|
736 |
* The output of this function will be used to attach files to e-mail messages.
|
737 |
*
|
738 |
* @param $component
|
739 |
* A Webform component array.
|
740 |
* @param $value
|
741 |
* An array of information containing the submission result, directly
|
742 |
* correlating to the webform_submitted_data database schema.
|
743 |
*
|
744 |
* @return array
|
745 |
* An array of files, each file is an array with following keys:
|
746 |
* - filepath: The relative path to the file.
|
747 |
* - filename: The name of the file including the extension.
|
748 |
* - filemime: The mimetype of the file.
|
749 |
* This will result in an array looking something like this:
|
750 |
*
|
751 |
* @code
|
752 |
* array[0] => array(
|
753 |
* 'filepath' => '/sites/default/files/attachment.txt',
|
754 |
* 'filename' => 'attachment.txt',
|
755 |
* 'filemime' => 'text/plain',
|
756 |
* );
|
757 |
* @endcode
|
758 |
*/
|
759 |
function _webform_attachments_component($component, $value) { |
760 |
$files = array(); |
761 |
$files[] = (array) file_load($value[0]); |
762 |
return $files; |
763 |
} |
764 |
|
765 |
/**
|
766 |
* Alter default settings for a newly created webform node.
|
767 |
*
|
768 |
* @param array $defaults
|
769 |
* Default settings for a newly created webform node as defined by
|
770 |
* webform_node_defaults().
|
771 |
*
|
772 |
* @see webform_node_defaults()
|
773 |
*/
|
774 |
function hook_webform_node_defaults_alter(array &$defaults) { |
775 |
$defaults['allow_draft'] = '1'; |
776 |
} |
777 |
|
778 |
/**
|
779 |
* Add additional fields to submission data downloads.
|
780 |
*
|
781 |
* @return array
|
782 |
* Keys and titles for default submission information.
|
783 |
*
|
784 |
* @see hook_webform_results_download_submission_information_data()
|
785 |
*/
|
786 |
function hook_webform_results_download_submission_information_info() { |
787 |
return array( |
788 |
'field_key_1' => t('Field Title 1'), |
789 |
'field_key_2' => t('Field Title 2'), |
790 |
); |
791 |
} |
792 |
|
793 |
/**
|
794 |
* Return values for submission data download fields.
|
795 |
*
|
796 |
* @param $token
|
797 |
* The name of the token being replaced.
|
798 |
* @param $submission
|
799 |
* The data for an individual submission from webform_get_submissions().
|
800 |
* @param array $options
|
801 |
* A list of options that define the output format. These are generally passed
|
802 |
* through from the GUI interface.
|
803 |
* @param $serial_start
|
804 |
* The starting position for the Serial column in the output.
|
805 |
* @param $row_count
|
806 |
* The number of the row being generated.
|
807 |
*
|
808 |
* @return string
|
809 |
* Value for requested submission information field.
|
810 |
*
|
811 |
* @see hook_webform_results_download_submission_information_info()
|
812 |
*/
|
813 |
function hook_webform_results_download_submission_information_data($token, $submission, array $options, $serial_start, $row_count) { |
814 |
switch ($token) { |
815 |
case 'field_key_1': |
816 |
return 'Field Value 1'; |
817 |
|
818 |
case 'field_key_2': |
819 |
return 'Field Value 2'; |
820 |
} |
821 |
} |
822 |
|
823 |
/**
|
824 |
* @}
|
825 |
*/
|
826 |
|
827 |
/**
|
828 |
* @defgroup webform_component Sample Webform Component
|
829 |
* @{
|
830 |
* In each of these examples, the word "component" should be replaced with the,
|
831 |
* name of the component type (such as textfield or select). These are not
|
832 |
* actual hooks, but instead samples of how Webform integrates with its own
|
833 |
* built-in components.
|
834 |
*/
|
835 |
|
836 |
/**
|
837 |
* Specify the default properties of a component.
|
838 |
*
|
839 |
* @return array
|
840 |
* An array defining the default structure of a component.
|
841 |
*/
|
842 |
function _webform_defaults_component() { |
843 |
return array( |
844 |
'name' => '', |
845 |
'form_key' => NULL, |
846 |
'required' => 0, |
847 |
'pid' => 0, |
848 |
'weight' => 0, |
849 |
'extra' => array( |
850 |
'options' => '', |
851 |
'questions' => '', |
852 |
'optrand' => 0, |
853 |
'qrand' => 0, |
854 |
'description' => '', |
855 |
'description_above' => FALSE, |
856 |
'private' => FALSE, |
857 |
'analysis' => TRUE, |
858 |
), |
859 |
); |
860 |
} |
861 |
|
862 |
/**
|
863 |
* Generate the form for editing a component.
|
864 |
*
|
865 |
* Create a set of form elements to be displayed on the form for editing this
|
866 |
* component. Use care naming the form items, as this correlates directly to the
|
867 |
* database schema. The component "Name" and "Description" fields are added to
|
868 |
* every component type and are not necessary to specify here (although they
|
869 |
* may be overridden if desired).
|
870 |
*
|
871 |
* @param array $component
|
872 |
* A Webform component array.
|
873 |
* @param array $form
|
874 |
* The form array.
|
875 |
* @param array $form_state
|
876 |
* The form state array.
|
877 |
*
|
878 |
* @return array
|
879 |
* An array of form items to be displayed on the edit component page
|
880 |
*/
|
881 |
function _webform_edit_component(array $component, array &$form, array &$form_state) { |
882 |
// Disabling the description if not wanted.
|
883 |
$form['description']['#access'] = FALSE; |
884 |
|
885 |
// Most options are stored in the "extra" array, which stores any settings
|
886 |
// unique to a particular component type.
|
887 |
$form['extra']['options'] = array( |
888 |
'#type' => 'textarea', |
889 |
'#title' => t('Options'), |
890 |
'#default_value' => $component['extra']['options'], |
891 |
'#description' => t('Key-value pairs may be entered separated by pipes. i.e. safe_key|Some readable option') . ' ' . theme('webform_token_help'), |
892 |
'#cols' => 60, |
893 |
'#rows' => 5, |
894 |
'#weight' => -3, |
895 |
'#required' => TRUE, |
896 |
); |
897 |
return $form; |
898 |
} |
899 |
|
900 |
/**
|
901 |
* Render a Webform component to be part of a form.
|
902 |
*
|
903 |
* @param $component
|
904 |
* A Webform component array.
|
905 |
* @param $value
|
906 |
* If editing an existing submission or resuming a draft, this will contain
|
907 |
* an array of values to be shown instead of the default in the component
|
908 |
* configuration. This value will always be an array, keyed numerically for
|
909 |
* each value saved in this field.
|
910 |
* @param $filter
|
911 |
* Whether or not to filter the contents of descriptions and values when
|
912 |
* rendering the component. Values need to be unfiltered to be editable by
|
913 |
* Form Builder.
|
914 |
* @param $submission
|
915 |
* The submission from which this component is being rendered. Usually not
|
916 |
* needed. Used by _webform_render_date() to validate using the submission's
|
917 |
* completion date.
|
918 |
*
|
919 |
* @return array
|
920 |
* $form_item
|
921 |
*
|
922 |
* @see _webform_client_form_add_component()
|
923 |
*/
|
924 |
function _webform_render_component($component, $value = NULL, $filter = TRUE, $submission = NULL) { |
925 |
$form_item = array( |
926 |
'#type' => 'textfield', |
927 |
'#title' => $filter ? webform_filter_xss($component['name']) : $component['name'], |
928 |
'#required' => $component['required'], |
929 |
'#weight' => $component['weight'], |
930 |
'#description' => $filter ? webform_filter_descriptions($component['extra']['description']) : $component['extra']['description'], |
931 |
'#default_value' => $filter ? webform_replace_tokens($component['value']) : $component['value'], |
932 |
'#theme_wrappers' => array('webform_element'), |
933 |
); |
934 |
|
935 |
if (isset($value)) { |
936 |
$form_item['#default_value'] = $value[0]; |
937 |
} |
938 |
|
939 |
return $form_item; |
940 |
} |
941 |
|
942 |
/**
|
943 |
* Allow modules to modify a webform component that will be rendered in a form.
|
944 |
*
|
945 |
* @param array $element
|
946 |
* The display element as returned by _webform_render_component().
|
947 |
* @param array $component
|
948 |
* A Webform component array.
|
949 |
*
|
950 |
* @see _webform_render_component()
|
951 |
*/
|
952 |
function hook_webform_component_render_alter(array &$element, array &$component) { |
953 |
if ($component['cid'] == 10) { |
954 |
$element['#title'] = 'My custom title'; |
955 |
$element['#default_value'] = 42; |
956 |
} |
957 |
} |
958 |
|
959 |
/**
|
960 |
* Display the result of a submission for a component.
|
961 |
*
|
962 |
* The output of this function will be displayed under the "Results" tab then
|
963 |
* "Submissions". This should output the saved data in some reasonable manner.
|
964 |
*
|
965 |
* @param $component
|
966 |
* A Webform component array.
|
967 |
* @param $value
|
968 |
* An array of information containing the submission result, directly
|
969 |
* correlating to the webform_submitted_data database table schema.
|
970 |
* @param $format
|
971 |
* Either 'html' or 'text'. Defines the format that the content should be
|
972 |
* returned as. Make sure that returned content is run through check_plain()
|
973 |
* or other filtering functions when returning HTML.
|
974 |
* @param $submission
|
975 |
* The submission. Used to generate tokens.
|
976 |
*
|
977 |
* @return array
|
978 |
* A renderable element containing at the very least these properties:
|
979 |
* - #title
|
980 |
* - #weight
|
981 |
* - #component
|
982 |
* - #format
|
983 |
* - #value
|
984 |
* Webform also uses #theme_wrappers to output the end result to the user,
|
985 |
* which will properly format the label and content for use within an e-mail
|
986 |
* (such as wrapping the text) or as HTML (ensuring consistent output).
|
987 |
*/
|
988 |
function _webform_display_component($component, $value, $format = 'html', $submission = array()) { |
989 |
return array( |
990 |
'#title' => $component['name'], |
991 |
'#weight' => $component['weight'], |
992 |
'#theme' => 'webform_display_textfield', |
993 |
'#theme_wrappers' => $format == 'html' ? array('webform_element') : array('webform_element_text'), |
994 |
'#post_render' => array('webform_element_wrapper'), |
995 |
'#field_prefix' => $component['extra']['field_prefix'], |
996 |
'#field_suffix' => $component['extra']['field_suffix'], |
997 |
'#component' => $component, |
998 |
'#format' => $format, |
999 |
'#value' => isset($value[0]) ? $value[0] : '', |
1000 |
); |
1001 |
} |
1002 |
|
1003 |
/**
|
1004 |
* Allow modules to modify a "display only" webform component.
|
1005 |
*
|
1006 |
* @param array $element
|
1007 |
* The display element as returned by _webform_display_component().
|
1008 |
* @param array $component
|
1009 |
* A Webform component array.
|
1010 |
*
|
1011 |
* @see _webform_display_component()
|
1012 |
*/
|
1013 |
function hook_webform_component_display_alter(array &$element, array &$component) { |
1014 |
if ($component['cid'] == 10) { |
1015 |
$element['#title'] = 'My custom title'; |
1016 |
$element['#default_value'] = 42; |
1017 |
} |
1018 |
} |
1019 |
|
1020 |
/**
|
1021 |
* Performs the conditional action set on an implemented component.
|
1022 |
*
|
1023 |
* Setting the form element allows form validation functions to see the value
|
1024 |
* that webform has set for the given component.
|
1025 |
*
|
1026 |
* @param array $component
|
1027 |
* The webform component array whose value is being set for the currently-
|
1028 |
* edited submission.
|
1029 |
* @param array $element
|
1030 |
* The form element currently being set.
|
1031 |
* @param array $form_state
|
1032 |
* The form's state.
|
1033 |
* @param string $value
|
1034 |
* The value to be set, as defined in the conditional action.
|
1035 |
*/
|
1036 |
function _webform_action_set_component(array $component, array &$element, array &$form_state, $value) { |
1037 |
$element['#value'] = $value; |
1038 |
form_set_value($element, $value, $form_state); |
1039 |
} |
1040 |
|
1041 |
/**
|
1042 |
* A hook for changing the input values before saving to the database.
|
1043 |
*
|
1044 |
* Webform expects a component to consist of a single field, or a single array
|
1045 |
* of fields. If you have a component that requires a deeper form tree
|
1046 |
* you must flatten the data into a single array using this callback
|
1047 |
* or by setting #parents on each field to avoid data loss and/or unexpected
|
1048 |
* behavior.
|
1049 |
*
|
1050 |
* Note that Webform will save the result of this function directly into the
|
1051 |
* database.
|
1052 |
*
|
1053 |
* @param $component
|
1054 |
* A Webform component array.
|
1055 |
* @param $value
|
1056 |
* The POST data associated with the user input.
|
1057 |
*
|
1058 |
* @return array
|
1059 |
* An array of values to be saved into the database. Note that this should be
|
1060 |
* a numerically keyed array.
|
1061 |
*/
|
1062 |
function _webform_submit_component($component, $value) { |
1063 |
// Clean up a phone number into 123-456-7890 format.
|
1064 |
if ($component['extra']['phone_number']) { |
1065 |
$number = preg_replace('/[^0-9]/', '', $value[0]); |
1066 |
if (strlen($number) == 7) { |
1067 |
$number = substr($number, 0, 3) . '-' . substr($number, 3, 4); |
1068 |
} |
1069 |
else {
|
1070 |
$number = substr($number, 0, 3) . '-' . substr($number, 3, 3) . '-' . substr($number, 6, 4); |
1071 |
} |
1072 |
} |
1073 |
|
1074 |
$value[0] = $number; |
1075 |
return $value; |
1076 |
} |
1077 |
|
1078 |
/**
|
1079 |
* Delete operation for a component or submission.
|
1080 |
*
|
1081 |
* @param $component
|
1082 |
* A Webform component array.
|
1083 |
* @param $value
|
1084 |
* An array of information containing the submission result, directly
|
1085 |
* correlating to the webform_submitted_data database schema.
|
1086 |
*/
|
1087 |
function _webform_delete_component($component, $value) { |
1088 |
// Delete corresponding files when a submission is deleted.
|
1089 |
if (!empty($value[0]) && ($file = webform_get_file($value[0]))) { |
1090 |
file_usage_delete($file, 'webform'); |
1091 |
file_delete($file);
|
1092 |
} |
1093 |
} |
1094 |
|
1095 |
/**
|
1096 |
* Module specific instance of hook_help().
|
1097 |
*
|
1098 |
* This allows each Webform component to add information into hook_help().
|
1099 |
*/
|
1100 |
function _webform_help_component($section) { |
1101 |
switch ($section) { |
1102 |
case 'admin/config/content/webform#grid_description': |
1103 |
return t('Allows creation of grid questions, denoted by radio buttons.'); |
1104 |
} |
1105 |
} |
1106 |
|
1107 |
/**
|
1108 |
* Module specific instance of hook_theme().
|
1109 |
*
|
1110 |
* This allows each Webform component to add information into hook_theme(). If
|
1111 |
* you specify a file to include, you must define the path to the module that
|
1112 |
* this file belongs to.
|
1113 |
*/
|
1114 |
function _webform_theme_component() { |
1115 |
return array( |
1116 |
'webform_grid' => array( |
1117 |
'render element' => 'element', |
1118 |
'file' => 'components/grid.inc', |
1119 |
'path' => drupal_get_path('module', 'webform'), |
1120 |
), |
1121 |
'webform_display_grid' => array( |
1122 |
'render element' => 'element', |
1123 |
'file' => 'components/grid.inc', |
1124 |
'path' => drupal_get_path('module', 'webform'), |
1125 |
), |
1126 |
); |
1127 |
} |
1128 |
|
1129 |
/**
|
1130 |
* Calculate and returns statistics about results for this component.
|
1131 |
*
|
1132 |
* This takes into account all submissions to this webform. The output of this
|
1133 |
* function will be displayed under the "Results" tab then "Analysis".
|
1134 |
*
|
1135 |
* @param $component
|
1136 |
* An array of information describing the component, directly correlating to
|
1137 |
* the webform_component database schema.
|
1138 |
* @param $sids
|
1139 |
* An optional array of submission IDs (sid). If supplied, the analysis will
|
1140 |
* be limited to these sids.
|
1141 |
* @param $single
|
1142 |
* Boolean flag determining if the details about a single component are being
|
1143 |
* shown. May be used to provided detailed information about a single
|
1144 |
* component's analysis, such as showing "Other" options within a select list.
|
1145 |
* @param $join
|
1146 |
* An optional SelectQuery object to be used to join with the submissions
|
1147 |
* table to restrict the submissions being analyzed.
|
1148 |
*
|
1149 |
* @return array
|
1150 |
* An array containing one or more of the following keys:
|
1151 |
* - table_rows: If this component has numeric data that can be represented in
|
1152 |
* a grid, return the values here. This array assumes a 2-dimensional
|
1153 |
* structure, with the first value being a label and subsequent values
|
1154 |
* containing a decimal or integer.
|
1155 |
* - table_header: If this component has more than a single set of values,
|
1156 |
* include a table header so each column can be labeled.
|
1157 |
* - other_data: If your component has non-numeric data to include, such as
|
1158 |
* a description or link, include that in the other_data array. Each item
|
1159 |
* may be a string or an array of values that matches the number of columns
|
1160 |
* in the table_header property.
|
1161 |
* At the very least, either table_rows or other_data should be provided.
|
1162 |
* Note that if you want your component's analysis to be available by default
|
1163 |
* without the user specifically enabling it, you must set
|
1164 |
* $component['extra']['analysis'] = TRUE in your
|
1165 |
* _webform_defaults_component() callback.
|
1166 |
*
|
1167 |
* @see _webform_defaults_component()
|
1168 |
*/
|
1169 |
function _webform_analysis_component($component, $sids = array(), $single = FALSE, $join = NULL) { |
1170 |
// Generate the list of options and questions.
|
1171 |
$options = _webform_select_options_from_text($component['extra']['options'], TRUE); |
1172 |
$questions = _webform_select_options_from_text($component['extra']['questions'], TRUE); |
1173 |
|
1174 |
// Generate a lookup table of results.
|
1175 |
$query = db_select('webform_submitted_data', 'wsd') |
1176 |
->fields('wsd', array('no', 'data')) |
1177 |
->condition('nid', $component['nid']) |
1178 |
->condition('cid', $component['cid']) |
1179 |
->condition('data', '', '<>') |
1180 |
->groupBy('no')
|
1181 |
->groupBy('data');
|
1182 |
$query->addExpression('COUNT(sid)', 'datacount'); |
1183 |
|
1184 |
if (count($sids)) { |
1185 |
$query->condition('sid', $sids, 'IN'); |
1186 |
} |
1187 |
|
1188 |
if ($join) { |
1189 |
$query->innerJoin($join, 'ws2_', 'wsd.sid = ws2_.sid'); |
1190 |
} |
1191 |
|
1192 |
$result = $query->execute(); |
1193 |
$counts = array(); |
1194 |
foreach ($result as $data) { |
1195 |
$counts[$data->no][$data->data] = $data->datacount; |
1196 |
} |
1197 |
|
1198 |
// Create an entire table to be put into the returned row.
|
1199 |
$rows = array(); |
1200 |
$header = array(''); |
1201 |
|
1202 |
// Add options as a header row.
|
1203 |
foreach ($options as $option) { |
1204 |
$header[] = $option; |
1205 |
} |
1206 |
|
1207 |
// Add questions as each row.
|
1208 |
foreach ($questions as $qkey => $question) { |
1209 |
$row = array($question); |
1210 |
foreach ($options as $okey => $option) { |
1211 |
$row[] = !empty($counts[$qkey][$okey]) ? $counts[$qkey][$okey] : 0; |
1212 |
} |
1213 |
$rows[] = $row; |
1214 |
} |
1215 |
|
1216 |
$other = array(); |
1217 |
$other[] = l(t('More information'), 'node/' . $component['nid'] . '/webform-results/analysis/' . $component['cid']); |
1218 |
|
1219 |
return array( |
1220 |
'table_header' => $header, |
1221 |
'table_rows' => $rows, |
1222 |
'other_data' => $other, |
1223 |
); |
1224 |
} |
1225 |
|
1226 |
/**
|
1227 |
* Return the result of a component value for display in a table.
|
1228 |
*
|
1229 |
* The output of this function will be displayed under the "Results" tab then
|
1230 |
* "Table".
|
1231 |
*
|
1232 |
* @param $component
|
1233 |
* A Webform component array.
|
1234 |
* @param $value
|
1235 |
* An array of information containing the submission result, directly
|
1236 |
* correlating to the webform_submitted_data database schema.
|
1237 |
*
|
1238 |
* @return string
|
1239 |
* Textual output formatted for human reading.
|
1240 |
*/
|
1241 |
function _webform_table_component($component, $value) { |
1242 |
$questions = array_values(_webform_component_options($component['extra']['questions'])); |
1243 |
$output = ''; |
1244 |
// Set the value as a single string.
|
1245 |
if (is_array($value)) { |
1246 |
foreach ($value as $item => $value) { |
1247 |
if ($value !== '') { |
1248 |
$output .= $questions[$item] . ': ' . check_plain($value) . '<br />'; |
1249 |
} |
1250 |
} |
1251 |
} |
1252 |
else {
|
1253 |
$output = check_plain(!isset($value['0']) ? '' : $value['0']); |
1254 |
} |
1255 |
return $output; |
1256 |
} |
1257 |
|
1258 |
/**
|
1259 |
* Return the header for this component to be displayed in a CSV file.
|
1260 |
*
|
1261 |
* The output of this function will be displayed under the "Results" tab then
|
1262 |
* "Download".
|
1263 |
*
|
1264 |
* @param $component
|
1265 |
* A Webform component array.
|
1266 |
* @param $export_options
|
1267 |
* An array of options that may configure export of this field.
|
1268 |
*
|
1269 |
* @return array
|
1270 |
* An array of data to be displayed in the first three rows of a CSV file, not
|
1271 |
* including either prefixed or trailing commas.
|
1272 |
*/
|
1273 |
function _webform_csv_headers_component($component, $export_options) { |
1274 |
$header = array(); |
1275 |
$header[0] = array(''); |
1276 |
$header[1] = array($export_options['header_keys'] ? $component['form_key'] : $component['name']); |
1277 |
$items = _webform_component_options($component['extra']['questions']); |
1278 |
$count = 0; |
1279 |
foreach ($items as $key => $item) { |
1280 |
// Empty column per sub-field in main header.
|
1281 |
if ($count != 0) { |
1282 |
$header[0][] = ''; |
1283 |
$header[1][] = ''; |
1284 |
} |
1285 |
// The value for this option.
|
1286 |
$header[2][] = $item; |
1287 |
$count++;
|
1288 |
} |
1289 |
|
1290 |
return $header; |
1291 |
} |
1292 |
|
1293 |
/**
|
1294 |
* Format the submitted data of a component for CSV downloading.
|
1295 |
*
|
1296 |
* The output of this function will be displayed under the "Results" tab then
|
1297 |
* "Download".
|
1298 |
*
|
1299 |
* @param $component
|
1300 |
* A Webform component array.
|
1301 |
* @param $export_options
|
1302 |
* An array of options that may configure export of this field.
|
1303 |
* @param $value
|
1304 |
* An array of information containing the submission result, directly
|
1305 |
* correlating to the webform_submitted_data database schema.
|
1306 |
*
|
1307 |
* @return array
|
1308 |
* An array of items to be added to the CSV file. Each value within the array
|
1309 |
* will be another column within the file. This function is called once for
|
1310 |
* every row of data.
|
1311 |
*/
|
1312 |
function _webform_csv_data_component($component, $export_options, $value) { |
1313 |
$questions = array_keys(_webform_select_options($component['extra']['questions'])); |
1314 |
$return = array(); |
1315 |
foreach ($questions as $key => $question) { |
1316 |
$return[] = isset($value[$key]) ? $value[$key] : ''; |
1317 |
} |
1318 |
return $return; |
1319 |
} |
1320 |
|
1321 |
/**
|
1322 |
* Fix the view field(s) that are automatically generated for number components.
|
1323 |
*
|
1324 |
* Provides each component the opportunity to adjust how this component is
|
1325 |
* displayed in a view as a field in a view table. For example, a component may
|
1326 |
* modify how it responds to click-sorting. Or it may add additional fields,
|
1327 |
* such as a grid component having a column for each question.
|
1328 |
*
|
1329 |
* @param array $component
|
1330 |
* A Webform component array.
|
1331 |
* @param array $fields
|
1332 |
* An array of field-definition arrays. Will be passed one field definition,
|
1333 |
* which may be modified. Additional fields may be added to the array.
|
1334 |
*
|
1335 |
* @return array
|
1336 |
* The modified $fields array.
|
1337 |
*/
|
1338 |
function _webform_view_field_component(array $component, array $fields) { |
1339 |
foreach ($fields as &$field) { |
1340 |
$field['webform_datatype'] = 'number'; |
1341 |
} |
1342 |
return $fields; |
1343 |
} |
1344 |
|
1345 |
/**
|
1346 |
* Modify the how a view was expanded to show all the components.
|
1347 |
*
|
1348 |
* This alter function is only called when the view is actually modified. It
|
1349 |
* provides modules an opportunity to alter the changes that webform made to
|
1350 |
* the view.
|
1351 |
*
|
1352 |
* This hook is called from webform_views_pre_view. If another module also
|
1353 |
* changes views by implementing this same views hook, the relative order of
|
1354 |
* execution of the two implementations will depend upon the module weights of
|
1355 |
* the two modules. Using hook_webform_view_alter instead guarantees an
|
1356 |
* opportunity to modify the view AFTER webform.
|
1357 |
*
|
1358 |
* @param object $view
|
1359 |
* The view object.
|
1360 |
* @param string $display_id
|
1361 |
* The display_id that was expanded by webform.
|
1362 |
* @param array $args
|
1363 |
* The arguments that were passed to the view.
|
1364 |
*/
|
1365 |
function hook_webform_view_alter($view, $display_id, array $args) { |
1366 |
// Don't show component with cid == 4.
|
1367 |
$fields = $view->get_items('field', $display_id); |
1368 |
foreach ($fields as $id => $field) { |
1369 |
if (isset($field['webform_cid']) && $field['webform_cid'] == 4) { |
1370 |
unset($fields[$id]); |
1371 |
} |
1372 |
} |
1373 |
$view->display[$display_id]->handler->set_option('fields', $fields); |
1374 |
} |
1375 |
|
1376 |
/**
|
1377 |
* Modify the list of mail systems that are capable of sending HTML email.
|
1378 |
*
|
1379 |
* @param array &$systems
|
1380 |
* An array of mail system class names.
|
1381 |
*/
|
1382 |
function hook_webform_html_capable_mail_systems_alter(array &$systems) { |
1383 |
if (module_exists('my_module')) { |
1384 |
$systems[] = 'MyModuleMailSystem'; |
1385 |
} |
1386 |
} |
1387 |
|
1388 |
/**
|
1389 |
* Define a list of webform exporters.
|
1390 |
*
|
1391 |
* @return array
|
1392 |
* A list of the available exporters provided by the module.
|
1393 |
*
|
1394 |
* @see webform_webform_exporters()
|
1395 |
*/
|
1396 |
function hook_webform_exporters() { |
1397 |
$exporters = array( |
1398 |
'webform_exporter_custom' => array( |
1399 |
'title' => t('Webform exporter name'), |
1400 |
'description' => t('The description for this exporter.'), |
1401 |
'handler' => 'webform_exporter_custom', |
1402 |
'file' => drupal_get_path('module', 'yourmodule') . '/includes/webform_exporter_custom.inc', |
1403 |
'weight' => 10, |
1404 |
), |
1405 |
); |
1406 |
|
1407 |
return $exporters; |
1408 |
} |
1409 |
|
1410 |
/**
|
1411 |
* Modify the list of webform exporters definitions.
|
1412 |
*
|
1413 |
* @param array &$exporters
|
1414 |
* A list of all available webform exporters.
|
1415 |
*/
|
1416 |
function hook_webform_exporters_alter(array &$exporters) { |
1417 |
$exporters['excel']['handler'] = 'customized_excel_exporter'; |
1418 |
$exporters['excel']['file'] = drupal_get_path('module', 'yourmodule') . '/includes/customized_excel_exporter.inc'; |
1419 |
} |
1420 |
|
1421 |
/**
|
1422 |
* Declare conditional types and their operators.
|
1423 |
*
|
1424 |
* Each conditional type defined here may then be referenced in
|
1425 |
* hook_webform_component_info(). For each type this hook also declares a set of
|
1426 |
* operators that may be applied to a component of this conditional type in
|
1427 |
* conditionals.
|
1428 |
*
|
1429 |
* @return array
|
1430 |
* A 2-dimensional array of operator configurations. The configurations are
|
1431 |
* keyed first by their conditional type then by operator key. Each operator
|
1432 |
* declaration is an array with the following keys:
|
1433 |
* - label: Translated label for this operator that is shown in the UI.
|
1434 |
* - comparison callback: A callback for server-side evaluation.
|
1435 |
* - js comparison callback: A JavaScript callback for client-side evaluation.
|
1436 |
* The callback will be looked for in the Drupal.webform object.
|
1437 |
* - form callback (optional): A form callback that allows configuring
|
1438 |
* additional parameters for this operator. Default:
|
1439 |
* 'webform_conditional_operator_text'.
|
1440 |
*
|
1441 |
* @see hook_webform_component_info()
|
1442 |
* @see callback_webform_conditional_comparision_operator()
|
1443 |
* @see callback_webform_conditional_rule_value_form()
|
1444 |
*/
|
1445 |
function hook_webform_conditional_operator_info() { |
1446 |
$operators = array(); |
1447 |
$operators['string']['not_equal'] = array( |
1448 |
'label' => t('is not'), |
1449 |
'comparison callback' => 'webform_conditional_operator_string_not_equal', |
1450 |
'js comparison callback' => 'conditionalOperatorStringNotEqual', |
1451 |
); |
1452 |
return $operators; |
1453 |
} |
1454 |
|
1455 |
/**
|
1456 |
* Alter the list of operators and conditional types.
|
1457 |
*
|
1458 |
* @param array $operators
|
1459 |
* A data structure as described in hook_webform_conditional_operator_info().
|
1460 |
*
|
1461 |
* @see hook_webform_conditional_operator_info()
|
1462 |
*/
|
1463 |
function hook_webform_conditional_operators_alter(array &$operators) { |
1464 |
$operators['string']['not_equal']['label'] = t('not equal'); |
1465 |
} |
1466 |
|
1467 |
/**
|
1468 |
* Evaluate the operator for a given set of values.
|
1469 |
*
|
1470 |
* This function will be called two times with potentially different kinds of
|
1471 |
* values: Once in _webform_client_form_validate() before any of the validate
|
1472 |
* handlers or the _webform_submit_COMPONENT() callback is called, and once in
|
1473 |
* webform_client_form_pages() after those handlers have been called.
|
1474 |
*
|
1475 |
* @param array $input_values
|
1476 |
* The values received from the browser.
|
1477 |
* @param mixed $rule_value
|
1478 |
* The value as configured in the form callback.
|
1479 |
* @param array $component
|
1480 |
* The component for which we are evaluating the operator.
|
1481 |
*
|
1482 |
* @return bool
|
1483 |
* The operation result.
|
1484 |
*/
|
1485 |
function callback_webfom_conditional_comparison_operator(array $input_values, $rule_value, array $component) { |
1486 |
foreach ($input_values as $value) { |
1487 |
if (strcasecmp($value, $rule_value)) { |
1488 |
return TRUE; |
1489 |
} |
1490 |
} |
1491 |
return FALSE; |
1492 |
} |
1493 |
|
1494 |
/**
|
1495 |
* Define a form element that configures your operator.
|
1496 |
*
|
1497 |
* @param object $node
|
1498 |
* The node for which the conditionals are being configured.
|
1499 |
*
|
1500 |
* @return string|string[]
|
1501 |
* Either a single rendered form element or a rendered form element per
|
1502 |
* component (keyed by cid). Make sure that none of the rendered strings
|
1503 |
* contains any HTML IDs as the form element will be rendered multiple times.
|
1504 |
* The JavaScript will take care of adding the appropriate name attributes.
|
1505 |
*
|
1506 |
* @see _webform_conditional_expand_value_forms()
|
1507 |
*/
|
1508 |
function callback_webform_conditional_rule_value_form($node) { |
1509 |
$forms = [];
|
1510 |
foreach ($node->webform['components'] as $cid => $component) { |
1511 |
if (webform_component_property($component['type'], 'conditional_type') == 'newsletter') { |
1512 |
$element = [
|
1513 |
'#type' => 'select', |
1514 |
'#options' => [
|
1515 |
'yes' => t('Opt-in'), |
1516 |
'no' => t('No opt-in'), |
1517 |
], |
1518 |
]; |
1519 |
$forms[$cid] = drupal_render($element); |
1520 |
} |
1521 |
} |
1522 |
return $forms; |
1523 |
} |
1524 |
|
1525 |
/**
|
1526 |
* @}
|
1527 |
*/
|