root / drupal7 / sites / all / modules / webform / webform.api.php @ 389fb945
1 | 85ad3d82 | Assos Assos | <?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 | 8c72e82a | Assos Assos | * @return array
|
28 | 85ad3d82 | Assos Assos | * 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 | 8c72e82a | Assos Assos | * - options callback: The name of a function implementing
|
33 | * callback_webform_options() that will return the list.
|
||
34 | 85ad3d82 | Assos Assos | * - 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 | 8c72e82a | Assos Assos | * @see hook_webform_select_options_info()
|
54 | 85ad3d82 | Assos Assos | */
|
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 | 8c72e82a | Assos Assos | * Define a list of options that Webform may use in a select component.
|
62 | 85ad3d82 | Assos Assos | *
|
63 | 8c72e82a | Assos Assos | * Callback for hook_webform_select_options_info().
|
64 | 85ad3d82 | Assos Assos | *
|
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 | 8c72e82a | Assos Assos | *
|
75 | * @return array
|
||
76 | 85ad3d82 | Assos Assos | * An array of key => value pairs suitable for a select list's #options
|
77 | * FormAPI property.
|
||
78 | */
|
||
79 | 8c72e82a | Assos Assos | function callback_webform_options($component, $flat, $arguments) { |
80 | 85ad3d82 | Assos Assos | $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 | a45e4bc1 | Assos Assos | /**
|
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 | 85ad3d82 | Assos Assos | /**
|
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 | a45e4bc1 | Assos Assos | $submission->data[$component_id][0] = 'foo'; |
139 | 85ad3d82 | Assos Assos | } |
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 | 8c72e82a | Assos Assos | *
|
217 | * @return array
|
||
218 | * List of action.
|
||
219 | 85ad3d82 | Assos Assos | */
|
220 | function hook_webform_submission_actions($node, $submission) { |
||
221 | feca1e4a | Assos Assos | $actions = array(); |
222 | a45e4bc1 | Assos Assos | |
223 | 85ad3d82 | Assos Assos | 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 | a45e4bc1 | Assos Assos | /**
|
235 | * Modify the draft to be presented for editing.
|
||
236 | *
|
||
237 | feca1e4a | Assos Assos | * When drafts are enabled for the webform, by default, a pre-existing draft is
|
238 | a45e4bc1 | Assos Assos | * 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 | 389fb945 | Assos Assos | * the pre-existing drafts should be presented.
|
242 | a45e4bc1 | Assos Assos | *
|
243 | feca1e4a | Assos Assos | * @param int $sid
|
244 | * The id of the most recent submission to be presented for editing. Change
|
||
245 | a45e4bc1 | Assos Assos | * to a different draft's sid or set to NULL for a new draft.
|
246 | * @param array $context
|
||
247 | feca1e4a | Assos Assos | * Array of context with indices 'nid' and 'uid'.
|
248 | a45e4bc1 | Assos Assos | */
|
249 | 01f36513 | Assos Assos | function hook_webform_draft_alter(&$sid, array $context) { |
250 | a45e4bc1 | Assos Assos | if ($_GET['newdraft']) { |
251 | $sid = NULL; |
||
252 | } |
||
253 | } |
||
254 | |||
255 | 85ad3d82 | Assos Assos | /**
|
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 | feca1e4a | Assos Assos | * submissions when viewing through the administrative interface.
|
260 | 85ad3d82 | Assos Assos | *
|
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 | 01f36513 | Assos Assos | *
|
304 | * @see hook_form_alter()
|
||
305 | * @see webform_component_edit_form()
|
||
306 | 85ad3d82 | Assos Assos | */
|
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 | a45e4bc1 | Assos Assos | /**
|
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 | 01f36513 | Assos Assos | function hook_webform_analysis_alter(array &$analysis) { |
366 | a45e4bc1 | Assos Assos | $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 | feca1e4a | Assos Assos | |
377 | a45e4bc1 | Assos Assos | /**
|
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 | 01f36513 | Assos Assos | function hook_webform_analysis_component_data_alter(array &$data, $node, array $component) { |
399 | a45e4bc1 | Assos Assos | 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 | 3753f249 | Assos Assos | /**
|
410 | * Alter a Webform submission's header when exported.
|
||
411 | */
|
||
412 | function hook_webform_csv_header_alter(&$header, $component) { |
||
413 | a45e4bc1 | Assos Assos | // Use the machine name for component headers, but only for the webform
|
414 | 3753f249 | Assos Assos | // 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 | 85ad3d82 | Assos Assos | /**
|
432 | * Define components to Webform.
|
||
433 | *
|
||
434 | 8c72e82a | Assos Assos | * @return array
|
435 | 85ad3d82 | Assos Assos | * 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 | 76bdcd04 | Assos Assos | * - private
|
450 | 85ad3d82 | Assos Assos | *
|
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 | feca1e4a | Assos Assos | * See the sample component implementation for details on each one of these
|
481 | * callbacks.
|
||
482 | 85ad3d82 | Assos Assos | *
|
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 | a45e4bc1 | Assos Assos | // This component includes an analysis callback. Defaults to TRUE.
|
493 | 'analysis' => TRUE, |
||
494 | |||
495 | 85ad3d82 | Assos Assos | // 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 | 01f36513 | Assos Assos | // If this component can be used for SPAM analysis.
|
537 | 85ad3d82 | Assos Assos | '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 | a45e4bc1 | Assos Assos | |
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 | 76bdcd04 | Assos Assos | |
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 | 85ad3d82 | Assos Assos | ), |
553 | a45e4bc1 | Assos Assos | |
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 | 85ad3d82 | Assos Assos | '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 | 3753f249 | Assos Assos | /**
|
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 | 85ad3d82 | Assos Assos | /**
|
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 | 8c72e82a | Assos Assos | *
|
627 | * @return bool
|
||
628 | 85ad3d82 | Assos Assos | * 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 | feca1e4a | Assos Assos | |
636 | 85ad3d82 | Assos Assos | case 'edit': |
637 | return FALSE; |
||
638 | feca1e4a | Assos Assos | |
639 | 85ad3d82 | Assos Assos | case 'delete': |
640 | return TRUE; |
||
641 | feca1e4a | Assos Assos | |
642 | 85ad3d82 | Assos Assos | 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 | a45e4bc1 | Assos Assos | * Access via this hook is in addition (adds permission) to the standard
|
653 | * webform access.
|
||
654 | 85ad3d82 | Assos Assos | *
|
655 | * @param $node
|
||
656 | * The Webform node to check access on.
|
||
657 | * @param $account
|
||
658 | * The user account to check access on.
|
||
659 | 8c72e82a | Assos Assos | *
|
660 | * @return bool
|
||
661 | 85ad3d82 | Assos Assos | * TRUE or FALSE if the user can access the webform results.
|
662 | 01f36513 | Assos Assos | *
|
663 | * @see webform_results_access()
|
||
664 | 85ad3d82 | Assos Assos | */
|
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 | c22e192e | Assos Assos | /**
|
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 | a45e4bc1 | Assos Assos | * @param object $node
|
682 | c22e192e | Assos Assos | * The Webform node to check access on.
|
683 | a45e4bc1 | Assos Assos | * @param object $account
|
684 | c22e192e | Assos Assos | * The user account to check access on.
|
685 | feca1e4a | Assos Assos | *
|
686 | * @return bool
|
||
687 | c22e192e | Assos Assos | * TRUE or FALSE if the user can access the webform results.
|
688 | 01f36513 | Assos Assos | *
|
689 | * @see webform_results_clear_access()
|
||
690 | c22e192e | Assos Assos | */
|
691 | function hook_webform_results_clear_access($node, $account) { |
||
692 | return user_access('my additional access', $account); |
||
693 | } |
||
694 | |||
695 | a45e4bc1 | Assos Assos | /**
|
696 | 01f36513 | Assos Assos | * Overrides the node_access and user_access permissions.
|
697 | *
|
||
698 | a45e4bc1 | Assos Assos | * 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 | feca1e4a | Assos Assos | *
|
717 | * @return bool|null
|
||
718 | a45e4bc1 | Assos Assos | * 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 | 01f36513 | Assos Assos | *
|
722 | * @see webform_node_update_access()
|
||
723 | a45e4bc1 | Assos Assos | */
|
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 | 85ad3d82 | Assos Assos | /**
|
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 | 8c72e82a | Assos Assos | *
|
744 | * @return array
|
||
745 | 85ad3d82 | Assos Assos | * 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 | feca1e4a | Assos Assos | *
|
751 | * @code
|
||
752 | 85ad3d82 | Assos Assos | * array[0] => array(
|
753 | * 'filepath' => '/sites/default/files/attachment.txt',
|
||
754 | * 'filename' => 'attachment.txt',
|
||
755 | * 'filemime' => 'text/plain',
|
||
756 | * );
|
||
757 | feca1e4a | Assos Assos | * @endcode
|
758 | 85ad3d82 | Assos Assos | */
|
759 | function _webform_attachments_component($component, $value) { |
||
760 | $files = array(); |
||
761 | $files[] = (array) file_load($value[0]); |
||
762 | return $files; |
||
763 | } |
||
764 | |||
765 | a45e4bc1 | Assos Assos | /**
|
766 | * Alter default settings for a newly created webform node.
|
||
767 | *
|
||
768 | * @param array $defaults
|
||
769 | 76bdcd04 | Assos Assos | * Default settings for a newly created webform node as defined by
|
770 | * webform_node_defaults().
|
||
771 | a45e4bc1 | Assos Assos | *
|
772 | * @see webform_node_defaults()
|
||
773 | */
|
||
774 | 01f36513 | Assos Assos | function hook_webform_node_defaults_alter(array &$defaults) { |
775 | a45e4bc1 | Assos Assos | $defaults['allow_draft'] = '1'; |
776 | } |
||
777 | |||
778 | /**
|
||
779 | * Add additional fields to submission data downloads.
|
||
780 | *
|
||
781 | 8c72e82a | Assos Assos | * @return array
|
782 | a45e4bc1 | Assos Assos | * 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 | 8c72e82a | Assos Assos | * @param array $options
|
801 | a45e4bc1 | Assos Assos | * 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 | 8c72e82a | Assos Assos | * @return string
|
809 | a45e4bc1 | Assos Assos | * 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 | feca1e4a | Assos Assos | |
818 | a45e4bc1 | Assos Assos | case 'field_key_2': |
819 | return 'Field Value 2'; |
||
820 | } |
||
821 | } |
||
822 | |||
823 | 85ad3d82 | Assos Assos | /**
|
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 | 8c72e82a | Assos Assos | * @return array
|
840 | 85ad3d82 | Assos Assos | * 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 | a45e4bc1 | Assos Assos | 'required' => 0, |
847 | 85ad3d82 | Assos Assos | 'pid' => 0, |
848 | 'weight' => 0, |
||
849 | 'extra' => array( |
||
850 | 'options' => '', |
||
851 | 'questions' => '', |
||
852 | 'optrand' => 0, |
||
853 | 'qrand' => 0, |
||
854 | 'description' => '', |
||
855 | 01d522a6 | Assos Assos | 'description_above' => FALSE, |
856 | a45e4bc1 | Assos Assos | 'private' => FALSE, |
857 | 'analysis' => TRUE, |
||
858 | 85ad3d82 | Assos Assos | ), |
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 | 01f36513 | Assos Assos | * @param array $component
|
872 | 85ad3d82 | Assos Assos | * A Webform component array.
|
873 | 01f36513 | Assos Assos | * @param array $form
|
874 | * The form array.
|
||
875 | * @param array $form_state
|
||
876 | * The form state array.
|
||
877 | 8c72e82a | Assos Assos | *
|
878 | * @return array
|
||
879 | 85ad3d82 | Assos Assos | * An array of form items to be displayed on the edit component page
|
880 | */
|
||
881 | 01f36513 | Assos Assos | function _webform_edit_component(array $component, array &$form, array &$form_state) { |
882 | 85ad3d82 | Assos Assos | // Disabling the description if not wanted.
|
883 | 01f36513 | Assos Assos | $form['description']['#access'] = FALSE; |
884 | 85ad3d82 | Assos Assos | |
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 | a45e4bc1 | Assos Assos | '#description' => t('Key-value pairs may be entered separated by pipes. i.e. safe_key|Some readable option') . ' ' . theme('webform_token_help'), |
892 | 85ad3d82 | Assos Assos | '#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 | a45e4bc1 | Assos Assos | * @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 | 85ad3d82 | Assos Assos | *
|
919 | 8c72e82a | Assos Assos | * @return array
|
920 | * $form_item
|
||
921 | *
|
||
922 | 85ad3d82 | Assos Assos | * @see _webform_client_form_add_component()
|
923 | */
|
||
924 | a45e4bc1 | Assos Assos | function _webform_render_component($component, $value = NULL, $filter = TRUE, $submission = NULL) { |
925 | 85ad3d82 | Assos Assos | $form_item = array( |
926 | '#type' => 'textfield', |
||
927 | a45e4bc1 | Assos Assos | '#title' => $filter ? webform_filter_xss($component['name']) : $component['name'], |
928 | '#required' => $component['required'], |
||
929 | 85ad3d82 | Assos Assos | '#weight' => $component['weight'], |
930 | a45e4bc1 | Assos Assos | '#description' => $filter ? webform_filter_descriptions($component['extra']['description']) : $component['extra']['description'], |
931 | '#default_value' => $filter ? webform_replace_tokens($component['value']) : $component['value'], |
||
932 | e9984459 | Assos Assos | '#theme_wrappers' => array('webform_element'), |
933 | 85ad3d82 | Assos Assos | ); |
934 | |||
935 | if (isset($value)) { |
||
936 | $form_item['#default_value'] = $value[0]; |
||
937 | } |
||
938 | |||
939 | return $form_item; |
||
940 | } |
||
941 | |||
942 | a45e4bc1 | Assos Assos | /**
|
943 | 76bdcd04 | Assos Assos | * Allow modules to modify a webform component that will be rendered in a form.
|
944 | a45e4bc1 | Assos Assos | *
|
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 | 01f36513 | Assos Assos | function hook_webform_component_render_alter(array &$element, array &$component) { |
953 | a45e4bc1 | Assos Assos | if ($component['cid'] == 10) { |
954 | $element['#title'] = 'My custom title'; |
||
955 | $element['#default_value'] = 42; |
||
956 | } |
||
957 | } |
||
958 | |||
959 | 85ad3d82 | Assos Assos | /**
|
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 | a45e4bc1 | Assos Assos | * @param $submission
|
975 | * The submission. Used to generate tokens.
|
||
976 | 8c72e82a | Assos Assos | *
|
977 | * @return array
|
||
978 | 85ad3d82 | Assos Assos | * 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 | a45e4bc1 | Assos Assos | function _webform_display_component($component, $value, $format = 'html', $submission = array()) { |
989 | 85ad3d82 | Assos Assos | 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 | a45e4bc1 | Assos Assos | /**
|
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 | 01f36513 | Assos Assos | function hook_webform_component_display_alter(array &$element, array &$component) { |
1014 | a45e4bc1 | Assos Assos | 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 | 01f36513 | Assos Assos | function _webform_action_set_component(array $component, array &$element, array &$form_state, $value) { |
1037 | a45e4bc1 | Assos Assos | $element['#value'] = $value; |
1038 | form_set_value($element, $value, $form_state); |
||
1039 | } |
||
1040 | |||
1041 | 85ad3d82 | Assos Assos | /**
|
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 | feca1e4a | Assos Assos | *
|
1058 | 01f36513 | Assos Assos | * @return array
|
1059 | 85ad3d82 | Assos Assos | * 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 | a45e4bc1 | Assos Assos | $number = preg_replace('/[^0-9]/', '', $value[0]); |
1066 | 85ad3d82 | Assos Assos | 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 | ca0757b9 | Assos Assos | if (!empty($value[0]) && ($file = webform_get_file($value[0]))) { |
1090 | file_usage_delete($file, 'webform'); |
||
1091 | file_delete($file);
|
||
1092 | 85ad3d82 | Assos Assos | } |
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 | a45e4bc1 | Assos Assos | * @param $join
|
1146 | * An optional SelectQuery object to be used to join with the submissions
|
||
1147 | * table to restrict the submissions being analyzed.
|
||
1148 | 8c72e82a | Assos Assos | *
|
1149 | * @return array
|
||
1150 | a45e4bc1 | Assos Assos | * 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 | 85ad3d82 | Assos Assos | */
|
1169 | a45e4bc1 | Assos Assos | function _webform_analysis_component($component, $sids = array(), $single = FALSE, $join = NULL) { |
1170 | 85ad3d82 | Assos Assos | // 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 | a45e4bc1 | Assos Assos | if ($join) { |
1189 | $query->innerJoin($join, 'ws2_', 'wsd.sid = ws2_.sid'); |
||
1190 | } |
||
1191 | |||
1192 | 85ad3d82 | Assos Assos | $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 | a45e4bc1 | Assos Assos | $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 | 85ad3d82 | Assos Assos | } |
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 | 8c72e82a | Assos Assos | *
|
1238 | * @return string
|
||
1239 | 85ad3d82 | Assos Assos | * 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 | 8c72e82a | Assos Assos | *
|
1269 | * @return array
|
||
1270 | 85ad3d82 | Assos Assos | * 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 | a45e4bc1 | Assos Assos | $header[1] = array($export_options['header_keys'] ? $component['form_key'] : $component['name']); |
1277 | 85ad3d82 | Assos Assos | $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 | 8c72e82a | Assos Assos | *
|
1307 | * @return array
|
||
1308 | 85ad3d82 | Assos Assos | * 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 | a45e4bc1 | Assos Assos | /**
|
1322 | 01f36513 | Assos Assos | * Fix the view field(s) that are automatically generated for number components.
|
1323 | a45e4bc1 | Assos Assos | *
|
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 | feca1e4a | Assos Assos | * A Webform component array.
|
1331 | a45e4bc1 | Assos Assos | * @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 | feca1e4a | Assos Assos | *
|
1335 | a45e4bc1 | Assos Assos | * @return array
|
1336 | * The modified $fields array.
|
||
1337 | */
|
||
1338 | 01f36513 | Assos Assos | function _webform_view_field_component(array $component, array $fields) { |
1339 | a45e4bc1 | Assos Assos | 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 | feca1e4a | Assos Assos | * opportunity to modify the view AFTER webform.
|
1357 | a45e4bc1 | Assos Assos | *
|
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 | feca1e4a | Assos Assos | * The arguments that were passed to the view.
|
1364 | a45e4bc1 | Assos Assos | */
|
1365 | 01f36513 | Assos Assos | function hook_webform_view_alter($view, $display_id, array $args) { |
1366 | feca1e4a | Assos Assos | // Don't show component with cid == 4.
|
1367 | a45e4bc1 | Assos Assos | $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 | 01f36513 | Assos Assos | function hook_webform_html_capable_mail_systems_alter(array &$systems) { |
1383 | a45e4bc1 | Assos Assos | if (module_exists('my_module')) { |
1384 | $systems[] = 'MyModuleMailSystem'; |
||
1385 | } |
||
1386 | } |
||
1387 | |||
1388 | 01d522a6 | Assos Assos | /**
|
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 | feca1e4a | Assos Assos | * @param array &$exporters
|
1414 | 01d522a6 | Assos Assos | * A list of all available webform exporters.
|
1415 | */
|
||
1416 | 01f36513 | Assos Assos | function hook_webform_exporters_alter(array &$exporters) { |
1417 | 01d522a6 | Assos Assos | $exporters['excel']['handler'] = 'customized_excel_exporter'; |
1418 | $exporters['excel']['file'] = drupal_get_path('module', 'yourmodule') . '/includes/customized_excel_exporter.inc'; |
||
1419 | } |
||
1420 | |||
1421 | 76bdcd04 | Assos Assos | /**
|
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 | 85ad3d82 | Assos Assos | /**
|
1526 | * @}
|
||
1527 | */ |