webform.pages.inc 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. <?php
  2. /**
  3. * @file
  4. * Menu callbacks and functions for configuring and editing webforms.
  5. */
  6. /**
  7. * Main configuration form for editing a webform node.
  8. */
  9. function webform_configure_form($form, &$form_state, $node) {
  10. form_load_include($form_state, 'inc', 'webform', 'includes/webform.components');
  11. $form['#attached']['library'][] = array('webform', 'admin');
  12. // Refresh the entity cache to get the latest submission number.
  13. $nid = $node->nid;
  14. entity_get_controller('node')->resetCache(array($nid));
  15. $node = node_load($nid);
  16. $form['#node'] = $node;
  17. $form['#submit'] = array(
  18. 'webform_configure_form_submit',
  19. 'webform_configure_form_submit_save',
  20. );
  21. $form['nid'] = array(
  22. '#type' => 'value',
  23. '#value' => $node->nid,
  24. );
  25. /* Start Edit Form */
  26. $form['submission'] = array(
  27. '#type' => 'fieldset',
  28. '#title' => t('Submission settings'),
  29. '#collapsible' => TRUE,
  30. '#collapsed' => FALSE,
  31. '#weight' => -4,
  32. );
  33. $form['submission']['confirmation'] = array(
  34. '#type' => 'text_format',
  35. '#title' => t('Confirmation message'),
  36. '#description' => t('Message to be shown upon successful submission. If the redirection location is set to <em>Confirmation page</em> it will be shown on its own page, otherwise this displays as a message. Supports Webform token replacements.') . ' ' . theme('webform_token_help', array('groups' => array('node', 'submission'))),
  37. '#default_value' => $node->webform['confirmation'],
  38. '#cols' => 40,
  39. '#rows' => 10,
  40. '#format' => $node->webform['confirmation_format'],
  41. '#parents' => array('confirmation'),
  42. );
  43. // Redirection settings.
  44. if (strpos($node->webform['redirect_url'], '<') === 0) {
  45. $redirect = trim($node->webform['redirect_url'], '<>');
  46. // Redirection is set to front page.
  47. if ($redirect == 'front') {
  48. $redirect = 'url';
  49. $redirect_url = $node->webform['redirect_url'];
  50. }
  51. else {
  52. $redirect_url = '';
  53. }
  54. }
  55. else {
  56. $redirect = 'url';
  57. $redirect_url = $node->webform['redirect_url'];
  58. }
  59. $form['submission']['redirection'] = array(
  60. '#type' => 'item',
  61. '#title' => t('Redirection location'),
  62. '#theme' => 'webform_advanced_redirection_form',
  63. '#description' => t('Choose where to redirect the user upon successful submission.') . ' ' . t('The <em>Custom URL</em> option supports Webform token replacements.') . ' ' . theme('webform_token_help', array('groups' => array('node', 'submission'))),
  64. );
  65. $form['submission']['redirection']['redirect'] = array(
  66. '#type' => 'radios',
  67. '#default_value' => $redirect,
  68. '#options' => array(
  69. 'confirmation' => t('Confirmation page'),
  70. 'url' => t('Custom URL'),
  71. 'none' => t('No redirect (reload current page)'),
  72. ),
  73. '#parents' => array('redirect'),
  74. );
  75. $form['submission']['redirection']['redirect_url'] = array(
  76. '#type' => 'textfield',
  77. '#title' => t('Redirect URL'),
  78. '#description' => t('URL to redirect the user to upon successful submission.'),
  79. '#default_value' => $redirect_url,
  80. '#maxlength' => 2048,
  81. '#parents' => array('redirect_url'),
  82. '#attributes' => array('title' => t('Custom URL value')),
  83. );
  84. // Submission limit settings for all submissions.
  85. $form['submission']['total_submit_limit'] = array(
  86. '#type' => 'item',
  87. '#title' => t('Total submissions limit'),
  88. '#theme' => 'webform_advanced_total_submit_limit_form',
  89. '#description' => t('Limit the total number of allowed submissions.'),
  90. );
  91. $form['submission']['total_submit_limit']['enforce_total_limit'] = array(
  92. '#type' => 'radios',
  93. '#options' => array('no' => t('Unlimited'), 'yes' => 'Limit to !count total submission(s) !timespan'),
  94. '#default_value' => $node->webform['total_submit_limit'] == -1 ? 'no' : 'yes',
  95. '#parents' => array('enforce_total_limit'),
  96. );
  97. $form['submission']['total_submit_limit']['total_submit_limit'] = array(
  98. '#type' => 'textfield',
  99. '#maxlength' => 8,
  100. '#size' => 8,
  101. '#default_value' => $node->webform['total_submit_limit'] != -1 ? $node->webform['total_submit_limit'] : '',
  102. '#parents' => array('total_submit_limit'),
  103. );
  104. $interval_options = array(
  105. '-1' => t('ever'),
  106. '60' => t('every minute'),
  107. '300' => t('every 5 minutes'),
  108. '3600' => t('every hour'),
  109. '86400' => t('every day'),
  110. '604800' => t('every week'),
  111. );
  112. $form['submission']['total_submit_limit']['total_submit_interval'] = array(
  113. '#type' => 'select',
  114. '#options' => $interval_options,
  115. '#default_value' => $node->webform['total_submit_interval'],
  116. '#parents' => array('total_submit_interval'),
  117. );
  118. // Submission limit per user settings.
  119. $form['submission']['submit_limit'] = array(
  120. '#type' => 'item',
  121. '#title' => t('Per user submission limit'),
  122. '#theme' => 'webform_advanced_submit_limit_form',
  123. '#description' => t('Limit the number of submissions <em>per user</em>. A user is identified by their user login if logged-in, or by their IP Address and Cookie if anonymous. Use of cookies may be modified in the global <a href="!url">Webform settings</a>.', array('!url' => url('admin/config/content/webform'))),
  124. );
  125. $form['submission']['submit_limit']['enforce_limit'] = array(
  126. '#type' => 'radios',
  127. '#options' => array('no' => t('Unlimited'), 'yes' => 'Limit each user to !count submission(s) !timespan'),
  128. '#default_value' => $node->webform['submit_limit'] == -1 ? 'no' : 'yes',
  129. '#parents' => array('enforce_limit'),
  130. );
  131. $form['submission']['submit_limit']['submit_limit'] = array(
  132. '#type' => 'textfield',
  133. '#maxlength' => 2,
  134. '#size' => 2,
  135. '#default_value' => $node->webform['submit_limit'] != -1 ? $node->webform['submit_limit'] : '',
  136. '#parents' => array('submit_limit'),
  137. );
  138. $form['submission']['submit_limit']['submit_interval'] = array(
  139. '#type' => 'select',
  140. '#options' => $interval_options,
  141. '#default_value' => $node->webform['submit_interval'],
  142. '#parents' => array('submit_interval'),
  143. );
  144. $form['submission']['status'] = array(
  145. '#type' => 'radios',
  146. '#title' => t('Status of this form'),
  147. '#default_value' => $node->webform['status'] == 0 ? 0 : 1,
  148. '#description' => t('Closing a form prevents any further submissions by any users.'),
  149. '#parents' => array('status'),
  150. '#options' => array(1 => t('Open'), 0 => t('Closed')),
  151. );
  152. /* End Edit Form */
  153. /* Start per-role submission control */
  154. $form['role_control'] = array(
  155. '#type' => 'fieldset',
  156. '#title' => t('Submission access'),
  157. '#collapsible' => TRUE,
  158. '#collapsed' => FALSE,
  159. '#description' => t('These permissions affect which roles can submit this webform. It does not prevent access to the webform page. If needing to prevent access to the webform page entirely, use a content access module such as <a href="http://drupal.org/project/taxonomy_access">Taxonomy Access</a> or <a href="http://drupal.org/project/node_privacy_byrole">Node Privacy by Role</a>.'),
  160. '#access' => webform_variable_get('webform_submission_access_control'),
  161. '#weight' => 10,
  162. '#states' => array(
  163. 'invisible' => array(
  164. ':input[name="confidential"]' => array('checked' => TRUE),
  165. ),
  166. ),
  167. );
  168. $user_roles = user_roles();
  169. foreach ($user_roles as $rid => $rname) {
  170. if ($rid == DRUPAL_ANONYMOUS_RID || $rid == DRUPAL_AUTHENTICATED_RID) {
  171. continue;
  172. }
  173. $user_roles[$rid] = webform_tt("user:rid:$rid:name", $rname);
  174. }
  175. $form['role_control']['roles'] = array(
  176. '#default_value' => $node->webform['roles'],
  177. '#options' => $user_roles,
  178. '#type' => 'checkboxes',
  179. '#title' => t('Roles that can submit this webform'),
  180. '#description' => t('The %authenticated role applies to any user signed into the site, regardless of other assigned roles.', array('%authenticated' => $user_roles[2])),
  181. );
  182. /* End per-role submission control */
  183. /* Start progress bar settings form */
  184. $form['progressbar'] = array(
  185. '#type' => 'fieldset',
  186. '#title' => t('Progress bar'),
  187. '#collapsible' => TRUE,
  188. '#collapsed' => TRUE,
  189. '#weight' => 15,
  190. );
  191. $progress_bar_style = array_filter(array(
  192. $node->webform['progressbar_page_number'] ? 'progressbar_page_number' : NULL,
  193. $node->webform['progressbar_percent'] ? 'progressbar_percent' : NULL,
  194. $node->webform['progressbar_bar'] ? 'progressbar_bar' : NULL,
  195. $node->webform['progressbar_pagebreak_labels'] ? 'progressbar_pagebreak_labels' : NULL,
  196. $node->webform['progressbar_include_confirmation'] ? 'progressbar_include_confirmation' : NULL,
  197. ));
  198. $form['progressbar']['webform_progressbar_style'] = array(
  199. '#type' => 'checkboxes',
  200. '#title' => t('Progress bar style'),
  201. '#options' => array(
  202. 'progressbar_bar' => t('Show progress bar'),
  203. 'progressbar_page_number' => t('Show page number as number of completed (i.e. Page 1 of 10)'),
  204. 'progressbar_percent' => t('Show percentage completed (i.e. 10%)'),
  205. 'progressbar_pagebreak_labels' => t('Show page labels from page break components'),
  206. 'progressbar_include_confirmation' => t('Include confirmation page in progress bar'),
  207. ),
  208. '#default_value' => $progress_bar_style,
  209. '#description' => t('Choose how the progress bar should be displayed for multi-page forms.'),
  210. );
  211. $form['progressbar']['progressbar_label_first'] = array(
  212. '#type' => 'textfield',
  213. '#title' => t('First page label'),
  214. '#default_value' => $node->webform['progressbar_label_first'],
  215. '#maxlength' => 255,
  216. '#description' => t('The first page label in the progress bar. Subseqent pages are titled by their page break label.'),
  217. '#states' => array(
  218. 'visible' => array(
  219. ':input[name="webform_progressbar_style[progressbar_pagebreak_labels]"]' => array('checked' => TRUE),
  220. ),
  221. ),
  222. );
  223. $form['progressbar']['progressbar_label_confirmation'] = array(
  224. '#type' => 'textfield',
  225. '#title' => t('Confirmation page label'),
  226. '#default_value' => $node->webform['progressbar_label_confirmation'],
  227. '#maxlength' => 255,
  228. '#states' => array(
  229. 'visible' => array(
  230. ':input[name="webform_progressbar_style[progressbar_pagebreak_labels]"]' => array('checked' => TRUE),
  231. ':input[name="webform_progressbar_style[progressbar_include_confirmation]"]' => array('checked' => TRUE),
  232. ),
  233. ),
  234. );
  235. /* End progress bar settings form */
  236. /* Preview page settings form */
  237. $form['preview'] = array(
  238. '#type' => 'fieldset',
  239. '#title' => t('Preview page'),
  240. '#collapsible' => TRUE,
  241. '#collapsed' => TRUE,
  242. '#weight' => 18,
  243. '#id' => 'webform-preview-fieldset',
  244. );
  245. $form['preview']['preview'] = array(
  246. '#type' => 'checkbox',
  247. '#title' => t('Enable preview page'),
  248. '#description' => t('Add a page for previewing the form before submitting.'),
  249. '#default_value' => $node->webform['preview'],
  250. '#id' => 'webform-preview-enable',
  251. );
  252. $form['preview']['settings'] = array(
  253. '#type' => 'container',
  254. '#states' => array(
  255. 'visible' => array(
  256. '#webform-preview-enable' => array('checked' => TRUE),
  257. ),
  258. ),
  259. '#id' => 'webform-preview-settings',
  260. '#theme_wrappers' => array('container'),
  261. );
  262. $form['preview']['settings']['preview_title'] = array(
  263. '#type' => 'textfield',
  264. '#title' => t('Preview page title'),
  265. '#default_value' => $node->webform['preview_title'],
  266. '#description' => t('The page title will be used in the progress bar (if enabled). If left blank, the default title %preview will be used.', array('%preview' => t('Preview'))),
  267. );
  268. $form['preview']['settings']['preview_next_button_label'] = array(
  269. '#type' => 'textfield',
  270. '#title' => t('Preview button label'),
  271. '#default_value' => $node->webform['preview_next_button_label'],
  272. '#description' => t('The text for the button that will proceed to the preview page. If left blank, the default label %preview will be used.', array('%preview' => t('Preview'))),
  273. '#size' => 20,
  274. );
  275. $form['preview']['settings']['preview_prev_button_label'] = array(
  276. '#type' => 'textfield',
  277. '#title' => t('Previous page button label'),
  278. '#default_value' => $node->webform['preview_prev_button_label'],
  279. '#description' => t('The text for the button to go backwards from the preview page. If left blank, the default label %previous will be used.', array('%previous' => t('< Previous'))),
  280. '#size' => 20,
  281. );
  282. $submit_button_text = $node->webform['submit_text'] ? t($node->webform['submit_text']) : t('Submit');
  283. $preview_default_message = t('Please review your submission. Your submission is not complete until you press the "@button" button!', array('@button' => $submit_button_text));
  284. $form['preview']['settings']['preview_message'] = array(
  285. '#type' => 'text_format',
  286. '#title' => t('Preview message'),
  287. '#default_value' => $node->webform['preview_message'],
  288. '#format' => $node->webform['preview_message_format'],
  289. '#description' => t('A message to be displayed on the preview page. If left blank, the message "!default" will be used. Supports Webform token replacements.', array('!default' => $preview_default_message)) . ' ' . theme('webform_token_help', array('groups' => array('node', 'submission'))),
  290. );
  291. $form['preview']['settings']['preview_components'] = array(
  292. '#type' => 'select',
  293. '#title' => t('Included preview values'),
  294. '#options' => webform_component_list($node, 'email', TRUE),
  295. '#default_value' => array_diff(array_keys($node->webform['components']), $node->webform['preview_excluded_components']),
  296. '#multiple' => TRUE,
  297. '#size' => 10,
  298. '#description' => t('If you wish to include only parts of the submission in the preview, select the components that should be included.'),
  299. '#process' => array('webform_component_select'),
  300. );
  301. /* End preview page settings form */
  302. /* Start advanced settings form */
  303. $form['advanced'] = array(
  304. '#type' => 'fieldset',
  305. '#title' => t('Advanced settings'),
  306. '#collapsible' => TRUE,
  307. '#collapsed' => TRUE,
  308. '#weight' => 20,
  309. );
  310. $form['advanced']['block'] = array(
  311. '#type' => 'checkbox',
  312. '#title' => t('Available as block'),
  313. '#default_value' => $node->webform['block'],
  314. '#description' => t('If enabled this webform will be available as a block.'),
  315. '#access' => user_access('administer blocks') || user_access('administer site configuration') || user_access('use panels dashboard'),
  316. );
  317. $form['advanced']['allow_draft'] = array(
  318. '#type' => 'checkbox',
  319. '#title' => t('Show "Save draft" button'),
  320. '#default_value' => $node->webform['allow_draft'],
  321. '#description' => t('Allow your users to save and finish the form later. This option is available only for authenticated users.'),
  322. );
  323. $form['advanced']['auto_save'] = array(
  324. '#type' => 'checkbox',
  325. '#title' => t('Automatically save as draft between pages and when there are validation errors'),
  326. '#default_value' => $node->webform['auto_save'],
  327. '#description' => t('Automatically save partial submissions when users click the "Next" or "Previous" buttons in a multipage form or when validation errors prevent form submission.'),
  328. );
  329. $form['advanced']['submit_notice'] = array(
  330. '#type' => 'checkbox',
  331. '#title' => t('Show the notification about previous submissions'),
  332. '#default_value' => $node->webform['submit_notice'],
  333. '#description' => t('Show the previous submissions notification that appears when users have previously submitted this form.'),
  334. );
  335. $form['advanced']['confidential'] = array(
  336. '#type' => 'checkbox',
  337. '#title' => t('Confidential submissions'),
  338. '#default_value' => $node->webform['confidential'],
  339. '#description' => t('Confidential submissions have no recorded IP address and must be submitted while logged out.'),
  340. );
  341. $form['advanced']['submit_text'] = array(
  342. '#type' => 'textfield',
  343. '#title' => t('Submit button label'),
  344. '#default_value' => $node->webform['submit_text'],
  345. '#description' => t('By default the submit button on this form will have the label <em>Submit</em>. Enter a new title here to override the default.'),
  346. '#size' => 20,
  347. );
  348. $form['advanced']['next_serial'] = array(
  349. '#type' => 'textfield',
  350. '#title' => t('Next submission number'),
  351. '#default_value' => $node->webform['next_serial'],
  352. '#description' => t('The value of the next submission number. This is usually 1 when you start and will go up with each form submission.'),
  353. '#size' => 8,
  354. '#maxlength' => 8,
  355. );
  356. /* End Advanced Settings Form */
  357. $form['actions'] = array(
  358. '#type' => 'actions',
  359. '#weight' => 300,
  360. );
  361. $form['actions']['submit'] = array(
  362. '#type' => 'submit',
  363. '#value' => t('Save configuration'),
  364. );
  365. return $form;
  366. }
  367. /**
  368. * Validate handler for webform_configure_form().
  369. */
  370. function webform_configure_form_validate($form, &$form_state) {
  371. // Ensure the entered redirect URL is valid.
  372. if ($form_state['values']['redirect'] == 'url') {
  373. $redirect_url = trim($form_state['values']['redirect_url']);
  374. if (empty($redirect_url)) {
  375. form_error($form['submission']['redirection']['redirect_url'], t('A valid URL is required for custom redirection.'));
  376. }
  377. elseif (strpos($redirect_url, 'http') === 0 && !valid_url(webform_replace_tokens($redirect_url, $form['#node']), TRUE)) {
  378. form_error($form['submission']['redirection']['redirect_url'], t('The entered URL is not a valid address.'));
  379. }
  380. else {
  381. form_set_value($form['submission']['redirection']['redirect_url'], $redirect_url, $form_state);
  382. }
  383. }
  384. elseif ($form_state['values']['redirect'] == 'confirmation') {
  385. form_set_value($form['submission']['redirection']['redirect_url'], '<confirmation>', $form_state);
  386. }
  387. else {
  388. form_set_value($form['submission']['redirection']['redirect_url'], '<none>', $form_state);
  389. }
  390. // Ensure only positive integers are entered as submission limits.
  391. foreach (array('total_submit_limit' => 'enforce_total_limit', 'submit_limit' => 'enforce_limit') as $field => $enforce_fk) {
  392. $limit = $form['submission'][$field][$field]['#value'];
  393. if ($form['submission'][$field][$enforce_fk]['#value'] !== 'no' && $limit !== '' && (int) $limit < 1 && (int) $limit !== -1) {
  394. form_error($form['submission'][$field][$field], t('The submission limit must be at least 1.'));
  395. }
  396. }
  397. // Prohibit the combination of confidential + per-user limit + ip-only
  398. // submission tracking for anonymous users as it would not be enforceable.
  399. if (webform_variable_get('webform_tracking_mode') == 'ip_address' &&
  400. $form_state['values']['confidential'] &&
  401. $form_state['values']['enforce_limit'] == 'yes') {
  402. // Note that FAPI doesn't actually support error highlighting on radio or
  403. // checkbox form elements.
  404. form_error($form['advanced']['confidential'],
  405. t('Choose a "Per user submission limit" or "Confidential submissions", but not both. Or ask the adminstrator to track anonymous users by cookie, rather than IP address only.'));
  406. }
  407. }
  408. /**
  409. * Submit handler for webform_configure_form().
  410. */
  411. function webform_configure_form_submit($form, &$form_state) {
  412. // Edit the node by reference just to shorten it up.
  413. $node = &$form['#node'];
  414. // Save the confirmation.
  415. $node->webform['confirmation'] = $form_state['values']['confirmation']['value'];
  416. $node->webform['confirmation_format'] = $form_state['values']['confirmation']['format'];
  417. // Save the redirect URL.
  418. $node->webform['redirect_url'] = $form_state['values']['redirect_url'];
  419. // Overall form status.
  420. $node->webform['status'] = $form_state['values']['status'];
  421. // Save roles.
  422. $node->webform['roles'] = array_keys(array_filter($form_state['values']['roles']));
  423. // Set the block option.
  424. $node->webform['block'] = $form_state['values']['block'];
  425. // Set the draft option.
  426. $node->webform['allow_draft'] = $form_state['values']['allow_draft'];
  427. // Set the auto-save draft option.
  428. $node->webform['auto_save'] = $form_state['values']['auto_save'];
  429. // Set the submit limit to -1 if set to unlimited.
  430. if ($form_state['values']['enforce_limit'] == 'no') {
  431. $node->webform['submit_limit'] = -1;
  432. $node->webform['submit_interval'] = -1;
  433. }
  434. else {
  435. $node->webform['submit_limit'] = (int) $form_state['values']['submit_limit'];
  436. $node->webform['submit_interval'] = (int) $form_state['values']['submit_interval'];
  437. }
  438. // Set the total submit limit to -1 if set to unlimited.
  439. if ($form_state['values']['enforce_total_limit'] == 'no') {
  440. $node->webform['total_submit_limit'] = -1;
  441. $node->webform['total_submit_interval'] = -1;
  442. }
  443. else {
  444. $node->webform['total_submit_limit'] = (int) $form_state['values']['total_submit_limit'];
  445. $node->webform['total_submit_interval'] = (int) $form_state['values']['total_submit_interval'];
  446. }
  447. // Set the progress bar preferences.
  448. $progress_bar_settings = array_filter($form_state['values']['webform_progressbar_style']);
  449. $node->webform['progressbar_page_number'] = in_array('progressbar_page_number', $progress_bar_settings);
  450. $node->webform['progressbar_percent'] = in_array('progressbar_percent', $progress_bar_settings);
  451. $node->webform['progressbar_bar'] = in_array('progressbar_bar', $progress_bar_settings);
  452. $node->webform['progressbar_pagebreak_labels'] = in_array('progressbar_pagebreak_labels', $progress_bar_settings);
  453. $node->webform['progressbar_include_confirmation'] = in_array('progressbar_include_confirmation', $progress_bar_settings);
  454. $node->webform['progressbar_label_first'] = $form_state['values']['progressbar_label_first'];
  455. $node->webform['progressbar_label_confirmation'] = $form_state['values']['progressbar_label_confirmation'];
  456. // Set the preview settings.
  457. $node->webform['preview'] = (int) $form_state['values']['preview'];
  458. $node->webform['preview_next_button_label'] = $form_state['values']['preview_next_button_label'];
  459. $node->webform['preview_prev_button_label'] = $form_state['values']['preview_prev_button_label'];
  460. $node->webform['preview_title'] = $form_state['values']['preview_title'];
  461. $node->webform['preview_message'] = $form_state['values']['preview_message']['value'];
  462. $node->webform['preview_message_format'] = $form_state['values']['preview_message']['format'];
  463. // Save the list of included preview components.
  464. // We actually maintain an *exclusion* list, so any new components will
  465. // default to being included in the preview until unchecked.
  466. $included = array_keys(array_filter((array) $form_state['values']['preview_components']));
  467. $excluded = array_diff(array_keys($node->webform['components']), $included);
  468. $node->webform['preview_excluded_components'] = $excluded;
  469. // Set submit notice.
  470. $node->webform['submit_notice'] = $form_state['values']['submit_notice'];
  471. // Set confidential.
  472. $node->webform['confidential'] = $form_state['values']['confidential'];
  473. // Set submit button text.
  474. $node->webform['submit_text'] = $form_state['values']['submit_text'];
  475. // Set next serial number. It must be a positive integer greater than any
  476. // existing serial number, which could have increased while this form was
  477. // being edited.
  478. $next_min = _webform_submission_serial_next_value_used($node->nid);
  479. $next_serial = (int) $form_state['values']['next_serial'];
  480. if ($next_serial < $next_min) {
  481. drupal_set_message(t('The next submission number was increased to @min to make it higher than existing submissions.',
  482. array('@min' => $next_min)));
  483. $next_serial = $next_min;
  484. }
  485. $node->webform['next_serial'] = $next_serial;
  486. }
  487. /**
  488. * Submit handler for webform_configure_form() that saves the node.
  489. *
  490. * This is separate from webform_configure_form_submit() to allow other modules
  491. * to add properties if needed into the $form['#node'] object before save.
  492. */
  493. function webform_configure_form_submit_save($form, &$form_state) {
  494. node_save($form['#node']);
  495. drupal_set_message(t('The form settings have been updated.'));
  496. $node = &$form['#node'];
  497. if (!$node->webform['block'] && function_exists('block_load') &&
  498. ($block = block_load('webform', 'client-block-' . $node->nid)) &&
  499. !empty($block->bid)) {
  500. // An existing block for this not-currently-available block was already configured.
  501. // See https://www.drupal.org/node/2365825
  502. // The core block module contains a bug which causes it to not remove blocks
  503. // which are no longer available in code. Therefore, to prevent the block from
  504. // being processed, it must be removed manually here.
  505. // Remove the block for all themes.
  506. db_delete('block')
  507. ->condition('module', 'webform')
  508. ->condition('delta', $block->delta)
  509. ->execute();
  510. // Remove any roles associated with the block.
  511. db_delete('block_role')
  512. ->condition('module', 'webform')
  513. ->condition('delta', $block->delta)
  514. ->execute();
  515. drupal_set_message(t('The block %info was deleted.', array('%info' => t('Webform: !title', array('!title' => $node->title)))));
  516. cache_clear_all();
  517. }
  518. }
  519. /**
  520. * Theme the redirection setting on the webform node form.
  521. */
  522. function theme_webform_advanced_redirection_form($variables) {
  523. $form = $variables['form'];
  524. // Add special class for setting the active radio button.
  525. $form['redirect_url']['#attributes']['class'][] = 'webform-set-active';
  526. // Remove wrappers around the inline Redirect URL field.
  527. $form['redirect_url']['#theme_wrappers'] = array();
  528. $form['redirect']['confirmation']['#theme_wrappers'] = array('webform_inline_radio');
  529. $form['redirect']['url']['#theme_wrappers'] = array('webform_inline_radio');
  530. $form['redirect']['none']['#theme_wrappers'] = array('webform_inline_radio');
  531. $form['redirect']['url']['#title'] = t('Custom URL: !redirect_url', array('!redirect_url' => drupal_render($form['redirect_url'])));
  532. return drupal_render_children($form);
  533. }
  534. /**
  535. * Theme the submit limit fieldset on the webform node form.
  536. */
  537. function theme_webform_advanced_submit_limit_form($variables) {
  538. $form = $variables['form'];
  539. $form['submit_limit']['#attributes']['class'][] = 'webform-set-active';
  540. $form['submit_interval']['#attributes']['class'][] = 'webform-set-active';
  541. // Remove div wrappers around limit options.
  542. $form['submit_limit']['#theme_wrappers'] = array();
  543. $form['submit_interval']['#theme_wrappers'] = array();
  544. $form['enforce_limit']['no']['#theme_wrappers'] = array('webform_inline_radio');
  545. $form['enforce_limit']['yes']['#theme_wrappers'] = array('webform_inline_radio');
  546. $form['enforce_limit']['yes']['#title'] = t('Limit each user to !count submission(s) !timespan', array('!count' => drupal_render($form['submit_limit']), '!timespan' => drupal_render($form['submit_interval'])));
  547. return drupal_render_children($form);
  548. }
  549. /**
  550. * Theme the total submit limit fieldset on the webform node form.
  551. */
  552. function theme_webform_advanced_total_submit_limit_form($variables) {
  553. $form = $variables['form'];
  554. $form['total_submit_limit']['#attributes']['class'][] = 'webform-set-active';
  555. $form['total_submit_interval']['#attributes']['class'][] = 'webform-set-active';
  556. // Remove div wrappers around limit options.
  557. $form['total_submit_limit']['#theme_wrappers'] = array();
  558. $form['total_submit_interval']['#theme_wrappers'] = array();
  559. $form['enforce_total_limit']['no']['#theme_wrappers'] = array('webform_inline_radio');
  560. $form['enforce_total_limit']['yes']['#theme_wrappers'] = array('webform_inline_radio');
  561. $form['enforce_total_limit']['yes']['#title'] = t('Limit to !count total submission(s) !timespan', array('!count' => drupal_render($form['total_submit_limit']), '!timespan' => drupal_render($form['total_submit_interval'])));
  562. return drupal_render_children($form);
  563. }