currentUser = $current_user; $this->messageManager = $message_manager; $this->tokenManager = $token_manager; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static( $container->get('current_user'), $container->get('webform.message_manager'), $container->get('webform.token_manager') ); } /** * {@inheritdoc} */ public function form(array $form, FormStateInterface $form_state) { /** @var \Drupal\webform\WebformInterface $webform */ $webform = $this->entity; $default_settings = $this->config('webform.settings')->get('settings'); $settings = $webform->getSettings(); // General. $form['general'] = [ '#type' => 'details', '#title' => $this->t('General settings'), '#open' => TRUE, ]; $form['general']['id'] = [ '#type' => 'item', '#title' => $this->t('ID'), '#markup' => $webform->id(), '#value' => $webform->id(), ]; $form['general']['title'] = [ '#type' => 'textfield', '#title' => $this->t('Title'), '#maxlength' => 255, '#default_value' => $webform->label(), '#required' => TRUE, '#id' => 'title', ]; $form['general']['description'] = [ '#type' => 'webform_html_editor', '#title' => $this->t('Administrative description'), '#default_value' => $webform->get('description'), ]; $form['general']['template'] = [ '#type' => 'checkbox', '#title' => $this->t('Allow this webform to be used as a template.'), '#description' => $this->t('If checked, this webform will be available as a template to all users who can create new webforms.'), '#access' => $this->moduleHandler->moduleExists('webform_templates'), '#default_value' => $webform->isTemplate(), ]; $form['general']['results_disabled'] = [ '#type' => 'checkbox', '#title' => $this->t('Disable saving of submissions.'), '#description' => $this->t('If saving of submissions is disabled, submission settings, submission limits, purging and the saving of drafts will be disabled. Submissions must be sent via an email or handled using a custom webform handler.', [':href' => Url::fromRoute('entity.webform.handlers_form', ['webform' => $webform->id()])->toString()]), '#return_value' => TRUE, '#default_value' => $settings['results_disabled'], ]; // Display warning when disabling the saving of submissions with no // handlers. if (!$webform->getHandlers(NULL, TRUE, WebformHandlerInterface::RESULTS_PROCESSED)->count()) { $this->messageManager->setWebform($webform); $form['general']['results_disabled_error'] = [ '#type' => 'webform_message', '#message_type' => 'warning', '#message_message' => $this->messageManager->get(WebformMessageManagerInterface::FORM_SAVE_EXCEPTION), '#states' => [ 'visible' => [ ':input[name="results_disabled"]' => ['checked' => TRUE], ':input[name="results_disabled_ignore"]' => ['checked' => FALSE], ], ], ]; $form['general']['results_disabled_ignore'] = [ '#type' => 'checkbox', '#title' => $this->t('Ignore disabled results warning'), '#description' => $this->t("If checked, all warnings and log messages about 'This webform is currently not saving any submitted data.' will be suppressed."), '#return_value' => TRUE, '#default_value' => $settings['results_disabled_ignore'], '#states' => [ 'visible' => [ ':input[name="results_disabled"]' => ['checked' => TRUE], ], ], ]; } // Page. $form['page'] = [ '#type' => 'details', '#title' => $this->t('URL path settings'), ]; $default_page_submit_path = trim($default_settings['default_page_base_path'], '/') . '/' . str_replace('_', '-', $webform->id()); $t_args = [ ':node_href' => ($this->moduleHandler->moduleExists('node')) ? Url::fromRoute('node.add', ['node_type' => 'webform'])->toString() : '', ':block_href' => ($this->moduleHandler->moduleExists('block')) ? Url::fromRoute('block.admin_display')->toString() : '', ]; $default_settings['default_page_submit_path'] = $default_page_submit_path; $default_settings['default_page_confirm_path'] = $default_page_submit_path . '/confirmation'; $form['page']['page'] = [ '#type' => 'checkbox', '#title' => $this->t('Allow users to post submission from a dedicated URL.'), '#description' => $this->t('If unchecked, this webform must be attached to a node or a block to receive submissions.', $t_args), '#default_value' => $settings['page'], ]; if ($this->moduleHandler->moduleExists('path')) { $form['page']['page_submit_path'] = [ '#type' => 'textfield', '#title' => $this->t('Webform URL alias'), '#description' => $this->t('Optionally specify an alternative URL by which the webform submit page can be accessed.', $t_args), '#default_value' => $settings['page_submit_path'], '#states' => [ 'visible' => [ ':input[name="page"]' => ['checked' => TRUE], ], ], ]; $form['page']['page_confirm_path'] = [ '#type' => 'textfield', '#title' => $this->t('Confirmation page URL alias'), '#description' => $this->t('Optionally specify an alternative URL by which the webform confirmation page can be accessed.', $t_args), '#default_value' => $settings['page_confirm_path'], '#states' => [ 'visible' => [ ':input[name="page"]' => ['checked' => TRUE], ], ], ]; } // Form. $form['form'] = [ '#type' => 'details', '#title' => $this->t('Webform settings'), ]; $form['form']['status'] = [ '#type' => 'radios', '#title' => $this->t('Webform status'), '#default_value' => $webform->get('status'), '#options' => [ WebformInterface::STATUS_OPEN => $this->t('Open'), WebformInterface::STATUS_CLOSED => $this->t('Closed'), WebformInterface::STATUS_SCHEDULED => $this->t('Scheduled'), ], '#states' => [ 'visible' => [ ':input[name="template"]' => ['checked' => FALSE], ], ], ]; $form['form']['scheduled'] = [ '#type' => 'item', '#input' => FALSE, '#attributes' => ['class' => 'container-inline'], '#description' => $this->t('If the open date/time is left blank, this webform will immediately be opened.') . '
' . $this->t('If the close date/time is left blank, this webform will never be closed.'), '#states' => [ 'visible' => [ ':input[name="template"]' => ['checked' => FALSE], ':input[name="status"]' => ['value' => WebformInterface::STATUS_SCHEDULED], ], ], ]; $form['form']['scheduled']['dates'] = [ '#type' => 'container', '#attributes' => ['class' => 'container-inline'], ]; $form['form']['scheduled']['dates']['open'] = [ '#type' => 'datetime', '#title' => $this->t('Open'), '#default_value' => $webform->get('open') ? DrupalDateTime::createFromTimestamp(strtotime($webform->get('open'))) : NULL, ]; $form['form']['scheduled']['dates']['space'] = ['#markup' => '   ']; $form['form']['scheduled']['dates']['close'] = [ '#type' => 'datetime', '#title' => $this->t('Close'), '#default_value' => $webform->get('close') ? DrupalDateTime::createFromTimestamp(strtotime($webform->get('close'))) : NULL, ]; $form['form']['form_closed_message'] = [ '#type' => 'webform_html_editor', '#title' => $this->t('Webform closed message'), '#description' => $this->t('A message to be displayed notifying the user that the webform is closed.'), '#default_value' => $settings['form_closed_message'], ]; $form['form']['form_exception_message'] = [ '#type' => 'webform_html_editor', '#title' => $this->t('Webform exception message'), '#description' => $this->t('A message to be displayed if the webform breaks.'), '#default_value' => $settings['form_exception_message'], ]; $form['form']['form_submit'] = [ '#type' => 'details', '#title' => $this->t('Webform submit button'), ]; $form['form']['form_submit']['form_submit_label'] = [ '#type' => 'textfield', '#title' => $this->t('Webform submit button label'), '#size' => 20, '#default_value' => $settings['form_submit_label'], ]; $form['form']['form_submit']['form_submit_attributes'] = [ '#type' => 'webform_element_attributes', '#title' => $this->t('Webform submit button'), '#classes' => $this->configFactory->get('webform.settings')->get('settings.button_classes'), '#default_value' => $settings['form_submit_attributes'], ]; $form['form']['form_prepopulate'] = [ '#type' => 'checkbox', '#title' => $this->t('Allow elements to be populated using query string parameters.'), '#description' => $this->t("If checked, elements can be populated using query string parameters. For example, appending ?name=John+Smith to a webform's URL would setting an the 'name' element's default value to 'John Smith'."), '#return_value' => TRUE, '#default_value' => $settings['form_prepopulate'], ]; $form['form']['form_prepopulate_source_entity'] = [ '#type' => 'checkbox', '#title' => $this->t('Allow source entity to be populated using query string parameters.'), '#description' => $this->t("If checked, source entity can be populated using query string parameters. For example, appending ?source_entity_type=user&source_entity_id=1 to a webform's URL would set a submission's 'Submitted to' value to '@user.", ['@user' => User::load(1)->label()]), '#return_value' => TRUE, '#default_value' => $settings['form_prepopulate_source_entity'], ]; $settings_elements = [ 'form_submit_once' => [ 'title' => $this->t('Prevent duplicate submissions'), 'all_description' => $this->t('Submit button is disabled immediately after is is clicked form all webforms.'), 'form_description' => $this->t('If checked, the submit button will be disabled immediately after is is clicked.'), ], 'form_disable_back' => [ 'title' => $this->t('Disable back button for all webforms'), 'all_description' => $this->t('Back button is disabled for all webforms.'), 'form_description' => $this->t('If checked, users will not be allowed to navigate back to the webform using the browsers back button.'), ], 'form_unsaved' => [ 'title' => $this->t('Warn users about unsaved changes'), 'all_description' => $this->t('Unsaved warning is enabled for all webforms.'), 'form_description' => $this->t('If checked, users will be displayed a warning message when they navigate away from a webform with unsaved changes.'), ], 'form_disable_autocomplete' => [ 'title' => $this->t('Disable autocompletion'), 'form_description' => $this->t('If checked, the autocomplete attribute will be set to off, which disables autocompletion for all form elements.', [':href' => 'http://www.w3schools.com/tags/att_form_autocomplete.asp']), ], 'form_novalidate' => [ 'title' => $this->t('Disable client-side validation'), 'all_description' => $this->t('Client-side validation is disabled for all webforms.'), 'form_description' => $this->t('If checked, the novalidate attribute, which disables client-side validation, will be added to this webform.', [':href' => 'http://www.w3schools.com/tags/att_form_novalidate.asp']), ], 'form_details_toggle' => [ 'title' => $this->t('Display collapse/expand all details link'), 'all_description' => $this->t('Expand/collapse all (details) link is automatically added to all webforms.'), 'form_description' => $this->t('If checked, an expand/collapse all (details) link will be added to this webform when there are two or more details elements available on the webform.'), ], ]; foreach ($settings_elements as $settings_key => $setting_element) { if (!empty($default_settings['default_' . $settings_key])) { $form['form'][$settings_key . '_disabled'] = [ '#type' => 'checkbox', '#title' => $setting_element['title'], '#description' => $setting_element['all_description'], '#disabled' => TRUE, '#default_value' => TRUE, ]; $form['form'][$settings_key] = [ '#type' => 'value', '#value' => $settings[$settings_key], ]; } else { $form['form'][$settings_key] = [ '#type' => 'checkbox', '#title' => $setting_element['title'], '#description' => $setting_element['form_description'], '#return_value' => TRUE, '#default_value' => $settings[$settings_key], ]; } } $form['form']['form_autofocus'] = [ '#type' => 'checkbox', '#title' => $this->t('Autofocus'), '#description' => $this->t('If checked, the first visible and enabled input will be focused when adding new submissions.'), '#return_value' => TRUE, '#default_value' => $settings['form_autofocus'], ]; // Attributes. $elements = $webform->getElementsDecoded(); $form['attributes'] = [ '#type' => 'details', '#title' => $this->t('Form attributes'), ]; $form['attributes']['attributes'] = [ '#type' => 'webform_element_attributes', '#title' => $this->t('Webform'), '#classes' => $this->configFactory->get('webform.settings')->get('settings.form_classes'), '#default_value' => (isset($elements['#attributes'])) ? $elements['#attributes'] : [], ]; // Wizard. $form['wizard'] = [ '#type' => 'details', '#title' => $this->t('Wizard settings'), '#states' => [ 'visible' => [ ':input[name="method"]' => ['value' => ''], ], ], ]; $form['wizard']['wizard_progress_bar'] = [ '#type' => 'checkbox', '#title' => $this->t('Show wizard progress bar'), '#return_value' => TRUE, '#default_value' => $settings['wizard_progress_bar'], ]; $form['wizard']['wizard_progress_pages'] = [ '#type' => 'checkbox', '#return_value' => TRUE, '#title' => $this->t('Show wizard progress pages'), '#default_value' => $settings['wizard_progress_pages'], ]; $form['wizard']['wizard_progress_percentage'] = [ '#type' => 'checkbox', '#return_value' => TRUE, '#title' => $this->t('Show wizard progress percentage'), '#default_value' => $settings['wizard_progress_percentage'], ]; $form['wizard']['wizard_prev_button'] = [ '#type' => 'details', '#title' => $this->t('Previous wizard page button'), '#description' => $this->t('This is used for the previous page button within a wizard.'), ]; $form['wizard']['wizard_prev_button']['wizard_prev_button_label'] = [ '#type' => 'textfield', '#title' => $this->t('Previous wizard page button label'), '#size' => 20, '#default_value' => $settings['wizard_prev_button_label'], ]; $form['wizard']['wizard_prev_button']['wizard_prev_button_attributes'] = [ '#type' => 'webform_element_attributes', '#title' => $this->t('Previous wizard page button'), '#classes' => $this->configFactory->get('webform.settings')->get('settings.button_classes'), '#default_value' => $settings['wizard_prev_button_attributes'], ]; $form['wizard']['wizard_next_button'] = [ '#type' => 'details', '#title' => $this->t('Next wizard page button'), '#description' => $this->t('This is used for the next page button within a wizard.'), ]; $form['wizard']['wizard_next_button']['wizard_next_button_label'] = [ '#type' => 'textfield', '#title' => $this->t('Next wizard page button label'), '#size' => 20, '#default_value' => $settings['wizard_next_button_label'], ]; $form['wizard']['wizard_next_button']['wizard_next_button_attributes'] = [ '#type' => 'webform_element_attributes', '#title' => $this->t('Next wizard page button'), '#classes' => $this->configFactory->get('webform.settings')->get('settings.button_classes'), '#default_value' => $settings['wizard_next_button_attributes'], ]; $form['wizard']['wizard_complete'] = [ '#type' => 'checkbox', '#title' => $this->t('Include confirmation page in progress'), '#return_value' => TRUE, '#default_value' => $settings['wizard_complete'], ]; $form['wizard']['wizard_start_label'] = [ '#type' => 'textfield', '#title' => $this->t('Wizard start label'), '#size' => 20, '#default_value' => $settings['wizard_start_label'], ]; $form['wizard']['wizard_complete_label'] = [ '#type' => 'textfield', '#title' => $this->t('Wizard end label'), '#size' => 20, '#default_value' => $settings['wizard_complete_label'], '#states' => [ 'visible' => [ ':input[name="wizard_complete"]' => ['checked' => TRUE], ], ], ]; // Preview. $form['preview'] = [ '#type' => 'details', '#title' => $this->t('Preview settings'), '#states' => [ 'visible' => [ ':input[name="method"]' => ['value' => ''], ], ], ]; $form['preview']['preview'] = [ '#type' => 'radios', '#title' => $this->t('Enable preview page'), '#options' => [ DRUPAL_DISABLED => $this->t('Disabled'), DRUPAL_OPTIONAL => $this->t('Optional'), DRUPAL_REQUIRED => $this->t('Required'), ], '#description' => $this->t('Add a page for previewing the webform before submitting.'), '#default_value' => $settings['preview'], ]; $form['preview']['settings'] = [ '#type' => 'container', '#states' => [ 'invisible' => [ ':input[name="preview"]' => ['value' => DRUPAL_DISABLED], ], ], ]; // Preview next button. $form['preview']['settings']['preview_next_button'] = [ '#type' => 'details', '#title' => $this->t('Preview button'), ]; $form['preview']['settings']['preview_next_button']['preview_next_button_label'] = [ '#type' => 'textfield', '#title' => $this->t('Preview button label'), '#description' => $this->t('The text for the button that will proceed to the preview page.'), '#size' => 20, '#default_value' => $settings['preview_next_button_label'], ]; $form['preview']['settings']['preview_next_button']['preview_next_button_attributes'] = [ '#type' => 'webform_element_attributes', '#title' => $this->t('Preview button'), '#classes' => $this->configFactory->get('webform.settings')->get('settings.button_classes'), '#default_value' => $settings['preview_next_button_attributes'], ]; // Preview previous button. $form['preview']['settings']['preview_prev_button'] = [ '#type' => 'details', '#title' => $this->t('Previous page button'), ]; $form['preview']['settings']['preview_prev_button']['preview_prev_button_label'] = [ '#type' => 'textfield', '#title' => $this->t('Previous page button label'), '#description' => $this->t('The text for the button to go backwards from the preview page.'), '#size' => 20, '#default_value' => $settings['preview_prev_button_label'], ]; $form['preview']['settings']['preview_prev_button']['preview_prev_button_attributes'] = [ '#type' => 'webform_element_attributes', '#title' => $this->t('Previous page button'), '#classes' => $this->configFactory->get('webform.settings')->get('settings.button_classes'), '#default_value' => $settings['preview_prev_button_attributes'], ]; $form['preview']['settings']['preview_message'] = [ '#type' => 'webform_html_editor', '#title' => $this->t('Preview message'), '#description' => $this->t('A message to be displayed on the preview page.'), '#default_value' => $settings['preview_message'], ]; // Draft. $form['draft'] = [ '#type' => 'details', '#title' => $this->t('Draft settings'), '#states' => [ 'visible' => [ ':input[name="results_disabled"]' => ['checked' => FALSE], ':input[name="method"]' => ['value' => ''], ], ], ]; $form['draft']['draft'] = [ '#type' => 'checkbox', '#title' => $this->t('Allow your users to save and finish the webform later.'), "#description" => $this->t('This option is available only for authenticated users.'), '#return_value' => TRUE, '#default_value' => $settings['draft'], ]; $form['draft']['settings'] = [ '#type' => 'container', '#states' => [ 'visible' => [ ':input[name="draft"]' => ['checked' => TRUE], ], ], ]; $form['draft']['settings']['draft_auto_save'] = [ '#type' => 'checkbox', '#return_value' => TRUE, '#title' => $this->t('Automatically save as draft when paging, previewing, and when there are validation errors.'), "#description" => $this->t('Automatically save partial submissions when users click the "Preview" button or when validation errors prevent a webform from being submitted.'), '#default_value' => $settings['draft_auto_save'], ]; $form['draft']['settings']['draft_button'] = [ '#type' => 'details', '#title' => $this->t('Draft button'), ]; $form['draft']['settings']['draft_button']['draft_button_label'] = [ '#type' => 'textfield', '#title' => $this->t('Draft button label'), '#description' => $this->t('The text for the button that will save a draft.'), '#size' => 20, '#default_value' => $settings['draft_button_label'], ]; $form['draft']['settings']['draft_button']['draft_button_attributes'] = [ '#type' => 'webform_element_attributes', '#title' => $this->t('Draft button'), '#classes' => $this->configFactory->get('webform.settings')->get('settings.button_classes'), '#default_value' => $settings['draft_button_attributes'], ]; $form['draft']['settings']['draft_saved_message'] = [ '#type' => 'webform_html_editor', '#title' => $this->t('Draft saved message'), '#description' => $this->t('Message to be displayed when a draft is saved.'), '#default_value' => $settings['draft_saved_message'], ]; $form['draft']['settings']['draft_loaded_message'] = [ '#type' => 'webform_html_editor', '#title' => $this->t('Draft loaded message'), '#description' => $this->t('Message to be displayed when a draft is loaded.'), '#default_value' => $settings['draft_loaded_message'], ]; // Submission. $form['submission'] = [ '#type' => 'details', '#title' => $this->t('Submission settings'), '#states' => [ 'visible' => [ ':input[name="results_disabled"]' => ['checked' => FALSE], ':input[name="method"]' => ['value' => ''], ], ], ]; $form['submission']['form_previous_submissions'] = [ '#type' => 'checkbox', '#title' => $this->t('Show the notification about previous submissions'), '#description' => $this->t('Show the previous submissions notification that appears when users have previously submitted this form.'), '#default_value' => $settings['form_previous_submissions'], ]; $form['submission']['form_confidential'] = [ '#type' => 'checkbox', '#title' => $this->t('Confidential submissions'), '#description' => $this->t('Confidential submissions have no recorded IP address and must be submitted while logged out.'), '#return_value' => TRUE, '#default_value' => $settings['form_confidential'], ]; $form['submission']['form_confidential_message'] = [ '#type' => 'webform_html_editor', '#title' => $this->t('Webform confidential message'), '#description' => $this->t('A message to be displayed when authenticated users try to access a confidential webform.'), '#default_value' => $settings['form_confidential_message'], '#states' => [ 'visible' => [ ':input[name="form_confidential"]' => ['checked' => TRUE], ], ], ]; $form['submission']['token_update'] = [ '#type' => 'checkbox', '#title' => $this->t('Allow users to update a submission using a secure token.'), '#description' => $this->t("If checked users will be able to update a submission using the webform's URL appended with the submission's (secure) token. The URL to update a submission will be available when viewing a submission's information and can be inserted into the an email using the [webform_submission:update-url] token."), '#return_value' => TRUE, '#default_value' => $settings['token_update'], ]; $form['submission']['next_serial'] = [ '#type' => 'number', '#title' => $this->t('Next submission number'), '#description' => $this->t('The value of the next submission number. This is usually 1 when you start and will go up with each webform submission.'), '#min' => 1, '#default_value' => $webform->getState('next_serial') ?: 1, ]; // Limits. $form['limits'] = [ '#type' => 'details', '#title' => $this->t('Submission limits'), '#states' => [ 'visible' => [ ':input[name="results_disabled"]' => ['checked' => FALSE], ':input[name="method"]' => ['value' => ''], ], ], ]; $form['limits']['limit_total'] = [ '#type' => 'number', '#title' => $this->t('Total submissions limit'), '#min' => 1, '#default_value' => $settings['limit_total'], ]; $form['limits']['entity_limit_total'] = [ '#type' => 'number', '#title' => $this->t('Total submissions limit per entity'), '#min' => 1, '#default_value' => $settings['entity_limit_total'], ]; $form['limits']['limit_total_message'] = [ '#type' => 'webform_html_editor', '#title' => $this->t('Total submissions limit message'), '#min' => 1, '#default_value' => $settings['limit_total_message'], ]; $form['limits']['limit_user'] = [ '#type' => 'number', '#title' => $this->t('Per user submission limit'), '#min' => 1, '#default_value' => $settings['limit_user'], ]; $form['limits']['entity_limit_user'] = [ '#type' => 'number', '#min' => 1, '#title' => $this->t('Per user submission limit per entity'), '#default_value' => $settings['entity_limit_user'], ]; $form['limits']['limit_user_message'] = [ '#type' => 'webform_html_editor', '#title' => $this->t('Per user submission limit message'), '#default_value' => $settings['limit_user_message'], ]; $form['purge'] = [ '#type' => 'details', '#title' => $this->t('Submission purging'), '#states' => [ 'visible' => [ ':input[name="results_disabled"]' => ['checked' => FALSE], ':input[name="method"]' => ['value' => ''], ], ], ]; $form['purge']['purge'] = [ '#type' => 'select', '#title' => $this->t('Automatically purge'), '#options' => [ WebformSubmissionStorageInterface::PURGE_NONE => $this->t('None'), WebformSubmissionStorageInterface::PURGE_DRAFT => $this->t('Draft'), WebformSubmissionStorageInterface::PURGE_COMPLETED => $this->t('Completed'), WebformSubmissionStorageInterface::PURGE_ALL => $this->t('Draft and completed'), ], '#default_value' => $settings['purge'], ]; $form['purge']['purge_days'] = [ '#type' => 'number', '#title' => $this->t('Days to retain submissions'), '#min' => 1, '#default_value' => $settings['purge_days'], '#states' => [ 'invisible' => ['select[name="purge"]' => ['value' => WebformSubmissionStorageInterface::PURGE_NONE]], 'optional' => ['select[name="purge"]' => ['value' => WebformSubmissionStorageInterface::PURGE_NONE]], ], '#field_suffix' => $this->t('days'), ]; // Confirmation. $form['confirmation'] = [ '#type' => 'details', '#title' => $this->t('Confirmation settings'), '#states' => [ 'visible' => [ ':input[name="method"]' => ['value' => ''], ], ], ]; $form['confirmation']['confirmation_type'] = [ '#title' => $this->t('Confirmation type'), '#type' => 'radios', '#options' => [ 'page' => $this->t('Page (redirects to new page and displays the confirmation message)'), 'inline' => $this->t('Inline (reloads the current page and replaces the webform with the confirmation message.)'), 'message' => $this->t('Message (reloads the current page/form and displays the confirmation message at the top of the page.)'), 'url' => $this->t('URL (redirects to a custom path or URL)'), 'url_message' => $this->t('URL with message (redirects to a custom path or URL and displays the confirmation message at the top of the page.)'), ], '#default_value' => $settings['confirmation_type'], ]; $form['confirmation']['confirmation_url'] = [ '#type' => 'textfield', '#title' => $this->t('Confirmation URL'), '#description' => $this->t('URL to redirect the user to upon successful submission.'), '#default_value' => $settings['confirmation_url'], '#maxlength' => NULL, '#states' => [ 'visible' => [ [':input[name="confirmation_type"]' => ['value' => 'url']], 'or', [':input[name="confirmation_type"]' => ['value' => 'url_message']], ], ], ]; $form['confirmation']['confirmation_title'] = [ '#type' => 'textfield', '#title' => $this->t('Confirmation title'), '#description' => $this->t('Page title to be shown upon successful submission.'), '#default_value' => $settings['confirmation_title'], '#states' => [ 'visible' => [ ':input[name="confirmation_type"]' => ['value' => 'page'], ], ], ]; $form['confirmation']['confirmation_message'] = [ '#type' => 'webform_html_editor', '#title' => $this->t('Confirmation message'), '#description' => $this->t('Message to be shown upon successful submission.'), '#default_value' => $settings['confirmation_message'], '#states' => [ 'invisible' => [ ':input[name="confirmation_type"]' => ['value' => 'url'], ], ], ]; $form['confirmation']['page'] = [ '#type' => 'container', '#states' => [ 'visible' => [ [':input[name="confirmation_type"]' => ['value' => 'page']], 'or', [':input[name="confirmation_type"]' => ['value' => 'inline']], ], ], ]; $form['confirmation']['page']['confirmation_attributes'] = [ '#type' => 'webform_element_attributes', '#title' => $this->t('Confirmation'), '#classes' => $this->configFactory->get('webform.settings')->get('settings.confirmation_classes'), '#default_value' => $settings['confirmation_attributes'], ]; $form['confirmation']['page']['confirmation_back'] = [ '#type' => 'checkbox', '#title' => $this->t('Display back to webform link'), '#return_value' => TRUE, '#default_value' => $settings['confirmation_back'], ]; $form['confirmation']['page']['back'] = [ '#type' => 'details', '#title' => $this->t('Confirmation back link'), '#states' => [ 'visible' => [ [':input[name="confirmation_back"]' => ['checked' => TRUE]], ], ], ]; $form['confirmation']['page']['back']['confirmation_back_label'] = [ '#type' => 'textfield', '#title' => $this->t('Confirmation back link label'), '#size' => 20, '#default_value' => $settings['confirmation_back_label'], ]; $form['confirmation']['page']['back']['confirmation_back_attributes'] = [ '#type' => 'webform_element_attributes', '#title' => $this->t('Confirmation back link'), '#classes' => $this->configFactory->get('webform.settings')->get('settings.confirmation_back_classes'), '#default_value' => $settings['confirmation_back_attributes'], ]; $form['confirmation']['token_tree_link'] = $this->tokenManager->buildTreeLink(); // Author. $form['author'] = [ '#type' => 'details', '#title' => $this->t('Author information'), '#access' => $this->currentUser()->hasPermission('administer webform'), ]; $form['author']['uid'] = [ '#type' => 'entity_autocomplete', '#title' => $this->t('Authored by'), '#description' => $this->t("The username of the webform author/owner."), '#target_type' => 'user', '#settings' => [ 'match_operator' => 'CONTAINS', ], '#selection_settings' => [ 'include_anonymous' => TRUE, ], '#default_value' => $webform->getOwner(), ]; // Custom. $properties = WebformElementHelper::getProperties($webform->getElementsDecoded()); // Set default properties. $properties += [ '#method' => '', '#action' => '', ]; $form['custom'] = [ '#type' => 'details', '#title' => $this->t('Custom settings'), '#open' => array_filter($properties) ? TRUE : FALSE, '#access' => !$this->moduleHandler->moduleExists('webform_ui') || $this->currentUser()->hasPermission('edit webform source'), ]; $form['custom']['method'] = [ '#type' => 'select', '#title' => $this->t('Method'), '#description' => $this->t('The HTTP method with which the form will be submitted.') . '
' . '' . $this->t('Selecting a custom POST or GET method will automatically disable wizards, previews, drafts, submissions, limits, purging, and confirmations.') . '', '#options' => [ '' => $this->t('POST (Default)'), 'post' => $this->t('POST (Custom)'), 'get' => $this->t('GET (Custom)'), ], '#default_value' => $properties['#method'], ]; $form['custom']['method_message'] = [ '#type' => 'webform_message', '#message_type' => 'warning', '#message_message' => $this->t("Please make sure this webform's action URL or path is setup to handle the webform's submission."), '#states' => [ 'invisible' => [ ':input[name="method"]' => ['value' => ''], ], ], ]; $form['custom']['action'] = [ '#type' => 'textfield', '#title' => $this->t('Action'), '#description' => $this->t('The URL or path to which the webform will be submitted.'), '#states' => [ 'invisible' => [ ':input[name="method"]' => ['value' => ''], ], 'optional' => [ ':input[name="method"]' => ['value' => ''], ], ], '#default_value' => $properties['#action'], ]; // Unset properties that are webform settings. unset( $properties['#method'], $properties['#action'], $properties['#novalidate'], $properties['#attributes'] ); $form['custom']['custom'] = [ '#type' => 'webform_codemirror', '#mode' => 'yaml', '#title' => $this->t('Custom properties'), '#description' => $this->t('Properties do not have to prepended with a hash (#) character, the hash character will be automatically added upon submission.') . '
' . $this->t('These properties and callbacks are not allowed: @properties', ['@properties' => WebformArrayHelper::toString(WebformArrayHelper::addPrefix(WebformElementHelper::$ignoredProperties))]), '#default_value' => WebformArrayHelper::removePrefix($properties), ]; $this->appendDefaultValueToElementDescriptions($form, $default_settings); return parent::form($form, $form_state); } /** * {@inheritdoc} */ public function validateForm(array &$form, FormStateInterface $form_state) { $values = $form_state->getValues(); if ($values['status'] === WebformInterface::STATUS_SCHEDULED && empty($values['open']) && empty($values['close'])) { $form_state->setErrorByName('status', $this->t('Please enter an open or close date')); } } /** * {@inheritdoc} */ public function save(array $form, FormStateInterface $form_state) { $values = $form_state->getValues(); /** @var \Drupal\webform\WebformInterface $webform */ $webform = $this->getEntity(); // Set open and close date/time. $webform->set('open', NULL); $webform->set('close', NULL); if ($values['status'] === WebformInterface::STATUS_SCHEDULED) { $webform->set('open', ($values['open']) ? $values['open']->format('c') : NULL); $webform->set('close', ($values['close']) ? $values['close']->format('c') : NULL); } // Set custom properties, class, and style. $elements = $webform->getElementsDecoded(); $elements = WebformElementHelper::removeProperties($elements); $properties = []; if (!empty($values['method'])) { $properties['#method'] = $values['method']; } if (!empty($values['action'])) { $properties['#action'] = $values['action']; } if (!empty($values['custom'])) { $properties += WebformArrayHelper::addPrefix($values['custom']); } if (!empty($values['attributes'])) { $properties['#attributes'] = $values['attributes']; } $elements = $properties + $elements; $webform->setElements($elements); // Remove custom properties and attributes. unset( $values['method'], $values['action'], $values['attributes'], $values['custom'] ); /** @var \Drupal\webform\WebformSubmissionStorageInterface $submission_storage */ $submission_storage = $this->entityTypeManager->getStorage('webform_submission'); // Set next serial number. $next_serial = (int) $values['next_serial']; $max_serial = $submission_storage->getMaxSerial($webform); if ($next_serial < $max_serial) { drupal_set_message($this->t('The next submission number was increased to @min to make it higher than existing submissions.', ['@min' => $max_serial])); $next_serial = $max_serial; } $webform->setState('next_serial', $next_serial); // Remove main properties. unset( $values['id'], $values['title'], $values['description'], $values['template'], $values['status'], $values['open'], $values['close'], $values['uid'], $values['next_serial'] ); // Remove disabled properties. unset( $values['form_novalidate_disabled'], $values['form_unsaved_disabled'], $values['form_details_toggle_disabled'] ); // Set settings. $webform->setSettings($values); // Save the webform. $webform->save(); $this->logger('webform')->notice('Webform settings @label saved.', ['@label' => $webform->label()]); drupal_set_message($this->t('Webform settings %label saved.', ['%label' => $webform->label()])); } /** * Append default value to an element's description. * * @param array $form * An associative array containing the structure of the form. * @param array $default_settings * An associative array container default webform settings. */ protected function appendDefaultValueToElementDescriptions(array &$form, array $default_settings) { foreach ($form as $key => &$element) { // Skip if not a FAPI element. if (Element::property($key) || !is_array($element)) { continue; } if (isset($element['#type']) && !empty($default_settings["default_$key"]) && empty($element['#disabled'])) { if (!isset($element['#description'])) { $element['#description'] = ''; } $element['#description'] .= ($element['#description'] ? '
' : ''); $element['#description'] .= $this->t('Defaults to: %value', ['%value' => $default_settings["default_$key"]]); } $this->appendDefaultValueToElementDescriptions($element, $default_settings); } } }