You are here

public function RedirectForm::validateForm in Redirect 8

Button-level validation handlers are highly discouraged for entity forms, as they will prevent entity validation from running. If the entity is going to be saved during the form submission, this method should be manually invoked from the button-level validation handler, otherwise an exception will be thrown.

Overrides ContentEntityForm::validateForm

File

src/Form/RedirectForm.php, line 93

Class

RedirectForm

Namespace

Drupal\redirect\Form

Code

public function validateForm(array &$form, FormStateInterface $form_state) {
  parent::validateForm($form, $form_state);
  $source = $form_state
    ->getValue([
    'redirect_source',
    0,
  ]);

  // Trim any trailing spaces from source url, leaving leading space as is.
  // leading space is still a valid candidate to add for 301 source url.
  $source['path'] = rtrim($source['path']);
  $form_state
    ->setValue('redirect_source', [
    $source,
  ]);
  $redirect = $form_state
    ->getValue([
    'redirect_redirect',
    0,
  ]);
  if ($source['path'] == '<front>') {
    $form_state
      ->setErrorByName('redirect_source', $this
      ->t('It is not allowed to create a redirect from the front page.'));
  }
  if (strpos($source['path'], '#') !== FALSE) {
    $form_state
      ->setErrorByName('redirect_source', $this
      ->t('The anchor fragments are not allowed.'));
  }
  if (strpos($source['path'], '/') === 0) {
    $form_state
      ->setErrorByName('redirect_source', $this
      ->t('The url to redirect from should not start with a forward slash (/).'));
  }
  try {
    $source_url = Url::fromUri('internal:/' . $source['path']);
    $redirect_url = Url::fromUri($redirect['uri']);

    // It is relevant to do this comparison only in case the source path has
    // a valid route. Otherwise the validation will fail on the redirect path
    // being an invalid route.
    if ($source_url
      ->toString() == $redirect_url
      ->toString()) {
      $form_state
        ->setErrorByName('redirect_redirect', $this
        ->t('You are attempting to redirect the page to itself. This will result in an infinite loop.'));
    }
  } catch (\InvalidArgumentException $e) {

    // Do nothing, we want to only compare the resulting URLs.
  }
  $parsed_url = UrlHelper::parse(trim($source['path']));
  $path = isset($parsed_url['path']) ? $parsed_url['path'] : NULL;
  $query = isset($parsed_url['query']) ? $parsed_url['query'] : NULL;
  $hash = Redirect::generateHash($path, $query, $form_state
    ->getValue('language')[0]['value']);

  // Search for duplicate.
  $redirects = \Drupal::entityTypeManager()
    ->getStorage('redirect')
    ->loadByProperties([
    'hash' => $hash,
  ]);
  if (!empty($redirects)) {
    $redirect = array_shift($redirects);
    if ($this->entity
      ->isNew() || $redirect
      ->id() != $this->entity
      ->id()) {
      $form_state
        ->setErrorByName('redirect_source', $this
        ->t('The source path %source is already being redirected. Do you want to <a href="@edit-page">edit the existing redirect</a>?', [
        '%source' => $source['path'],
        '@edit-page' => $redirect
          ->toUrl('edit-form')
          ->toString(),
      ]));
    }
  }
}