Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 /**
|
Chris@0
|
4 * @file
|
Chris@0
|
5 * Install, update, and uninstall functions for the Locale module.
|
Chris@0
|
6 */
|
Chris@0
|
7
|
Chris@0
|
8 use Drupal\Core\Url;
|
Chris@0
|
9
|
Chris@0
|
10 /**
|
Chris@0
|
11 * Implements hook_install().
|
Chris@0
|
12 */
|
Chris@0
|
13 function locale_install() {
|
Chris@0
|
14 // Create the interface translations directory and ensure it's writable.
|
Chris@0
|
15 if (!$directory = \Drupal::config('locale.settings')->get('translation.path')) {
|
Chris@0
|
16 $site_path = \Drupal::service('site.path');
|
Chris@0
|
17 $directory = $site_path . '/files/translations';
|
Chris@0
|
18 \Drupal::configFactory()->getEditable('locale.settings')->set('translation.path', $directory)->save();
|
Chris@0
|
19 }
|
Chris@0
|
20 file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
|
Chris@0
|
21 }
|
Chris@0
|
22
|
Chris@0
|
23 /**
|
Chris@0
|
24 * Implements hook_uninstall().
|
Chris@0
|
25 */
|
Chris@0
|
26 function locale_uninstall() {
|
Chris@0
|
27 $config = \Drupal::config('locale.settings');
|
Chris@0
|
28 // Delete all JavaScript translation files.
|
Chris@0
|
29 $locale_js_directory = 'public://' . $config->get('javascript.directory');
|
Chris@0
|
30
|
Chris@0
|
31 if (is_dir($locale_js_directory)) {
|
Chris@0
|
32 $locale_javascripts = \Drupal::state()->get('locale.translation.javascript') ?: [];
|
Chris@0
|
33 foreach ($locale_javascripts as $langcode => $file_suffix) {
|
Chris@0
|
34 if (!empty($file_suffix)) {
|
Chris@0
|
35 file_unmanaged_delete($locale_js_directory . '/' . $langcode . '_' . $file_suffix . '.js');
|
Chris@0
|
36 }
|
Chris@0
|
37 }
|
Chris@0
|
38 // Delete the JavaScript translations directory if empty.
|
Chris@0
|
39 if (!file_scan_directory($locale_js_directory, '/.*/')) {
|
Chris@0
|
40 drupal_rmdir($locale_js_directory);
|
Chris@0
|
41 }
|
Chris@0
|
42 }
|
Chris@0
|
43
|
Chris@0
|
44 // Clear variables.
|
Chris@0
|
45 \Drupal::state()->delete('system.javascript_parsed');
|
Chris@0
|
46 \Drupal::state()->delete('locale.translation.plurals');
|
Chris@0
|
47 \Drupal::state()->delete('locale.translation.javascript');
|
Chris@0
|
48 }
|
Chris@0
|
49
|
Chris@0
|
50 /**
|
Chris@0
|
51 * Implements hook_schema().
|
Chris@0
|
52 */
|
Chris@0
|
53 function locale_schema() {
|
Chris@0
|
54 $schema['locales_source'] = [
|
Chris@0
|
55 'description' => 'List of English source strings.',
|
Chris@0
|
56 'fields' => [
|
Chris@0
|
57 'lid' => [
|
Chris@0
|
58 'type' => 'serial',
|
Chris@0
|
59 'not null' => TRUE,
|
Chris@0
|
60 'description' => 'Unique identifier of this string.',
|
Chris@0
|
61 ],
|
Chris@0
|
62 'source' => [
|
Chris@0
|
63 'type' => 'text',
|
Chris@0
|
64 'mysql_type' => 'blob',
|
Chris@0
|
65 'not null' => TRUE,
|
Chris@0
|
66 'description' => 'The original string in English.',
|
Chris@0
|
67 ],
|
Chris@0
|
68 'context' => [
|
Chris@0
|
69 'type' => 'varchar_ascii',
|
Chris@0
|
70 'length' => 255,
|
Chris@0
|
71 'not null' => TRUE,
|
Chris@0
|
72 'default' => '',
|
Chris@0
|
73 'description' => 'The context this string applies to.',
|
Chris@0
|
74 ],
|
Chris@0
|
75 'version' => [
|
Chris@0
|
76 'type' => 'varchar_ascii',
|
Chris@0
|
77 'length' => 20,
|
Chris@0
|
78 'not null' => TRUE,
|
Chris@0
|
79 'default' => 'none',
|
Chris@0
|
80 'description' => 'Version of Drupal where the string was last used (for locales optimization).',
|
Chris@0
|
81 ],
|
Chris@0
|
82 ],
|
Chris@0
|
83 'primary key' => ['lid'],
|
Chris@0
|
84 'indexes' => [
|
Chris@0
|
85 'source_context' => [['source', 30], 'context'],
|
Chris@0
|
86 ],
|
Chris@0
|
87 ];
|
Chris@0
|
88
|
Chris@0
|
89 $schema['locales_target'] = [
|
Chris@0
|
90 'description' => 'Stores translated versions of strings.',
|
Chris@0
|
91 'fields' => [
|
Chris@0
|
92 'lid' => [
|
Chris@0
|
93 'type' => 'int',
|
Chris@0
|
94 'not null' => TRUE,
|
Chris@0
|
95 'default' => 0,
|
Chris@0
|
96 'description' => 'Source string ID. References {locales_source}.lid.',
|
Chris@0
|
97 ],
|
Chris@0
|
98 'translation' => [
|
Chris@0
|
99 'type' => 'text',
|
Chris@0
|
100 'mysql_type' => 'blob',
|
Chris@0
|
101 'not null' => TRUE,
|
Chris@0
|
102 'description' => 'Translation string value in this language.',
|
Chris@0
|
103 ],
|
Chris@0
|
104 'language' => [
|
Chris@0
|
105 'type' => 'varchar_ascii',
|
Chris@0
|
106 'length' => 12,
|
Chris@0
|
107 'not null' => TRUE,
|
Chris@0
|
108 'default' => '',
|
Chris@0
|
109 'description' => 'Language code. References {language}.langcode.',
|
Chris@0
|
110 ],
|
Chris@0
|
111 'customized' => [
|
Chris@0
|
112 'type' => 'int',
|
Chris@0
|
113 'not null' => TRUE,
|
Chris@0
|
114 // LOCALE_NOT_CUSTOMIZED
|
Chris@0
|
115 'default' => 0,
|
Chris@0
|
116 'description' => 'Boolean indicating whether the translation is custom to this site.',
|
Chris@0
|
117 ],
|
Chris@0
|
118 ],
|
Chris@0
|
119 'primary key' => ['language', 'lid'],
|
Chris@0
|
120 'foreign keys' => [
|
Chris@0
|
121 'locales_source' => [
|
Chris@0
|
122 'table' => 'locales_source',
|
Chris@0
|
123 'columns' => ['lid' => 'lid'],
|
Chris@0
|
124 ],
|
Chris@0
|
125 ],
|
Chris@0
|
126 'indexes' => [
|
Chris@0
|
127 'lid' => ['lid'],
|
Chris@0
|
128 ],
|
Chris@0
|
129 ];
|
Chris@0
|
130
|
Chris@0
|
131 $schema['locales_location'] = [
|
Chris@0
|
132 'description' => 'Location information for source strings.',
|
Chris@0
|
133 'fields' => [
|
Chris@0
|
134 'lid' => [
|
Chris@0
|
135 'type' => 'serial',
|
Chris@0
|
136 'not null' => TRUE,
|
Chris@0
|
137 'description' => 'Unique identifier of this location.',
|
Chris@0
|
138 ],
|
Chris@0
|
139 'sid' => [
|
Chris@0
|
140 'type' => 'int',
|
Chris@0
|
141 'not null' => TRUE,
|
Chris@0
|
142 'description' => 'Unique identifier of this string.',
|
Chris@0
|
143 ],
|
Chris@0
|
144 'type' => [
|
Chris@0
|
145 'type' => 'varchar_ascii',
|
Chris@0
|
146 'length' => 50,
|
Chris@0
|
147 'not null' => TRUE,
|
Chris@0
|
148 'default' => '',
|
Chris@0
|
149 'description' => 'The location type (file, config, path, etc).',
|
Chris@0
|
150 ],
|
Chris@0
|
151 'name' => [
|
Chris@0
|
152 'type' => 'varchar',
|
Chris@0
|
153 'length' => 255,
|
Chris@0
|
154 'not null' => TRUE,
|
Chris@0
|
155 'default' => '',
|
Chris@0
|
156 'description' => 'Type dependent location information (file name, path, etc).',
|
Chris@0
|
157 ],
|
Chris@0
|
158 'version' => [
|
Chris@0
|
159 'type' => 'varchar_ascii',
|
Chris@0
|
160 'length' => 20,
|
Chris@0
|
161 'not null' => TRUE,
|
Chris@0
|
162 'default' => 'none',
|
Chris@0
|
163 'description' => 'Version of Drupal where the location was found.',
|
Chris@0
|
164 ],
|
Chris@0
|
165 ],
|
Chris@0
|
166 'primary key' => ['lid'],
|
Chris@0
|
167 'foreign keys' => [
|
Chris@0
|
168 'locales_source' => [
|
Chris@0
|
169 'table' => 'locales_source',
|
Chris@0
|
170 'columns' => ['sid' => 'lid'],
|
Chris@0
|
171 ],
|
Chris@0
|
172 ],
|
Chris@0
|
173 'indexes' => [
|
Chris@0
|
174 'string_id' => ['sid'],
|
Chris@0
|
175 'string_type' => ['sid', 'type'],
|
Chris@0
|
176 ],
|
Chris@0
|
177 ];
|
Chris@0
|
178
|
Chris@0
|
179 $schema['locale_file'] = [
|
Chris@0
|
180 'description' => 'File import status information for interface translation files.',
|
Chris@0
|
181 'fields' => [
|
Chris@0
|
182 'project' => [
|
Chris@0
|
183 'type' => 'varchar_ascii',
|
Chris@0
|
184 'length' => '255',
|
Chris@0
|
185 'not null' => TRUE,
|
Chris@0
|
186 'default' => '',
|
Chris@0
|
187 'description' => 'A unique short name to identify the project the file belongs to.',
|
Chris@0
|
188 ],
|
Chris@0
|
189 'langcode' => [
|
Chris@0
|
190 'type' => 'varchar_ascii',
|
Chris@0
|
191 'length' => '12',
|
Chris@0
|
192 'not null' => TRUE,
|
Chris@0
|
193 'default' => '',
|
Chris@0
|
194 'description' => 'Language code of this translation. References {language}.langcode.',
|
Chris@0
|
195 ],
|
Chris@0
|
196 'filename' => [
|
Chris@0
|
197 'type' => 'varchar',
|
Chris@0
|
198 'length' => 255,
|
Chris@0
|
199 'not null' => TRUE,
|
Chris@0
|
200 'default' => '',
|
Chris@0
|
201 'description' => 'Filename of the imported file.',
|
Chris@0
|
202 ],
|
Chris@0
|
203 'version' => [
|
Chris@0
|
204 'type' => 'varchar',
|
Chris@0
|
205 'length' => '128',
|
Chris@0
|
206 'not null' => TRUE,
|
Chris@0
|
207 'default' => '',
|
Chris@0
|
208 'description' => 'Version tag of the imported file.',
|
Chris@0
|
209 ],
|
Chris@0
|
210 'uri' => [
|
Chris@0
|
211 'type' => 'varchar',
|
Chris@0
|
212 'length' => 255,
|
Chris@0
|
213 'not null' => TRUE,
|
Chris@0
|
214 'default' => '',
|
Chris@0
|
215 'description' => 'URI of the remote file, the resulting local file or the locally imported file.',
|
Chris@0
|
216 ],
|
Chris@0
|
217 'timestamp' => [
|
Chris@0
|
218 'type' => 'int',
|
Chris@0
|
219 'not null' => FALSE,
|
Chris@0
|
220 'default' => 0,
|
Chris@0
|
221 'description' => 'Unix timestamp of the imported file.',
|
Chris@0
|
222 ],
|
Chris@0
|
223 'last_checked' => [
|
Chris@0
|
224 'type' => 'int',
|
Chris@0
|
225 'not null' => FALSE,
|
Chris@0
|
226 'default' => 0,
|
Chris@0
|
227 'description' => 'Unix timestamp of the last time this translation was confirmed to be the most recent release available.',
|
Chris@0
|
228 ],
|
Chris@0
|
229 ],
|
Chris@0
|
230 'primary key' => ['project', 'langcode'],
|
Chris@0
|
231 ];
|
Chris@0
|
232 return $schema;
|
Chris@0
|
233 }
|
Chris@0
|
234
|
Chris@0
|
235 /**
|
Chris@0
|
236 * Implements hook_requirements().
|
Chris@0
|
237 */
|
Chris@0
|
238 function locale_requirements($phase) {
|
Chris@0
|
239 $requirements = [];
|
Chris@0
|
240 if ($phase == 'runtime') {
|
Chris@0
|
241 $available_updates = [];
|
Chris@0
|
242 $untranslated = [];
|
Chris@0
|
243 $languages = locale_translatable_language_list();
|
Chris@0
|
244
|
Chris@0
|
245 if ($languages) {
|
Chris@0
|
246 // Determine the status of the translation updates per language.
|
Chris@0
|
247 $status = locale_translation_get_status();
|
Chris@0
|
248 if ($status) {
|
Chris@0
|
249 foreach ($status as $project) {
|
Chris@0
|
250 foreach ($project as $langcode => $project_info) {
|
Chris@0
|
251 if (empty($project_info->type)) {
|
Chris@0
|
252 $untranslated[$langcode] = $languages[$langcode]->getName();
|
Chris@0
|
253 }
|
Chris@0
|
254 elseif ($project_info->type == LOCALE_TRANSLATION_LOCAL || $project_info->type == LOCALE_TRANSLATION_REMOTE) {
|
Chris@0
|
255 $available_updates[$langcode] = $languages[$langcode]->getName();
|
Chris@0
|
256 }
|
Chris@0
|
257 }
|
Chris@0
|
258 }
|
Chris@0
|
259
|
Chris@0
|
260 if ($available_updates || $untranslated) {
|
Chris@0
|
261 if ($available_updates) {
|
Chris@0
|
262 $requirements['locale_translation'] = [
|
Chris@0
|
263 'title' => t('Translation update status'),
|
Chris@0
|
264 'value' => \Drupal::l(t('Updates available'), new Url('locale.translate_status')),
|
Chris@0
|
265 'severity' => REQUIREMENT_WARNING,
|
Chris@0
|
266 'description' => t('Updates available for: @languages. See the <a href=":updates">Available translation updates</a> page for more information.', ['@languages' => implode(', ', $available_updates), ':updates' => \Drupal::url('locale.translate_status')]),
|
Chris@0
|
267 ];
|
Chris@0
|
268 }
|
Chris@0
|
269 else {
|
Chris@0
|
270 $requirements['locale_translation'] = [
|
Chris@0
|
271 'title' => t('Translation update status'),
|
Chris@0
|
272 'value' => t('Missing translations'),
|
Chris@0
|
273 'severity' => REQUIREMENT_INFO,
|
Chris@0
|
274 'description' => t('Missing translations for: @languages. See the <a href=":updates">Available translation updates</a> page for more information.', ['@languages' => implode(', ', $untranslated), ':updates' => \Drupal::url('locale.translate_status')]),
|
Chris@0
|
275 ];
|
Chris@0
|
276 }
|
Chris@0
|
277 }
|
Chris@0
|
278 else {
|
Chris@0
|
279 $requirements['locale_translation'] = [
|
Chris@0
|
280 'title' => t('Translation update status'),
|
Chris@0
|
281 'value' => t('Up to date'),
|
Chris@0
|
282 'severity' => REQUIREMENT_OK,
|
Chris@0
|
283 ];
|
Chris@0
|
284 }
|
Chris@0
|
285 }
|
Chris@0
|
286 else {
|
Chris@0
|
287 $requirements['locale_translation'] = [
|
Chris@0
|
288 'title' => t('Translation update status'),
|
Chris@0
|
289 'value' => \Drupal::l(t('Can not determine status'), new Url('locale.translate_status')),
|
Chris@0
|
290 'severity' => REQUIREMENT_WARNING,
|
Chris@0
|
291 'description' => t('No translation status is available. See the <a href=":updates">Available translation updates</a> page for more information.', [':updates' => \Drupal::url('locale.translate_status')]),
|
Chris@0
|
292 ];
|
Chris@0
|
293 }
|
Chris@0
|
294 }
|
Chris@0
|
295 }
|
Chris@0
|
296 return $requirements;
|
Chris@0
|
297 }
|
Chris@0
|
298
|
Chris@0
|
299 /**
|
Chris@0
|
300 * Delete translation status data in state.
|
Chris@0
|
301 */
|
Chris@0
|
302 function locale_update_8300() {
|
Chris@0
|
303 // Delete the old translation status data, it will be rebuilt and stored in
|
Chris@0
|
304 // the new key value collection.
|
Chris@0
|
305 \Drupal::state()->delete('locale.translation_status');
|
Chris@0
|
306 }
|
Chris@0
|
307
|
Chris@0
|
308 /**
|
Chris@0
|
309 * Update default server pattern value to use https.
|
Chris@0
|
310 */
|
Chris@0
|
311 function locale_update_8500() {
|
Chris@0
|
312 $update_url = \Drupal::config('locale.settings')->get('translation.default_server_pattern');
|
Chris@0
|
313 if ($update_url == 'http://ftp.drupal.org/files/translations/%core/%project/%project-%version.%language.po') {
|
Chris@0
|
314 \Drupal::configFactory()->getEditable('locale.settings')
|
Chris@0
|
315 ->set('translation.default_server_pattern', 'https://ftp.drupal.org/files/translations/%core/%project/%project-%version.%language.po')
|
Chris@0
|
316 ->save();
|
Chris@0
|
317 }
|
Chris@0
|
318 }
|