Updated all the contrib modules to their latest versions.
[yaffs-website] / web / modules / contrib / redirect / src / RedirectRepository.php
1 <?php
2
3 namespace Drupal\redirect;
4
5 use Drupal\Core\Config\ConfigFactoryInterface;
6 use Drupal\Core\Database\Connection;
7 use Drupal\Core\Entity\EntityManagerInterface;
8 use Drupal\Core\Language\Language;
9 use Drupal\redirect\Entity\Redirect;
10 use Drupal\redirect\Exception\RedirectLoopException;
11
12 class RedirectRepository {
13
14   /**
15    * @var \Drupal\Core\Entity\EntityManagerInterface
16    */
17   protected $manager;
18
19   /**
20    * @var \Drupal\Core\Database\Connection
21    */
22   protected $connection;
23
24   /**
25    * @var \Drupal\Core\Config\ImmutableConfig
26    */
27   protected $config;
28
29   /**
30    * An array of found redirect IDs to avoid recursion.
31    *
32    * @var array
33    */
34   protected $foundRedirects = [];
35
36   /**
37    * Constructs a \Drupal\redirect\EventSubscriber\RedirectRequestSubscriber object.
38    *
39    * @param \Drupal\Core\Entity\EntityManagerInterface $manager
40    *   The entity manager service.
41    * @param \Drupal\Core\Database\Connection $connection
42    *   The database connection.
43    */
44   public function __construct(EntityManagerInterface $manager, Connection $connection, ConfigFactoryInterface $config_factory) {
45     $this->manager = $manager;
46     $this->connection = $connection;
47     $this->config = $config_factory->get('redirect.settings');
48   }
49
50   /**
51    * Gets a redirect for given path, query and language.
52    *
53    * @param string $source_path
54    *   The redirect source path.
55    * @param array $query
56    *   The redirect source path query.
57    * @param $language
58    *   The language for which is the redirect.
59    *
60    * @return \Drupal\redirect\Entity\Redirect
61    *   The matched redirect entity.
62    *
63    * @throws \Drupal\redirect\Exception\RedirectLoopException
64    */
65   public function findMatchingRedirect($source_path, array $query = [], $language = Language::LANGCODE_NOT_SPECIFIED) {
66     $source_path = ltrim($source_path, '/');
67     $hashes = [Redirect::generateHash($source_path, $query, $language)];
68     if ($language != Language::LANGCODE_NOT_SPECIFIED) {
69       $hashes[] = Redirect::generateHash($source_path, $query, Language::LANGCODE_NOT_SPECIFIED);
70     }
71
72     // Add a hash without the query string if using passthrough querystrings.
73     if (!empty($query) && $this->config->get('passthrough_querystring')) {
74       $hashes[] = Redirect::generateHash($source_path, [], $language);
75       if ($language != Language::LANGCODE_NOT_SPECIFIED) {
76         $hashes[] = Redirect::generateHash($source_path, [], Language::LANGCODE_NOT_SPECIFIED);
77       }
78     }
79
80     // Load redirects by hash. A direct query is used to improve performance.
81     $rid = $this->connection->query('SELECT rid FROM {redirect} WHERE hash IN (:hashes[]) ORDER BY LENGTH(redirect_source__query) DESC', [':hashes[]' => $hashes])->fetchField();
82
83     if (!empty($rid)) {
84       // Check if this is a loop.
85       if (in_array($rid, $this->foundRedirects)) {
86         throw new RedirectLoopException('/' . $source_path, $rid);
87       }
88       $this->foundRedirects[] = $rid;
89
90       $redirect = $this->load($rid);
91
92       // Find chained redirects.
93       if ($recursive = $this->findByRedirect($redirect, $language)) {
94         // Reset found redirects.
95         $this->foundRedirects = [];
96         return $recursive;
97       }
98
99       return $redirect;
100     }
101
102     return NULL;
103   }
104
105   /**
106    * Helper function to find recursive redirects.
107    *
108    * @param \Drupal\redirect\Entity\Redirect
109    *   The redirect object.
110    * @param string $language
111    *   The language to use.
112    */
113   protected function findByRedirect(Redirect $redirect, $language) {
114     $uri = $redirect->getRedirectUrl();
115     $base_url = \Drupal::request()->getBaseUrl();
116     $generated_url = $uri->toString(TRUE);
117     $path = ltrim(substr($generated_url->getGeneratedUrl(), strlen($base_url)), '/');
118     $query = $uri->getOption('query') ?: [];
119     $return_value = $this->findMatchingRedirect($path, $query, $language);
120     return $return_value ? $return_value->addCacheableDependency($generated_url) : $return_value;
121   }
122
123   /**
124    * Finds redirects based on the source path.
125    *
126    * @param string $source_path
127    *   The redirect source path (without the query).
128    *
129    * @return \Drupal\redirect\Entity\Redirect[]
130    *   Array of redirect entities.
131    */
132   public function findBySourcePath($source_path) {
133     $ids = $this->manager->getStorage('redirect')->getQuery()
134       ->condition('redirect_source.path', $source_path, 'LIKE')
135       ->execute();
136     return $this->manager->getStorage('redirect')->loadMultiple($ids);
137   }
138
139   /**
140    * Finds redirects based on the destination URI.
141    *
142    * @param string[] $destination_uri
143    *   List of destination URIs, for example ['internal:/node/123'].
144    *
145    * @return \Drupal\redirect\Entity\Redirect[]
146    *   Array of redirect entities.
147    */
148   public function findByDestinationUri(array $destination_uri) {
149     $storage = $this->manager->getStorage('redirect');
150     $ids = $storage->getQuery()
151       ->condition('redirect_redirect.uri', $destination_uri, 'IN')
152       ->execute();
153     return $storage->loadMultiple($ids);
154   }
155
156   /**
157    * Load redirect entity by id.
158    *
159    * @param int $redirect_id
160    *   The redirect id.
161    *
162    * @return \Drupal\redirect\Entity\Redirect
163    */
164   public function load($redirect_id) {
165     return $this->manager->getStorage('redirect')->load($redirect_id);
166   }
167
168   /**
169    * Loads multiple redirect entities.
170    *
171    * @param array $redirect_ids
172    *   Redirect ids to load.
173    *
174    * @return \Drupal\redirect\Entity\Redirect[]
175    *   List of redirect entities.
176    */
177   public function loadMultiple(array $redirect_ids = NULL) {
178     return $this->manager->getStorage('redirect')->loadMultiple($redirect_ids);
179   }
180 }