locale.install

Same filename in other branches
  1. 9 core/modules/locale/locale.install
  2. 8.9.x core/modules/locale/locale.install
  3. 10 core/modules/locale/locale.install
  4. 11.x core/modules/locale/locale.install

Install, update and uninstall functions for the locale module.

File

modules/locale/locale.install

View source
<?php


/**
 * @file
 * Install, update and uninstall functions for the locale module.
 */

/**
 * Implements hook_install().
 */
function locale_install() {
    // locales_source.source and locales_target.target are not used as binary
    // fields; non-MySQL database servers need to ensure the field type is text
    // and that LIKE produces a case-sensitive comparison.
    db_insert('languages')->fields(array(
        'language' => 'en',
        'name' => 'English',
        'native' => 'English',
        'direction' => 0,
        'enabled' => 1,
        'weight' => 0,
        'javascript' => '',
    ))
        ->execute();
}

/**
 * @addtogroup updates-6.x-to-7.x
 * @{
 */

/**
 * Add context field index and allow longer location.
 */
function locale_update_7000() {
    db_drop_index('locales_source', 'source');
    db_add_index('locales_source', 'source_context', array(
        array(
            'source',
            30,
        ),
        'context',
    ));
    // Also drop the 'textgroup_location' index added by the i18nstrings module
    // of the i18n project, which prevents the below schema update from running.
    if (db_index_exists('locales_source', 'textgroup_location')) {
        db_drop_index('locales_source', 'textgroup_location');
    }
    db_change_field('locales_source', 'location', '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.',
    ));
}

/**
 * Upgrade language negotiation settings.
 */
function locale_update_7001() {
    require_once DRUPAL_ROOT . '/includes/language.inc';
    require_once DRUPAL_ROOT . '/includes/locale.inc';
    require_once DRUPAL_ROOT . '/modules/locale/locale.module';
    switch (variable_get('language_negotiation', 0)) {
        // LANGUAGE_NEGOTIATION_NONE.
        case 0:
            $negotiation = array();
            break;
        // LANGUAGE_NEGOTIATION_PATH_DEFAULT.
        case 1:
            $negotiation = array(
                LOCALE_LANGUAGE_NEGOTIATION_URL,
            );
            // In Drupal 6 path prefixes are shown for the default language only when
            // language negotiation is set to LANGUAGE_NEGOTIATION_PATH, while in
            // Drupal 7 path prefixes are always shown if not empty. Hence we need to
            // ensure that the default language has an empty prefix to avoid breaking
            // the site URLs with a prefix that previously was missing.
            $default = language_default();
            $default->prefix = '';
            variable_set('language_default', $default);
            db_update('languages')->fields(array(
                'prefix' => $default->prefix,
            ))
                ->condition('language', $default->language)
                ->execute();
            break;
        // LANGUAGE_NEGOTIATION_PATH.
        case 2:
            $negotiation = array(
                LOCALE_LANGUAGE_NEGOTIATION_URL,
                LOCALE_LANGUAGE_NEGOTIATION_USER,
                LOCALE_LANGUAGE_NEGOTIATION_BROWSER,
            );
            break;
        // LANGUAGE_NEGOTIATION_DOMAIN.
        case 3:
            variable_set('locale_language_negotiation_url_part', LOCALE_LANGUAGE_NEGOTIATION_URL_DOMAIN);
            $negotiation = array(
                LOCALE_LANGUAGE_NEGOTIATION_URL,
            );
            break;
    }
    // Save the new language negotiation options.
    language_negotiation_set(LANGUAGE_TYPE_INTERFACE, array_flip($negotiation));
    language_negotiation_set(LANGUAGE_TYPE_CONTENT, array(
        LOCALE_LANGUAGE_NEGOTIATION_INTERFACE => 0,
    ));
    language_negotiation_set(LANGUAGE_TYPE_URL, array(
        LOCALE_LANGUAGE_NEGOTIATION_URL => 0,
    ));
    // Save admininstration UI settings.
    $type = LANGUAGE_TYPE_INTERFACE;
    $provider_weights = array_flip(array_keys(locale_language_negotiation_info()));
    variable_set("locale_language_providers_weight_{$type}", $provider_weights);
    // Unset the old language negotiation system variable.
    variable_del('language_negotiation');
    return array();
}

/**
 * Updates URL language negotiation by adding the URL fallback detection method.
 */
