1 |
85ad3d82
|
Assos Assos
|
<?php
|
2 |
|
|
|
3 |
|
|
/**
|
4 |
|
|
* @file
|
5 |
|
|
* Install, update and uninstall functions for the locale module.
|
6 |
|
|
*/
|
7 |
|
|
|
8 |
|
|
/**
|
9 |
|
|
* Implements hook_install().
|
10 |
|
|
*/
|
11 |
|
|
function locale_install() {
|
12 |
|
|
// locales_source.source and locales_target.target are not used as binary
|
13 |
|
|
// fields; non-MySQL database servers need to ensure the field type is text
|
14 |
|
|
// and that LIKE produces a case-sensitive comparison.
|
15 |
|
|
|
16 |
|
|
db_insert('languages')
|
17 |
|
|
->fields(array(
|
18 |
|
|
'language' => 'en',
|
19 |
|
|
'name' => 'English',
|
20 |
|
|
'native' => 'English',
|
21 |
|
|
'direction' => 0,
|
22 |
|
|
'enabled' => 1,
|
23 |
|
|
'weight' => 0,
|
24 |
|
|
'javascript' => '',
|
25 |
|
|
))
|
26 |
|
|
->execute();
|
27 |
|
|
}
|
28 |
|
|
|
29 |
|
|
/**
|
30 |
|
|
* @addtogroup updates-6.x-to-7.x
|
31 |
|
|
* @{
|
32 |
|
|
*/
|
33 |
|
|
|
34 |
|
|
/**
|
35 |
|
|
* Add context field index and allow longer location.
|
36 |
|
|
*/
|
37 |
|
|
function locale_update_7000() {
|
38 |
|
|
db_drop_index('locales_source', 'source');
|
39 |
|
|
db_add_index('locales_source', 'source_context', array(array('source', 30), 'context'));
|
40 |
|
|
|
41 |
|
|
// Also drop the 'textgroup_location' index added by the i18nstrings module
|
42 |
|
|
// of the i18n project, which prevents the below schema update from running.
|
43 |
|
|
if (db_index_exists('locales_source', 'textgroup_location')) {
|
44 |
|
|
db_drop_index('locales_source', 'textgroup_location');
|
45 |
|
|
}
|
46 |
|
|
|
47 |
|
|
db_change_field('locales_source', 'location', 'location', array(
|
48 |
|
|
'type' => 'text',
|
49 |
|
|
'not null' => FALSE,
|
50 |
|
|
'size' => 'big',
|
51 |
|
|
'description' => 'Drupal path in case of online discovered translations or file path in case of imported strings.',
|
52 |
|
|
));
|
53 |
|
|
}
|
54 |
|
|
|
55 |
|
|
/**
|
56 |
|
|
* Upgrade language negotiation settings.
|
57 |
|
|
*/
|
58 |
|
|
function locale_update_7001() {
|
59 |
|
|
require_once DRUPAL_ROOT . '/includes/language.inc';
|
60 |
|
|
require_once DRUPAL_ROOT . '/includes/locale.inc';
|
61 |
|
|
require_once DRUPAL_ROOT . '/modules/locale/locale.module';
|
62 |
|
|
|
63 |
|
|
switch (variable_get('language_negotiation', 0)) {
|
64 |
|
|
// LANGUAGE_NEGOTIATION_NONE.
|
65 |
|
|
case 0:
|
66 |
|
|
$negotiation = array();
|
67 |
|
|
break;
|
68 |
|
|
|
69 |
|
|
// LANGUAGE_NEGOTIATION_PATH_DEFAULT.
|
70 |
|
|
case 1:
|
71 |
|
|
$negotiation = array(LOCALE_LANGUAGE_NEGOTIATION_URL);
|
72 |
|
|
// In Drupal 6 path prefixes are shown for the default language only when
|
73 |
|
|
// language negotiation is set to LANGUAGE_NEGOTIATION_PATH, while in
|
74 |
|
|
// Drupal 7 path prefixes are always shown if not empty. Hence we need to
|
75 |
|
|
// ensure that the default language has an empty prefix to avoid breaking
|
76 |
|
|
// the site URLs with a prefix that previously was missing.
|
77 |
|
|
$default = language_default();
|
78 |
|
|
$default->prefix = '';
|
79 |
|
|
variable_set('language_default', $default);
|
80 |
|
|
db_update('languages')
|
81 |
|
|
->fields(array('prefix' => $default->prefix))
|
82 |
|
|
->condition('language', $default->language)
|
83 |
|
|
->execute();
|
84 |
|
|
break;
|
85 |
|
|
|
86 |
|
|
// LANGUAGE_NEGOTIATION_PATH.
|
87 |
|
|
case 2:
|
88 |
|
|
$negotiation = array(LOCALE_LANGUAGE_NEGOTIATION_URL, LOCALE_LANGUAGE_NEGOTIATION_USER, LOCALE_LANGUAGE_NEGOTIATION_BROWSER);
|
89 |
|
|
break;
|
90 |
|
|
|
91 |
|
|
// LANGUAGE_NEGOTIATION_DOMAIN.
|
92 |
|
|
case 3:
|
93 |
|
|
variable_set('locale_language_negotiation_url_part', LOCALE_LANGUAGE_NEGOTIATION_URL_DOMAIN);
|
94 |
|
|
$negotiation = array(LOCALE_LANGUAGE_NEGOTIATION_URL);
|
95 |
|
|
break;
|
96 |
|
|
}
|
97 |
|
|
|
98 |
|
|
// Save the new language negotiation options.
|
99 |
|
|
language_negotiation_set(LANGUAGE_TYPE_INTERFACE, array_flip($negotiation));
|
100 |
|
|
language_negotiation_set(LANGUAGE_TYPE_CONTENT, array(LOCALE_LANGUAGE_NEGOTIATION_INTERFACE => 0));
|
101 |
|
|
language_negotiation_set(LANGUAGE_TYPE_URL, array(LOCALE_LANGUAGE_NEGOTIATION_URL => 0));
|
102 |
|
|
|
103 |
|
|
// Save admininstration UI settings.
|
104 |
|
|
$type = LANGUAGE_TYPE_INTERFACE;
|
105 |
|
|
$provider_weights = array_flip(array_keys(locale_language_negotiation_info()));
|
106 |
|
|
variable_set("locale_language_providers_weight_$type", $provider_weights);
|
107 |
|
|
|
108 |
|
|
// Unset the old language negotiation system variable.
|
109 |
|
|
variable_del('language_negotiation');
|
110 |
|
|
|
111 |
|
|
return array();
|
112 |
|
|
}
|
113 |
|
|
|
114 |
|
|
/**
|
115 |
|
|
* Updates URL language negotiation by adding the URL fallback detection method.
|
116 |
|
|
*/
|
117 |
|
|
function locale_update_7002() {
|
118 |
|
|
// language.inc may not have been included during bootstrap if there is not
|
119 |
|
|
// more than one language currently enabled.
|
120 |
|
|
require_once DRUPAL_ROOT . '/includes/language.inc';
|
121 |
|
|
$language_types_info = language_types_info();
|
122 |
|
|
$info = $language_types_info[LANGUAGE_TYPE_URL];
|
123 |
|
|
if (isset($info['fixed'])) {
|
124 |
|
|
language_negotiation_set(LANGUAGE_TYPE_URL, array_flip($info['fixed']));
|
125 |
|
|
}
|
126 |
|
|
}
|
127 |
|
|
|
128 |
|
|
/**
|
129 |
|
|
* @} End of "addtogroup updates-6.x-to-7.x".
|
130 |
|
|
*/
|
131 |
|
|
|
132 |
|
|
/**
|
133 |
|
|
* @addtogroup updates-7.x-extra
|
134 |
|
|
* @{
|
135 |
|
|
*/
|
136 |
|
|
|
137 |
|
|
/**
|
138 |
|
|
* Update "language_count" variable.
|
139 |
|
|
*/
|
140 |
|
|
function locale_update_7003() {
|
141 |
|
|
$languages = language_list('enabled');
|
142 |
|
|
variable_set('language_count', count($languages[1]));
|
143 |
|
|
}
|
144 |
|
|
|
145 |
|
|
/**
|
146 |
|
|
* Remove duplicates in {locales_source}.
|
147 |
|
|
*/
|
148 |
|
|
function locale_update_7004() {
|
149 |
|
|
// Look up all duplicates. For each set of duplicates, we select the row
|
150 |
|
|
// with the lowest lid as the "master" that will be preserved.
|
151 |
|
|
$result_source = db_query("SELECT MIN(lid) AS lid, source, context FROM {locales_source} WHERE textgroup = 'default' GROUP BY source, context HAVING COUNT(*) > 1");
|
152 |
|
|
|
153 |
|
|
$conflict = FALSE;
|
154 |
|
|
foreach ($result_source as $source) {
|
155 |
|
|
// Find all rows in {locales_target} that are translations of the same
|
156 |
|
|
// string (incl. context).
|
157 |
|
|
$result_target = db_query("SELECT t.lid, t.language, t.plural, t.translation FROM {locales_source} s JOIN {locales_target} t ON s.lid = t.lid WHERE s.source = :source AND s.context = :context AND s.textgroup = 'default' ORDER BY lid", array(
|
158 |
|
|
':source' => $source->source,
|
159 |
|
|
':context' => $source->context,
|
160 |
|
|
));
|
161 |
|
|
|
162 |
|
|
$translations = array();
|
163 |
|
|
$keep_lids = array($source->lid);
|
164 |
|
|
foreach ($result_target as $target) {
|
165 |
|
|
if (!isset($translations[$target->language])) {
|
166 |
|
|
$translations[$target->language] = $target->translation;
|
167 |
|
|
if ($target->lid != $source->lid) {
|
168 |
|
|
// Move translation to the master lid.
|
169 |
|
|
db_query('UPDATE {locales_target} SET lid = :new_lid WHERE lid = :old_lid', array(
|
170 |
|
|
':new_lid' => $source->lid,
|
171 |
|
|
':old_lid' => $target->lid));
|
172 |
|
|
}
|
173 |
|
|
}
|
174 |
|
|
elseif ($translations[$target->language] == $target->translation) {
|
175 |
|
|
// Delete duplicate translation.
|
176 |
|
|
db_query('DELETE FROM {locales_target} WHERE lid = :lid AND language = :language', array(
|
177 |
|
|
':lid' => $target->lid,
|
178 |
|
|
':language' => $target->language));
|
179 |
|
|
}
|
180 |
|
|
else {
|
181 |
|
|
// The same string is translated into several different strings in one
|
182 |
|
|
// language. We do not know which is the preferred, so we keep them all.
|
183 |
|
|
$keep_lids[] = $target->lid;
|
184 |
|
|
$conflict = TRUE;
|
185 |
|
|
}
|
186 |
|
|
}
|
187 |
|
|
|
188 |
|
|
// Delete rows in {locales_source} that are no longer referenced from
|
189 |
|
|
// {locales_target}.
|
190 |
|
|
db_delete('locales_source')
|
191 |
|
|
->condition('source', $source->source)
|
192 |
|
|
->condition('context', $source->context)
|
193 |
|
|
->condition('textgroup', 'default')
|
194 |
|
|
->condition('lid', $keep_lids, 'NOT IN')
|
195 |
|
|
->execute();
|
196 |
|
|
}
|
197 |
|
|
|
198 |
|
|
if ($conflict) {
|
199 |
|
|
$url = 'http://drupal.org/node/746240';
|
200 |
|
|
drupal_set_message('Your {locales_source} table contains duplicates that could not be removed automatically. See <a href="' . $url .'" target="_blank">' . $url . '</a> for more information.', 'warning');
|
201 |
|
|
}
|
202 |
|
|
}
|
203 |
|
|
|
204 |
|
|
/**
|
205 |
|
|
* Increase {locales_languages}.formula column's length.
|
206 |
|
|
*/
|
207 |
|
|
function locale_update_7005() {
|
208 |
|
|
db_change_field('languages', 'formula', 'formula', array(
|
209 |
|
|
'type' => 'varchar',
|
210 |
|
|
'length' => 255,
|
211 |
|
|
'not null' => TRUE,
|
212 |
|
|
'default' => '',
|
213 |
|
|
'description' => 'Plural formula in PHP code to evaluate to get plural indexes.',
|
214 |
|
|
));
|
215 |
|
|
}
|
216 |
|
|
|
217 |
|
|
/**
|
218 |
|
|
* @} End of "addtogroup updates-7.x-extra".
|
219 |
|
|
*/
|
220 |
|
|
|
221 |
|
|
/**
|
222 |
|
|
* Implements hook_uninstall().
|
223 |
|
|
*/
|
224 |
|
|
function locale_uninstall() {
|
225 |
|
|
// Delete all JavaScript translation files.
|
226 |
|
|
$locale_js_directory = 'public://' . variable_get('locale_js_directory', 'languages');
|
227 |
|
|
|
228 |
|
|
if (is_dir($locale_js_directory)) {
|
229 |
|
|
$files = db_query('SELECT language, javascript FROM {languages}');
|
230 |
|
|
foreach ($files as $file) {
|
231 |
|
|
if (!empty($file->javascript)) {
|
232 |
|
|
file_unmanaged_delete($locale_js_directory . '/' . $file->language . '_' . $file->javascript . '.js');
|
233 |
|
|
}
|
234 |
|
|
}
|
235 |
|
|
// Delete the JavaScript translations directory if empty.
|
236 |
|
|
if (!file_scan_directory($locale_js_directory, '/.*/')) {
|
237 |
|
|
drupal_rmdir($locale_js_directory);
|
238 |
|
|
}
|
239 |
|
|
}
|
240 |
|
|
|
241 |
|
|
// Clear variables.
|
242 |
|
|
variable_del('language_default');
|
243 |
|
|
variable_del('language_count');
|
244 |
|
|
variable_del('language_types');
|
245 |
|
|
variable_del('locale_language_negotiation_url_part');
|
246 |
|
|
variable_del('locale_language_negotiation_session_param');
|
247 |
|
|
variable_del('language_content_type_default');
|
248 |
|
|
variable_del('language_content_type_negotiation');
|
249 |
|
|
variable_del('locale_cache_strings');
|
250 |
|
|
variable_del('locale_js_directory');
|
251 |
|
|
variable_del('javascript_parsed');
|
252 |
|
|
variable_del('locale_field_language_fallback');
|
253 |
|
|
variable_del('locale_cache_length');
|
254 |
|
|
|
255 |
|
|
foreach (language_types() as $type) {
|
256 |
|
|
variable_del("language_negotiation_$type");
|
257 |
|
|
variable_del("locale_language_providers_weight_$type");
|
258 |
|
|
}
|
259 |
|
|
|
260 |
|
|
foreach (node_type_get_types() as $type => $content_type) {
|
261 |
|
|
$setting = variable_del("language_content_type_$type");
|
262 |
|
|
}
|
263 |
|
|
|
264 |
|
|
// Switch back to English: with a $language->language value different from 'en'
|
265 |
|
|
// successive calls of t() might result in calling locale(), which in turn might
|
266 |
|
|
// try to query the unexisting {locales_source} and {locales_target} tables.
|
267 |
|
|
drupal_language_initialize();
|
268 |
|
|
|
269 |
|
|
}
|
270 |
|
|
|
271 |
|
|
/**
|
272 |
|
|
* Implements hook_schema().
|
273 |
|
|
*/
|
274 |
|
|
function locale_schema() {
|
275 |
|
|
$schema['languages'] = array(
|
276 |
|
|
'description' => 'List of all available languages in the system.',
|
277 |
|
|
'fields' => array(
|
278 |
|
|
'language' => array(
|
279 |
|
|
'type' => 'varchar',
|
280 |
|
|
'length' => 12,
|
281 |
|
|
'not null' => TRUE,
|
282 |
|
|
'default' => '',
|
283 |
|
|
'description' => "Language code, e.g. 'de' or 'en-US'.",
|
284 |
|
|
),
|
285 |
|
|
'name' => array(
|
286 |
|
|
'type' => 'varchar',
|
287 |
|
|
'length' => 64,
|
288 |
|
|
'not null' => TRUE,
|
289 |
|
|
'default' => '',
|
290 |
|
|
'description' => 'Language name in English.',
|
291 |
|
|
),
|
292 |
|
|
'native' => array(
|
293 |
|
|
'type' => 'varchar',
|
294 |
|
|
'length' => 64,
|
295 |
|
|
'not null' => TRUE,
|
296 |
|
|
'default' => '',
|
297 |
|
|
'description' => 'Native language name.',
|
298 |
|
|
),
|
299 |
|
|
'direction' => array(
|
300 |
|
|
'type' => 'int',
|
301 |
|
|
'not null' => TRUE,
|
302 |
|
|
'default' => 0,
|
303 |
|
|
'description' => 'Direction of language (Left-to-Right = 0, Right-to-Left = 1).',
|
304 |
|
|
),
|
305 |
|
|
'enabled' => array(
|
306 |
|
|
'type' => 'int',
|
307 |
|
|
'not null' => TRUE,
|
308 |
|
|
'default' => 0,
|
309 |
|
|
'description' => 'Enabled flag (1 = Enabled, 0 = Disabled).',
|
310 |
|
|
),
|
311 |
|
|
'plurals' => array(
|
312 |
|
|
'type' => 'int',
|
313 |
|
|
'not null' => TRUE,
|
314 |
|
|
'default' => 0,
|
315 |
|
|
'description' => 'Number of plural indexes in this language.',
|
316 |
|
|
),
|
317 |
|
|
'formula' => array(
|
318 |
|
|
'type' => 'varchar',
|
319 |
|
|
'length' => 255,
|
320 |
|
|
'not null' => TRUE,
|
321 |
|
|
'default' => '',
|
322 |
|
|
'description' => 'Plural formula in PHP code to evaluate to get plural indexes.',
|
323 |
|
|
),
|
324 |
|
|
'domain' => array(
|
325 |
|
|
'type' => 'varchar',
|
326 |
|
|
'length' => 128,
|
327 |
|
|
'not null' => TRUE,
|
328 |
|
|
'default' => '',
|
329 |
|
|
'description' => 'Domain to use for this language.',
|
330 |
|
|
),
|
331 |
|
|
'prefix' => array(
|
332 |
|
|
'type' => 'varchar',
|
333 |
|
|
'length' => 128,
|
334 |
|
|
'not null' => TRUE,
|
335 |
|
|
'default' => '',
|
336 |
|
|
'description' => 'Path prefix to use for this language.',
|
337 |
|
|
),
|
338 |
|
|
'weight' => array(
|
339 |
|
|
'type' => 'int',
|
340 |
|
|
'not null' => TRUE,
|
341 |
|
|
'default' => 0,
|
342 |
|
|
'description' => 'Weight, used in lists of languages.',
|
343 |
|
|
),
|
344 |
|
|
'javascript' => array(
|
345 |
|
|
'type' => 'varchar',
|
346 |
|
|
'length' => 64,
|
347 |
|
|
'not null' => TRUE,
|
348 |
|
|
'default' => '',
|
349 |
|
|
'description' => 'Location of JavaScript translation file.',
|
350 |
|
|
),
|
351 |
|
|
),
|
352 |
|
|
'primary key' => array('language'),
|
353 |
|
|
'indexes' => array(
|
354 |
|
|
'list' => array('weight', 'name'),
|
355 |
|
|
),
|
356 |
|
|
);
|
357 |
|
|
|
358 |
|
|
$schema['locales_source'] = array(
|
359 |
|
|
'description' => 'List of English source strings.',
|
360 |
|
|
'fields' => array(
|
361 |
|
|
'lid' => array(
|
362 |
|
|
'type' => 'serial',
|
363 |
|
|
'not null' => TRUE,
|
364 |
|
|
'description' => 'Unique identifier of this string.',
|
365 |
|
|
),
|
366 |
|
|
'location' => array(
|
367 |
|
|
'type' => 'text',
|
368 |
|
|
'not null' => FALSE,
|
369 |
|
|
'size' => 'big',
|
370 |
|
|
'description' => 'Drupal path in case of online discovered translations or file path in case of imported strings.',
|
371 |
|
|
),
|
372 |
|
|
'textgroup' => array(
|
373 |
|
|
'type' => 'varchar',
|
374 |
|
|
'length' => 255,
|
375 |
|
|
'not null' => TRUE,
|
376 |
|
|
'default' => 'default',
|
377 |
|
|
'description' => 'A module defined group of translations, see hook_locale().',
|
378 |
|
|
),
|
379 |
|
|
'source' => array(
|
380 |
|
|
'type' => 'text',
|
381 |
|
|
'mysql_type' => 'blob',
|
382 |
|
|
'not null' => TRUE,
|
383 |
|
|
'description' => 'The original string in English.',
|
384 |
|
|
),
|
385 |
|
|
'context' => array(
|
386 |
|
|
'type' => 'varchar',
|
387 |
|
|
'length' => 255,
|
388 |
|
|
'not null' => TRUE,
|
389 |
|
|
'default' => '',
|
390 |
|
|
'description' => 'The context this string applies to.',
|
391 |
|
|
),
|
392 |
|
|
'version' => array(
|
393 |
|
|
'type' => 'varchar',
|
394 |
|
|
'length' => 20,
|
395 |
|
|
'not null' => TRUE,
|
396 |
|
|
'default' => 'none',
|
397 |
|
|
'description' => 'Version of Drupal, where the string was last used (for locales optimization).',
|
398 |
|
|
),
|
399 |
|
|
),
|
400 |
|
|
'primary key' => array('lid'),
|
401 |
|
|
'indexes' => array(
|
402 |
|
|
'source_context' => array(array('source', 30), 'context'),
|
403 |
|
|
),
|
404 |
|
|
);
|
405 |
|
|
|
406 |
|
|
$schema['locales_target'] = array(
|
407 |
|
|
'description' => 'Stores translated versions of strings.',
|
408 |
|
|
'fields' => array(
|
409 |
|
|
'lid' => array(
|
410 |
|
|
'type' => 'int',
|
411 |
|
|
'not null' => TRUE,
|
412 |
|
|
'default' => 0,
|
413 |
|
|
'description' => 'Source string ID. References {locales_source}.lid.',
|
414 |
|
|
),
|
415 |
|
|
'translation' => array(
|
416 |
|
|
'type' => 'text',
|
417 |
|
|
'mysql_type' => 'blob',
|
418 |
|
|
'not null' => TRUE,
|
419 |
|
|
'description' => 'Translation string value in this language.',
|
420 |
|
|
),
|
421 |
|
|
'language' => array(
|
422 |
|
|
'type' => 'varchar',
|
423 |
|
|
'length' => 12,
|
424 |
|
|
'not null' => TRUE,
|
425 |
|
|
'default' => '',
|
426 |
|
|
'description' => 'Language code. References {languages}.language.',
|
427 |
|
|
),
|
428 |
|
|
'plid' => array(
|
429 |
|
|
'type' => 'int',
|
430 |
|
|
'not null' => TRUE, // This should be NULL for no referenced string, not zero.
|
431 |
|
|
'default' => 0,
|
432 |
|
|
'description' => 'Parent lid (lid of the previous string in the plural chain) in case of plural strings. References {locales_source}.lid.',
|
433 |
|
|
),
|
434 |
|
|
'plural' => array(
|
435 |
|
|
'type' => 'int',
|
436 |
|
|
'not null' => TRUE,
|
437 |
|
|
'default' => 0,
|
438 |
|
|
'description' => 'Plural index number in case of plural strings.',
|
439 |
|
|
),
|
440 |
|
|
),
|
441 |
|
|
'primary key' => array('language', 'lid', 'plural'),
|
442 |
|
|
'foreign keys' => array(
|
443 |
|
|
'locales_source' => array(
|
444 |
|
|
'table' => 'locales_source',
|
445 |
|
|
'columns' => array('lid' => 'lid'),
|
446 |
|
|
),
|
447 |
|
|
),
|
448 |
|
|
'indexes' => array(
|
449 |
|
|
'lid' => array('lid'),
|
450 |
|
|
'plid' => array('plid'),
|
451 |
|
|
'plural' => array('plural'),
|
452 |
|
|
),
|
453 |
|
|
);
|
454 |
|
|
|
455 |
|
|
return $schema;
|
456 |
|
|
}
|