629 lines
22 KiB
Plaintext
629 lines
22 KiB
Plaintext
<?php
|
|
|
|
/**
|
|
* @file
|
|
* Install, update and uninstall functions for the locale module.
|
|
*/
|
|
|
|
/**
|
|
* Implements hook_uninstall().
|
|
*/
|
|
function locale_uninstall() {
|
|
// Delete all JavaScript translation files.
|
|
$locale_js_directory = 'public://' . variable_get('locale_js_directory', 'languages');
|
|
|
|
if (is_dir($locale_js_directory)) {
|
|
$locale_javascripts = variable_get('locale_translation_javascript', array());
|
|
foreach ($locale_javascripts as $langcode => $file_suffix) {
|
|
if (!empty($file_suffix)) {
|
|
file_unmanaged_delete($locale_js_directory . '/' . $langcode . '_' . $file_suffix . '.js');
|
|
}
|
|
}
|
|
// Delete the JavaScript translations directory if empty.
|
|
if (!file_scan_directory($locale_js_directory, '/.*/')) {
|
|
drupal_rmdir($locale_js_directory);
|
|
}
|
|
}
|
|
|
|
// Clear variables.
|
|
variable_del('locale_cache_strings');
|
|
variable_del('locale_js_directory');
|
|
variable_del('javascript_parsed');
|
|
variable_del('locale_cache_length');
|
|
variable_del('locale_translation_plurals');
|
|
variable_del('locale_translation_javascript');
|
|
|
|
// Remove all node type language variables. Node module might have been
|
|
// enabled, but may be disabled, so use a wildcard delete.
|
|
db_delete('variable')
|
|
->condition('name', db_like('language_content_type_') . '%', 'LIKE')
|
|
->execute();
|
|
}
|
|
|
|
/**
|
|
* Implements hook_schema().
|
|
*/
|
|
function locale_schema() {
|
|
$schema['locales_source'] = array(
|
|
'description' => 'List of English source strings.',
|
|
'fields' => array(
|
|
'lid' => array(
|
|
'type' => 'serial',
|
|
'not null' => TRUE,
|
|
'description' => 'Unique identifier of this string.',
|
|
),
|
|
'location' => array(
|
|
'type' => 'text',
|
|
'not null' => FALSE,
|
|
'size' => 'big',
|
|
'description' => 'Drupal path in case of online discovered translations or file path in case of imported strings.',
|
|
),
|
|
'source' => array(
|
|
'type' => 'text',
|
|
'mysql_type' => 'blob',
|
|
'not null' => TRUE,
|
|
'description' => 'The original string in English.',
|
|
),
|
|
'context' => array(
|
|
'type' => 'varchar',
|
|
'length' => 255,
|
|
'not null' => TRUE,
|
|
'default' => '',
|
|
'description' => 'The context this string applies to.',
|
|
),
|
|
'version' => array(
|
|
'type' => 'varchar',
|
|
'length' => 20,
|
|
'not null' => TRUE,
|
|
'default' => 'none',
|
|
'description' => 'Version of Drupal, where the string was last used (for locales optimization).',
|
|
),
|
|
),
|
|
'primary key' => array('lid'),
|
|
'indexes' => array(
|
|
'source_context' => array(array('source', 30), 'context'),
|
|
),
|
|
);
|
|
|
|
$schema['locales_target'] = array(
|
|
'description' => 'Stores translated versions of strings.',
|
|
'fields' => array(
|
|
'lid' => array(
|
|
'type' => 'int',
|
|
'not null' => TRUE,
|
|
'default' => 0,
|
|
'description' => 'Source string ID. References {locales_source}.lid.',
|
|
),
|
|
'translation' => array(
|
|
'type' => 'text',
|
|
'mysql_type' => 'blob',
|
|
'not null' => TRUE,
|
|
'description' => 'Translation string value in this language.',
|
|
),
|
|
'language' => array(
|
|
'type' => 'varchar',
|
|
'length' => 12,
|
|
'not null' => TRUE,
|
|
'default' => '',
|
|
'description' => 'Language code. References {language}.langcode.',
|
|
),
|
|
'customized' => array(
|
|
'type' => 'int',
|
|
'not null' => TRUE,
|
|
'default' => 0, // LOCALE_NOT_CUSTOMIZED
|
|
'description' => 'Boolean indicating whether the translation is custom to this site.',
|
|
),
|
|
),
|
|
'primary key' => array('language', 'lid'),
|
|
'foreign keys' => array(
|
|
'locales_source' => array(
|
|
'table' => 'locales_source',
|
|
'columns' => array('lid' => 'lid'),
|
|
),
|
|
),
|
|
'indexes' => array(
|
|
'lid' => array('lid'),
|
|
),
|
|
);
|
|
|
|
$schema['locale_file'] = array(
|
|
'description' => 'File import status information for interface translation files.',
|
|
'fields' => array(
|
|
'langcode' => array(
|
|
'description' => 'Reference to the {languages}.langcode for this translation.',
|
|
'type' => 'varchar',
|
|
'length' => '12',
|
|
'not null' => TRUE,
|
|
),
|
|
'filename' => array(
|
|
'description' => 'Filename for importing the file.',
|
|
'type' => 'varchar',
|
|
'length' => 255,
|
|
'not null' => TRUE,
|
|
'default' => '',
|
|
),
|
|
'uri' => array(
|
|
'description' => 'File system path for importing the file.',
|
|
'type' => 'varchar',
|
|
'length' => 255,
|
|
'not null' => TRUE,
|
|
'default' => '',
|
|
),
|
|
'timestamp' => array(
|
|
'description' => 'Unix timestamp of the file itself from the point when it was last imported.',
|
|
'type' => 'int',
|
|
'not null' => FALSE,
|
|
'default' => 0,
|
|
),
|
|
),
|
|
'primary key' => array('uri', 'langcode'),
|
|
);
|
|
|
|
return $schema;
|
|
}
|
|
|
|
/**
|
|
* @addtogroup updates-7.x-to-8.x
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* Drop textgroup support.
|
|
*
|
|
* Update assumes i18n migrated this data before the update happened. Core
|
|
* never used textgroups for anything, so it is not our job to find place
|
|
* for the data elsewhere.
|
|
*/
|
|
function locale_update_8000() {
|
|
$subquery = db_select('locales_source', 'ls')
|
|
->fields('ls', array('lid'))
|
|
->condition('ls.textgroup', 'default', '<>');
|
|
db_delete('locales_target')
|
|
->condition('lid', $subquery, 'IN')
|
|
->execute();
|
|
db_delete('locales_source')
|
|
->condition('textgroup', 'default', '<>')
|
|
->execute();
|
|
db_drop_field('locales_source', 'textgroup');
|
|
}
|
|
|
|
/**
|
|
* Language type 'language' renamed to 'language_interface'.
|
|
*
|
|
* @ingroup config_upgrade
|
|
*/
|
|
function locale_update_8001() {
|
|
// Only change language_types if we had this setting saved. Keep order
|
|
// of types because that is significant for value dependency.
|
|
$types = variable_get('language_types', NULL);
|
|
if (!empty($types) && isset($types['language'])) {
|
|
$new_types = array();
|
|
foreach ($types as $key => $type) {
|
|
$new_types[$key == 'language' ? 'language_interface' : $key] = $type;
|
|
}
|
|
variable_set('language_types', $new_types);
|
|
}
|
|
|
|
// Rename language_negotiation_language setting if exists.
|
|
$setting = variable_get('language_negotiation_language', NULL);
|
|
if ($setting !== NULL) {
|
|
variable_set('language_negotiation_language_interface', $setting);
|
|
variable_del('language_negotiation_language');
|
|
}
|
|
|
|
// Rename locale_language_providers_weight_language setting if exists.
|
|
$weight = variable_get('locale_language_providers_weight_language', NULL);
|
|
if ($weight !== NULL) {
|
|
variable_set('locale_language_providers_weight_language_interface', $weight);
|
|
variable_del('locale_language_providers_weight_language');
|
|
}
|
|
|
|
// Update block data in all core block related tables. Contributed modules
|
|
// storing data for blocks will need to update for themselves.
|
|
$block_tables = array('block', 'block_node_type', 'block_role');
|
|
foreach ($block_tables as $table) {
|
|
// Perform the update only if the language switcher block data is available.
|
|
$block_data = db_query_range('SELECT 1 FROM {' . $table . '} WHERE delta = :delta AND module = :module', 0, 1, array(':delta' => 'language', ':module' => 'locale'))
|
|
->fetchField();
|
|
if ($block_data) {
|
|
// If block information is rebuilt before performing the update, we might
|
|
// already have data for the new delta. In this case we need to remove it
|
|
// to avoid integrity constraint violation errors.
|
|
db_delete($table)
|
|
->condition('delta', 'language_interface')
|
|
->condition('module', 'locale')
|
|
->execute();
|
|
db_update($table)
|
|
->fields(array(
|
|
'delta' => 'language_interface',
|
|
))
|
|
->condition('delta', 'language')
|
|
->condition('module', 'locale')
|
|
->execute();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes duplicates in {locales_source}.
|
|
*
|
|
* Aggressively removes duplicates that has not already been removed by
|
|
* locale_update_7004() in Drupal 7.x.
|
|
*/
|
|
function locale_update_8002() {
|
|
// Look up all duplicates.
|
|
$results = db_query("SELECT source, context FROM {locales_source} GROUP BY source, context HAVING COUNT(*) > 1");
|
|
|
|
// For each set of duplicates, select one row that should survive, preferably
|
|
// one that has been translated, and delete the rest.
|
|
foreach ($results as $row) {
|
|
$lid = db_query("SELECT s.lid FROM {locales_source} s LEFT JOIN {locales_target} t ON s.lid = t.lid WHERE s.source = :source AND s.context = :context ORDER BY translation IS NULL", array(
|
|
':source' => $row->source,
|
|
':context' => $row->context,
|
|
))->fetchField();
|
|
db_delete('locales_source')
|
|
->condition('source', $row->source)
|
|
->condition('context', $row->context)
|
|
->condition('lid', $lid, '<>')
|
|
->execute();
|
|
}
|
|
|
|
// Finally remove any rows from {locales_target} that refer to non-existing
|
|
// lids.
|
|
$subquery = db_select('locales_source', 't')->fields('t', array('lid'));
|
|
db_delete('locales_target')->condition('lid', $subquery, 'NOT IN')->execute();
|
|
}
|
|
|
|
/**
|
|
* Converts language domains to new format.
|
|
*
|
|
* @ingroup config_upgrade
|
|
*/
|
|
function locale_update_8003() {
|
|
$message = '';
|
|
$domains = variable_get('locale_language_negotiation_url_domains', array());
|
|
// $used_domains keeps track of the domain names in use.
|
|
$used_domains = array();
|
|
foreach ($domains as $langcode => $domain) {
|
|
// Domain names can not contain protocol and/or ports.
|
|
if (!empty($domain)) {
|
|
$host = 'http://' . str_replace(array('http://', 'https://'), '', $domain);
|
|
if (parse_url($host, PHP_URL_HOST) != $domain) {
|
|
$domains[$langcode] = parse_url($host, PHP_URL_HOST);
|
|
}
|
|
if (array_key_exists($domain, $used_domains)) {
|
|
if (empty($message)) {
|
|
$message = 'Some languages are using the same domain name, you should change these domain names at ' . l('URL language detection configuration', 'admin/config/regional/language/configure/url' . '.');
|
|
}
|
|
}
|
|
else {
|
|
$used_domains[$domain] = $domain;
|
|
}
|
|
}
|
|
}
|
|
variable_set('locale_language_negotiation_url_domains', $domains);
|
|
|
|
if (!empty($message)) {
|
|
return $message;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Rename language providers to language negotiation methods.
|
|
*
|
|
* @ingroup config_upgrade
|
|
*/
|
|
function locale_update_8004() {
|
|
$types = variable_get('language_types', NULL);
|
|
if (!empty($types)) {
|
|
foreach ($types as $type => $configurable) {
|
|
// Rename the negotiation and language switch callback keys.
|
|
$negotiation = variable_get('language_negotiation_' . $type, NULL);
|
|
if (!empty($negotiation)) {
|
|
foreach ($negotiation as $method_id => &$method) {
|
|
$method['callbacks']['negotiation'] = $method['callbacks']['language'];
|
|
unset($method['callbacks']['language']);
|
|
if (isset($method['callbacks']['switcher'])) {
|
|
$method['callbacks']['language_switch'] = $method['callbacks']['switcher'];
|
|
unset($method['callbacks']['switcher']);
|
|
}
|
|
}
|
|
variable_set('language_negotiation_' . $type, $negotiation);
|
|
}
|
|
|
|
// Rename the language negotiation methods weight variable.
|
|
$weight = variable_get('locale_language_providers_weight_' . $type , NULL);
|
|
if ($weight !== NULL) {
|
|
variable_set('language_negotiation_methods_weight_' . $type , $weight);
|
|
variable_del('locale_language_providers_weight_' . $type);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update plural interface translations to new format.
|
|
*
|
|
* See http://drupal.org/node/532512#comment-5679184 for the details of the
|
|
* structures handled in this update.
|
|
*/
|
|
function locale_update_8005() {
|
|
// Collect all LIDs that are sources to plural variants.
|
|
$results = db_query("SELECT lid, plid FROM {locales_target} WHERE plural <> 0");
|
|
$plural_lids = array();
|
|
foreach ($results as $row) {
|
|
// Need to collect both LID and PLID. The LID for the first (singular)
|
|
// string can only be retrieved from the first plural's PLID given no
|
|
// other indication. The last plural variant is never referenced, so we
|
|
// need to store the LID directly for that. We never know whether we are
|
|
// on the last plural though, so we always remember LID too.
|
|
$plural_lids[] = $row->lid;
|
|
$plural_lids[] = $row->plid;
|
|
}
|
|
$plural_lids = array_unique($plural_lids);
|
|
|
|
if (!empty($plural_lids)) {
|
|
// Look up all translations for these source strings. Ordering by language
|
|
// will group the strings by language, the 'plid' order will get the strings
|
|
// in singular/plural order and 'plural' will get them in precise sequential
|
|
// order needed.
|
|
$results = db_query("SELECT s.lid, s.source, t.translation, t.plid, t.plural, t.language FROM {locales_source} s LEFT JOIN {locales_target} t ON s.lid = t.lid WHERE s.lid IN (:lids) ORDER BY t.language, t.plid, t.plural", array(':lids' => $plural_lids));
|
|
|
|
// Collect the strings into an array and combine values as we go.
|
|
$strings = array();
|
|
$parents_to_sources = array();
|
|
$remove_lids = array();
|
|
foreach ($results as $child) {
|
|
$strings[$child->language][$child->lid] = array(
|
|
'source' => array($child->source),
|
|
'translation' => array($child->translation),
|
|
);
|
|
|
|
if (empty($child->plid)) {
|
|
// Non-children strings point to themselves as parents. This makes it
|
|
// easy to look up the utmost parents for any plurals.
|
|
$parents_to_sources[$child->lid] = $child->lid;
|
|
}
|
|
else {
|
|
// Children strings point to their utmost parents. Because we get data
|
|
// in PLID order, we can ensure that all previous parents have data now,
|
|
// so we can just copy the parent's data about their parent, etc.
|
|
$parents_to_sources[$child->lid] = $parents_to_sources[$child->plid];
|
|
|
|
// Append translation to the utmost parent's translation string.
|
|
$utmost_parent = &$strings[$child->language][$parents_to_sources[$child->plid]];
|
|
// Drop the Drupal-specific numbering scheme from the end of plural
|
|
// formulas.
|
|
$utmost_parent['translation'][] = str_replace('@count[' . $child->plural .']', '@count', $child->translation);
|
|
if (count($utmost_parent['source']) < 2) {
|
|
// Append source to the utmost parent's source string only if it is
|
|
// the plural variant. Further Drupal specific plural variants are not
|
|
// to be retained for source strings.
|
|
$utmost_parent['source'][] = $child->source;
|
|
}
|
|
|
|
// All plural variant LIDs are to be removed with their translations.
|
|
// Only the singular LIDs will be kept.
|
|
$remove_lids[] = $child->lid;
|
|
}
|
|
}
|
|
|
|
// Do updates for all source strings and all translations.
|
|
$updated_sources = array();
|
|
foreach ($strings as $langcode => $translations) {
|
|
foreach($translations as $lid => $translation) {
|
|
if (!in_array($lid, $updated_sources)) {
|
|
// Only update source string if not yet updated. We merged these
|
|
// within the translation lookups because plural information was only
|
|
// available with the translation, but we don't need to save it again
|
|
// for every language.
|
|
db_update('locales_source')
|
|
->fields(array(
|
|
'source' => implode(LOCALE_PLURAL_DELIMITER, $translation['source']),
|
|
))
|
|
->condition('lid', $lid)
|
|
->execute();
|
|
$updated_sources[] = $lid;
|
|
}
|
|
db_update('locales_target')
|
|
->fields(array(
|
|
'translation' => implode(LOCALE_PLURAL_DELIMITER, $translation['translation']),
|
|
))
|
|
->condition('lid', $lid)
|
|
->condition('language', $langcode)
|
|
->execute();
|
|
}
|
|
}
|
|
|
|
// Remove all plural LIDs from source and target. only keep those which were
|
|
// originally used for the singular strings (now updated to contain the
|
|
// serialized version of plurals).
|
|
$remove_lids = array_unique($remove_lids);
|
|
db_delete('locales_source')
|
|
->condition('lid', $remove_lids, 'IN')
|
|
->execute();
|
|
db_delete('locales_target')
|
|
->condition('lid', $remove_lids, 'IN')
|
|
->execute();
|
|
}
|
|
|
|
// Drop the primary key because it contains 'plural'.
|
|
db_drop_primary_key('locales_target');
|
|
|
|
// Remove the 'plid' and 'plural' columns and indexes.
|
|
db_drop_index('locales_target', 'plid');
|
|
db_drop_field('locales_target', 'plid');
|
|
db_drop_index('locales_target', 'plural');
|
|
db_drop_field('locales_target', 'plural');
|
|
|
|
// Add back a primary key without 'plural'.
|
|
db_add_primary_key('locales_target', array('language', 'lid'));
|
|
}
|
|
|
|
/**
|
|
* Add column to track customized string status to locales_target.
|
|
*/
|
|
function locale_update_8006() {
|
|
$spec = array(
|
|
'type' => 'int',
|
|
'not null' => TRUE,
|
|
'default' => 0, // LOCALE_NOT_CUSTOMIZED
|
|
'description' => 'Boolean indicating whether the translation is custom to this site.',
|
|
);
|
|
db_add_field('locales_target', 'customized', $spec);
|
|
}
|
|
|
|
/**
|
|
* Convert language_negotiation_* variables to use the new callbacks.
|
|
*
|
|
* @ingroup config_upgrade
|
|
*/
|
|
function locale_update_8007() {
|
|
$variable_names = array(
|
|
'language_negotiation_language_interface',
|
|
'language_negotiation_language_content',
|
|
'language_negotiation_language_url',
|
|
);
|
|
// Add all language type weight variables. As the function language_types()
|
|
// is not available its functionality is rebuild.
|
|
$language_types = variable_get('language_types', array(
|
|
LANGUAGE_TYPE_INTERFACE => TRUE,
|
|
LANGUAGE_TYPE_CONTENT => FALSE,
|
|
LANGUAGE_TYPE_URL => FALSE,
|
|
));
|
|
foreach ($language_types as $language_type => $configurable) {
|
|
$variable_names[] = 'language_negotiation_methods_weight_' . $language_type;
|
|
}
|
|
$callback_map = array(
|
|
'locale_language_from_url' => 'language_from_url',
|
|
'locale_language_switcher_url' => 'language_switcher_url',
|
|
'locale_language_url_rewrite_url' => 'language_url_rewrite_url',
|
|
'locale_language_from_session' => 'language_from_session',
|
|
'locale_language_switcher_session' => 'language_switcher_session',
|
|
'locale_language_url_rewrite_session' => 'language_url_rewrite_session',
|
|
'locale_language_from_user' => 'language_from_user',
|
|
'locale_language_from_browser' => 'language_from_browser',
|
|
'locale_language_url_fallback' => 'language_url_fallback',
|
|
'locale_language_from_interface' => 'language_from_interface',
|
|
);
|
|
$type_map = array(
|
|
'locale-interface' => 'language-interface',
|
|
'locale-url' => 'language-url',
|
|
'locale-url-fallback' => 'language-url-fallback',
|
|
'locale-browser' => 'language-browser',
|
|
'locale-user' => 'language-user',
|
|
'locale-session' => 'language-session',
|
|
);
|
|
foreach ($variable_names as $variable_name) {
|
|
$value = variable_get($variable_name);
|
|
// Skip processing if the variable is not stored in the db.
|
|
if ($value === NULL) {
|
|
continue;
|
|
}
|
|
$new_value = $value;
|
|
foreach ($value as $type => $type_settings) {
|
|
// Convert the file.
|
|
if (isset($type_settings['file']) && (strpos($type_settings['file'], 'core/includes/locale.inc') !== FALSE)) {
|
|
$new_value[$type]['file'] = 'core/modules/language/language.negotiation.inc';
|
|
}
|
|
// Convert the callbacks.
|
|
if (is_array($type_settings) && isset($type_settings['callbacks'])) {
|
|
foreach ($type_settings['callbacks'] as $key => $callback) {
|
|
if (isset($callback_map[$callback])) {
|
|
$new_value[$type]['callbacks'][$key] = $callback_map[$callback];
|
|
}
|
|
}
|
|
}
|
|
// Convert the type.
|
|
if (isset($type_map[$type])) {
|
|
$new_value[$type_map[$type]] = $new_value[$type];
|
|
unset($new_value[$type]);
|
|
}
|
|
}
|
|
// If necessary maintain the order of the values / keys of the variable.
|
|
if (stristr($variable_name, 'language_negotiation_methods_weight_') !== FALSE) {
|
|
asort($new_value);
|
|
}
|
|
variable_set($variable_name, $new_value);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Rename the option variables of the locale language negotiation.
|
|
*
|
|
* @ingroup config_upgrade
|
|
*/
|
|
function locale_update_8008() {
|
|
$variable_name_map = array(
|
|
'locale_language_negotiation_url_part' => 'language_negotiation_url_part',
|
|
'locale_language_negotiation_url_domains' => 'language_negotiation_url_domains',
|
|
'locale_language_negotiation_url_prefixes' => 'language_negotiation_url_prefixes',
|
|
'locale_language_negotiation_session_param' => 'language_negotiation_session_param',
|
|
);
|
|
foreach ($variable_name_map as $deprecated_variable_name => $new_variable_name) {
|
|
// Check if this variable is stored in the db and if so rename it.
|
|
$value = variable_get($deprecated_variable_name);
|
|
if ($value !== NULL) {
|
|
variable_set($new_variable_name, $value);
|
|
variable_del($deprecated_variable_name);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Convert locale blocks to language blocks.
|
|
*/
|
|
function locale_update_8009() {
|
|
$block_tables = array('block', 'block_node_type', 'block_role');
|
|
foreach ($block_tables as $table) {
|
|
db_update($table)
|
|
->fields(array('module' => 'language'))
|
|
->condition('module', 'locale')
|
|
->execute();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add {locale_file} table.
|
|
*/
|
|
function locale_update_8010() {
|
|
$table = array(
|
|
'description' => 'File import status information for interface translation files.',
|
|
'fields' => array(
|
|
'langcode' => array(
|
|
'description' => 'Reference to the {languages}.langcode for this translation.',
|
|
'type' => 'varchar',
|
|
'length' => '12',
|
|
'not null' => TRUE,
|
|
),
|
|
'filename' => array(
|
|
'description' => 'Filename for importing the file.',
|
|
'type' => 'varchar',
|
|
'length' => 255,
|
|
'not null' => TRUE,
|
|
'default' => '',
|
|
),
|
|
'uri' => array(
|
|
'description' => 'File system path for importing the file.',
|
|
'type' => 'varchar',
|
|
'length' => 255,
|
|
'not null' => TRUE,
|
|
'default' => '',
|
|
),
|
|
'timestamp' => array(
|
|
'description' => 'Unix timestamp of the file itself from the point when it was last imported.',
|
|
'type' => 'int',
|
|
'not null' => FALSE,
|
|
'default' => 0,
|
|
),
|
|
),
|
|
'primary key' => array('uri', 'langcode'),
|
|
);
|
|
db_create_table('locale_file', $table);
|
|
}
|
|
|
|
/**
|
|
* @} End of "addtogroup updates-7.x-to-8.x".
|
|
* The next series of updates should start at 9000.
|
|
*/
|