You are here

public function AutosaveFormAlterTrait::autosaveFormSubmit in Autosave Form 8

Form submission handler for autosaving forms.

File

src/Form/AutosaveFormAlterTrait.php, line 159

Class

AutosaveFormAlterTrait
Provides a trait for common autosave form alterations.

Namespace

Drupal\autosave_form\Form

Code

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

  // As this processing might take some time we want to prevent that if the
  // connection is terminated the user input will be lost.
  ignore_user_abort(TRUE);
  if (!$this
    ->isAutosaveSubmitValid($form_state)) {
    $form_state
      ->disableCache();
    return;
  }

  // Having an autosave form session id also ensures that after resuming
  // editing the new autosaved entities will be saved to the same autosave
  // session id.
  $autosave_form_session_id = $this
    ->getAutosaveFormSessionID($form_state);
  $current_user_id = $this->currentUser
    ->id();
  $autosaved_form_state = $this
    ->getLastAutosavedFormState($form_state, $autosave_form_session_id, $current_user_id);

  // If there is non-autosaved state for this session then we have to put the
  // user input into a temporary store and on each autosave submit compare
  // against it for changes and after the first change compare with the last
  // autosaved state.
  if (is_null($autosaved_form_state)) {
    if ($initial_user_input = $this->keyValueExpirableFactory
      ->get('autosave_form')
      ->get($autosave_form_session_id)) {
      $autosaved_form_state_input = $initial_user_input;
    }
    else {

      // 6 hours cache life time for forms should be plenty, like the form
      // cache.
      $expire = 21600;
      $this->keyValueExpirableFactory
        ->get('autosave_form')
        ->setWithExpire($autosave_form_session_id, $form_state
        ->getUserInput(), $expire);

      // This is the first where we cache the user input initially and we are
      // done.
      $form_state
        ->disableCache();
      return;
    }
  }
  else {
    $autosaved_form_state_input = $autosaved_form_state
      ->getUserInput();
  }

  // Subsequent autosaving - compare the user input only. This should be
  // sufficient to detect changes in the fields.
  $form_state_input = $form_state
    ->getUserInput();
  $skip_from_comparison_keys = [
    'form_build_id',
    'form_token',
    'ajax_page_state',
    'autosave_form_last_autosave_timestamp',
    AutosaveFormInterface::AUTOSAVE_RESTORE_ELEMENT_NAME,
    AutosaveFormInterface::AUTOSAVE_REJECT_ELEMENT_NAME,
    'autosave_restore_discard',
  ];
  foreach ($skip_from_comparison_keys as $skip_from_comparison_key) {
    unset($autosaved_form_state_input[$skip_from_comparison_key]);
    unset($form_state_input[$skip_from_comparison_key]);
  }
  $store = $autosaved_form_state_input != $form_state_input;
  if ($store) {
    $autosave_timestamp = $this->time
      ->getRequestTime();
    $form_state
      ->set('autosave_form_last_autosave_timestamp', $autosave_timestamp);
    $form_state
      ->setTemporaryValue('autosave_form_last_autosave_timestamp', $autosave_timestamp);
    $this
      ->storeState($form_state, $autosave_form_session_id, $autosave_timestamp, $current_user_id);
    $this->keyValueExpirableFactory
      ->get('autosave_form')
      ->delete($autosave_form_session_id);
  }

  // We don't have to cache the form each time an autosave submission is
  // triggered, especially when we've skipped the form validation.
  $form_state
    ->disableCache();
}