You are here

public function WebformSubmissionForm::form in Webform 8.5

Same name and namespace in other branches
  1. 6.x src/WebformSubmissionForm.php \Drupal\webform\WebformSubmissionForm::form()

Gets the actual form array to be built.

Overrides ContentEntityForm::form

See also

\Drupal\Core\Entity\EntityForm::processForm()

\Drupal\Core\Entity\EntityForm::afterBuild()

File

src/WebformSubmissionForm.php, line 724

Class

WebformSubmissionForm
Provides a webform to collect and edit submissions.

Namespace

Drupal\webform

Code

public function form(array $form, FormStateInterface $form_state) {

  /* @var $webform_submission \Drupal\webform\WebformSubmissionInterface */
  $webform_submission = $this
    ->getEntity();
  $source_entity = $webform_submission
    ->getSourceEntity();
  $webform = $this
    ->getWebform();

  // Add a reference to the webform's id to the $form render array.
  $form['#webform_id'] = $webform
    ->id();

  // Track current page name or index by setting the
  // "data-webform-wizard-page"
  // attribute which is used Drupal.behaviors.webformWizardTrackPage.
  //
  // The data parameter is append to the URL after the form has
  // been submitted.
  //
  // @see js/webform.wizard.track.js
  $track = $this
    ->getWebform()
    ->getSetting('wizard_track');
  if ($track && $this
    ->getRequest()
    ->isMethod('POST')) {
    $current_page = $this
      ->getCurrentPage($form, $form_state);
    if ($track === 'index') {
      $pages = $this
        ->getWebform()
        ->getPages($this->operation);
      $track_pages = array_flip(array_keys($pages));
      $form['#attributes']['data-webform-wizard-current-page'] = $track_pages[$current_page] + 1;
    }
    else {
      $form['#attributes']['data-webform-wizard-current-page'] = $current_page;
    }
  }

  // Disable the default $form['#theme'] templates.
  // If the webform's id begins with an underscore the #theme
  // was automatically being set to 'webform_submission__WEBFORM_ID', this
  // causes the form to be rendered using the 'webform_submission' template.
  // @see \Drupal\Core\Form\FormBuilder::prepareForm
  // @see webform-submission-form.html.twig
  $form['#theme'] = [
    'webform_submission_form',
  ];

  // Define very specific webform classes, this override the form's
  // default classes.
  // @see \Drupal\Core\Form\FormBuilder::retrieveForm
  $webform_id = Html::cleanCssIdentifier($webform
    ->id());
  $operation = $this->operation;
  $class = [];
  $class[] = "webform-submission-form";
  $class[] = "webform-submission-{$operation}-form";
  $class[] = "webform-submission-{$webform_id}-form";
  $class[] = "webform-submission-{$webform_id}-{$operation}-form";
  if ($source_entity) {
    $source_entity_type = $source_entity
      ->getEntityTypeId();
    $source_entity_id = $source_entity
      ->id();
    $class[] = "webform-submission-{$webform_id}-{$source_entity_type}-{$source_entity_id}-form";
    $class[] = "webform-submission-{$webform_id}-{$source_entity_type}-{$source_entity_id}-{$operation}-form";
  }
  array_walk($class, [
    '\\Drupal\\Component\\Utility\\Html',
    'getClass',
  ]);
  $form['#attributes']['class'] = $class;

  // Get last class, which is the most specific, as #states prefix.
  // @see \Drupal\webform\WebformSubmissionForm::addStatesPrefix
  $this->statesPrefix = '.' . end($class);

  // Check for a custom webform, track it, and return it.
  if ($custom_form = $this
    ->getCustomForm($form, $form_state)) {
    $custom_form['#custom_form'] = TRUE;
    return $custom_form;
  }
  $form = parent::form($form, $form_state);

  /* Information */

  // Prepend webform submission data using the default view without the data.
  if (!$webform_submission
    ->isNew() && !$webform_submission
    ->isDraft()) {
    $form['navigation'] = [
      '#type' => 'webform_submission_navigation',
      '#webform_submission' => $webform_submission,
      '#weight' => -20,
    ];
    $form['information'] = [
      '#type' => 'webform_submission_information',
      '#webform_submission' => $webform_submission,
      '#source_entity' => $this->sourceEntity,
      '#weight' => -19,
    ];
  }

  /* Confirmation */

  // Add confirmation modal.
  if ($webform_confirmation_modal = $form_state
    ->get('webform_confirmation_modal')) {
    $form['webform_confirmation_modal'] = [
      '#type' => 'webform_message',
      '#message_type' => 'status',
      '#message_message' => [
        'title' => [
          '#markup' => $webform_confirmation_modal['title'],
          '#prefix' => '<b class="webform-confirmation-modal--title">',
          '#suffix' => '</b><br/>',
        ],
        'content' => [
          'content' => $webform_confirmation_modal['content'],
          '#prefix' => '<div class="webform-confirmation-modal--content">',
          '#suffix' => '</div>',
        ],
      ],
      '#attributes' => [
        'class' => [
          'js-hide',
          'webform-confirmation-modal',
          'js-webform-confirmation-modal',
        ],
      ],
      '#weight' => -1000,
      '#attached' => [
        'library' => [
          'webform/webform.confirmation.modal',
        ],
      ],
      '#element_validate' => [
        '::removeConfirmationModal',
      ],
    ];
  }

  /* Data */

  // Get and prepopulate (via query string) submission data.
  $data = $webform_submission
    ->getData();

  /* Elements */

  // Get webform elements.
  $elements = $webform_submission
    ->getWebform()
    ->getElementsInitialized();

  // Populate webform elements with webform submission data.
  $this
    ->populateElements($elements, $data);

  // Prepare webform elements.
  $this
    ->prepareElements($elements, $form, $form_state);

  // Add wizard progress tracker and page links to the webform.
  $pages = $webform
    ->getPages($this->operation);
  if ($pages && $operation !== 'edit_all') {
    $current_page = $this
      ->getCurrentPage($form, $form_state);

    // Add hidden pages submit actions.
    $form['pages'] = $this
      ->pagesElement($form, $form_state);

    // Add progress tracker.
    $display_wizard_progress = $this
      ->getWebformSetting('wizard_progress_bar') || $this
      ->getWebformSetting('wizard_progress_pages') || $this
      ->getWebformSetting('wizard_progress_percentage');
    if ($current_page && $display_wizard_progress) {
      $form['progress'] = [
        '#theme' => 'webform_progress',
        '#webform' => $this
          ->getWebform(),
        '#webform_submission' => $webform_submission,
        '#current_page' => $current_page,
        '#operation' => $this->operation,
        '#weight' => -20,
      ];
    }
  }

  // Required indicator.
  $current_page = $this
    ->getCurrentPage($form, $form_state);
  if ($current_page !== WebformInterface::PAGE_PREVIEW && $this
    ->getWebformSetting('form_required') && $webform
    ->hasRequired()) {
    $form['required'] = [
      '#theme' => 'webform_required',
      '#label' => $this
        ->getWebformSetting('form_required_label'),
    ];
  }

  // Append elements to the webform.
  $form['elements'] = $elements;

  // Pages: Set current wizard or preview page.
  $this
    ->displayCurrentPage($form, $form_state);

  // Move all $elements properties to the $form.
  $this
    ->setFormPropertiesFromElements($form, $elements);

  // Attach libraries to the form.
  $this
    ->attachLibraries($form, $form_state);

  // Attach behaviors to the form.
  $this
    ->attachBehaviors($form, $form_state);

  // Add #after_build callbacks.
  $form['#after_build'][] = '::afterBuild';
  return $form;
}