예제 #1
0
 /**
  * Gets a redirect for given path, query and language.
  *
  * @param string $source_path
  *   The redirect source path.
  * @param array $query
  *   The redirect source path query.
  * @param $language
  *   The language for which is the redirect.
  *
  * @return \Drupal\redirect\Entity\Redirect
  *   The matched redirect entity.
  *
  * @throws \Drupal\redirect\Exception\RedirectLoopException
  */
 public function findMatchingRedirect($source_path, array $query = [], $language = Language::LANGCODE_NOT_SPECIFIED)
 {
     $hashes = [Redirect::generateHash($source_path, $query, $language)];
     if ($language != Language::LANGCODE_NOT_SPECIFIED) {
         $hashes[] = Redirect::generateHash($source_path, $query, Language::LANGCODE_NOT_SPECIFIED);
     }
     // Add a hash without the query string if using passthrough querystrings.
     if (!empty($query) && $this->config->get('passthrough_querystring')) {
         $hashes[] = Redirect::generateHash($source_path, [], $language);
         if ($language != Language::LANGCODE_NOT_SPECIFIED) {
             $hashes[] = Redirect::generateHash($source_path, [], Language::LANGCODE_NOT_SPECIFIED);
         }
     }
     // Load redirects by hash. A direct query is used to improve performance.
     $rid = $this->connection->query('SELECT rid FROM {redirect} WHERE hash IN (:hashes[]) ORDER BY LENGTH(redirect_source__query) DESC', [':hashes[]' => $hashes])->fetchField();
     if (!empty($rid)) {
         // Check if this is a loop.
         if (in_array($rid, $this->foundRedirects)) {
             throw new RedirectLoopException('/' . $source_path, $rid);
         }
         $this->foundRedirects[] = $rid;
         $redirect = $this->load($rid);
         // Find chained redirects.
         if ($recursive = $this->findByRedirect($redirect, $language)) {
             // Reset found redirects.
             $this->foundRedirects = [];
             return $recursive;
         }
         return $redirect;
     }
     return NULL;
 }
예제 #2
0
파일: Redirect.php 프로젝트: omero/camp-gdl
 /**
  * {@inheritdoc}
  */
 public function preSave(EntityStorageInterface $storage_controller)
 {
     $this->set('hash', Redirect::generateHash($this->redirect_source->path, (array) $this->redirect_source->query, $this->language()->getId()));
 }
예제 #3
0
 /**
  * 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.');
     }
 }
예제 #4
0
 /**
  * {@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'))));
         }
     }
 }