Backup of db before drupal security update
[yaffs-website] / web / core / modules / config_translation / src / ConfigNamesMapper.php
1 <?php
2
3 namespace Drupal\config_translation;
4
5 use Drupal\config_translation\Exception\ConfigMapperLanguageException;
6 use Drupal\Core\Config\ConfigFactoryInterface;
7 use Drupal\Core\Config\TypedConfigManagerInterface;
8 use Drupal\Core\Language\LanguageInterface;
9 use Drupal\Core\Language\LanguageManagerInterface;
10 use Drupal\Core\Plugin\PluginBase;
11 use Drupal\Core\Routing\RouteMatchInterface;
12 use Drupal\Core\Routing\RouteProviderInterface;
13 use Drupal\Core\StringTranslation\TranslationInterface;
14 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
15 use Drupal\Core\Url;
16 use Drupal\locale\LocaleConfigManager;
17 use Symfony\Component\DependencyInjection\ContainerInterface;
18 use Symfony\Component\Routing\Route;
19 use Symfony\Component\Routing\RouteCollection;
20
21 /**
22  * Configuration mapper base implementation.
23  */
24 class ConfigNamesMapper extends PluginBase implements ConfigMapperInterface, ContainerFactoryPluginInterface {
25
26   /**
27    * The configuration factory.
28    *
29    * @var \Drupal\Core\Config\ConfigFactoryInterface
30    */
31   protected $configFactory;
32
33   /**
34    * The typed config manager.
35    *
36    * @var \Drupal\Core\Config\TypedConfigManagerInterface
37    */
38   protected $typedConfigManager;
39
40   /**
41    * The typed configuration manager.
42    *
43    * @var \Drupal\locale\LocaleConfigManager
44    */
45   protected $localeConfigManager;
46
47   /**
48    * The mapper plugin discovery service.
49    *
50    * @var \Drupal\config_translation\ConfigMapperManagerInterface
51    */
52   protected $configMapperManager;
53
54   /**
55    * The route provider.
56    *
57    * @var \Drupal\Core\Routing\RouteProviderInterface
58    */
59   protected $routeProvider;
60
61   /**
62    * The base route object that the mapper is attached to.
63    *
64    * @return \Symfony\Component\Routing\Route
65    */
66   protected $baseRoute;
67
68   /**
69    * The available routes.
70    *
71    * @var \Symfony\Component\Routing\RouteCollection
72    */
73   protected $routeCollection;
74
75   /**
76    * The language code of the language this mapper, if any.
77    *
78    * @var string|null
79    */
80   protected $langcode = NULL;
81
82   /**
83    * The language manager.
84    *
85    * @var \Drupal\Core\Language\LanguageManagerInterface
86    */
87   protected $languageManager;
88
89   /**
90    * Constructs a ConfigNamesMapper.
91    *
92    * @param $plugin_id
93    *   The config mapper plugin ID.
94    * @param mixed $plugin_definition
95    *   An array of plugin information with the following keys:
96    *   - title: The title of the mapper, used for generating page titles.
97    *   - base_route_name: The route name of the base route this mapper is
98    *     attached to.
99    *   - names: (optional) An array of configuration names.
100    *   - weight: (optional) The weight of this mapper, used in mapper listings.
101    *     Defaults to 20.
102    *   - list_controller: (optional) Class name for list controller used to
103    *     generate lists of this type of configuration.
104    * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
105    *   The configuration factory.
106    * @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_config
107    *   The typed configuration manager.
108    * @param \Drupal\locale\LocaleConfigManager $locale_config_manager
109    *   The locale configuration manager.
110    * @param \Drupal\config_translation\ConfigMapperManagerInterface $config_mapper_manager
111    *   The mapper plugin discovery service.
112    * @param \Drupal\Core\Routing\RouteProviderInterface $route_provider
113    *   The route provider.
114    * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
115    *   The string translation manager.
116    * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
117    *   The language manager.
118    *
119    * @throws \Symfony\Component\Routing\Exception\RouteNotFoundException
120    *   Throws an exception if the route specified by the 'base_route_name' in
121    *   the plugin definition could not be found by the route provider.
122    */
123   public function __construct($plugin_id, $plugin_definition, ConfigFactoryInterface $config_factory, TypedConfigManagerInterface $typed_config, LocaleConfigManager $locale_config_manager, ConfigMapperManagerInterface $config_mapper_manager, RouteProviderInterface $route_provider, TranslationInterface $string_translation, LanguageManagerInterface $language_manager) {
124     $this->pluginId = $plugin_id;
125     $this->pluginDefinition = $plugin_definition;
126     $this->routeProvider = $route_provider;
127
128     $this->configFactory = $config_factory;
129     $this->typedConfigManager = $typed_config;
130     $this->localeConfigManager = $locale_config_manager;
131     $this->configMapperManager = $config_mapper_manager;
132
133     $this->stringTranslation = $string_translation;
134     $this->languageManager = $language_manager;
135   }
136
137   /**
138    * {@inheritdoc}
139    */
140   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
141     // Note that we ignore the plugin $configuration because mappers have
142     // nothing to configure in themselves.
143     return new static (
144       $plugin_id,
145       $plugin_definition,
146       $container->get('config.factory'),
147       $container->get('config.typed'),
148       $container->get('locale.config_manager'),
149       $container->get('plugin.manager.config_translation.mapper'),
150       $container->get('router.route_provider'),
151       $container->get('string_translation'),
152       $container->get('language_manager')
153     );
154   }
155
156   /**
157    * {@inheritdoc}
158    */
159   public function setRouteCollection(RouteCollection $collection) {
160     $this->routeCollection = $collection;
161   }
162
163   /**
164    * {@inheritdoc}
165    */
166   public function getTitle() {
167     // A title from a *.config_translation.yml. Should be translated for
168     // display in the current page language.
169     return $this->t($this->pluginDefinition['title']);
170   }
171
172   /**
173    * {@inheritdoc}
174    */
175   public function getBaseRouteName() {
176     return $this->pluginDefinition['base_route_name'];
177   }
178
179   /**
180    * {@inheritdoc}
181    */
182   public function getBaseRouteParameters() {
183     return [];
184   }
185
186   /**
187    * {@inheritdoc}
188    */
189   public function getBaseRoute() {
190     if ($this->routeCollection) {
191       return $this->routeCollection->get($this->getBaseRouteName());
192     }
193     else {
194       return $this->routeProvider->getRouteByName($this->getBaseRouteName());
195     }
196   }
197
198   /**
199    * Allows to process all config translation routes.
200    *
201    * @param \Symfony\Component\Routing\Route $route
202    *   The route object to process.
203    */
204   protected function processRoute(Route $route) {
205   }
206
207   /**
208    * {@inheritdoc}
209    */
210   public function getBasePath() {
211     return Url::fromRoute($this->getBaseRouteName(), $this->getBaseRouteParameters())->getInternalPath();
212   }
213
214   /**
215    * {@inheritdoc}
216    */
217   public function getOverviewRouteName() {
218     return 'config_translation.item.overview.' . $this->getBaseRouteName();
219   }
220
221   /**
222    * {@inheritdoc}
223    */
224   public function getOverviewRouteParameters() {
225     return $this->getBaseRouteParameters();
226   }
227
228   /**
229    * {@inheritdoc}
230    */
231   public function getOverviewRoute() {
232     $route = new Route(
233       $this->getBaseRoute()->getPath() . '/translate',
234       [
235         '_controller' => '\Drupal\config_translation\Controller\ConfigTranslationController::itemPage',
236         'plugin_id' => $this->getPluginId(),
237       ],
238       ['_config_translation_overview_access' => 'TRUE']
239     );
240     $this->processRoute($route);
241     return $route;
242   }
243
244   /**
245    * {@inheritdoc}
246    */
247   public function getOverviewPath() {
248     return Url::fromRoute($this->getOverviewRouteName(), $this->getOverviewRouteParameters())->getInternalPath();
249   }
250
251   /**
252    * {@inheritdoc}
253    */
254   public function getAddRouteName() {
255     return 'config_translation.item.add.' . $this->getBaseRouteName();
256   }
257
258   /**
259    * {@inheritdoc}
260    */
261   public function getAddRouteParameters() {
262     // If sub-classes provide route parameters in getBaseRouteParameters(), they
263     // probably also want to provide those for the add, edit, and delete forms.
264     $parameters = $this->getBaseRouteParameters();
265     $parameters['langcode'] = $this->langcode;
266     return $parameters;
267   }
268
269   /**
270    * {@inheritdoc}
271    */
272   public function getAddRoute() {
273     $route = new Route(
274       $this->getBaseRoute()->getPath() . '/translate/{langcode}/add',
275       [
276         '_form' => '\Drupal\config_translation\Form\ConfigTranslationAddForm',
277         'plugin_id' => $this->getPluginId(),
278       ],
279       ['_config_translation_form_access' => 'TRUE']
280     );
281     $this->processRoute($route);
282     return $route;
283   }
284
285   /**
286    * {@inheritdoc}
287    */
288   public function getEditRouteName() {
289     return 'config_translation.item.edit.' . $this->getBaseRouteName();
290   }
291
292   /**
293    * {@inheritdoc}
294    */
295   public function getEditRouteParameters() {
296     return $this->getAddRouteParameters();
297   }
298
299   /**
300    * {@inheritdoc}
301    */
302   public function getEditRoute() {
303     $route = new Route(
304       $this->getBaseRoute()->getPath() . '/translate/{langcode}/edit',
305       [
306         '_form' => '\Drupal\config_translation\Form\ConfigTranslationEditForm',
307         'plugin_id' => $this->getPluginId(),
308       ],
309       ['_config_translation_form_access' => 'TRUE']
310     );
311     $this->processRoute($route);
312     return $route;
313   }
314
315   /**
316    * {@inheritdoc}
317    */
318   public function getDeleteRouteName() {
319     return 'config_translation.item.delete.' . $this->getBaseRouteName();
320   }
321
322   /**
323    * {@inheritdoc}
324    */
325   public function getDeleteRouteParameters() {
326     return $this->getAddRouteParameters();
327   }
328
329   /**
330    * {@inheritdoc}
331    */
332   public function getDeleteRoute() {
333     $route = new Route(
334       $this->getBaseRoute()->getPath() . '/translate/{langcode}/delete',
335       [
336         '_form' => '\Drupal\config_translation\Form\ConfigTranslationDeleteForm',
337         'plugin_id' => $this->getPluginId(),
338       ],
339       ['_config_translation_form_access' => 'TRUE']
340     );
341     $this->processRoute($route);
342     return $route;
343   }
344
345   /**
346    * {@inheritdoc}
347    */
348   public function getConfigNames() {
349     return $this->pluginDefinition['names'];
350   }
351
352   /**
353    * {@inheritdoc}
354    */
355   public function addConfigName($name) {
356     $this->pluginDefinition['names'][] = $name;
357   }
358
359   /**
360    * {@inheritdoc}
361    */
362   public function getWeight() {
363     return $this->pluginDefinition['weight'];
364   }
365
366   /**
367    * {@inheritdoc}
368    */
369   public function populateFromRouteMatch(RouteMatchInterface $route_match) {
370     $this->langcode = $route_match->getParameter('langcode');
371   }
372
373   /**
374    * {@inheritdoc}
375    */
376   public function getTypeLabel() {
377     return $this->getTitle();
378   }
379
380   /**
381    * {@inheritdoc}
382    */
383   public function getLangcode() {
384     $langcodes = array_map([$this, 'getLangcodeFromConfig'], $this->getConfigNames());
385
386     if (count(array_unique($langcodes)) > 1) {
387       throw new ConfigMapperLanguageException('A config mapper can only contain configuration for a single language.');
388     }
389
390     return reset($langcodes);
391   }
392
393   /**
394    * {@inheritdoc}
395    */
396   public function getLangcodeFromConfig($config_name) {
397     // Default to English if no language code was provided in the file.
398     // Although it is a best practice to include a language code, if the
399     // developer did not think about a multilingual use case, we fall back
400     // on assuming the file is English.
401     return $this->configFactory->get($config_name)->get('langcode') ?: 'en';
402   }
403
404   /**
405    * {@inheritdoc}
406    */
407   public function setLangcode($langcode) {
408     $this->langcode = $langcode;
409     return $this;
410   }
411
412   /**
413    * {@inheritdoc}
414    */
415   public function getConfigData() {
416     $config_data = [];
417     foreach ($this->getConfigNames() as $name) {
418       $config_data[$name] = $this->configFactory->getEditable($name)->get();
419     }
420     return $config_data;
421   }
422
423   /**
424    * {@inheritdoc}
425    */
426   public function hasSchema() {
427     foreach ($this->getConfigNames() as $name) {
428       if (!$this->typedConfigManager->hasConfigSchema($name)) {
429         return FALSE;
430       }
431     }
432     return TRUE;
433   }
434
435   /**
436    * {@inheritdoc}
437    */
438   public function hasTranslatable() {
439     foreach ($this->getConfigNames() as $name) {
440       if ($this->configMapperManager->hasTranslatable($name)) {
441         return TRUE;
442       }
443     }
444     return FALSE;
445   }
446
447   /**
448    * {@inheritdoc}
449    */
450   public function hasTranslation(LanguageInterface $language) {
451     foreach ($this->getConfigNames() as $name) {
452       if ($this->localeConfigManager->hasTranslation($name, $language->getId())) {
453         return TRUE;
454       }
455     }
456     return FALSE;
457   }
458
459   /**
460    * {@inheritdoc}
461    */
462   public function getTypeName() {
463     return $this->t('Settings');
464   }
465
466   /**
467    * {@inheritdoc}
468    */
469   public function getOperations() {
470     return [
471       'translate' => [
472         'title' => $this->t('Translate'),
473         'url' => Url::fromRoute($this->getOverviewRouteName(), $this->getOverviewRouteParameters()),
474       ],
475     ];
476   }
477
478   /**
479    * {@inheritdoc}
480    */
481   public function getContextualLinkGroup() {
482     return NULL;
483   }
484
485 }