f8de322f620660f1dae05ccbc426bb8ba3b637d1
[yaffs-website] / web / modules / contrib / pathauto / pathauto.install
1 <?php
2
3 /**
4  * @file
5  * Install, update, and uninstall functions for Pathauto.
6  *
7  * @ingroup pathauto
8  */
9
10 use Drupal\Core\Entity\Entity\EntityFormDisplay;
11 use Drupal\Core\Plugin\Context\Context;
12 use Drupal\Core\Plugin\Context\ContextDefinition;
13 use Drupal\pathauto\Entity\PathautoPattern;
14
15 /**
16  * Implements hook_install().
17  */
18 function pathauto_install() {
19   // Set the weight to 1
20   module_set_weight('pathauto', 1);
21
22   // Ensure the url_alias table exists.
23   _pathauto_ensure_url_alias_table_exists();
24 }
25
26 /**
27  * Helper function to ensure the url_alias table exists.
28  *
29  * Only necessary on Drupal 8.1.x.
30  *
31  * @see https://www.drupal.org/node/2704821
32  */
33 function _pathauto_ensure_url_alias_table_exists() {
34   $alias_storage = \Drupal::service('path.alias_storage');
35   if (method_exists($alias_storage, 'schemaDefinition')) {
36     $database_schema = \Drupal::database()->schema();
37     if (!$database_schema->tableExists($alias_storage::TABLE)) {
38       $schema_definition = $alias_storage->schemaDefinition();
39       $database_schema->createTable($alias_storage::TABLE, $schema_definition);
40     }
41   }
42 }
43
44 /**
45  * Updates pathauto widgets to use the path widget ID.
46  */
47 function pathauto_update_8001() {
48
49   // Replace values in the 'entity.definitions.installed' keyvalue collection.
50   $collection = \Drupal::service('keyvalue')->get('entity.definitions.installed');
51   foreach ($collection->getAll() as $key => $definitions) {
52     if (!is_array($definitions) || empty($definitions['path'])) {
53       continue;
54     }
55
56     // Retrieve and change path base field definition.
57     $path_definition = $definitions['path'];
58     if (($options = $path_definition->getDisplayOptions('form')) && $options['type'] = 'pathauto') {
59       $options['type'] = 'path';
60       $path_definition->setDisplayOptions('form', $options);
61       // Save the new value.
62       $collection->set($key, $definitions);
63     }
64
65   }
66
67   foreach (EntityFormDisplay::loadMultiple() as $form_display) {
68     if ($component = $form_display->getComponent('path')) {
69       if (isset($component['type']) && $component['type'] == 'pathauto') {
70         $component['type'] = 'path';
71         $form_display->setComponent('path', $component);
72         $form_display->save();
73       }
74     }
75   }
76 }
77
78 /**
79  * Converts patterns from configuration objects to configuration entities.
80  */
81 function pathauto_update_8100() {
82   \Drupal::service('module_installer')->install(['ctools']);
83
84   $messages = array();
85   /** @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_bundle_info */
86   $entity_bundle_info = \Drupal::service('entity_type.bundle.info');
87   $entity_type_manager = \Drupal::entityTypeManager();
88   $language_manager = \Drupal::languageManager();
89   $entity_type_manager->clearCachedDefinitions();
90   \Drupal::service('plugin.manager.alias_type')->clearCachedDefinitions();
91   $entity_types = $entity_type_manager->getDefinitions();
92
93   // 1. Load all patterns.
94   $config = \Drupal::configFactory()->getEditable('pathauto.pattern');
95   $patterns = $config->get('patterns');
96
97   // 2. Create a configuration entity per pattern.
98   foreach ($patterns as $entity_type => $entity_patterns) {
99     if (!array_key_exists($entity_type, $entity_types)) {
100       // We found an unknown entity type. Report it.
101       $messages[] = t('Entity of type @type was not processed. It defines the following patterns: @patterns', array(
102         '@type' => $entity_type,
103         '@patterns' => print_r($entity_patterns, TRUE),
104       ));
105       continue;
106     }
107     $entity_label = $entity_types[$entity_type]->getLabel();
108
109     if (!empty($entity_patterns['default'])) {
110       // This is a pattern for an entity type, such as "node".
111       $pattern = PathautoPattern::create([
112         'id' => $entity_type,
113         'label' => $entity_label,
114         'type' => 'canonical_entities:' . $entity_type,
115         'pattern' => $entity_patterns['default'],
116         'weight' => 0,
117       ]);
118       $pattern->save();
119     }
120
121     // Loop over bundles and create patterns if they have a value.
122     // Bundle keys may have a language suffix for language-dependant patterns.
123     if (isset($entity_patterns['bundles'])) {
124       $bundle_info = $entity_bundle_info->getBundleInfo($entity_type);
125       foreach ($entity_patterns['bundles'] as $bundle => $bundle_patterns) {
126         if (empty($bundle_patterns['default'])) {
127           // This bundle does not define a pattern. Move on to the next one.
128           continue;
129         }
130
131         if (isset($bundle_info[$bundle])) {
132           // This is a pattern for a bundle, such as "node_article".
133           $pattern = PathautoPattern::create([
134             'id' => $entity_type . '_' . $bundle,
135             'label' => $entity_label . ' ' . $bundle_info[$bundle]['label'],
136             'type' => 'canonical_entities:' . $entity_type,
137             'pattern' => $bundle_patterns['default'],
138             'weight' => -5,
139           ]);
140
141           // Add the bundle condition.
142           $pattern->addSelectionCondition([
143             'id' => 'entity_bundle:' . $entity_type,
144             'bundles' => array($bundle => $bundle),
145             'negate' => FALSE,
146             'context_mapping' => [ $entity_type => $entity_type ],
147           ]);
148
149           $pattern->save();
150         }
151         else {
152           // This is either a language dependent pattern such as "article_es" or
153           // an unknown bundle or langcode. Let's figure it out.
154           $matches = NULL;
155           $langcode = NULL;
156           $extracted_bundle = NULL;
157           $language = NULL;
158           preg_match('/^(.*)_([a-z-]*)$/', $bundle, $matches);
159           if (count($matches) == 3) {
160             list(, $extracted_bundle, $langcode) = $matches;
161             $language = $language_manager->getLanguage($langcode);
162           }
163           // Validate bundle, langcode and language.
164           if (!isset($bundle_info[$extracted_bundle]) || ($langcode == NULL) || ($language == NULL)) {
165             $messages[] = t('Unrecognized entity bundle @entity:@bundle was not processed. It defines the following patterns: @patterns', array(
166               '@entity' => $entity_type,
167               '@bundle' => $bundle,
168               '@patterns' => print_r($entity_patterns, TRUE),
169             ));
170             continue;
171           }
172
173           // This is a pattern for a bundle and a language, such as "node_article_es".
174           $pattern = PathautoPattern::create([
175             'id' => $entity_type . '_' . $extracted_bundle . '_' . str_replace('-', '_', $langcode),
176             'label' => $entity_label . ' ' . $bundle_info[$extracted_bundle]['label'] . ' ' . $language->getName(),
177             'type' => 'canonical_entities:' . $entity_type,
178             'pattern' => $bundle_patterns['default'],
179             'weight' => -10,
180           ]);
181
182           // Add the bundle condition.
183           $pattern->addSelectionCondition([
184             'id' => 'entity_bundle:' . $entity_type,
185             'bundles' => array($extracted_bundle => $extracted_bundle),
186             'negate' => FALSE,
187             'context_mapping' => [ $entity_type => $entity_type ],
188           ]);
189
190           // Add the language condition.
191           $language_mapping = $entity_type . ':' . $entity_type_manager->getDefinition($entity_type)->getKey('langcode') . ':language';
192           $pattern->addSelectionCondition([
193             'id' => 'language',
194             'langcodes' => [ $langcode => $langcode ],
195             'negate' => FALSE,
196             'context_mapping' => [
197               'language' => $language_mapping,
198             ]
199           ]);
200
201           // Add the context relationship for this language.
202           $pattern->addRelationship($language_mapping, 'Language');
203
204           $pattern->save();
205         }
206       }
207     }
208   }
209
210   // 3. Delete the old configuration object that stores patterns.
211   $config->delete();
212
213   // 4. Print out messages.
214   if (!empty($messages)) {
215     return implode('</br>', $messages);
216   }
217 }
218
219 /**
220  * Update relationship storage.
221  */
222 function pathauto_update_8101() {
223   foreach (\Drupal::configFactory()->listAll('pathauto.pattern.') as $pattern_config_name) {
224     $pattern_config = \Drupal::configFactory()->getEditable($pattern_config_name);
225
226     $relationships = [];
227     foreach ((array) $pattern_config->get('context_definitions') as $context_definition) {
228       $relationships[$context_definition['id']] = ['label' => $context_definition['label']];
229     }
230
231     $pattern_config->clear('context_definitions');
232     $pattern_config->set('relationships', $relationships);
233     $pattern_config->save();
234   }
235 }
236
237 /**
238  * Update node type conditions from entity_bundle to node_type.
239  */
240 function pathauto_update_8102() {
241   // Load all pattern configuration entities.
242   foreach (\Drupal::configFactory()->listAll('pathauto.pattern.') as $pattern_config_name) {
243     $pattern_config = \Drupal::configFactory()->getEditable($pattern_config_name);
244
245     // Loop patterns and swap the entity_bundle:node plugin by the node_type
246     // plugin.
247     if ($pattern_config->get('type') == 'canonical_entities:node') {
248       $selection_criteria = $pattern_config->get('selection_criteria');
249       foreach ($selection_criteria as $uuid => $condition) {
250         if ($condition['id'] == 'entity_bundle:node') {
251           $selection_criteria[$uuid]['id'] = 'node_type';
252           $pattern_config->set('selection_criteria', $selection_criteria);
253           $pattern_config->save();
254           break;
255         }
256       }
257     }
258   }
259 }
260
261 /**
262  * Fix invalid default value for ignore_words.
263  */
264 function pathauto_update_8103() {
265   $config_factory = \Drupal::configFactory();
266   $config = $config_factory->getEditable('pathauto.settings');
267   $ignore_words = $config->get('ignore_words');
268   if ($ignore_words === ', in, is,that, the  , this, with, ') {
269     $config->set('ignore_words', 'a, an, as, at, before, but, by, for, from, is, in, into, like, of, off, on, onto, per, since, than, the, this, that, to, up, via, with')->save(TRUE);
270   }
271 }
272
273 /**
274  * Resave patterns so that lookup keys are updated.
275  */
276 function pathauto_update_8104() {
277   \Drupal::entityTypeManager()->clearCachedDefinitions();
278   // Load all pattern configuration entities and save them, so that the new
279   // status lookup keys are saved.
280   foreach (\Drupal::configFactory()->listAll('pathauto.pattern.') as $pattern_config_name) {
281     $pattern_config = \Drupal::configFactory()->getEditable($pattern_config_name);
282     $pattern_config->save();
283   }
284 }
285
286 /**
287  * Ensure the url_alias table exists.
288  */
289 function pathauto_update_8105() {
290   _pathauto_ensure_url_alias_table_exists();
291 }
292
293 /**
294  * Update default configuration for enabled entity types.
295  */
296 function pathauto_update_8106() {
297   $config_factory = \Drupal::configFactory();
298   $config = $config_factory->getEditable('pathauto.settings');
299   $config->set('enabled_entity_types', ['user']);
300   $config->save();
301 }