Commit 769c0085 authored by Ryan McVeigh's avatar Ryan McVeigh
Browse files

Issue #3270874 by rymcveigh, samuel.mortenson, lkacenja: Validation bypass via...

Issue #3270874 by rymcveigh, samuel.mortenson, lkacenja: Validation bypass via multiple submit button clicks
parent 1fc48633
Loading
Loading
Loading
Loading
+55 −18
Original line number Diff line number Diff line
@@ -2,7 +2,6 @@

namespace Drupal\webformnavigation\Plugin\WebformHandler;

use Drupal;
use Drupal\Core\Form\FormStateInterface;
use Drupal\webform\Plugin\WebformHandlerBase;
use Drupal\webform\WebformInterface;
@@ -107,7 +106,7 @@ class WebformNavigationHandler extends WebformHandlerBase {
  public function alterForm(array &$form, FormStateInterface $form_state, WebformSubmissionInterface $webform_submission) {
    $this->debug(__FUNCTION__);
    // Log the current page.
    $current_page = $webform_submission->getCurrentPage();
    $current_page = $this->webformNavigationHelper->getCurrentPage($webform_submission);
    $webform = $webform_submission->getWebform();
    // Get navigation webform settings.
    $forward_navigation = $webform->getThirdPartySetting('webformnavigation', 'forward_navigation');
@@ -123,37 +122,47 @@ class WebformNavigationHandler extends WebformHandlerBase {
        if ($page_key != 'webform_confirmation') {
          $form['pages'][$page_key]['#access'] = TRUE;
          $form['pages'][$page_key]['#validate'] = $validations;
          $form['pages'][$page_key]['#attributes']['formnovalidate'] = 'formnovalidate';
        }
      }
      // Set our loggers to the draft update if it is set.
      if (isset($form['actions']['draft'])) {
        // Add a logger to the next validators.
        $form['actions']['draft']['#validate'] = $validations;
      }
      // Set our loggers to the previous update if it is set.

      // Add a logger to the prev validators.
      if (isset($form['actions']['wizard_prev'])) {
        // Add a logger to the next validators.
        $form['actions']['wizard_prev']['#validate'] = $validations;
        $form['actions']['wizard_prev']['#attributes']['formnovalidate'] = 'formnovalidate';
      }

      // Add a logger to the draft validators.
      if (isset($form['actions']['draft'])) {
        $form['actions']['draft']['#validate'] = $validations;
      }
      // Add a custom validator to the final submit.
      $form['actions']['submit']['#validate'][] = 'webformnavigation_submission_validation';
      // Log the page visit.
      $visited = $this->webformNavigationHelper->hasVisitedPage($webform_submission, $current_page);
      // Log the page if it has not been visited before.
      if (!$visited) {
        $this->webformNavigationHelper->logPageVisit($webform_submission, $current_page);
      }
      elseif ($current_page != 'webform_confirmation') {
      if ($current_page != 'webform_confirmation') {
        // Display any errors.
        $errors = $this->webformNavigationHelper->getErrors($webform_submission);
        // Make sure we haven't already set errors.
        if (!empty($errors[$current_page])) {
          foreach ($errors[$current_page] as $error) {
            Drupal::messenger()->addError($error);
        $errors = $this->webformNavigationHelper->getErrors($webform_submission, $current_page);
        // Make sure we show the errors for the page.
        if (!empty($errors)) {
          foreach ($errors as $error) {
            $this->messenger()->addError($error);
          }
        }
      }
    }
    // Bypass validation of the next click.
    $prevent_next_validation = $webform->getThirdPartySetting('webformnavigation', 'prevent_next_validation');

    // Actions to perform if prevent_next_validation is set.
    if ($prevent_next_validation && isset($form['actions']['wizard_next'])) {
      $form['actions']['wizard_next']['#validate'] = [
        '::validateForm',
        '::draft',
      ];
    }
  }

  /**
@@ -168,7 +177,30 @@ class WebformNavigationHandler extends WebformHandlerBase {
    $forward_navigation = $webform->getThirdPartySetting('webformnavigation', 'forward_navigation');
    // Actions to perform if forward navigation is enabled and there are pages.
    if ($forward_navigation && $webform->hasWizardPages()) {
      $triggering_element = $form_state->getTriggeringElement();
      // Log the current page errors.
      $this->webformNavigationHelper->logPageErrors($webform_submission, $form_state);
      // Validate everything on the final submit.
      if (isset($triggering_element['#validate']) && in_array('::complete', $triggering_element['#validate'])) {
        $this->webformNavigationHelper->validateAllPages($webform_submission, $form_state, $form);
        $logged_errors = $this->webformNavigationHelper->getErrors($webform_submission);
        if (!empty($logged_errors)) {
          $form_state->clearErrors();
          foreach ($logged_errors as $page_name => $errors) {
            if (!empty($errors) && $this->webformNavigationHelper->hasAccessToPage($page_name, $webform_submission)) {
              if ($page = $webform->getPage('edit', $page_name)) {
                $form_state->setErrorByName($page_name, [
                  '#theme' => 'item_list',
                  '#items' => $errors,
                  '#title' => $this->t('@title Page', [
                    '@title' => $page['#title'],
                  ]),
                ]);
              }
            }
          }
        }
      }
    }
  }

@@ -179,6 +211,11 @@ class WebformNavigationHandler extends WebformHandlerBase {
   */
  public function submitForm(array &$form, FormStateInterface $form_state, WebformSubmissionInterface $webform_submission) {
    $this->debug(__FUNCTION__);
    $triggering_element = $form_state->getTriggeringElement();
    if (isset($triggering_element['#page'])) {
      $form_state->set('current_page', $triggering_element['#page']);
      $webform_submission->setCurrentPage($triggering_element['#page']);
    }
  }

  /**
@@ -245,7 +282,7 @@ class WebformNavigationHandler extends WebformHandlerBase {
    // Log the initial page if this is an insert.
    if (!$update && $forward_navigation && $webform->hasWizardPages()) {
      $pages = $webform->getPages('add', $webform_submission);
      // Log the first page
      // Log the first page.
      $this->webformNavigationHelper->logPageVisit($webform_submission, array_keys($pages)[0]);
      // Log any stashed errors.
      $this->webformNavigationHelper->logStashedPageErrors($webform_submission);
+134 −54
Original line number Diff line number Diff line
@@ -2,13 +2,14 @@

namespace Drupal\webformnavigation;

use Drupal;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Form\FormState;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Drupal\webform\WebformInterface;
use Drupal\webform\WebformSubmissionInterface;
use Drupal\webform_submission_log\WebformSubmissionLogManager;
@@ -29,7 +30,7 @@ class WebformNavigationHelper {
  const ERROR_OPERATION = 'errors';

  /**
   * Name of the page visited operation
   * Name of the page visited operation.
   */
  const PAGE_VISITED_OPERATION = 'page visited';

@@ -44,6 +45,8 @@ class WebformNavigationHelper {
  const TEMP_STORE_KEY = 'webformnavigation_errors';

  /**
   * The webform submission log manager.
   *
   * @var \Drupal\webform_submission_log\WebformSubmissionLogManager
   */
  protected $webform_submission_log_manager;
@@ -76,21 +79,46 @@ class WebformNavigationHelper {
   */
  protected $form_builder;

  /**
   * The current user account.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected AccountInterface $current_user;

  /**
   * The private temp store.
   *
   * @var \Drupal\Core\TempStore\PrivateTempStoreFactory
   */
  protected PrivateTempStoreFactory $private_temp_store;

  /**
   * AutosaveHelper constructor.
   *
   * @param \Drupal\webform_submission_log\WebformSubmissionLogManager $webform_submission_log_manager
   *   The webform submission logger service.
   * @param \Drupal\Core\Database\Connection $datababse
   *   The database service.
   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
   *   The messenger service.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager service.
   * @param \Drupal\Core\Form\FormBuilderInterface $form_builder
   *   The form builder service.
   * @param \Drupal\Core\Session\AccountInterface $current_user
   *   The current user.
   * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $private_temp_store
   *   The private temp store.
   */
  public function __construct(WebformSubmissionLogManager $webform_submission_log_manager, Connection $datababse, MessengerInterface $messenger, EntityTypeManagerInterface $entity_type_manager, FormBuilderInterface $form_builder) {
  public function __construct(WebformSubmissionLogManager $webform_submission_log_manager, Connection $datababse, MessengerInterface $messenger, EntityTypeManagerInterface $entity_type_manager, FormBuilderInterface $form_builder, AccountInterface $current_user, PrivateTempStoreFactory $private_temp_store) {
    $this->webform_submission_log_manager = $webform_submission_log_manager;
    $this->database = $datababse;
    $this->messenger = $messenger;
    $this->entity_type_manager = $entity_type_manager;
    $this->form_builder = $form_builder;
    $this->current_user = $current_user;
    $this->private_temp_store = $private_temp_store;
  }

  /**
@@ -142,14 +170,13 @@ class WebformNavigationHelper {
   *
   * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
   *   A webform submission entity.
   *
   * @param string|null $page
   *   Set to page name if you only want the data for a particular page.
   *
   * @return array
   *   An array of errors.
   */
  public function getErrors(WebformSubmissionInterface $webform_submission, $page = NULL) {
  public function getErrors(WebformSubmissionInterface $webform_submission, string $page = NULL) {
    // Get outta here if the submission hasn't been saved yet.
    if (empty($webform_submission->id())) {
      return [];
@@ -167,7 +194,12 @@ class WebformNavigationHelper {
    $query->range(0, 1);
    $submission_log = $query->execute()->fetch();
    $data = !empty($submission_log->data) ? unserialize($submission_log->data) : [];
    return (!empty($page) && !empty($data[$page])) ? $data[$page] : $data;
    // Return the data just for the page if it is requested.
    if (!empty($page)) {
      return !empty($data[$page]) ? $data[$page] : [];
    }
    // Return everything.
    return $data;
  }

  /**
@@ -196,9 +228,9 @@ class WebformNavigationHelper {
        'sid' => $webform_submission->id(),
        'operation' => self::PAGE_VISITED_OPERATION,
        'handler_id' => self::HANDLER_ID,
        'uid' => Drupal::currentUser()->id(),
        'uid' => $this->current_user->id(),
        'data' => $page,
        'timestamp' => (string) Drupal::time()->getRequestTime(),
        'timestamp' => (string) \Drupal::time()->getRequestTime(),
      ];
      $query = $this->database->insert(self::TABLE, $fields);
      $query->fields($fields)->execute();
@@ -214,8 +246,7 @@ class WebformNavigationHelper {
   * @throws \Exception
   */
  public function logStashedPageErrors(WebformSubmissionInterface $webform_submission) {
    /** @var \Drupal\Core\TempStore\PrivateTempStore $store */
    $store = Drupal::service('tempstore.private')->get('webformnavigation');
    $store = $this->private_temp_store->get('webformnavigation');
    $errors = $store->get(self::TEMP_STORE_KEY);
    // Get outta here if there are not any stashed errors.
    if (empty($errors)) {
@@ -243,7 +274,9 @@ class WebformNavigationHelper {
    $form_errors = $form_state->getErrors();
    $current_errors = $this->getErrors($webform_submission);
    $paged_errors = empty($current_errors) ? [] : $current_errors;
    $current_page = $webform_submission->getCurrentPage();
    $current_page = $this->getCurrentPage($webform_submission);
    // Let's not create too many logs.
    $this->deleteSubmissionLogs($webform_submission, TRUE);
    // Reset the current page's errors with those set in the form state.
    $paged_errors[$current_page] = [];
    foreach ($form_errors as $element => $error) {
@@ -252,6 +285,8 @@ class WebformNavigationHelper {
      // Place error on current page if the page is empty.
      if (!empty($page) && is_string($page)) {
        $paged_errors[$page][$element] = $error;
        // Log the page visit if needed.
        $this->logPageVisit($webform_submission, $current_page);
      }
      else {
        $paged_errors[$current_page][$element] = $error;
@@ -259,8 +294,7 @@ class WebformNavigationHelper {
    }
    // Stash the errors and return if the submission hasn't been created yet.
    if (empty($webform_submission->id())) {
      /** @var \Drupal\Core\TempStore\PrivateTempStore $store */
      $store = Drupal::service('tempstore.private')->get('webformnavigation');
      $store = $this->private_temp_store->get('webformnavigation');
      $store->set(self::TEMP_STORE_KEY, $paged_errors);
      return;
    }
@@ -288,9 +322,9 @@ class WebformNavigationHelper {
        'sid' => $webform_submission->id(),
        'operation' => self::ERROR_OPERATION,
        'handler_id' => self::HANDLER_ID,
        'uid' => Drupal::currentUser()->id(),
        'uid' => $this->current_user->id(),
        'data' => serialize($errors),
        'timestamp' => (string) Drupal::time()->getRequestTime(),
        'timestamp' => (string) \Drupal::time()->getRequestTime(),
      ];
      $this->database->insert(self::TABLE)->fields($fields)->execute();
    }
@@ -301,8 +335,10 @@ class WebformNavigationHelper {
   *
   * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
   *   A webform submission entity.
   * @param bool $keep_visited
   *   Set to TRUE if you would like to keep the page visited logs.
   */
  public function deleteSubmissionLogs(WebformSubmissionInterface $webform_submission) {
  public function deleteSubmissionLogs(WebformSubmissionInterface $webform_submission, bool $keep_visited = FALSE) {
    // Get outta here if the submission hasn't been saved yet.
    if (empty($webform_submission->id())) {
      return;
@@ -310,6 +346,9 @@ class WebformNavigationHelper {
    $query = $this->database->delete(self::TABLE);
    $query->condition('webform_id', $webform_submission->getWebform()->id());
    $query->condition('sid', $webform_submission->id());
    if ($keep_visited) {
      $query->condition('operation', self::PAGE_VISITED_OPERATION, '!=');
    }
    $query->execute();
  }

@@ -318,13 +357,13 @@ class WebformNavigationHelper {
   *
   * @param \Drupal\webform\WebformInterface $webform
   *   A webform entity.
   * @param $element
   *   A webform element.
   * @param string $element
   *   The element's key.
   *
   * @return mixed
   *   A page an element belongs to.
   */
  public function getElementPage(WebformInterface $webform, $element) {
  public function getElementPage(WebformInterface $webform, string $element) {
    $element = $webform->getElement($element);
    return !empty($element) && array_key_exists('#webform_parents', $element) ? $element['#webform_parents'][0] : NULL;
  }
@@ -336,66 +375,107 @@ class WebformNavigationHelper {
   *   A webform submission.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current form state.
   * @param array $form
   *   The current form.
   *
   * @throws \Drupal\Core\Entity\EntityStorageException
   * @throws \Exception
   */
  public function validateAllPages(WebformSubmissionInterface $webform_submission, FormStateInterface $form_state) {
  public function validateAllPages(WebformSubmissionInterface $webform_submission, FormStateInterface $form_state, array $form) {
    // Get outta here if we are already validating the form.
    if ($form_state->get('validating') == TRUE) {
      return;
    }
    // Validate and log pages we have yet to visit.
    $webform = $webform_submission->getWebform();
    foreach ($webform->getPages() as $key => $page) {
      // Log and validate all the pages.
      if ($key != 'webform_confirmation' && empty($page['#states'])) {
        // Lets make sure we don't create a validation loop.
    $form_state->set('validating', TRUE);
        // Stash existing error messages.
        $error_messages = $this->messenger->messagesByType(MessengerInterface::TYPE_ERROR);
        $this->validateSinglePage($webform_submission, $key);
        // Delete all form related error messages so we don't repeat ourselves.
        $this->messenger->deleteByType(MessengerInterface::TYPE_ERROR);
        // Restore existing error message.
        foreach ($error_messages as $error_message) {
          $this->messenger->addError($error_message);
    $errors = [];
    $current_page = $this->getCurrentPage($webform_submission);
    // Validate the submission.
    foreach ($webform_submission->getWebform()->getPages() as $page_name => $page) {
      if ($page_name != 'webform_confirmation' && $this->hasAccessToPage($page_name, $webform_submission)) {
        $form_state->set('current_page', $page_name);
        $this->logPageVisit($webform_submission, $page_name);
        $new_errors = $this->validateSubmission($webform_submission, $form, $form_state);
        if (!empty($new_errors)) {
          $errors = array_merge($errors, $new_errors);
        }
      }
    }
    // Reset the submission to it's original settings.

    // Set and log the errors.
    if (!empty($errors)) {
      foreach ($errors as $name => $error) {
        $form_state->setErrorByName($name, $error);
      }
      $this->logPageErrors($webform_submission, $form_state);
    }
    // Reset the form state to its original settings.
    $form_state->set('current_page', $current_page);
    $form_state->set('validating', FALSE);
  }

  /**
   * Validates a single page of a submission.
   * Validates a submission.
   *
   * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
   *   A webform submission.
   * @param string $page
   *   The machine name of the target page.
   * @param array $form
   *   The current form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current form state.
   *
   * @throws \Drupal\Core\Entity\EntityStorageException
   * @return array
   *   An array of errors.
   */
  private function validateSinglePage(WebformSubmissionInterface $webform_submission, string $page) {
    // Stash the current page.
    $current_page = $webform_submission->getCurrentPage();
    // Let's ensure we are on the page that needs to be validated.
    $webform_submission->setCurrentPage($page)->save();
    // Build a new form for this submission.
  private function validateSubmission(WebformSubmissionInterface $webform_submission, array $form, FormStateInterface $form_state) {
    /** @var \Drupal\webform\WebformSubmissionForm $form_object */
    $form_object = $this->entity_type_manager->getFormObject('webform_submission', 'api');
    $form_object = $this->entity_type_manager->getFormObject('webform_submission', 'edit');
    $form_object->copyFormValuesToEntity($webform_submission, $form, $form_state);
    $form_object->setEntity($webform_submission);

    // Create an empty form state which will be populated when the submission
    // form is submitted.
    $new_form_state = new FormState();
    // Lets make sure we don't create a validation loop.
    $new_form_state->set('validating', TRUE);

    // Set the triggering element to an empty element to prevent
    // errors from managed files.
    // @see \Drupal\file\Element\ManagedFile::validateManagedFile
    $new_form_state->setTriggeringElement(['#parents' => []]);

    // Get existing error messages.
    $error_messages = $this->messenger->messagesByType(MessengerInterface::TYPE_ERROR);

    // Submit the form.
    $this->form_builder->submitForm($form_object, $new_form_state);
    $this->logPageVisit($webform_submission, $page);
    $this->logPageErrors($webform_submission, $new_form_state);
    // Return to the original page.
    $webform_submission->setCurrentPage($current_page);

    // Get the errors.
    $errors = $new_form_state->getErrors();

    // Delete all form related error messages.
    $this->messenger->deleteByType(MessengerInterface::TYPE_ERROR);

    // Restore existing error message.
    foreach ($error_messages as $error_message) {
      $this->messenger->addError($error_message);
    }

    // Return the errors.
    return $errors ?? [];
  }

  /**
   * Checks to see if the current page is available.
   *
   * @param string $page
   *   The page in question.
   * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
   *   The webform submission in question.
   *
   * @return bool
   *   True if the page is available.
   */
  public function hasAccessToPage(string $page, WebformSubmissionInterface $webform_submission) {
    $webform = $webform_submission->getWebform();
    $pages = $webform->getPages('edit', $webform_submission);
    return in_array($page, array_keys($pages));
  }

}
+3 −67
Original line number Diff line number Diff line
@@ -141,13 +141,13 @@ function webformnavigation_webform_third_party_settings_form_alter(&$form, FormS
    '#type' => 'webform_message',
    '#message_type' => 'warning',
    '#message_message' => t('You must enable the Webform Navigation submission handler under the <a href=":href">Emails / Handlers tab</a> for forward navigation to work.', [
      ':href' => $webform->toUrl('handlers')->toString()
      ':href' => $webform->toUrl('handlers')->toString(),
    ]),
    '#states' => [
      'visible' => [
        [':input[name="third_party_settings[webformnavigation][forward_navigation]"]' => ['checked' => TRUE]],
      ],
    ]
    ],
  ];
  $form['third_party_settings']['webformnavigation']['forward_navigation'] = [
    '#type' => 'checkbox',
@@ -173,71 +173,6 @@ function webformnavigation_webform_third_party_settings_form_alter(&$form, FormS
  ];
}

/**
 * Implements hook_webform_submission_form_alter().
 */
function webformnavigation_webform_submission_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
  /** @var \Drupal\webform\WebformSubmissionInterface $webform_submission */
  $webform_submission = $form_state->getFormObject()->getEntity();
  $webform = $webform_submission->getWebform();
  // Get navigation webform settings.
  $prevent_next_validation = $webform->getThirdPartySetting('webformnavigation', 'prevent_next_validation');

  // Actions to perform if prevent_next_validation is set.
  if ($prevent_next_validation && isset($form['actions']['wizard_next'])) {
    $form['actions']['wizard_next']['#validate'][] = '::noValidate';
  }
}

/**
 * Programmatically validate a webform submission.
 *
 * @param array $form
 *   An associative array containing the structure of the form.
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 *   The current state of the form.
 *
 * @throws \Exception
 */
function webformnavigation_submission_validation(array &$form, FormStateInterface $form_state) {
  /** @var \Drupal\webformnavigation\WebformNavigationHelper $webformnavigation_helper */
  $webformnavigation_helper = Drupal::service('webformnavigation.helper');
  /** @var \Drupal\webform\WebformSubmissionInterface $webform_submission */
  $webform_submission = $form_state->getFormObject()->getEntity();
  $webform = $webform_submission->getWebform();
  $has_errors = FALSE;
  // Ensure each page has been validated.
  $webformnavigation_helper->validateAllPages($webform_submission, $form_state);
  // Log the form errors.
  $webformnavigation_helper->logPageErrors($webform_submission, $form_state);
  // Clear errors and place the submission errors above them.
  $form_state->clearErrors();
  // Validate our submission values.
  $logged_errors = $webformnavigation_helper->getErrors($webform_submission);
  // Set form errors if the values are in-valid.
  foreach ($webform_submission->getWebform()->getPages('edit', $webform_submission) as $page_key => $page) {
    $page_errors = !empty($logged_errors[$page_key]) ? $logged_errors[$page_key] : [];
    if (!empty($page_errors)) {
      $has_errors = TRUE;
      // Set an error on the page to create separation in the error message.
      $page_message = t('<p class="webformnavigation-page-title"><strong>@title Page</strong></p>', ['@title' => $page['#title']]);
      $form_state->setErrorByName($page_key, $page_message);
      // Parse through the errors and set a form error for each.
      foreach ($page_errors as $field => $error) {
        $message = t('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;• @message', ['@message' => $error]);
        $form_state->setErrorByName($field, $message);
      }
    }
  }
  // Add additional error message if defined in the settings.
  if ($has_errors && !empty($webform->getThirdPartySetting('webformnavigation', 'additional_error_message'))) {
    $keys = array_keys($webform->getElementsInitializedAndFlattened());
    $additional_error_message = $webform->getThirdPartySetting('webformnavigation', 'additional_error_message');
    $message = t('<br><p class="webformnavigation-additional-message">@message</p>', ['@message' => $additional_error_message]);
    $form_state->setErrorByName($keys[1], $message);
  }
}

/**
 * Implements hook_entity_update().
 */
@@ -253,6 +188,7 @@ function webformnavigation_webform_presave(WebformInterface $webform) {
        case WebformSubmissionStorageInterface::PURGE_COMPLETED:
          $purge = WebformSubmissionStorageInterface::PURGE_ALL;
          break;

        default:
          $purge = WebformSubmissionStorageInterface::PURGE_DRAFT;
          break;
+1 −1
Original line number Diff line number Diff line
services:
  webformnavigation.helper:
    class: \Drupal\webformnavigation\WebformNavigationHelper
    arguments: ['@webform_submission_log.manager', '@database', '@messenger', '@entity_type.manager', '@form_builder']
    arguments: ['@webform_submission_log.manager', '@database', '@messenger', '@entity_type.manager', '@form_builder', '@current_user', '@tempstore.private']