function locale_update_7002() {
    // language.inc may not have been included during bootstrap if there is not
    // more than one language currently enabled.
    require_once DRUPAL_ROOT . '/includes/language.inc';
    $language_types_info = language_types_info();
    $info = $language_types_info[LANGUAGE_TYPE_URL];
    if (isset($info['fixed'])) {
        language_negotiation_set(LANGUAGE_TYPE_URL, array_flip($info['fixed']));
    }
}

/**
 * @} End of "addtogroup updates-6.x-to-7.x".
 */

/**
 * @addtogroup updates-7.x-extra
 * @{
 */

/**
 * Update "language_count" variable.
 */
function locale_update_7003() {
    $languages = language_list('enabled');
    variable_set('language_count', count($languages[1]));
}

/**
 * Remove duplicates in {locales_source}.
 */
function locale_update_7004() {
    // Look up all duplicates. For each set of duplicates, we select the row
    // with the lowest lid as the "master" that will be preserved.
    $result_source = db_query("SELECT MIN(lid) AS lid, source, context FROM {locales_source} WHERE textgroup = 'default' GROUP BY source, context HAVING COUNT(*) > 1");
    $conflict = FALSE;
    foreach ($result_source as $source) {
        // Find all rows in {locales_target} that are translations of the same
        // string (incl. context).
        $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(
            ':source' => $source->source,
            ':context' => $source->context,
        ));
        $translations = array();
        $keep_lids = array(
            $source->lid,
        );
        foreach ($result_target as $target) {
            if (!isset($translations[$target->language])) {
                $translations[$target->language] = $target->translation;
                if ($target->lid != $source->lid) {
                    // Move translation to the master lid.
                    db_query('UPDATE {locales_target} SET lid = :new_lid WHERE lid = :old_lid', array(
                        ':new_lid' => $source->lid,
                        ':old_lid' => $target->lid,
                    ));
                }
            }
            elseif ($translations[$target->language] == $target->translation) {
                // Delete duplicate translation.
                db_query('DELETE FROM {locales_target} WHERE lid = :lid AND language = :language', array(
                    ':lid' => $target->lid,
                    ':language' => $target->language,
                ));
            }
            else {
                // The same string is translated into several different strings in one
                // language. We do not know which is the preferred, so we keep them all.
                $keep_lids[] = $target->lid;
                $conflict = TRUE;
            }
        }
        // Delete rows in {locales_source} that are no longer referenced from
        // {locales_target}.
        db_delete('locales_source')->condition('source', $source->source)
            ->condition('context', $source->context)
            ->condition('textgroup', 'default')
            ->condition('lid', $keep_lids, 'NOT IN')
            ->execute();
    }
    if ($conflict) {
        $url = 'http://drupal.org/node/746240';
        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');
    }
}

/**
 * Increase {locales_languages}.formula column's length.
 */
function locale_update_7005() {
    db_change_field('languages', 'formula', 'formula', array(
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
        'description' => 'Plural formula in PHP code to evaluate to get plural indexes.',
    ));
}

/**
 * @} End of "addtogroup updates-7.x-extra".
 */

/**
 * 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)) {
        $files = db_query('SELECT language, javascript FROM {languages}');
        foreach ($files as $file) {
            if (!empty($file->javascript)) {
                file_unmanaged_delete($locale_js_directory . '/' . $file->language . '_' . $file->javascript . '.js');
            }
        }
        // Delete the JavaScript translations directory if empty.
        if (!file_scan_directory($locale_js_directory, '/.*/')) {
            drupal_rmdir($locale_js_directory);
        }
    }
    // Clear variables.
    variable_del('language_default');
    variable_del('language_count');
    variable_del('language_types');
    variable_del('locale_language_negotiation_url_part');
    variable_del('locale_language_negotiation_session_param');
    variable_del('language_content_type_default');
    variable_del('language_content_type_negotiation');
    variable_del('locale_cache_strings');
    variable_del('locale_js_directory');
    variable_del('javascript_parsed');
    variable_del('locale_field_language_fallback');
    variable_del('locale_cache_length');
    foreach (language_types() as $type) {
        variable_del("language_negotiation_{$type}");
        variable_del("locale_language_providers_weight_{$type}");
    }
    foreach (node_type_get_types() as $type => $content_type) {
        $setting = variable_del("language_content_type_{$type}");
    }
    // Switch back to English: with a $language->language value different from 'en'
    // successive calls of t() might result in calling locale(), which in turn might
    // try to query the unexisting {locales_source} and {locales_target} tables.
    drupal_language_initialize();
}

