You are here

public function WebformSubmissionForm::setEntity in Webform 6.x

Same name and namespace in other branches
  1. 8.5 src/WebformSubmissionForm.php \Drupal\webform\WebformSubmissionForm::setEntity()

This is the best place to override an entity form's default settings because it is called immediately after the form object is initialized.

Overrides EntityForm::setEntity

See also

\Drupal\Core\Entity\EntityFormBuilder::getForm

2 calls to WebformSubmissionForm::setEntity()
WebformSubmissionDuplicateForm::prepareEntity in src/WebformSubmissionDuplicateForm.php
Prepares the entity object before the form is built first.
WebformSubmissionForm::reset in src/WebformSubmissionForm.php
Webform submission handler for the 'reset' action.

File

src/WebformSubmissionForm.php, line 275

Class

WebformSubmissionForm
Provides a webform to collect and edit submissions.

Namespace

Drupal\webform

Code

public function setEntity(EntityInterface $entity) {

  // Create new metadata to be applie when the form is built.
  // @see \Drupal\webform\WebformSubmissionForm::buildForm
  $this->bubbleableMetadata = new WebformBubbleableMetadata();

  /** @var \Drupal\webform\WebformSubmissionInterface $entity */
  $webform = $entity
    ->getWebform();

  // Initialize the webform submission entity by getting it default data
  // and storing its original data.
  if (!isset($this->originalData)) {

    // Store the original data passed via the EntityFormBuilder.
    // This allows us to reset the submission to it's original state
    // via ::reset.
    // @see \Drupal\Core\Entity\EntityFormBuilder::getForm
    // @see \Drupal\webform\Entity\Webform::getSubmissionForm
    // @see \Drupal\webform\WebformSubmissionForm::reset
    $this->originalData = $entity
      ->getRawData();
  }

  // Get the submission data and only call WebformSubmission::setData once.
  $data = $entity
    ->getRawData();

  // If ?_webform_test is defined for the current webform, override
  // the 'add' operation with 'test' operation.
  if ($this->operation === 'add' && $this
    ->getRequest()->query
    ->get('_webform_test') === $webform
    ->id() && $webform
    ->access('test')) {
    $this->operation = 'test';
  }

  // Generate test data.
  if ($this->operation === 'test' && $webform
    ->access('test')) {
    $webform
      ->applyVariants($entity);
    $data = $webform
      ->getVariantsData($entity) + $this->generate
      ->getData($webform) + $data;
  }

  // Get the source entity and allow webform submission to be used as a source
  // entity.
  $source_entity = $entity
    ->getSourceEntity(TRUE) ?: $this->requestHandler
    ->getCurrentSourceEntity([
    'webform',
  ]);
  if ($source_entity === $entity) {
    $source_entity = $this->requestHandler
      ->getCurrentSourceEntity([
      'webform',
      'webform_submission',
    ]);
  }

  // Handle paragraph source entity.
  if ($source_entity && $source_entity
    ->getEntityTypeId() === 'paragraph') {

    // Disable :clear suffix to prevent webform tokens from being removed.
    $data = $this->tokenManager
      ->replace($data, $source_entity, [], [
      'suffixes' => [
        'clear' => FALSE,
      ],
    ], $this->bubbleableMetadata);
    $source_entity = WebformSourceEntityManager::getMainSourceEntity($source_entity);
  }

  // Set source entity.
  $this->sourceEntity = $source_entity;

  // Get account.
  $account = $this
    ->currentUser();

  // Load entity from token or saved draft when not editing or testing
  // submission form.
  if (!in_array($this->operation, [
    'edit',
    'edit_all',
    'test',
  ])) {
    $token = $this
      ->getRequest()->query
      ->get('token');
    $webform_submission_token = $this
      ->getStorage()
      ->loadFromToken($token, $webform, $source_entity);
    if ($webform_submission_token) {
      $entity = $webform_submission_token;
      $data = $entity
        ->getRawData();
      $this->operation = 'edit';
    }
    elseif ($webform
      ->getSetting('draft') !== WebformInterface::DRAFT_NONE) {
      if ($webform
        ->getSetting('draft_multiple')) {

        // Allow multiple drafts to be restored using token.
        // This allows the webform's public facing URL to be used instead of
        // the admin URL of the webform.
        $webform_submission_token = $this
          ->getStorage()
          ->loadFromToken($token, $webform, $source_entity, $account);
        if ($webform_submission_token && $webform_submission_token
          ->isDraft()) {
          $entity = $webform_submission_token;
          $data = $entity
            ->getRawData();
        }
        elseif (isset($_POST['webform_submission_token'])) {
          $webform_submission_token = $this
            ->getStorage()
            ->loadFromToken($_POST['webform_submission_token'], $webform, $source_entity, $account);
          if ($webform_submission_token && $webform_submission_token
            ->isDraft()) {
            $entity = $webform_submission_token;
            $data = $entity
              ->getRawData();
          }
        }
      }
      elseif ($webform_submission_draft = $this
        ->getStorage()
        ->loadDraft($webform, $source_entity, $account)) {

        // Else load the most recent draft.
        $entity = $webform_submission_draft;
        $data = $entity
          ->getRawData();
      }
    }
  }

  // Set entity before calling get last submission.
  $this->entity = $entity;
  if ($entity
    ->isNew()) {
    $last_submission = NULL;
    if ($webform
      ->getSetting('limit_total_unique')) {

      // Require user to have update any submission access.
      if (!$webform
        ->access('submission_view_any') || !$webform
        ->access('submission_update_any')) {
        throw new AccessDeniedHttpException();
      }

      // Get last webform/source entity submission.
      $last_submission = $this
        ->getStorage()
        ->getLastSubmission($webform, $source_entity, NULL, [
        'in_draft' => FALSE,
      ]);
    }
    elseif ($webform
      ->getSetting('limit_user_unique')) {

      // Require user to be authenticated to access a unique submission.
      if (!$account
        ->isAuthenticated()) {
        throw new AccessDeniedHttpException();
      }

      // Require user to have update own submission access.
      if (!$webform
        ->access('submission_view_own') || !$webform
        ->access('submission_update_own')) {
        throw new AccessDeniedHttpException();
      }

      // Get last user submission.
      $last_submission = $this
        ->getStorage()
        ->getLastSubmission($webform, $source_entity, $account, [
        'in_draft' => FALSE,
      ]);
    }

    // If the webform is closed and user can not update any submission,
    // block the submission from being updated.
    if ($webform
      ->isClosed() && !$webform
      ->access('submission_update_any')) {
      $last_submission = NULL;
    }

    // Set last submission and switch to the edit operation.
    if ($last_submission) {
      $entity = $last_submission;
      $data = $entity
        ->getRawData();
      $this->operation = 'edit';
    }
  }

  // Autofill with previous submission.
  if ($this->operation === 'add' && $entity
    ->isNew() && $webform
    ->getSetting('autofill')) {
    if ($last_submission = $this
      ->getStorage()
      ->getLastSubmission($webform, $source_entity, $account, [
      'in_draft' => FALSE,
      'access_check' => FALSE,
    ])) {
      $excluded_elements = $webform
        ->getSetting('autofill_excluded_elements') ?: [];
      $last_submission_data = array_diff_key($last_submission
        ->getRawData(), $excluded_elements);
      $data = $last_submission_data + $data;
    }
  }

  // Get default data and append it to the submission's data.
  // This allows computed elements to be executed and tokens
  // to be replaced using the webform's default data.
  $default_data = $webform
    ->getElementsDefaultData();
  $default_data = $this->tokenManager
    ->replace($default_data, $entity, [], [], $this->bubbleableMetadata);
  $data += $default_data;

  // Set data and calculate computed values.
  $entity
    ->setData($data);

  // Override settings.
  $this
    ->overrideSettings($entity);

  // Set the webform's current operation.
  $webform
    ->setOperation($this->operation);
  return parent::setEntity($entity);
}