Version 1
[yaffs-website] / web / modules / contrib / redirect / src / RedirectRepository.php
diff --git a/web/modules/contrib/redirect/src/RedirectRepository.php b/web/modules/contrib/redirect/src/RedirectRepository.php
new file mode 100644 (file)
index 0000000..6c79199
--- /dev/null
@@ -0,0 +1,160 @@
+<?php
+
+namespace Drupal\redirect;
+
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Database\Connection;
+use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Language\Language;
+use Drupal\redirect\Entity\Redirect;
+use Drupal\redirect\Exception\RedirectLoopException;
+
+class RedirectRepository {
+
+  /**
+   * @var \Drupal\Core\Entity\EntityManagerInterface
+   */
+  protected $manager;
+
+  /**
+   * @var \Drupal\Core\Database\Connection
+   */
+  protected $connection;
+
+  /**
+   * @var \Drupal\Core\Config\ImmutableConfig
+   */
+  protected $config;
+
+  /**
+   * An array of found redirect IDs to avoid recursion.
+   *
+   * @var array
+   */
+  protected $foundRedirects = [];
+
+  /**
+   * Constructs a \Drupal\redirect\EventSubscriber\RedirectRequestSubscriber object.
+   *
+   * @param \Drupal\Core\Entity\EntityManagerInterface $manager
+   *   The entity manager service.
+   * @param \Drupal\Core\Database\Connection $connection
+   *   The database connection.
+   */
+  public function __construct(EntityManagerInterface $manager, Connection $connection, ConfigFactoryInterface $config_factory) {
+    $this->manager = $manager;
+    $this->connection = $connection;
+    $this->config = $config_factory->get('redirect.settings');
+  }
+
+  /**
+   * 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;
+  }
+
+  /**
+   * 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);
+  }
+
+  /**
+   * Finds redirects based on the source path.
+   *
+   * @param string $source_path
+   *   The redirect source path (without the query).
+   *
+   * @return \Drupal\redirect\Entity\Redirect[]
+   *   Array of redirect entities.
+   */
+  public function findBySourcePath($source_path) {
+    $ids = $this->manager->getStorage('redirect')->getQuery()
+      ->condition('redirect_source.path', $source_path, 'LIKE')
+      ->execute();
+    return $this->manager->getStorage('redirect')->loadMultiple($ids);
+  }
+
+  /**
+   * Load redirect entity by id.
+   *
+   * @param int $redirect_id
+   *   The redirect id.
+   *
+   * @return \Drupal\redirect\Entity\Redirect
+   */
+  public function load($redirect_id) {
+    return $this->manager->getStorage('redirect')->load($redirect_id);
+  }
+
+  /**
+   * Loads multiple redirect entities.
+   *
+   * @param array $redirect_ids
+   *   Redirect ids to load.
+   *
+   * @return \Drupal\redirect\Entity\Redirect[]
+   *   List of redirect entities.
+   */
+  public function loadMultiple(array $redirect_ids = NULL) {
+    return $this->manager->getStorage('redirect')->loadMultiple($redirect_ids);
+  }
+}