/**
 * Implements hook_schema().
 */
function locale_schema() {
    $schema['languages'] = array(
        'description' => 'List of all available languages in the system.',
        'fields' => array(
            'language' => array(
                'type' => 'varchar',
                'length' => 12,
                'not null' => TRUE,
                'default' => '',
                'description' => "Language code, e.g. 'de' or 'en-US'.",
            ),
            'name' => array(
                'type' => 'varchar',
                'length' => 64,
                'not null' => TRUE,
                'default' => '',
                'description' => 'Language name in English.',
            ),
            'native' => array(
                'type' => 'varchar',
                'length' => 64,
                'not null' => TRUE,
                'default' => '',
                'description' => 'Native language name.',
            ),
            'direction' => array(
                'type' => 'int',
                'not null' => TRUE,
                'default' => 0,
                'description' => 'Direction of language (Left-to-Right = 0, Right-to-Left = 1).',
            ),
            'enabled' => array(
                'type' => 'int',
                'not null' => TRUE,
                'default' => 0,
                'description' => 'Enabled flag (1 = Enabled, 0 = Disabled).',
            ),
            'plurals' => array(
                'type' => 'int',
                'not null' => TRUE,
                'default' => 0,
                'description' => 'Number of plural indexes in this language.',
            ),
            'formula' => array(
                'type' => 'varchar',
                'length' => 255,
                'not null' => TRUE,
                'default' => '',
                'description' => 'Plural formula in PHP code to evaluate to get plural indexes.',
            ),
            'domain' => array(
                'type' => 'varchar',
                'length' => 128,
                'not null' => TRUE,
                'default' => '',
                'description' => 'Domain to use for this language.',
            ),
            'prefix' => array(
                'type' => 'varchar',
                'length' => 128,
                'not null' => TRUE,
                'default' => '',
                'description' => 'Path prefix to use for this language.',
            ),
            'weight' => array(
                'type' => 'int',
                'not null' => TRUE,
                'default' => 0,
                'description' => 'Weight, used in lists of languages.',
            ),
            'javascript' => array(
                'type' => 'varchar',
                'length' => 64,
                'not null' => TRUE,
                'default' => '',
                'description' => 'Location of JavaScript translation file.',
            ),
        ),
        'primary key' => array(
            'language',
        ),
        'indexes' => array(
            'list' => array(
                'weight',
                'name',
            ),
        ),
    );
    $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.',
            ),
            'textgroup' => array(
                'type' => 'varchar',
                'length' => 255,
                'not null' => TRUE,
                'default' => 'default',
                'description' => 'A module defined group of translations, see hook_locale().',
            ),
            '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 {languages}.language.',
            ),
            'plid' => array(
                'type' => 'int',
                'not null' => TRUE,
                // This should be NULL for no referenced string, not zero.
'default' => 0,
                'description' => 'Parent lid (lid of the previous string in the plural chain) in case of plural strings. References {locales_source}.lid.',
            ),
            'plural' => array(
                'type' => 'int',
                'not null' => TRUE,
                'default' => 0,
                'description' => 'Plural index number in case of plural strings.',
            ),
        ),
        'primary key' => array(
            'language',
            'lid',
            'plural',
        ),
        'foreign keys' => array(
            'locales_source' => array(
                'table' => 'locales_source',
                'columns' => array(
                    'lid' => 'lid',
                ),
            ),
        ),
        'indexes' => array(
            'lid' => array(
                'lid',
            ),
            'plid' => array(
                'plid',
            ),
            'plural' => array(
                'plural',
            ),
        ),
    );
    return $schema;
}

Functions

Title Deprecated Summary
locale_install Implements hook_install().
locale_schema Implements hook_schema().
locale_uninstall Implements hook_uninstall().
locale_update_7000 Add context field index and allow longer location.
locale_update_7001 Upgrade language negotiation settings.
locale_update_7002 Updates URL language negotiation by adding the URL fallback detection method.
locale_update_7003 Update "language_count" variable.
locale_update_7004 Remove duplicates in {locales_source}.
locale_update_7005 Increase {locales_languages}.formula column's length.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.