/[drupal]/contributions/modules/webform/webform.module
ViewVC logotype

Contents of /contributions/modules/webform/webform.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.141 - (show annotations) (download) (as text)
Fri Nov 6 01:59:43 2009 UTC (2 weeks, 6 days ago) by quicksketch
Branch: MAIN
CVS Tags: HEAD
Changes since 1.140: +2 -2 lines
File MIME type: text/x-php
#447054 by Liam Morland: You have already submitted the form message is displayed even before the user submits the form.
1 <?php
2 // $Id: webform.module,v 1.140 2009/11/06 01:11:58 quicksketch Exp $
3
4 /**
5 * This module provides a simple way to create forms and questionnaires.
6 *
7 * The initial development of this module was sponsered by ÅF Industri AB, Open
8 * Source City and Karlstad University Library. Continued development sponsored
9 * by Lullabot.
10 *
11 * @author Nathan Haug <nate@lullabot.com>
12 * @author Pontus Ullgren <ullgren@user.sourceforge.net>
13 */
14
15 /**
16 * Implementation of hook_help().
17 */
18 function webform_help($section = 'admin/help#webform', $arg = NULL) {
19 $output = '';
20 switch ($section) {
21 case 'admin/settings/webform':
22 $output = t('Webforms are forms and questionnaires. To add one, select <a href="!url">Create content -&gt; Webform</a>.', array('!url' => url('node/add/webform')));
23 break;
24 case 'admin/help#webform':
25 $output = t("<p>This module lets you create forms or questionnaires and define their content. Submissions from these forms are stored in the database and optionally also sent by e-mail to a predefined address.</p>
26 <p>Here is how to create one:</p>
27 <ul>
28 <li>Go to Create Content and add a webform</li>
29 <li>Add a description to be displayed as a teaser and above the actual form.</li>
30 <li>Add a confirmation message or redirect node that is to be displayed after successful submission.</li>
31 <li>Add one or more components to your form.</li>
32 <li>Optionally add an e-mail address to which submissions will be sent. If no email address is specified, no e-mail will be sent when submissions are made through the form.</li>
33 <li>Optionally select an e-mail (or hidden) component that will be used to populate the return e-mail address on any sent e-mail.</li>
34 <li>Optionally select a textfield (or hidden) component that will be used to populate the subject e-mail field on any sent e-mail.</li>
35 </ul>
36 <p>Help on adding and configuring the components will be shown after you add your first component.</p>
37 <p>The content of submitted forms is stored in the database table <i>webform_submitted_data</i> as key-value pairs.</p>
38 ");
39 break;
40 case 'node/add#webform':
41 $output = t('A webform can be a questionnaires, contact or request forms. It can be used to let visitors make contact, register for a event or to enable a complex survey.');
42 break;
43 case 'node/%/webform/components':
44 $output .= '<p>'. t('This page displays all the components currently configured for this webform node. You may add any number of components to the form, even multiple of the same type. To add a new component, fill in a name and select a type from the fields at the bottom of the table. Submit the form to create the new component or update any changed form values.') .'</p>';
45 $output .= '<p>'. t('Click on any existing component\'s name to edit its settings.') .'</p>';
46 break;
47 }
48 if (strstr($section, 'admin/settings/webform#')) {
49 // Call help hooks in plugins:
50 $components = webform_load_components(TRUE);
51 foreach ($components as $key => $component) {
52 $help_function = '_webform_help_'. $key;
53 if (function_exists($help_function)) {
54 $output .= $help_function($section);
55 }
56 }
57 }
58
59 return $output;
60 }
61
62 /**
63 * Implementation of hook_menu().
64 */
65 function webform_menu() {
66 $items = array();
67
68 // Submissions listing.
69 $items['admin/content/webform'] = array(
70 'title' => 'Webforms',
71 'page callback' => 'webform_admin_content',
72 'access callback' => 'user_access',
73 'access arguments' => array('access webform results'),
74 'description' => 'View and edit all the available webforms on your site.',
75 'type' => MENU_NORMAL_ITEM,
76 );
77
78 // Admin Settings.
79 $items['admin/settings/webform'] = array(
80 'title' => 'Webform',
81 'page callback' => 'drupal_get_form',
82 'page arguments' => array('webform_admin_settings'),
83 'access callback' => 'user_access',
84 'access arguments' => array('administer site configuration'),
85 'description' => 'Global configuration of webform functionality.',
86 'type' => MENU_NORMAL_ITEM,
87 );
88
89 // Node page tabs.
90 $items['node/%webform_menu/done'] = array(
91 'title' => 'Webform confirmation',
92 'page callback' => '_webform_confirmation',
93 'page arguments' => array(1),
94 'access callback' => 'node_access',
95 'access arguments' => array('view', 1),
96 'type' => MENU_CALLBACK,
97 );
98 $items['node/%webform_menu/webform'] = array(
99 'title' => 'Webform',
100 'page callback' => 'webform_components_page',
101 'page arguments' => array(1),
102 'access callback' => 'node_access',
103 'access arguments' => array('update', 1),
104 'file' => 'includes/webform.components.inc',
105 'weight' => 1,
106 'type' => MENU_LOCAL_TASK,
107 );
108 $items['node/%webform_menu/webform/components'] = array(
109 'title' => 'Form components',
110 'page callback' => 'webform_components_page',
111 'page arguments' => array(1),
112 'access callback' => 'node_access',
113 'access arguments' => array('update', 1),
114 'file' => 'includes/webform.components.inc',
115 'weight' => 0,
116 'type' => MENU_DEFAULT_LOCAL_TASK,
117 );
118 $items['node/%webform_menu/webform/configure'] = array(
119 'title' => 'Form settings',
120 'page callback' => 'drupal_get_form',
121 'page arguments' => array('webform_configure_form', 1),
122 'access callback' => 'node_access',
123 'access arguments' => array('update', 1),
124 'file' => 'includes/webform.pages.inc',
125 'weight' => 2,
126 'type' => MENU_LOCAL_TASK,
127 );
128
129 // Node e-mail forms.
130 $items['node/%webform_menu/webform/emails'] = array(
131 'title' => 'E-mails',
132 'page callback' => 'drupal_get_form',
133 'page arguments' => array('webform_emails_form', 1),
134 'access callback' => 'node_access',
135 'access arguments' => array('update', 1),
136 'file' => 'includes/webform.emails.inc',
137 'weight' => 1,
138 'type' => MENU_LOCAL_TASK,
139 );
140 $items['node/%webform_menu/webform/emails/%webform_menu_email'] = array(
141 'title' => 'Edit e-mail settings',
142 'load arguments' => array(1),
143 'page arguments' => array('webform_email_edit_form', 1, 4),
144 'access callback' => 'node_access',
145 'access arguments' => array('update', 1),
146 'file' => 'includes/webform.emails.inc',
147 'type' => MENU_LOCAL_TASK,
148 );
149 $items['node/%webform_menu/webform/emails/%webform_menu_email/delete'] = array(
150 'title' => 'Delete e-mail settings',
151 'load arguments' => array(1),
152 'page arguments' => array('webform_email_delete_form', 1, 4),
153 'access callback' => 'node_access',
154 'access arguments' => array('update', 1),
155 'type' => MENU_LOCAL_TASK,
156 );
157
158 // Node component forms.
159 $items['node/%webform_menu/webform/components/%webform_menu_component'] = array(
160 'load arguments' => array(1, 5),
161 'page callback' => 'drupal_get_form',
162 'page arguments' => array('webform_component_edit_form', 1, 4, FALSE),
163 'access callback' => 'node_access',
164 'access arguments' => array('update', 1),
165 'type' => MENU_LOCAL_TASK,
166 );
167 $items['node/%webform_menu/webform/components/%webform_menu_component/clone'] = array(
168 'load arguments' => array(1, 5),
169 'page callback' => 'drupal_get_form',
170 'page arguments' => array('webform_component_edit_form', 1, 4, TRUE),
171 'access callback' => 'node_access',
172 'access arguments' => array('update', 1),
173 'type' => MENU_LOCAL_TASK,
174 );
175 $items['node/%webform_menu/webform/components/%webform_menu_component/delete'] = array(
176 'load arguments' => array(1, 5),
177 'page callback' => 'drupal_get_form',
178 'page arguments' => array('webform_component_delete_form', 1, 4),
179 'access callback' => 'node_access',
180 'access arguments' => array('update', 1),
181 'type' => MENU_LOCAL_TASK,
182 );
183
184 // Node webform results.
185 $items['node/%webform_menu/webform-results'] = array(
186 'title' => 'Results',
187 'page callback' => 'webform_results_submissions',
188 'page arguments' => array(1, FALSE, '50'),
189 'access callback' => 'webform_results_access',
190 'access arguments' => array(1, 'access webform results'),
191 'file' => 'includes/webform.report.inc',
192 'weight' => 2,
193 'type' => MENU_LOCAL_TASK,
194 );
195 $items['node/%webform_menu/webform-results/submissions'] = array(
196 'title' => 'Submissions',
197 'page callback' => 'webform_results_submissions',
198 'page arguments' => array(1, FALSE, '50'),
199 'access callback' => 'webform_results_access',
200 'access arguments' => array(1, 'access webform results'),
201 'file' => 'includes/webform.report.inc',
202 'weight' => 4,
203 'type' => MENU_DEFAULT_LOCAL_TASK,
204 );
205 $items['node/%webform_menu/webform-results/analysis'] = array(
206 'title' => 'Analysis',
207 'page callback' => 'webform_results_analysis',
208 'page arguments' => array(1),
209 'access callback' => 'webform_results_access',
210 'access arguments' => array(1, 'access webform results'),
211 'file' => 'includes/webform.report.inc',
212 'weight' => 5,
213 'type' => MENU_LOCAL_TASK,
214 );
215 $items['node/%webform_menu/webform-results/table'] = array(
216 'title' => 'Table',
217 'page callback' => 'webform_results_table',
218 'page arguments' => array(1, '50'),
219 'access callback' => 'webform_results_access',
220 'access arguments' => array(1, 'access webform results'),
221 'file' => 'includes/webform.report.inc',
222 'weight' => 6,
223 'type' => MENU_LOCAL_TASK,
224 );
225 $items['node/%webform_menu/webform-results/download'] = array(
226 'title' => 'Download',
227 'page callback' => 'drupal_get_form',
228 'page arguments' => array('webform_results_download_form', 1),
229 'access callback' => 'webform_results_access',
230 'access arguments' => array(1, 'access webform results'),
231 'file' => 'includes/webform.report.inc',
232 'weight' => 7,
233 'type' => MENU_LOCAL_TASK,
234 );
235 $items['node/%webform_menu/webform-results/clear'] = array(
236 'title' => 'Clear',
237 'page callback' => 'drupal_get_form',
238 'page arguments' => array('webform_results_clear_form', 1),
239 'access callback' => 'webform_results_access',
240 'access arguments' => array(1, 'clear webform results'),
241 'file' => 'includes/webform.report.inc',
242 'weight' => 8,
243 'type' => MENU_LOCAL_TASK,
244 );
245
246 // Node submissions.
247 $items['node/%webform_menu/submissions'] = array(
248 'title' => 'Submissions',
249 'page callback' => 'webform_results_submissions',
250 'page arguments' => array(1, TRUE, '50'),
251 'access callback' => 'webform_submission_access',
252 'access arguments' => array(1, NULL, 'list'),
253 'file' => 'includes/webform.report.inc',
254 'type' => MENU_CALLBACK,
255 );
256 $items['node/%webform_menu/submission/%webform_menu_submission'] = array(
257 'title' => 'Webform submission',
258 'load arguments' => array(1),
259 'page callback' => 'webform_client_form_load',
260 'page arguments' => array(1, 3, FALSE, FALSE),
261 'access callback' => 'webform_submission_access',
262 'access arguments' => array(1, 3, 'view'),
263 'type' => MENU_CALLBACK,
264 );
265 $items['node/%webform_menu/submission/%webform_menu_submission/view'] = array(
266 'title' => 'View',
267 'load arguments' => array(1),
268 'page callback' => 'webform_client_form_load',
269 'page arguments' => array(1, 3, FALSE, FALSE),
270 'access callback' => 'webform_submission_access',
271 'access arguments' => array(1, 3, 'view'),
272 'weight' => 0,
273 'type' => MENU_DEFAULT_LOCAL_TASK,
274 );
275 $items['node/%webform_menu/submission/%webform_menu_submission/edit'] = array(
276 'title' => 'Edit',
277 'load arguments' => array(1),
278 'page callback' => 'webform_client_form_load',
279 'page arguments' => array(1, 3, TRUE, FALSE),
280 'access callback' => 'webform_submission_access',
281 'access arguments' => array(1, 3, 'edit'),
282 'weight' => 1,
283 'type' => MENU_LOCAL_TASK,
284 );
285 $items['node/%webform_menu/submission/%webform_menu_submission/delete'] = array(
286 'title' => 'Delete',
287 'load arguments' => array(1),
288 'page callback' => 'drupal_get_form',
289 'page arguments' => array('webform_submission_delete_form', 1, 3),
290 'access callback' => 'webform_submission_access',
291 'access arguments' => array(1, 3, 'delete'),
292 'weight' => 2,
293 'type' => MENU_LOCAL_TASK,
294 );
295
296 return $items;
297 }
298
299 /**
300 * Menu loader callback. Load a webform node if the given nid is a webform.
301 */
302 function webform_menu_load($nid) {
303 if (!is_numeric($nid)) {
304 return FALSE;
305 }
306 $node = node_load($nid);
307 if (!isset($node->type) || $node->type != 'webform') {
308 return FALSE;
309 }
310 return $node;
311 }
312
313 /**
314 * Menu loader callback. Load a webform submission if the given sid is a valid.
315 */
316 function webform_menu_submission_load($sid, $nid) {
317 module_load_include('inc', 'webform', 'includes/webform.submissions');
318 $submission = webform_get_submission($nid, $sid);
319 return empty($submission) ? FALSE : $submission;
320 }
321
322 /**
323 * Menu loader callback. Load a webform component if the given cid is a valid.
324 */
325 function webform_menu_component_load($cid, $nid, $type) {
326 module_load_include('inc', 'webform', 'includes/webform.components');
327 if ($cid == 'new') {
328 $components = webform_load_components();
329 $component = in_array($type, array_keys($components)) ? array('type' => $type, 'name' => $_GET['name'], 'mandatory' => $_GET['mandatory'], 'email' => $_GET['email'], 'pid' => $_GET['pid'], 'weight' => $_GET['weight']) : FALSE;
330 }
331 else {
332 $node = node_load($nid);
333 $component = isset($node->webform['components'][$cid]) ? $node->webform['components'][$cid] : FALSE;
334 }
335 webform_component_defaults($component);
336 return $component;
337 }
338
339
340 /**
341 * Menu loader callback. Load a webform e-mail if the given eid is a valid.
342 */
343 function webform_menu_email_load($eid, $nid) {
344 module_load_include('inc', 'webform', 'includes/webform.emails');
345 $node = node_load($nid);
346 if ($eid == 'new') {
347 $email = array(
348 'email' => '',
349 'subject' => 'default',
350 'from_name' => 'default',
351 'from_address' => 'default',
352 'template' => 'default',
353 );
354 if (isset($_GET['option']) && isset($_GET['email'])) {
355 $type = $_GET['option'];
356 if ($type == 'custom') {
357 $email['email'] = $_GET['email'];
358 }
359 elseif ($type == 'component' && isset($node->webform['components'][$_GET['email']])) {
360 $email['email'] = $_GET['email'];
361 }
362 }
363 }
364 else {
365 $email = isset($node->webform['emails'][$eid]) ? $node->webform['emails'][$eid] : FALSE;
366 }
367
368 return $email;
369 }
370
371 function webform_submission_access($node, $submission, $op = 'view', $account = NULL) {
372 global $user;
373 $account = isset($account) ? $account : $user;
374
375 switch ($op) {
376 case 'view':
377 return user_access('access webform results') || (user_access('access own webform submissions') && ($account->uid == $submission->uid));
378 case 'edit':
379 return user_access('edit webform submissions') || (user_access('edit own webform submissions') && ($account->uid == $submission->uid));
380 case 'delete':
381 return user_access('edit webform submissions') || (user_access('edit own webform submissions') && ($account->uid == $submission->uid)) || user_access('clear webform results');
382 case 'list':
383 return user_access('access webform results') || user_access('access webform submissions') || (user_access('access own webform submissions') && $user->uid);
384 }
385 }
386
387 /**
388 * Menu access callback. Ensure a user both access and node 'view' permission.
389 */
390 function webform_results_access($node, $perm) {
391 return node_access('view', $node) && user_access($perm);
392 }
393
394 /**
395 * Implementation of hook_init().
396 */
397 function webform_init() {
398 if (module_exists('form_builder') && strpos($_GET['q'], 'admin/build/form-builder') !== FALSE) {
399 module_load_include('inc', 'webform', 'includes/webform.form_builder');
400 }
401 }
402
403 /**
404 * Implementation of hook_perm().
405 */
406 function webform_perm() {
407 return array('create webforms', 'edit own webforms', 'edit webforms', 'access webform results', 'clear webform results', 'access own webform submissions', 'edit own webform submissions', 'edit webform submissions', 'use PHP for additional processing');
408 }
409
410 /**
411 * Implementation of hook_theme().
412 */
413 function webform_theme() {
414 $theme = array(
415 // webform.module.
416 'webform_view' => array(
417 'arguments' => array('node' => NULL, 'teaser' => NULL, 'page' => NULL, 'form' => NULL, 'enabled' => NULL),
418 ),
419 'webform_view_messages' => array(
420 'arguments' => array('node' => NULL, 'teaser' => NULL, 'page' => NULL, 'submission_count' => NULL, 'limit_exceeded' => NULL, 'allowed_roles' => NULL),
421 ),
422 'webform_form' => array(
423 'arguments' => array('form' => NULL),
424 'template' => 'templates/webform-form',
425 'pattern' => 'webform_form_[0-9]+',
426 ),
427 'webform_advanced_submit_limit_form' => array(
428 'arguments' => array('form' => NULL),
429 'file' => 'includes/webform.pages.inc',
430 ),
431 'webform_admin_settings' => array(
432 'arguments' => array('form' => NULL),
433 ),
434 'webform_confirmation' => array(
435 'arguments' => array('node' => NULL, 'sid' => NULL),
436 'template' => 'templates/webform-confirmation',
437 'pattern' => 'webform_confirmation_[0-9]+',
438 ),
439 'webform_mail_message' => array(
440 'arguments' => array('form_values' => NULL, 'node' => NULL, 'sid' => NULL, 'cid' => NULL),
441 'template' => 'templates/webform-mail',
442 'pattern' => 'webform_mail(_[0-9]+)?',
443 ),
444 'webform_mail_fields' => array(
445 'arguments' => array('cid' => NULL, 'value' => NULL, 'node' => NULL, 'indent' => NULL),
446 ),
447 'webform_mail_headers' => array(
448 'arguments' => array('form_values' => NULL, 'node' => NULL, 'sid' => NULL, 'cid' => NULL),
449 'pattern' => 'webform_mail_headers_[0-9]+',
450 ),
451 'webform_admin_content' => array(
452 'arguments' => array('nodes' => NULL),
453 ),
454 'webform_token_help' => array(
455 'arguments' => array(),
456 ),
457 // webform.emails.inc.
458 'webform_emails_form' => array(
459 'arguments' => array('form' => NULL),
460 'file' => 'includes/webform.emails.inc',
461 ),
462 'webform_email_add_form' => array(
463 'arguments' => array('form' => NULL),
464 'file' => 'includes/webform.emails.inc',
465 ),
466 'webform_email_edit_form' => array(
467 'arguments' => array('form' => NULL),
468 'file' => 'includes/webform.emails.inc',
469 ),
470 // webform_components.inc.
471 'webform_components_page' => array(
472 'arguments' => array('node' => NULL, 'mode' => NULL, 'form' => NULL),
473 ),
474 'webform_components_form' => array(
475 'arguments' => array('form' => NULL),
476 ),
477 // webform_report.inc.
478 'webform_results_per_page' => array(
479 'arguments' => array('total_count' => NULL, 'pager_count' => NULL),
480 ),
481 'webform_results_submissions_header' => array(
482 'arguments' => array('node' => NULL),
483 ),
484 'webform_results_submissions' => array(
485 'arguments' => array('node' => NULL, 'submissions' => NULL, 'total_count' => NULL, 'pager_count' => NULL),
486 ),
487 'webform_results_table_header' => array(
488 'arguments' => array('node' => NULL),
489 ),
490 'webform_results_table' => array(
491 'arguments' => array('node' => NULL, 'components' => NULL, 'submissions' => NULL, 'node' => NULL, 'total_count' => NULL, 'pager_count' => NULL),
492 ),
493 );
494 // Theme functions in all components.
495 $components = webform_load_components(TRUE);
496 foreach ($components as $key => $component) {
497 $theme_hook = '_webform_theme_'. $key;
498 if (function_exists($theme_hook)) {
499 $theme = array_merge($theme, $theme_hook());
500 }
501 }
502 return $theme;
503 }
504
505 /**
506 * Implementation of hook_node_info().
507 */
508 function webform_node_info() {
509 return array(
510 'webform' => array(
511 'name' => t('Webform'),
512 'module' => 'webform',
513 'description' => t('Create a new form or questionnaire accessible to users. Submission results and statistics are recorded and accessible to privileged users.'),
514 )
515 );
516 }
517
518 /**
519 * Implementation of hook_access().
520 */
521 function webform_access($op, $node, $account) {
522 switch ($op) {
523 case 'create':
524 return user_access('create webforms', $account);
525 case 'update':
526 case 'delete':
527 if (user_access('edit webforms', $account) || (user_access('edit own webforms', $account) && ($account->uid == $node->uid))) {
528 return TRUE;
529 }
530 }
531 }
532
533 /**
534 * Implementation of hook_forms().
535 * All webform_client_form forms share the same form handler
536 */
537 function webform_forms($form_id) {
538 $forms = array();
539 if (strpos($form_id, 'webform_client_form_') === 0) {
540 $forms[$form_id]['callback'] = 'webform_client_form';
541 }
542 return $forms;
543 }
544
545 /**
546 * Implementation of hook_file_download().
547 *
548 * Only allow users with view webform submissions to download files.
549 */
550 function webform_file_download($file) {
551 $file = file_check_location(file_directory_path() .'/'. $file, file_directory_path() .'/webform/');
552 if ($file && user_access('access webform results')) {
553 $info = image_get_info(file_create_path($file));
554 if (isset($info['mime_type'])) {
555 $headers = array('Content-type: '. $info['mime_type']);
556 }
557 else {
558 $headers = array(
559 'Content-type: force-download',
560 'Content-disposition: attachment',
561 );
562 }
563 return $headers;
564 }
565 }
566
567 /**
568 * Implementation of hook_insert().
569 */
570 function webform_insert($node) {
571 module_load_include('inc', 'webform', 'includes/webform.components');
572
573 // Insert the Webform.
574 db_query("INSERT INTO {webform} (nid, confirmation, confirmation_format, teaser, submit_notice, submit_text, submit_limit, submit_interval, additional_validate, additional_submit) VALUES (%d, '%s', %d, %d, %d, '%s', %d, %d, '%s', '%s')", $node->nid, $node->webform['confirmation'], $node->webform['confirmation_format'], $node->webform['teaser'], $node->webform['submit_notice'], $node->webform['submit_text'], $node->webform['submit_limit'], $node->webform['submit_interval'], $node->webform['additional_validate'], $node->webform['additional_submit']);
575
576 // Insert the components into the database. Used with clone.module.
577 if (isset($node->webform['components']) && !empty($node->webform['components'])) {
578 foreach ($node->webform['components'] as $cid => $component) {
579 $component['nid'] = $node->nid;
580 webform_component_insert($component);
581 }
582 }
583
584 // Set the per-role submission access control.
585 foreach (array_filter($node->webform['roles']) as $rid) {
586 db_query('INSERT INTO {webform_roles} (nid, rid) VALUES (%d, %d)', $node->nid, $rid);
587 }
588 }
589
590 /**
591 * Implementation of hook_update().
592 */
593 function webform_update($node) {
594 // Update the webform by deleting existing data and replacing with the new.
595 db_query('DELETE FROM {webform} WHERE nid = %d', $node->nid);
596 db_query('DELETE FROM {webform_component} WHERE nid = %d', $node->nid);
597 db_query('DELETE FROM {webform_roles} WHERE nid = %d', $node->nid);
598 webform_insert($node);
599 }
600
601 /**
602 * Implementation of hook_delete().
603 */
604 function webform_delete(&$node) {
605 // Allow components clean up extra data, such as uploaded files.
606 module_load_include('inc', 'webform', 'includes/webform.components');
607 foreach ($node->webform['components'] as $cid => $component) {
608 webform_component_delete($node->nid, $cid);
609 }
610
611 // Remove any trace of webform data from the database.
612 db_query('DELETE FROM {webform} WHERE nid = %d', $node->nid);
613 db_query('DELETE FROM {webform_component} WHERE nid = %d', $node->nid);
614 db_query('DELETE FROM {webform_roles} WHERE nid = %d', $node->nid);
615 db_query('DELETE FROM {webform_submissions} WHERE nid = %d', $node->nid);
616 db_query('DELETE FROM {webform_submitted_data} WHERE nid = %d', $node->nid);
617 }
618
619 /**
620 * Implementation of hook_load().
621 */
622 function webform_load($node) {
623 module_load_include('inc', 'webform', 'includes/webform.components');
624 $additions = new stdClass();
625
626 if ($webform = db_fetch_array(db_query('SELECT * FROM {webform} WHERE nid = %d', $node->nid))) {
627 $additions->webform = $webform;
628
629 $additions->webform['roles'] = array();
630 $result = db_query('SELECT rid FROM {webform_roles} WHERE nid = %d', $node->nid);
631 while ($role = db_fetch_object($result)) {
632 $additions->webform['roles'][] = $role->rid;
633 }
634
635 $additions->webform['emails'] = array();
636 $result = db_query('SELECT * FROM {webform_emails} WHERE nid = %d', $node->nid);
637 while ($email = db_fetch_array($result)) {
638 $additions->webform['emails'][$email['eid']] = $email;
639 }
640 }
641 else {
642 $additions->webform = array(
643 'confirmation' => '',
644 'confirmation_format' => FILTER_FORMAT_DEFAULT,
645 'teaser' => 0,
646 'submit_notice' => 0,
647 'submit_text' => '',
648 'submit_limit' => -1,
649 'submit_interval' => -1,
650 'additional_validate' => '',
651 'additional_submit' => '',
652 'roles' => array(1, 2),
653 'emails' => array(),
654 );
655 }
656
657 $additions->webform['components'] = array();
658 $additions->webform['additional_emails'] = array();
659 $result = db_query('SELECT * FROM {webform_component} WHERE nid = %d ORDER BY weight, name', $node->nid);
660 while ($c = db_fetch_array($result)) {
661 $component =& $additions->webform['components'][$c['cid']];
662 $component['nid'] = $node->nid;
663 $component['cid'] = $c['cid'];
664 $component['form_key'] = $c['form_key'] ? $c['form_key'] : $c['cid'];
665 $component['name'] = t($c['name']);
666 $component['type'] = $c['type'];
667 $component['value'] = $c['value'];
668 $component['extra'] = unserialize($c['extra']);
669 $component['mandatory'] = $c['mandatory'];
670 $component['email'] = $c['email'];
671 $component['pid'] = $c['pid'];
672 $component['weight'] = $c['weight'];
673 if (isset($component['extra']['email']) && $component['extra']['email']) {
674 $additions->webform['additional_emails'][$c['cid']] = $c['cid'];
675 }
676
677 webform_component_defaults($component);
678 }
679
680 // Organize the components into a fieldset-based order.
681 if (!empty($additions->webform['components'])) {
682 $component_tree = array();
683 $page_count = 1;
684 _webform_components_tree_build($additions->webform['components'], $component_tree, 0, $page_count);
685 $additions->webform['components'] = _webform_components_tree_flatten($component_tree['children']);
686 }
687 return $additions;
688 }
689
690 /**
691 * Implementation of hook_link().
692 * Always add a "view form" link.
693 */
694 function webform_link($type, $node = NULL, $teaser = FALSE) {
695 $links = array();
696 if (isset($node->type) && $node->type === 'webform') {
697 if ($teaser && !$node->webform['teaser']) {
698 $links['webform_goto'] = array(
699 'title' => t('Go to form'),
700 'href' => 'node/'. $node->nid,
701 'attributes' => array('title' => t('View this form.'), 'class' => 'read-more')
702 );
703 }
704 }
705 return $links;
706 }
707
708 /**
709 * Implementation of hook_form().
710 *
711 * Creates the standard form for editing or creating a webform.
712 */
713 function webform_form(&$node, &$form_state) {
714 // Set node defaults if empty.
715 if (!isset($node->nid) && !isset($node->webform)) {
716 $node->nid = 0;
717 $additions = webform_load($node);
718 $node->webform = $additions->webform;
719 $node->nid = NULL;
720 }
721
722 $form = node_content_form($node, $form_state);
723
724 $form['webform'] = array(
725 '#type' => 'value',
726 '#value' => $node->webform,
727 );
728
729 return $form;
730 }
731
732 /**
733 * Implementation of hook_form_alter().
734 */
735 function webform_form_alter(&$form, $form_state, $form_id) {
736 if ($form_id == 'webform_node_form' && empty($form['nid']['#value'])) {
737 $form['buttons']['submit']['#submit'][] = 'webform_form_submit';
738 }
739 }
740
741 /**
742 * Submit handler for the webform node form.
743 *
744 * Redirect the user to the components form on new node inserts. Note that this
745 * fires after the hook_submit() function above.
746 */
747 function webform_form_submit($form, &$form_state) {
748 drupal_set_message(t('The new webform %title has been created. Add new fields to your webform with the form below.', array('%title' => $form_state['values']['title'])));
749 $form_state['redirect'] = 'node/'. $form_state['nid'] .'/webform/components';
750 }
751
752 /**
753 * Implementation of hook_view().
754 */
755 function webform_view(&$node, $teaser = 0, $page = 0) {
756 global $user;
757
758 // If a teaser, do not display the form.
759 if ($teaser && !$node->webform['teaser']) {
760 $node->content['teaser'] = array('#value' => check_markup($node->teaser, $node->format, FALSE));
761 return $node;
762 }
763
764 $submission = array();
765 $submission_count = 0;
766 $enabled = TRUE;
767 $logging_in = FALSE;
768 $limit_exceeded = FALSE;
769
770 if ($node->build_mode == NODE_BUILD_PREVIEW) {
771 $additions = webform_load($node);
772 $node->webform['components'] = $additions->webform['components'];
773 }
774
775 // When logging in using a form on the same page as a webform node, surpress
776 // output messages so that they don't show up after the user has logged in.
777 // See http://drupal.org/node/239343.
778 if (isset($_POST['op']) && isset($_POST['name']) && isset($_POST['pass'])) {
779 $logging_in = TRUE;
780 }
781
782 // Check if the user's role can submit this webform.
783 if (variable_get('webform_submission_access_control', 1)) {
784 $allowed_roles = array();
785 foreach ($node->webform['roles'] as $rid) {
786 $allowed_roles[$rid] = isset($user->roles[$rid]) ? TRUE : FALSE;
787 }
788 if (array_search(TRUE, $allowed_roles) === FALSE && $user->uid != 1) {
789 $enabled = FALSE;
790 }
791 }
792 else {
793 // If not using Webform submission access control, allow for all roles.
794 $allowed_roles = array_keys(user_roles());
795 }
796
797 // Check if the user can add another submission.
798 if ($node->webform['submit_limit'] != -1) { // -1: Submissions are never throttled.
799 module_load_include('inc', 'webform', 'includes/webform.submissions');
800
801 if ($limit_exceeded = _webform_submission_limit_check($node)) {
802 $enabled = FALSE;
803 }
804 }
805
806 // Get a count of previous submissions by this user.
807 if ($user->uid && (user_access('access own webform submissions') || user_access('access webform results') || user_access('access webform submissions'))) {
808 $submission_count = db_result(db_query('SELECT count(*) FROM {webform_submissions} WHERE nid = %d AND uid = %d', $node->nid, $user->uid));
809 }
810
811 // Render the form and generate the output.
812 $form = drupal_get_form('webform_client_form_'. $node->nid, $node, $submission, $enabled);
813 $output = theme('webform_view', $node, $teaser, $page, $form, $enabled);
814
815 // Remove the surrounding <form> tag if this is a preview.
816 if ($node->build_mode == NODE_BUILD_PREVIEW) {
817 $output = preg_replace('/<\/?form[^>]*>/', '', $output);
818 }
819
820 // Print out messages for the webform.
821 if (!$node->build_mode == NODE_BUILD_PREVIEW && !$logging_in) {
822 theme('webform_view_messages', $node, $teaser, $page, $submission_count, $limit_exceeded, $allowed_roles);
823 }
824
825 // Add the output to the node.
826 $node = node_prepare($node, $teaser);
827 if (isset($output)) {
828 $node->content['webform'] = array('#value' => $output, '#weight' => 1);
829 }
830
831 return $node;
832 }
833
834 /**
835 * Output the Webform into the node content.
836 *
837 * @param $node
838 * The webform node object.
839 * @param $teaser
840 * If this webform is being displayed as the teaser view of the node.
841 * @param $page
842 * If this webform node is being viewed as the main content of the page.
843 * @param $form
844 * The rendered form.
845 * @param $enabled
846 * If the form allowed to be completed by the current user.
847 */
848 function theme_webform_view($node, $teaser, $page, $form, $enabled) {
849 // Only show the form if this user is allowed access.
850 if ($enabled) {
851 return $form;
852 }
853 }
854
855 /**
856 * Display a message to a user if they are not allowed to fill out a form.
857 *
858 * @param $node
859 * The webform node object.
860 * @param $teaser
861 * If this webform is being displayed as the teaser view of the node.
862 * @param $page
863 * If this webform node is being viewed as the main content of the page.
864 * @param $submission_count
865 * The number of submissions this user has already submitted. Not calculated
866 * for anonymous users.
867 * @param $limit_exceeded
868 * Boolean value if the submission limit for this user has been exceeded.
869 * @param $allowed_roles
870 * A list of user roles that are allowed to submit this webform.
871 */
872 function theme_webform_view_messages($node, $teaser, $page, $submission_count, $limit_exceeded, $allowed_roles) {
873 global $user;
874
875 $type = 'notice';
876
877 // If not allowed to submit the form, give an explaination.
878 if (array_search(TRUE, $allowed_roles) === FALSE && $user->uid != 1) {
879 if (empty($allowed_roles)) {
880 // No roles are allowed to submit the form.
881 $message = t('Submissions for this form are closed.');
882 }
883 elseif (isset($allowed_roles[2])) {
884 // The "authenticated user" role is allowed to submit and the user is currently logged-out.
885 $message = t('You must <a href="!login">login</a> or <a href="!register">register</a> to view this form.', array('!login' => url(('user/login'), array('query' => drupal_get_destination())), '!register' => url(('user/register'), array('query' => drupal_get_destination()))));
886 }
887 else {
888 // The user must be some other role to submit.
889 $message = t('You do not have permission to view this form.');
890 }
891 }
892
893 // If the user has exceeded the limit of submissions, explain the limit.
894 elseif ($limit_exceeded) {
895 if ($node->webform['submit_interval'] == -1 && $node->webform['submit_limit'] > 1) {
896 $message = t('You have submitted this form the maximum number of times (@count).', array('@count' => $node->webform['submit_limit']));
897 }
898 elseif ($node->webform['submit_interval'] == -1 && $node->webform['submit_limit'] == 1) {
899 $message = t('You have already submitted this form.');
900 }
901 else {
902 $message = t('You may not submit another entry at this time.');
903 }
904 $type = 'error';
905 }
906
907 // If the user has submitted before, give them a link to their submissions.
908 if ($submission_count > 0 && $node->webform['submit_notice'] == 1) {
909 if (empty($message)) {
910 $message = t('You have already submitted this form.') .' '. t('<a href="!url">View your previous submissions</a>.', array('!url' => url('node/'. $node->nid .'/submissions')));
911 }
912 else {
913 $message .= ' '. t('<a href="!url">View your previous submissions</a>.', array('!url' => url('node/'. $node->nid .'/submissions')));
914 }
915 }
916
917 if ($page && isset($message)) {
918 drupal_set_message($message, $type);
919 }
920 }
921
922 /**
923 * Implementation of hook_mail().
924 */
925 function webform_mail($key, &$message, $params) {
926 $message['headers'] = array_merge($message['headers'], $params['headers']);
927 $message['subject'] = $params['subject'];
928 $message['body'][] = $params['message'];
929 }
930
931 /**
932 * Menu callback for admin/webform/settings.
933 */
934 function webform_admin_settings() {
935 module_load_include('inc', 'webform', 'includes/webform.export');
936
937 $form['components'] = array(
938 '#type' => 'fieldset',
939 '#title' => t('Available components'),
940 '#collapsible' => TRUE,
941 '#collapsed' => FALSE,
942 '#description' => t('These are the available field types for your installation of Webform. You may disable any of these components by unchecking its corresponding box. Only checked components will be available in existing or new webforms.'),
943 );
944
945 // Add each component to the form:
946 $component_types = webform_load_components(TRUE);
947 foreach ($component_types as $key => $component) {
948 $form['components']['webform_enable_'. $key] = array(
949 '#title' => $component,
950 '#description' => module_invoke('webform', 'help', 'admin/settings/webform#'. $key .'_description'),
951 '#type' => 'checkbox',
952 '#checked_value' => 1,
953 '#default_value' => variable_get('webform_enable_'. $key, 1),
954 );
955 }
956
957 $form['email'] = array(
958 '#type' => 'fieldset',
959 '#title' => t('Default e-mail values'),
960 '#collapsible' => TRUE,
961 '#collapsed' => FALSE,
962 );
963
964 $form['email']['webform_default_from_address'] = array(
965 '#type' => 'textfield',
966 '#title' => t('From address'),
967 '#default_value' => variable_get('webform_default_from_address', variable_get('site_mail', ini_get('sendmail_from'))),
968 '#description' => t('The default sender address for emailed webform results; often the e-mail address of the maintainer of your forms.'),
969 );
970
971 $form['email']['webform_default_from_name'] = array(
972 '#type' => 'textfield',
973 '#title' => t('From name'),
974 '#default_value' => variable_get('webform_default_from_name', variable_get('site_name', '')),
975 '#description' => t('The default sender name which is used along with the default from address.'),
976 );
977
978 $form['email']['webform_default_subject'] = array(
979 '#type' => 'textfield',
980 '#title' => t('Default subject'),
981 '#default_value' => variable_get('webform_default_subject', t('Form submission from: %title')),
982 '#description' => t('The default subject line of any e-mailed results.'),
983 );
984
985 $form['advanced'] = array(
986 '#type' => 'fieldset',
987 '#title' => t('Advanced options'),
988 '#collapsible' => TRUE,
989 '#collapsed' => TRUE,
990 );
991
992 $form['advanced']['webform_use_cookies'] = array(
993 '#type' => 'checkbox',
994 '#checked_value' => 1,
995 '#title' => t('Allow cookies for tracking submissions'),
996 '#default_value' => variable_get('webform_use_cookies', 0),
997 '#description' => t('<a href="http://www.wikipedia.org/wiki/HTTP_cookie">Cookies</a> can be used to help prevent the same user from repeatedly submitting a webform. This feature is not needed for limiting submissions per user, though it can increase accuracy in some situations. Besides cookies, Webform also uses IP addresses and site usernames to prevent repeated submissions.'),
998 );
999
1000 $form['advanced']['webform_email_address_format'] = array(
1001 '#type' => 'radios',
1002 '#title' => t('E-mail address format'),
1003 '#options' => array(
1004 'long' => t('Long format: "Example Name" &lt;name@example.com&gt;'),
1005 'short' => t('Short format: name@example.com'),
1006 ),
1007 '#default_value' => variable_get('webform_email_address_format', 'long'),
1008 '#description' => t('Most servers support the "long" format which will allow for more friendly From addresses in e-mails sent. However many Windows-based servers are unable to send in the long format. Change this option if experiencing problems sending e-mails with Webform.'),
1009 );
1010
1011 $form['advanced']['webform_export_format'] = array(
1012 '#type' => 'radios',
1013 '#title' => t('Default export format'),
1014 '#options' => webform_export_list(),
1015 '#default_value' => variable_get('webform_export_format', 'delimited'),
1016 );
1017
1018 $form['advanced']['webform_csv_delimiter'] = array(
1019 '#type' => 'select',
1020 '#title' => t('Default export delimiter'),
1021 '#description' => t('This is the delimiter used in the CSV/TSV file when downloading Webform results. Using tabs in the export is the most reliable method for preserving non-latin characters. You may want to change this to another character depending on the program with which you anticipate importing results.'),
1022 '#default_value' => variable_get('webform_csv_delimiter', '\t'),
1023 '#options' => array(
1024 ',' => t('Comma (,)'),
1025 '\t' => t('Tab (\t)'),
1026 ';' => t('Semicolon (;)'),
1027 ':' => t('Colon (:)'),
1028 '|' => t('Pipe (|)'),
1029 '.' => t('Period (.)'),
1030 ' ' => t('Space ( )'),
1031 ),
1032 );
1033
1034 $form['advanced']['webform_submission_access_control'] = array(
1035 '#type' => 'radios',
1036 '#title' => t('Submission access control'),
1037 '#options' => array(
1038 '1' => t('Select the user roles that may submit each individual webform'),
1039 '0' => t('Disable Webform submission access control'),
1040 ),
1041 '#default_value' => variable_get('webform_submission_access_control', 1),
1042 '#description' => t('By default, the configuration form for each webform allows the administrator to choose which roles may submit the form. You may want to allow users to always submit the form if you are using a separate node access module to control access to webform nodes themselves.'),
1043 );
1044
1045 $form['advanced']['webform_debug'] = array(
1046 '#type' => 'select',
1047 '#title' => t('Webforms debug'),
1048 '#default_value' => variable_get('webform_debug', 0),
1049 '#options' => array(0 => t('Off'), 1 => t('Log submissions'), 2 => t('Full debug')),
1050 '#description' => t('Set to "Log submissions" to log all submissions in the watchdog. Set to "Full debug" to print debug info on submission.')
1051 );
1052
1053 $form = system_settings_form($form);
1054 $form['#theme'] = 'webform_admin_settings';
1055
1056 return $form;
1057 }
1058
1059 function theme_webform_admin_settings($form) {
1060 // Format the components into a table.
1061 foreach (element_children($form['components']) as $key) {
1062 $row = array();
1063 $row[] = $form['components'