get('translation.path')) { $directory = conf_path() . '/files/translations'; \Drupal::config('locale.settings')->set('translation.path', $directory)->save(); } file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); } /** * Implements hook_uninstall(). */ function locale_uninstall() { $config = \Drupal::config('locale.settings'); // Delete all JavaScript translation files. $locale_js_directory = 'public://' . $config->get('javascript.directory'); if (is_dir($locale_js_directory)) { $locale_javascripts = \Drupal::state()->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. \Drupal::state()->delete('system.javascript_parsed'); \Drupal::state()->delete('locale.translation.plurals'); \Drupal::state()->delete('locale.translation.javascript'); } /** * 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.', ), '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['locales_location'] = array( 'description' => 'Location information for source strings.', 'fields' => array( 'lid' => array( 'type' => 'serial', 'not null' => TRUE, 'description' => 'Unique identifier of this location.', ), 'sid' => array( 'type' => 'int', 'not null' => TRUE, 'description' => 'Unique identifier of this string.', ), 'type' => array( 'type' => 'varchar', 'length' => 50, 'not null' => TRUE, 'default' => '', 'description' => 'The location type (file, config, path, etc).', ), 'name' => array( 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', 'description' => 'Type dependent location information (file name, path, etc).', ), 'version' => array( 'type' => 'varchar', 'length' => 20, 'not null' => TRUE, 'default' => 'none', 'description' => 'Version of Drupal where the location was found.', ), ), 'primary key' => array('lid'), 'foreign keys' => array( 'locales_source' => array( 'table' => 'locales_source', 'columns' => array('sid' => 'lid'), ), ), 'indexes' => array( 'string_id' => array('sid'), 'string_type' => array('sid', 'type'), ), ); $schema['locale_file'] = array( 'description' => 'File import status information for interface translation files.', 'fields' => array( 'project' => array( 'type' => 'varchar', 'length' => '255', 'not null' => TRUE, 'default' => '', 'description' => 'A unique short name to identify the project the file belongs to.', ), 'langcode' => array( 'type' => 'varchar', 'length' => '12', 'not null' => TRUE, 'default' => '', 'description' => 'Language code of this translation. References {language}.langcode.', ), 'filename' => array( 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', 'description' => 'Filename of the imported file.', ), 'version' => array( 'type' => 'varchar', 'length' => '128', 'not null' => TRUE, 'default' => '', 'description' => 'Version tag of the imported file.', ), 'uri' => array( 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', 'description' => 'URI of the remote file, the resulting local file or the locally imported file.', ), 'timestamp' => array( 'type' => 'int', 'not null' => FALSE, 'default' => 0, 'description' => 'Unix timestamp of the imported file.', ), 'last_checked' => array( 'type' => 'int', 'not null' => FALSE, 'default' => 0, 'description' => 'Unix timestamp of the last time this translation was confirmed to be the most recent release available.', ), ), 'primary key' => array('project', 'langcode'), ); $schema['locale_project'] = array( 'description' => 'Translation status information for projects and server data.', 'fields' => array( 'name' => array( 'description' => 'A unique short name to identify the project.', 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, ), 'project_type' => array( 'description' => 'Project type: core, module, or theme.', 'type' => 'varchar', 'length' => 15, 'not null' => TRUE, ), 'core' => array( // http://drupal.org/node/542202#core has an example. 'description' => 'Core compatibility string for this project, for example: 8.x', 'type' => 'varchar', 'length' => 4, 'not null' => TRUE, 'default' => '', ), 'version' => array( // http://drupal.org/node/467026 has examples. 'description' => 'The version release of the project, for example: 8.x-2.1 or 8.x-1.0-dev', 'type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => '', ), 'server_pattern' => array( 'description' => 'Pattern of path and name of the gettext file at the translation server.', 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', ), 'status' => array( // locale.compare.inc gives possible values for status. 'description' => 'The status of the project. Possible values are: 1 = enabled, 0 = disabled.', 'type' => 'int', 'not null' => TRUE, 'default' => 1, ), ), 'primary key' => array('name'), ); return $schema; } /** * Implements hook_requirements(). */ function locale_requirements($phase) { $requirements = array(); if ($phase == 'runtime') { $available_updates = array(); $untranslated = array(); $languages = locale_translatable_language_list(); if ($languages) { // Determine the status of the translation updates per language. $status = locale_translation_get_status(); if ($status) { foreach ($status as $project) { foreach ($project as $langcode => $project_info) { if (empty($project_info->type)) { $untranslated[$langcode] = $languages[$langcode]->name; } elseif ($project_info->type == LOCALE_TRANSLATION_LOCAL || $project_info->type == LOCALE_TRANSLATION_REMOTE) { $available_updates[$langcode] = $languages[$langcode]->name; } } } if ($available_updates || $untranslated) { if ($available_updates) { $requirements['locale_translation'] = array( 'title' => 'Translation update status', 'value' => l(t('Updates available'), 'admin/reports/translations'), 'severity' => REQUIREMENT_WARNING, 'description' => t('Updates available for: @languages. See the Available translation updates page for more information.', array('@languages' => implode(', ', $available_updates), '@updates' => url('admin/reports/translations'))), ); } else { $requirements['locale_translation'] = array( 'title' => 'Translation update status', 'value' => t('Missing translations'), 'severity' => REQUIREMENT_INFO, 'description' => t('Missing translations for: @languages. See the Available translation updates page for more information.', array('@languages' => implode(', ', $untranslated), '@updates' => url('admin/reports/translations'))), ); } } else { $requirements['locale_translation'] = array( 'title' => 'Translation update status', 'value' => t('Up to date'), 'severity' => REQUIREMENT_OK, ); } } else { $requirements['locale_translation'] = array( 'title' => 'Translation update status', 'value' => l(t('Can not determine status'), 'admin/reports/translations'), 'severity' => REQUIREMENT_WARNING, 'description' => t('No translation status is available. See the Available translation updates page for more information.', array('@updates' => url('admin/reports/translations'))), ); } } } return $requirements; } /** * @addtogroup updates-7.x-to-8.x * @{ */ /** * Drops 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 a 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 = update_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; } update_variable_set('language_types', $new_types); } // Rename language_negotiation_language setting if exists. $setting = update_variable_get('language_negotiation_language', NULL); if ($setting !== NULL) { update_variable_set('language_negotiation_language_interface', $setting); update_variable_del('language_negotiation_language'); } // Rename locale_language_providers_weight_language setting if exists. $weight = update_variable_get('locale_language_providers_weight_language', NULL); if ($weight !== NULL) { update_variable_set('locale_language_providers_weight_language_interface', $weight); update_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 = ''; $config = \Drupal::config('language.negotiation'); $domains = $config->get('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; } } } $config->set('url.domains', $domains)->save(); if (!empty($message)) { return $message; } } /** * Rename language providers to language negotiation methods. * * @ingroup config_upgrade */ function locale_update_8004() { $types = update_variable_get('language_types', NULL); if (!empty($types)) { foreach ($types as $type => $configurable) { // Rename the negotiation and language switch callback keys. $negotiation = update_variable_get('language_negotiation_' . $type, NULL); if (!empty($negotiation)) { foreach ($negotiation as &$method) { if (isset($method['callbacks']['language'])) { $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']); } } update_variable_set('language_negotiation_' . $type, $negotiation); } // Rename the language negotiation methods weight variable. $weight = update_variable_get('locale_language_providers_weight_' . $type , NULL); if ($weight !== NULL) { update_variable_set('language_negotiation_methods_weight_' . $type , $weight); update_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')); } /** * 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 = update_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 = update_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); } update_variable_set($variable_name, $new_value); } } /** * Update locale variables to config or state systems as appropriate. * * @ingroup config_upgrade */ function locale_update_8008() { update_variables_to_config('locale.settings', array( 'locale_cache_strings' => 'cache_strings', 'locale_js_directory' => 'javascript.directory', )); update_variables_to_config('language.negotiation', array( 'locale_language_negotiation_session_param' => 'session.parameter', 'locale_language_negotiation_url_part' => 'url.source', )); } /** * 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( '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); } /** * Add a cache table and locale_project table for the locale module. */ function locale_update_8011() { // Add locale_project table. db_create_table('locale_project', array( 'description' => 'Translation status information for projects and server data.', 'fields' => array( 'name' => array( 'description' => 'A unique short name to identify the project.', 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, ), 'project_type' => array( 'description' => 'Project type, may be core, module, theme', 'type' => 'varchar', 'length' => 15, 'not null' => TRUE, ), 'core' => array( 'description' => 'Core compatibility string for this project.', 'type' => 'varchar', 'length' => 4, 'not null' => TRUE, 'default' => '', ), 'version' => array( 'description' => 'The release version of the project.', 'type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => '', ), 'server_pattern' => array( 'description' => 'Pattern of path and name of the gettext file at the translation server.', 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', ), 'status' => array( 'description' => 'The update status of the project.', 'type' => 'int', 'not null' => TRUE, 'default' => 1, ), ), 'primary key' => array('name'), )); } /** * Renames language_default language negotiation method to language_selected. */ function locale_update_8013() { // @todo We only need language.inc here because LANGUAGE_NEGOTIATION_SELECTED // is defined there. Remove this line once that has been converted to a class // constant. require_once DRUPAL_ROOT . '/core/includes/language.inc'; $weight = update_variable_get('language_negotiation_methods_weight_language_interface', NULL); if ($weight !== NULL) { $weight[LANGUAGE_NEGOTIATION_SELECTED] = $weight['language-default']; unset($weight['language-default']); update_variable_set('language_negotiation_methods_weight_language_interface', $weight); } $negotiation_interface = update_variable_get('language_negotiation_language_interface', NULL); if ($negotiation_interface !== NULL) { if (isset($negotiation_interface['language-default'])) { $negotiation_interface[LANGUAGE_NEGOTIATION_SELECTED] = $negotiation_interface['language-default']; $negotiation_interface[LANGUAGE_NEGOTIATION_SELECTED]['callbacks']['negotiation'] = 'language_from_selected'; unset($negotiation_interface['language-default']); update_variable_set('language_negotiation_language_interface', $negotiation_interface); } } } /** * Drop old 'location' field. */ function locale_update_8014() { db_drop_field('locales_source', 'location'); } /** * Build a new {locale_file} table. */ function locale_update_8015() { // The existing table has a primary key on uri and langcode. The new key // is on project and langcode. There is no project data in the existing table, // and it may not be possible to generate this reliably. Therefore we drop // the table and build it again. db_drop_table('locale_file'); $table = array( 'description' => 'File import status information for interface translation files.', 'fields' => array( 'project' => array( 'type' => 'varchar', 'length' => '255', 'not null' => TRUE, 'default' => '', 'description' => 'A unique short name to identify the project the file belongs to.', ), 'langcode' => array( 'type' => 'varchar', 'length' => '12', 'not null' => TRUE, 'default' => '', 'description' => 'Language code of this translation. References {language}.langcode.', ), 'filename' => array( 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', 'description' => 'Filename of the imported file.', ), 'version' => array( 'type' => 'varchar', 'length' => '128', 'not null' => TRUE, 'default' => '', 'description' => 'Version tag of the imported file.', ), 'uri' => array( 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', 'description' => 'URI of the remote file, the resulting local file or the locally imported file.', ), 'timestamp' => array( 'type' => 'int', 'not null' => FALSE, 'default' => 0, 'description' => 'Unix timestamp of the imported file.', ), 'last_checked' => array( 'type' => 'int', 'not null' => FALSE, 'default' => 0, 'description' => 'Unix timestamp of the last time this translation was confirmed to be the most recent release available.', ), ), 'primary key' => array('project', 'langcode'), ); db_create_table('locale_file', $table); } /** * Converts localized date formats. */ function locale_update_8016() { // Fetch all date types from {date_format_type}. $result = db_query('SELECT * FROM {date_format_locale}'); foreach ($result as $format) { $language = $format->language; // Create config objects for the language if not yet done. \Drupal::config("locale.config.$language.system.date_format." . $format->type) ->set('pattern.php', $format->format) ->save(); } } /** * Moves locale translation directory settings from variable to config. * * @ingroup config_upgrade */ function locale_update_8017() { update_variables_to_config('locale.settings', array( 'locale_translate_file_directory' => 'translation.path', )); } /** * Removes the field language fallback settings as it is no longer supported. * * @ingroup config_upgrade */ function locale_update_8018() { update_variable_del('locale_field_language_fallback'); } /** * @} End of "addtogroup updates-7.x-to-8.x". * The next series of updates should start at 9000. */