diff --git a/redirect.module b/redirect.module index 18e61cf..b379b3e 100644 --- a/redirect.module +++ b/redirect.module @@ -263,13 +263,6 @@ function locale_form_redirect_edit_form_alter(array &$form, FormStateInterface $ ]; } -/** - * Ajax callback for the redirect link widget. - */ -function redirect_source_link_get_status_messages(array $form, FormStateInterface $form_state) { - return $form['redirect_source']['widget'][0]['status_box']; -} - /** * Implements hook_entity_extra_field_info(). */ diff --git a/src/Form/RedirectForm.php b/src/Form/RedirectForm.php index 23fd3ad..cd208ca 100644 --- a/src/Form/RedirectForm.php +++ b/src/Form/RedirectForm.php @@ -10,6 +10,8 @@ use Drupal\Core\Routing\MatchingRouteNotFoundException; use Drupal\Core\Url; use Drupal\redirect\Entity\Redirect; use Drupal\Core\Form\FormStateInterface; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; +use Symfony\Component\Routing\Exception\ResourceNotFoundException; class RedirectForm extends ContentEntityForm { @@ -143,6 +145,32 @@ class RedirectForm extends ContentEntityForm { '@edit-page' => $redirect->toUrl('edit-form')->toString()])); } } + + // If creating a new Redirect and the source path is an existing path, recommend an alias instead. + if ($this->entity->isNew() && $source['path'] && !($form_state->getStorage()['redirect_source_warning'] ?? NULL) && !$form_state->hasAnyErrors()) { + $source_path = trim($source['path']); + + // Warning about creating a redirect from a valid path. + // + // @todo Exception driven logic. Find a better way to determine if we have a valid path. + try { + \Drupal::service('router')->match('/' . $form_state->getValue(['redirect_source', 0, 'path'])); + $storage = $form_state->getStorage(); + $storage['redirect_source_warning'] = TRUE; + $form_state->setStorage($storage); + $form_state->setRebuild(); + $this->messenger()->addWarning($this->t('The source path %path appears to be a valid path. It is preferred to create URL aliases for existing paths rather than redirects.', [ + '%path' => $source_path, + '@url-alias' => Url::fromRoute('entity.path_alias.add_form')->toString(), + ])); + } + catch (ResourceNotFoundException $e) { + // Do nothing, expected behaviour. + } + catch (AccessDeniedHttpException $e) { + // Do nothing, expected behaviour. + } + } } /** diff --git a/src/Plugin/Field/FieldWidget/RedirectSourceWidget.php b/src/Plugin/Field/FieldWidget/RedirectSourceWidget.php index a07f218..5a0c533 100644 --- a/src/Plugin/Field/FieldWidget/RedirectSourceWidget.php +++ b/src/Plugin/Field/FieldWidget/RedirectSourceWidget.php @@ -50,52 +50,6 @@ class RedirectSourceWidget extends WidgetBase { '#attributes' => ['data-disable-refocus' => 'true'], ]; - // If creating new URL add checks. - if ($items->getEntity()->isNew()) { - $element['status_box'] = [ - '#prefix' => '', - ]; - - $source_path = $form_state->getValue(['redirect_source', 0, 'path']); - if ($source_path) { - $source_path = trim($source_path); - - // Warning about creating a redirect from a valid path. - // @todo - Hmm... exception driven logic. Find a better way how to - // determine if we have a valid path. - try { - \Drupal::service('router')->match('/' . $form_state->getValue(['redirect_source', 0, 'path'])); - $element['status_box'][]['#markup'] = '
' . $this->t('The source path %path is likely a valid path. It is preferred to create URL aliases for existing paths rather than redirects.', - ['%path' => $source_path, '@url-alias' => Url::fromRoute('entity.path_alias.add_form')->toString()]) . '
'; - } - catch (ResourceNotFoundException $e) { - // Do nothing, expected behaviour. - } - catch (AccessDeniedHttpException $e) { - // @todo Source lookup results in an access denied, deny access? - } - - // Warning about the path being already redirected. - $parsed_url = UrlHelper::parse($source_path); - $path = isset($parsed_url['path']) ? $parsed_url['path'] : NULL; - if (!empty($path)) { - /** @var \Drupal\redirect\RedirectRepository $repository */ - $repository = \Drupal::service('redirect.repository'); - $redirects = $repository->findBySourcePath($path); - if (!empty($redirects)) { - $redirect = array_shift($redirects); - $element['status_box'][]['#markup'] = '
' . $this->t('The base source path %source is already being redirected. Do you want to edit the existing redirect?', ['%source' => $source_path, '@edit-page' => $redirect->toUrl('edit-form')->toString()]) . '
'; - } - } - } - - $element['path']['#ajax'] = [ - 'callback' => 'redirect_source_link_get_status_messages', - 'wrapper' => 'redirect-link-status', - ]; - } - return $element; } diff --git a/tests/src/FunctionalJavascript/RedirectJavascriptTest.php b/tests/src/FunctionalJavascript/RedirectJavascriptTest.php index 83ee44d..2170954 100644 --- a/tests/src/FunctionalJavascript/RedirectJavascriptTest.php +++ b/tests/src/FunctionalJavascript/RedirectJavascriptTest.php @@ -125,32 +125,29 @@ class RedirectJavascriptTest extends WebDriverTestBase { $redirect = array_shift($redirects); $this->assertEquals(Url::fromUri('base:non-existing', ['query' => ['key' => 'value']])->toString(), $redirect->getSourceUrl()); - // Test the source url hints. - // The hint about an existing base path. - $this->drupalGet('admin/config/search/redirect/add'); - $page->fillField('redirect_source[0][path]', 'non-existing?key=value'); - $page->fillField('redirect_redirect[0][uri]', ''); - $this->assertSession()->assertWaitOnAjaxRequest(); - $this->assertSession()->responseContains( - 'The base source path non-existing?key=value is already being redirected. Do you want to edit the existing redirect?' - ); - + // Test validation. // The hint about a valid path. $this->drupalGet('admin/config/search/redirect/add'); - $page->fillField('redirect_source[0][path]', 'node'); - $page->fillField('redirect_redirect[0][uri]', ''); - $this->assertSession()->assertWaitOnAjaxRequest(); + $this->submitForm([ + 'redirect_source[0][path]' => 'node', + 'redirect_redirect[0][uri]' => '', + ], 'Save'); $this->assertSession()->responseContains( - 'The source path node is likely a valid path. It is preferred to create URL aliases for existing paths rather than redirects.' + 'The source path node appears to be a valid path. It is preferred to create URL aliases for existing paths rather than redirects.', ); - // Test validation. + // This warning should only happen once. + $page->pressButton('Save'); + $this->assertSession()->pageTextContains('The redirect has been saved.'); + // Delete the redirect that was just created. + $nodeRedirect = $this->repository->findMatchingRedirect('node'); + $nodeRedirect->delete(); + // Duplicate redirect. $this->drupalGet('admin/config/search/redirect/add'); $page = $this->getSession()->getPage(); $page->fillField('redirect_source[0][path]', 'non-existing?key=value'); $page->fillField('redirect_redirect[0][uri]', '/node'); - $this->assertSession()->assertWaitOnAjaxRequest(); $page->pressButton('Save'); $this->assertSession()->responseContains( 'The source path non-existing?key=value is already being redirected. Do you want to edit the existing redirect?'