cms/drupal/modules/locale/locale.install
changeset 541 e756a8c72c3d
equal deleted inserted replaced
540:07239de796bb 541:e756a8c72c3d
       
     1 <?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 }
       
   457