Updated all the contrib modules to their latest versions.
[yaffs-website] / web / modules / contrib / pathauto / src / AliasUniquifier.php
1 <?php
2
3 namespace Drupal\pathauto;
4
5 use Drupal\Component\Utility\Unicode;
6 use Drupal\Core\Config\ConfigFactoryInterface;
7 use Drupal\Core\Extension\ModuleHandlerInterface;
8 use Drupal\Core\Language\LanguageInterface;
9 use Drupal\Core\Path\AliasManagerInterface;
10 use Drupal\Core\Routing\RouteProviderInterface;
11
12 /**
13  * Provides a utility for creating a unique path alias.
14  */
15 class AliasUniquifier implements AliasUniquifierInterface {
16
17   /**
18    * Config factory.
19    *
20    * @var \Drupal\Core\Config\ConfigFactoryInterface
21    */
22   protected $configFactory;
23
24   /**
25    * The alias storage helper.
26    *
27    * @var \Drupal\pathauto\AliasStorageHelperInterface
28    */
29   protected $aliasStorageHelper;
30
31   /**
32    * The module handler.
33    *
34    * @var \Drupal\Core\Extension\ModuleHandlerInterface
35    */
36   protected $moduleHandler;
37
38   /**
39    * The route provider service.
40    *
41    * @var \Drupal\Core\Routing\RouteProviderInterface
42    */
43   protected $routeProvider;
44
45   /**
46    * The alias manager.
47    *
48    * @var \Drupal\Core\Path\AliasManagerInterface
49    */
50   protected $aliasManager;
51
52   /**
53    * Creates a new AliasUniquifier.
54    *
55    * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
56    *   The config factory.
57    * @param \Drupal\pathauto\AliasStorageHelperInterface $alias_storage_helper
58    *   The alias storage helper.
59    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
60    *   The module handler.
61    * @param \Drupal\Core\Routing\RouteProviderInterface $route_provider
62    *   The route provider service.
63    * @param \Drupal\Core\Path\AliasManagerInterface $alias_manager
64    *   The alias manager.
65    */
66   public function __construct(ConfigFactoryInterface $config_factory, AliasStorageHelperInterface $alias_storage_helper, ModuleHandlerInterface $module_handler, RouteProviderInterface $route_provider, AliasManagerInterface $alias_manager) {
67     $this->configFactory = $config_factory;
68     $this->aliasStorageHelper = $alias_storage_helper;
69     $this->moduleHandler = $module_handler;
70     $this->routeProvider = $route_provider;
71     $this->aliasManager = $alias_manager;
72   }
73
74   /**
75    * {@inheritdoc}
76    */
77   public function uniquify(&$alias, $source, $langcode) {
78     $config = $this->configFactory->get('pathauto.settings');
79
80     if (!$this->isReserved($alias, $source, $langcode)) {
81       return;
82     }
83
84     // If the alias already exists, generate a new, hopefully unique, variant.
85     $maxlength = min($config->get('max_length'), $this->aliasStorageHelper->getAliasSchemaMaxlength());
86     $separator = $config->get('separator');
87     $original_alias = $alias;
88
89     $i = 0;
90     do {
91       // Append an incrementing numeric suffix until we find a unique alias.
92       $unique_suffix = $separator . $i;
93       $alias = Unicode::truncate($original_alias, $maxlength - Unicode::strlen($unique_suffix), TRUE) . $unique_suffix;
94       $i++;
95     } while ($this->isReserved($alias, $source, $langcode));
96   }
97
98   /**
99    * {@inheritdoc}
100    */
101   public function isReserved($alias, $source, $langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED) {
102     // Check if this alias already exists.
103     if ($existing_source = $this->aliasManager->getPathByAlias($alias, $langcode)) {
104       if ($existing_source != $alias) {
105         // If it is an alias for the provided source, it is allowed to keep using
106         // it. If not, then it is reserved.
107         return $existing_source != $source;
108       }
109
110     }
111
112     // Then check if there is a route with the same path.
113     if ($this->isRoute($alias)) {
114       return TRUE;
115     }
116     // Finally check if any other modules have reserved the alias.
117     $args = array(
118       $alias,
119       $source,
120       $langcode,
121     );
122     $implementations = $this->moduleHandler->getImplementations('pathauto_is_alias_reserved');
123     foreach ($implementations as $module) {
124
125       $result = $this->moduleHandler->invoke($module, 'pathauto_is_alias_reserved', $args);
126
127       if (!empty($result)) {
128         // As soon as the first module says that an alias is in fact reserved,
129         // then there is no point in checking the rest of the modules.
130         return TRUE;
131       }
132     }
133
134     return FALSE;
135   }
136
137   /**
138    * Verify if the given path is a valid route.
139    *
140    * @param string $path
141    *   A string containing a relative path.
142    *
143    * @return bool
144    *   TRUE if the path already exists.
145    *
146    * @throws \InvalidArgumentException
147    */
148   public function isRoute($path) {
149     if (is_file(DRUPAL_ROOT . '/' . $path) || is_dir(DRUPAL_ROOT . '/' . $path)) {
150       // Do not allow existing files or directories to get assigned an automatic
151       // alias. Note that we do not need to use is_link() to check for symbolic
152       // links since this returns TRUE for either is_file() or is_dir() already.
153       return TRUE;
154     }
155
156     $routes = $this->routeProvider->getRoutesByPattern($path);
157
158     // Only return true for an exact match, ignore placeholders.
159     foreach ($routes as $route) {
160       if ($route->getPath() == $path) {
161         return TRUE;
162       }
163     }
164
165     return FALSE;
166
167   }
168
169 }