/** * Tests the Drupal 6 path redirect to Drupal 8 migration. */ public function testPathRedirect() { /** @var Redirect $redirect */ $redirect = Redirect::load(5); $this->assertSame($this->getMigration('d6_path_redirect')->getIdMap()->lookupDestinationID(array(5)), array($redirect->id())); $this->assertSame("/test/source/url", $redirect->getSourceUrl()); $this->assertSame("base:test/redirect/url", $redirect->getRedirectUrl()->toUriString()); $redirect = Redirect::load(7); $this->assertSame("/test/source/url2", $redirect->getSourceUrl()); $this->assertSame("http://test/external/redirect/url?foo=bar&biz=buz", $redirect->getRedirectUrl()->toUriString()); }
/** * {@inheritdoc} */ public function preSave(EntityStorageInterface $storage_controller) { $this->set('hash', Redirect::generateHash($this->redirect_source->path, (array) $this->redirect_source->query, $this->language()->getId())); }
/** * Test redirect entity logic. */ public function testRedirectEntity() { // Create a redirect and test if hash has been generated correctly. /** @var \Drupal\redirect\Entity\Redirect $redirect */ $redirect = $this->controller->create(); $redirect->setSource('some-url', array('key' => 'val')); $redirect->setRedirect('node'); $redirect->save(); $this->assertEqual(Redirect::generateHash('some-url', array('key' => 'val'), Language::LANGCODE_NOT_SPECIFIED), $redirect->getHash()); // Update the redirect source query and check if hash has been updated as // expected. $redirect->setSource('some-url', array('key1' => 'val1')); $redirect->save(); $this->assertEqual(Redirect::generateHash('some-url', array('key1' => 'val1'), Language::LANGCODE_NOT_SPECIFIED), $redirect->getHash()); // Update the redirect source path and check if hash has been updated as // expected. $redirect->setSource('another-url', array('key1' => 'val1')); $redirect->save(); $this->assertEqual(Redirect::generateHash('another-url', array('key1' => 'val1'), Language::LANGCODE_NOT_SPECIFIED), $redirect->getHash()); // Update the redirect language and check if hash has been updated as // expected. $redirect->setLanguage('de'); $redirect->save(); $this->assertEqual(Redirect::generateHash('another-url', array('key1' => 'val1'), 'de'), $redirect->getHash()); // Create a few more redirects to test the select. for ($i = 0; $i < 5; $i++) { $redirect = $this->controller->create(); $redirect->setSource($this->randomMachineName()); $redirect->save(); } /** @var \Drupal\redirect\RedirectRepository $repository */ $repository = \Drupal::service('redirect.repository'); $redirect = $repository->findMatchingRedirect('another-url', array('key1' => 'val1'), 'de'); if (!empty($redirect)) { $this->assertEqual($redirect->getSourceUrl(), '/another-url?key1=val1'); } else { $this->fail(t('Failed to find matching redirect.')); } // Load the redirect based on url. $redirects = $repository->findBySourcePath('another-url'); $redirect = array_shift($redirects); if (!empty($redirect)) { $this->assertEqual($redirect->getSourceUrl(), '/another-url?key1=val1'); } else { $this->fail(t('Failed to find redirect by source path.')); } // Test passthrough_querystring. $redirect = $this->controller->create(); $redirect->setSource('a-different-url'); $redirect->setRedirect('node'); $redirect->save(); $redirect = $repository->findMatchingRedirect('a-different-url', ['key1' => 'val1'], 'de'); if (!empty($redirect)) { $this->assertEqual($redirect->getSourceUrl(), '/a-different-url'); } else { $this->fail('Failed to find redirect by source path with query string.'); } // Add another redirect to the same path, with a query. This should always // be found before the source without a query set. /** @var \Drupal\redirect\Entity\Redirect $new_redirect */ $new_redirect = $this->controller->create(); $new_redirect->setSource('a-different-url', ['foo' => 'bar']); $new_redirect->setRedirect('node'); $new_redirect->save(); $found = $repository->findMatchingRedirect('a-different-url', ['foo' => 'bar'], 'de'); if (!empty($found)) { $this->assertEqual($found->getSourceUrl(), '/a-different-url?foo=bar'); } else { $this->fail('Failed to find a redirect by source path with query string.'); } // Hashes should be case-insensitive since the source paths are. /** @var \Drupal\redirect\Entity\Redirect $redirect */ $redirect = $this->controller->create(); $redirect->setSource('Case-Sensitive-Path'); $redirect->setRedirect('node'); $redirect->save(); $found = $repository->findBySourcePath('case-sensitive-path'); if (!empty($found)) { $found = reset($found); $this->assertEqual($found->getSourceUrl(), '/Case-Sensitive-Path'); } else { $this->fail('findBySourcePath is case sensitive'); } $found = $repository->findMatchingRedirect('case-sensitive-path'); if (!empty($found)) { $this->assertEqual($found->getSourceUrl(), '/Case-Sensitive-Path'); } else { $this->fail('findMatchingRedirect is case sensitive.'); } }
/** * {@inheritdoc} */ public function validateForm(array &$form, FormStateInterface $form_state) { parent::validateForm($form, $form_state); $source = $form_state->getValue(array('redirect_source', 0)); $redirect = $form_state->getValue(array('redirect_redirect', 0)); if ($source['path'] == '<front>') { $form_state->setErrorByName('redirect_source', t('It is not allowed to create a redirect from the front page.')); } if (strpos($source['path'], '#') !== FALSE) { $form_state->setErrorByName('redirect_source', t('The anchor fragments are not allowed.')); } if (strpos($source['path'], '/') === 0) { $form_state->setErrorByName('redirect_source', 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', 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::entityManager()->getStorage('redirect')->loadByProperties(array('hash' => $hash)); if (!empty($redirects)) { $redirect = array_shift($redirects); if ($this->entity->isNew() || $redirect->id() != $this->entity->id()) { $form_state->setErrorByName('redirect_source', t('The source path %source is already being redirected. Do you want to <a href="@edit-page">edit the existing redirect</a>?', array('%source' => $source['path'], '@edit-page' => $redirect->url('edit-form')))); } } }
/** * Helper function to find recursive redirects. * * @param \Drupal\redirect\Entity\Redirect * The redirect object. * @param string $language * The language to use. */ protected function findByRedirect(Redirect $redirect, $language) { $uri = $redirect->getRedirectUrl(); $baseUrl = \Drupal::request()->getBaseUrl(); $path = ltrim(substr($uri->toString(), strlen($baseUrl)), '/'); $query = $uri->getOption('query') ?: []; return $this->findMatchingRedirect($path, $query, $language); }