locale.module

Same filename and directory in other branches
  1. 10 core/modules/locale/locale.module
  2. 11.x core/modules/locale/locale.module
  3. 9 core/modules/locale/locale.module
  4. 8.9.x core/modules/locale/locale.module
  5. 7.x modules/locale/locale.module

File

core/modules/locale/locale.module

View source
<?php


/**
 * @file
 */

use Drupal\Core\Installer\InstallerKernel;
use Drupal\Core\Form\FormStateInterface;
use Drupal\locale\CurrentImport;
use Drupal\locale\LocaleDefaultOptions;
use Drupal\locale\LocaleFetch;
use Drupal\locale\File\LocaleFileManager;
use Drupal\locale\LocaleConfigBatch;
use Drupal\locale\CurrentImportStorage;
use Drupal\locale\Hook\LocaleFormHooks;
use Drupal\locale\LocaleJs;
use Drupal\locale\LocaleProjectRepository;
use Drupal\locale\LocaleSource;
use Drupal\locale\LocaleLanguages;
use Drupal\locale\LocaleXss;

/**
 * Regular expression pattern used to localize JavaScript strings.
 */
const LOCALE_JS_STRING = '(?:(?:\'(?:\\\\\'|[^\'])*\'|"(?:\\\\"|[^"])*")(?:\\s*\\+\\s*)?)+';

/**
 * Regular expression pattern used to match simple JS object literal.
 *
 * This pattern matches a basic JS object, but will fail on an object with
 * nested objects. Used in JS file parsing for string arg processing.
 */
const LOCALE_JS_OBJECT = '\\{.*?\\}';

/**
 * Regular expression to match an object containing a key 'context'.
 *
 * Pattern to match a JS object containing a 'context key' with a string value,
 * which is captured. Will fail if there are nested objects.
 */
define('LOCALE_JS_OBJECT_CONTEXT', '
  \\{              # match object literal start
  .*?             # match anything, non-greedy
  (?:             # match a form of "context"
    \'context\'
    |
    "context"
    |
    context
  )
  \\s*:\\s*         # match key-value separator ":"
  (' . LOCALE_JS_STRING . ')  # match context string
  .*?             # match anything, non-greedy
  \\}              # match end of object literal
');

/**
 * Flag for locally not customized interface translation.
 *
 * Such translations are imported from .po files downloaded from
 * localize.drupal.org for example.
 */
const LOCALE_NOT_CUSTOMIZED = 0;

/**
 * Flag for locally customized interface translation.
 *
 * Such translations are edited from their imported originals on the user
 * interface or are imported as customized.
 */
const LOCALE_CUSTOMIZED = 1;

/**
 * Translation update mode: Use local files only.
 *
 * When checking for available translation updates, only local files will be
 * used. Any remote translation file will be ignored. Also custom modules and
 * themes which have set a "server pattern" to use a remote translation server
 * will be ignored.
 */
const LOCALE_TRANSLATION_USE_SOURCE_LOCAL = 'local';

/**
 * Translation update mode: Use both remote and local files.
 *
 * When checking for available translation updates, both local and remote files
 * will be checked.
 */
const LOCALE_TRANSLATION_USE_SOURCE_REMOTE_AND_LOCAL = 'remote_and_local';

/**
 * The number of seconds the translations status entry should be considered.
 */
const LOCALE_TRANSLATION_STATUS_TTL = 600;

/**
 * UI option for override of existing translations. Override any translation.
 */
const LOCALE_TRANSLATION_OVERWRITE_ALL = 'all';

/**
 * UI option for override of existing translations.
 *
 * Only override non-customized translations.
 */
const LOCALE_TRANSLATION_OVERWRITE_NON_CUSTOMIZED = 'non_customized';

/**
 * UI option for override of existing translations.
 *
 * Don't override existing translations.
 */
const LOCALE_TRANSLATION_OVERWRITE_NONE = 'none';

/**
 * Translation source is a remote file.
 */
const LOCALE_TRANSLATION_REMOTE = 'remote';

/**
 * Translation source is a local file.
 */
const LOCALE_TRANSLATION_LOCAL = 'local';

/**
 * Translation source is the current translation.
 */
const LOCALE_TRANSLATION_CURRENT = 'current';

/**
 * Returns list of translatable languages.
 *
 * @return array
 *   Array of installed languages keyed by language name. English is omitted
 *   unless it is marked as translatable.
 *
 * @deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. Use
 *   \Drupal::service(LocaleLanguages::class)->getTranslatableLanguages()
 *   instead.
 *
 * @see https://www.drupal.org/node/3616293
 */
function locale_translatable_language_list() {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. Use \\Drupal::service(LocaleLanguages::class)->getTranslatableLanguages() instead. See https://www.drupal.org/node/3616293', E_USER_DEPRECATED);
  return \Drupal::service(LocaleLanguages::class)->getTranslatableLanguages();
}

/**
 * Returns plural form index for a specific number.
 *
 * The index is computed from the formula of this language.
 *
 * @param int $count
 *   Number to return plural for.
 * @param string|null $langcode
 *   (optional) Language code to translate to a language other than what is used
 *   to display the page, or NULL for current language. Defaults to NULL.
 *
 * @return int
 *   The numeric index of the plural variant to use for this $langcode and
 *   $count combination or -1 if the language was not found or does not have a
 *   plural formula.
 */
function locale_get_plural($count, $langcode = NULL) {
  $language_interface = \Drupal::languageManager()->getCurrentLanguage();
  // Used to store precomputed plural indexes corresponding to numbers
  // individually for each language.
  $plural_indexes =& drupal_static(__FUNCTION__ . ':plurals', []);
  $langcode = $langcode ?: $language_interface->getId();
  if (!isset($plural_indexes[$langcode][$count])) {
    // Retrieve and statically cache the plural formulas for all languages.
    $plural_formulas = \Drupal::service('locale.plural.formula')->getFormula($langcode);
    // If there is a plural formula for the language, evaluate it for the given
    // $count and statically cache the result for the combination of language
    // and count, since the result will always be identical.
    if (!empty($plural_formulas)) {
      // Plural formulas are stored as an array for 0-199. 100 is the highest
      // modulo used but storing 0-99 is not enough because below 100 we often
      // find exceptions (1, 2, etc).
      $index = $count > 199 ? 100 + $count % 100 : $count;
      $plural_indexes[$langcode][$count] = $plural_formulas[$index] ?? $plural_formulas['default'];
    }
    elseif ($langcode == 'en') {
      $plural_indexes[$langcode][$count] = (int) ($count != 1);
    }
    else {
      $plural_indexes[$langcode][$count] = -1;
    }
  }
  return $plural_indexes[$langcode][$count];
}

/**
 * Updates default configuration when new modules or themes are installed.
 *
 * @deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. Use
 *   \Drupal::service('locale.config_manager')->updateDefaultConfigLangcodes()
 *   instead.
 *
 * @see https://www.drupal.org/node/3595086
 */
function locale_system_set_config_langcodes() : void {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. Use \\Drupal::service("locale.config_manager")->updateDefaultConfigLangcodes() instead. See https://www.drupal.org/node/3595086', E_USER_DEPRECATED);
  \Drupal::service('locale.config_manager')->updateDefaultConfigLangcodes();
}

/**
 * Imports translations when new modules or themes are installed.
 *
 * This function will start a batch to import translations for the added
 * components.
 *
 * @param array $components
 *   An array of arrays of component (theme and/or module) names to import
 *   translations for, indexed by type.
 *
 * @deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. There
 *   is no replacement.
 *
 * @see https://www.drupal.org/node/3595086
 */
function locale_system_update(array $components) : void {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. There is no replacement. See https://www.drupal.org/node/3595086', E_USER_DEPRECATED);
  $components += [
    'module' => [],
    'theme' => [],
  ];
  $list = array_merge($components['module'], $components['theme']);
  // Skip running the translation imports if in the installer,
  // because it would break out of the installer flow. We have
  // built-in support for translation imports in the installer.
  if (!InstallerKernel::installationAttempted() && \Drupal::service(LocaleLanguages::class)->getTranslatableLanguages()) {
    $module_handler = \Drupal::moduleHandler();
    if (\Drupal::config('locale.settings')->get('translation.import_enabled')) {
      $module_handler->loadInclude('locale', 'inc', 'locale.compare');
      // Update the list of translatable projects and start the import batch.
      // Only when new projects are added the update batch will be triggered.
      // Not each enabled module will introduce a new project. E.g. sub modules.
      $projects = array_keys(\Drupal::service(LocaleProjectRepository::class)->buildProjects());
      if ($list = array_intersect($list, $projects)) {
        $module_handler->loadInclude('locale', 'inc', 'locale.fetch');
        // Get translation status of the projects, download and update
        // translations.
        $options = LocaleDefaultOptions::updateOptions();
        $batch = \Drupal::service(LocaleFetch::class)->buildUpdateBatch($list, [], $options);
        batch_set($batch);
      }
    }
    // Construct a batch to update configuration for all components. Installing
    // this component may have installed configuration from any number of other
    // components. Do this even if import is not enabled because parsing new
    // configuration may expose new source strings.
    $module_handler->loadInclude('locale', 'inc', 'locale.bulk');
    if ($batch = \Drupal::service(LocaleConfigBatch::class)->buildBatch([], [], [], TRUE)) {
      batch_set($batch);
    }
  }
}

/**
 * Delete translation history of modules and themes.
 *
 * Only the translation history is removed, not the source strings or
 * translations. This is not possible because strings are shared between
 * modules and we have no record of which string is used by which module.
 *
 * @param array $components
 *   An array of arrays of component (theme and/or module) names to import
 *   translations for, indexed by type.
 *
 * @deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. There
 *   is no replacement.
 *
 * @see https://www.drupal.org/node/3595086
 */
function locale_system_remove($components) : void {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. There is no replacement. See https://www.drupal.org/node/3595086', E_USER_DEPRECATED);
  $components += [
    'module' => [],
    'theme' => [],
  ];
  $list = array_merge($components['module'], $components['theme']);
  if (\Drupal::service(LocaleLanguages::class)->getTranslatableLanguages()) {
    $module_handler = \Drupal::moduleHandler();
    $module_handler->loadInclude('locale', 'inc', 'locale.compare');
    $module_handler->loadInclude('locale', 'inc', 'locale.bulk');
    // Only when projects are removed, the translation files and records will be
    // deleted. Not each disabled module will remove a project, e.g., sub
    // modules.
    $projects = array_keys(\Drupal::service(LocaleProjectRepository::class)->getAll());
    if ($list = array_intersect($list, $projects)) {
      // Remove translation files.
      \Drupal::service(LocaleFileManager::class)->deleteTranslationFiles($list, []);
      // Remove translatable projects.
      \Drupal::service(LocaleProjectRepository::class)->deleteMultiple($list);
      // Clear the translation status.
      \Drupal::service(LocaleSource::class)->deleteSources($list);
    }
  }
}

/**
 * Returns a list of translation files given a list of JavaScript files.
 *
 * This function checks all JavaScript files passed and invokes parsing if they
 * have not yet been parsed for Drupal.t() and Drupal.formatPlural() calls.
 * Also refreshes the JavaScript translation files if necessary, and returns
 * the filepath to the translation file (if any).
 *
 * @param array $files
 *   An array of local file paths.
 * @param \Drupal\Core\Language\LanguageInterface $language_interface
 *   The interface language the files should be translated into.
 *
 * @return string|null
 *   The filepath to the translation file or NULL if no translation is
 *   applicable.
 *
 * @deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. Use
 *   \Drupal::service(LocaleJs::class)->jsTranslate() instead.
 *
 * @see https://www.drupal.org/node/3616293
 */
function locale_js_translate(array $files = [], $language_interface = NULL) {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. Use \\Drupal::service(LocaleJs::class)->jsTranslate() instead. See https://www.drupal.org/node/3616293', E_USER_DEPRECATED);
  return \Drupal::service(LocaleJs::class)->jsTranslate($files, $language_interface);
}

/**
 * Form submission handler for language_admin_add_form().
 *
 * Set a batch for a newly-added language.
 *
 * @deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. Use
 *   \Drupal::service(LocaleFormHooks::class)
 *   ->formLanguageAdminAddFormAlterSubmit() instead.
 *
 * @see https://www.drupal.org/node/3595086
 */
function locale_form_language_admin_add_form_alter_submit($form, FormStateInterface $form_state) : void {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. Use \\Drupal::service(LocaleFormHooks::class)->formLanguageAdminAddFormAlterSubmit() instead. See https://www.drupal.org/node/3595086', E_USER_DEPRECATED);
  \Drupal::moduleHandler()->loadInclude('locale', 'fetch.inc');
  \Drupal::moduleHandler()->loadInclude('locale', 'bulk.inc');
  \Drupal::service(LocaleFormHooks::class)->formLanguageAdminAddFormAlterSubmit($form, $form_state);
}

/**
 * Form submission handler for language_admin_edit_form().
 *
 * @deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. Use
 *   \Drupal::service(LocaleFormHooks::class)
 *   ->formLanguageAdminEditFormAlterSubmit() instead.
 *
 * @see https://www.drupal.org/node/3595086
 */
function locale_form_language_admin_edit_form_alter_submit($form, FormStateInterface $form_state) : void {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. Use \\Drupal::service(LocaleFormHooks::class)->formLanguageAdminEditFormAlterSubmit() instead. See https://www.drupal.org/node/3595086', E_USER_DEPRECATED);
  \Drupal::service(LocaleFormHooks::class)->formLanguageAdminEditFormAlterSubmit($form, $form_state);
}

/**
 * Checks whether $langcode is a language supported as a locale target.
 *
 * @param string $langcode
 *   The language code.
 *
 * @return bool
 *   Whether $langcode can be translated to in locale.
 *
 * @deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. Use
 *   \Drupal::service(LocaleLanguages::class)->isTranslatable()
 *   instead.
 *
 * @see https://www.drupal.org/node/3616293
 */
function locale_is_translatable($langcode) {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. Use \\Drupal::service(LocaleLanguages::class)->isTranslatable() instead. See https://www.drupal.org/node/3616293', E_USER_DEPRECATED);
  return \Drupal::service(LocaleLanguages::class)->isTranslatable($langcode);
}

/**
 * Submit handler for the file system settings form.
 *
 * Clears the translation status when the Interface translations directory
 * changes. Without a translations directory local po files in the directory
 * should be ignored. The old translation status is no longer valid.
 *
 * @deprecated in drupal:11.4.0 and is removed from drupal:12.0.0. There is no
 *   replacement.
 *
 * @see https://www.drupal.org/node/3571594
 */
function locale_system_file_system_settings_submit(&$form, FormStateInterface $form_state) : void {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.4.0 and is removed from drupal:12.0.0. There is no replacement. See https://www.drupal.org/node/3571594', E_USER_DEPRECATED);
  if ($form['translation_path']['#default_value'] != $form_state->getValue('translation_path')) {
    \Drupal::service(LocaleSource::class)->clearSources();
  }
  \Drupal::configFactory()->getEditable('locale.settings')
    ->set('translation.path', $form_state->getValue('translation_path'))
    ->save();
}

/**
 * Gets current translation status from the {locale_file} table.
 *
 * @return array
 *   Array of translation file objects.
 *
 * @deprecated in drupal:11.4.0 and is removed from drupal:13.0.0. There
 *   is no direct replacement use
 *   \Drupal::service(CurrentImportStorage::class)->get() with the
 *   project and langcode instead.
 *
 *  @see https://www.drupal.org/node/3037162
 */
function locale_translation_get_file_history() {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.4.0 and is removed from drupal:13.0.0. There is no direct replacement use \\Drupal::service(CurrentImportStorage::class)->get() with the project and langcode instead. See https://www.drupal.org/node/3037162', E_USER_DEPRECATED);
  // drupal_static() was removed as invalidation no longer happens.
  $history = [];
  // Get file history from the database.
  $result = \Drupal::database()->select('locale_file')
    ->fields('locale_file', [
    'project',
    'langcode',
    'filename',
    'version',
    'uri',
    'timestamp',
    'hash',
    'last_checked',
  ])
    ->execute()
    ->fetchAll();
  foreach ($result as $file) {
    $file->type = $file->timestamp ? LOCALE_TRANSLATION_CURRENT : '';
    $history[$file->project][$file->langcode] = $file;
  }
  return $history;
}

/**
 * Updates the {locale_file} table.
 *
 * @param object $source
 *   Object representing the project just imported.
 *
 * @return int
 *   FALSE on failure. Otherwise SAVED_NEW or SAVED_UPDATED.
 *
 * @deprecated in drupal:11.4.0 and is removed from drupal:13.0.0. Use
 *   \Drupal::service(CurrentImportStorage::class)->save() instead.
 *
 *  @see https://www.drupal.org/node/3037162
 */
function locale_translation_update_file_history($source) {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.4.0 and is removed from drupal:13.0.0. Use \\Drupal::service(CurrentImportStorage::class)->save(). See https://www.drupal.org/node/3037162', E_USER_DEPRECATED);
  \Drupal::service(CurrentImportStorage::class)->save(CurrentImport::createFromSource($source));
  // The api returns void.
  return SAVED_NEW;
}

/**
 * Deletes the history of downloaded translations.
 *
 * @param array $projects
 *   Project name(s) to be deleted from the file history. If both project(s) and
 *   language code(s) are specified the conditions will be ANDed.
 * @param array $langcodes
 *   Language code(s) to be deleted from the file history.
 *
 * @deprecated in drupal:11.4.0 and is removed from drupal:13.0.0. Use
 *   \Drupal::service(CurrentImportStorage::class)->delete() instead.
 *
 *  @see https://www.drupal.org/node/3037162
 */
function locale_translation_file_history_delete($projects = [], $langcodes = []) : void {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.4.0 and is removed from drupal:13.0.0. Use \\Drupal::service(CurrentImportStorage::class)->delete(). See https://www.drupal.org/node/3037162', E_USER_DEPRECATED);
  \Drupal::service(CurrentImportStorage::class)->delete($projects, $langcodes);
}

/**
 * Gets the current translation status.
 *
 * @deprecated in drupal:11.4.0 and is removed from drupal:13.0.0. Use
 *  \Drupal::service(LocaleSource::class)->loadSources() instead.
 *
 * @see https://www.drupal.org/node/3591660
 */
function locale_translation_get_status($projects = NULL, $langcodes = NULL) : array {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.4.0 and is removed from drupal:13.0.0. Use \\Drupal::service(LocaleSource::class)->loadSources(). See https://www.drupal.org/node/3591660', E_USER_DEPRECATED);
  \Drupal::moduleHandler()->loadInclude('locale', 'inc', 'locale.translation');
  return \Drupal::service(LocaleSource::class)->loadSources($projects, $langcodes);
}

/**
 * Saves the status of translation sources in static cache.
 *
 * @param string $project
 *   Machine readable project name.
 * @param string $langcode
 *   Language code.
 * @param string $type
 *   Type of data to be stored.
 * @param object $data
 *   File object also containing timestamp when the translation is last updated.
 *
 * @deprecated in drupal:11.4.0 and is removed from drupal:13.0.0. Use
 *   \Drupal::service(LocaleSource::class)->saveSource() instead.
 *
 * @see https://www.drupal.org/node/3591660
 */
function locale_translation_status_save($project, $langcode, $type, $data) : void {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.4.0 and is removed from drupal:13.0.0. Use \\Drupal::service(LocaleSource::class)->saveSource(). See https://www.drupal.org/node/3591660', E_USER_DEPRECATED);
  \Drupal::service(LocaleSource::class)->saveSource($project, $langcode, $type, $data);
}

/**
 * Delete language entries from the status cache.
 *
 * @param array $langcodes
 *   Language code(s) to be deleted from the cache.
 *
 * @deprecated in drupal:11.4.0 and is removed from drupal:13.0.0. Use
 *   \Drupal::service(LocaleSource::class)->deleteSourcesByLanguage() instead.
 *
 * @see https://www.drupal.org/node/3591660
 */
function locale_translation_status_delete_languages($langcodes) : void {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.4.0 and is removed from drupal:13.0.0. Use \\Drupal::service(LocaleSource::class)->deleteSourcesByLanguage(). See https://www.drupal.org/node/3591660', E_USER_DEPRECATED);
  foreach ($langcodes as $langcode) {
    \Drupal::service(LocaleSource::class)->deleteSourcesByLanguage($langcode);
  }
}

/**
 * Delete project entries from the status cache.
 *
 * @param array $projects
 *   Project name(s) to be deleted from the cache.
 *
 * @deprecated in drupal:11.4.0 and is removed from drupal:13.0.0. Use
 *    \Drupal::service(LocaleSource::class)->deleteSources() instead.
 *
 * @see https://www.drupal.org/node/3591660
 */
function locale_translation_status_delete_projects($projects) : void {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.4.0 and is removed from drupal:13.0.0. Use \\Drupal::service(LocaleSource::class)->deleteSources(). See https://www.drupal.org/node/3591660', E_USER_DEPRECATED);
  \Drupal::service(LocaleSource::class)->deleteSources($projects);
}

/**
 * Clear the translation status cache.
 *
 * @deprecated in drupal:11.4.0 and is removed from drupal:13.0.0. Use
 *     \Drupal::service(LocaleSource::class)->clearSources() instead.
 *
 * @see https://www.drupal.org/node/3591660
 */
function locale_translation_clear_status() : void {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.4.0 and is removed from drupal:13.0.0. Use \\Drupal::service(LocaleSource::class)->clearSources(). See https://www.drupal.org/node/3591660', E_USER_DEPRECATED);
  \Drupal::service(LocaleSource::class)->clearSources();
}

/**
 * Checks whether remote translation sources are used.
 *
 * @return bool
 *   Returns TRUE if remote translations sources should be taken into account
 *   when checking or importing translation files, FALSE otherwise.
 *
 * @deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. There is no
 *   replacement.
 *
 * @see https://www.drupal.org/node/3616293
 */
function locale_translation_use_remote_source() {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. There is no replacement. See https://www.drupal.org/node/3616293', E_USER_DEPRECATED);
  return \Drupal::config('locale.settings')->get('translation.use_source') == LOCALE_TRANSLATION_USE_SOURCE_REMOTE_AND_LOCAL;
}

/**
 * Check that a string is safe to be added or imported as a translation.
 *
 * This test can be used to detect possibly bad translation strings. It should
 * not have any false positives. But it is only a test, not a transformation,
 * as it destroys valid HTML. We cannot reliably filter translation strings
 * on import because some strings are irreversibly corrupted. For example,
 * an &amp; in the translation would get encoded to &amp;amp; by
 * \Drupal\Component\Utility\Xss::filter() before being put in the database,
 * and thus would be displayed incorrectly.
 *
 * The allowed tag list is like \Drupal\Component\Utility\Xss::filterAdmin(),
 * but omitting div and img as not needed for translation and likely to cause
 * layout issues (div) or a possible attack vector (img).
 *
 * @deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. Use
 *   LocaleXss::stringIsSafe() instead.
 *
 * @see https://www.drupal.org/node/3616293
 */
function locale_string_is_safe($string) {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. Use LocaleXss::stringIsSafe() instead. See https://www.drupal.org/node/3616293', E_USER_DEPRECATED);
  return LocaleXss::stringIsSafe($string);
}

/**
 * Refresh related information after string translations have been updated.
 *
 * The information that will be refreshed includes:
 * - JavaScript translations.
 * - Locale cache.
 * - Render cache.
 *
 * @param array $langcodes
 *   Language codes for updated translations.
 * @param array $lids
 *   (optional) List of string identifiers that have been updated / created.
 *   If not provided, all caches for the affected languages are cleared.
 *
 * @deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. Use
 *   \Drupal::service(LocaleJs::class)->refreshTranslations() instead.
 *
 * @see https://www.drupal.org/node/3619103
 */
function _locale_refresh_translations($langcodes, $lids = []) : void {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. Use \\Drupal::service(LocaleJs::class)->refreshTranslations() instead. See https://www.drupal.org/node/3619103', E_USER_DEPRECATED);
  \Drupal::service(LocaleJs::class)->refreshTranslations($langcodes, $lids);
}

/**
 * Refreshes configuration after string translations have been updated.
 *
 * @param array $langcodes
 *   Language codes for updated translations.
 * @param array $lids
 *   List of string identifiers that have been updated / created.
 *
 * @deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. There is no
 *   replacement.
 *
 * @see https://www.drupal.org/node/3619103
 */
function _locale_refresh_configuration(array $langcodes, array $lids) : void {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. There is no replacement. See https://www.drupal.org/node/3619103', E_USER_DEPRECATED);
  $locale_config_manager = \Drupal::service('locale.config_manager');
  if ($lids && $langcodes && $names = $locale_config_manager->getStringNames($lids)) {
    $locale_config_manager->updateConfigTranslations($names, $langcodes);
  }
}

/**
 * Removes the quotes and string concatenations from the string.
 *
 * @param string $string
 *   Single or double quoted strings, optionally concatenated by plus (+) sign.
 *
 * @return string
 *   String with leading and trailing quotes removed.
 *
 * @deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. There is no
 *   replacement.
 *
 * @see https://www.drupal.org/node/3619103
 */
function _locale_strip_quotes($string) {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. There is no replacement. See https://www.drupal.org/node/3619103', E_USER_DEPRECATED);
  return implode('', preg_split('~(?<!\\\\)[\'"]\\s*\\+\\s*[\'"]~s', substr($string, 1, -1)));
}

/**
 * Parses a JavaScript file, extracts translatable strings, and saves them.
 *
 * Strings are extracted from both Drupal.t() and Drupal.formatPlural().
 *
 * @param string $filepath
 *   File name to parse.
 *
 * @throws Exception
 *   If a non-local file is attempted to be parsed.
 *
 * @deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. Use
 *   \Drupal::service(LocaleJs::class)->parseJsFile() instead.
 *
 * @see https://www.drupal.org/node/3619103
 */
function _locale_parse_js_file($filepath) : void {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. Use \\Drupal::service(LocaleJs::class)->parseJsFile() instead. See https://www.drupal.org/node/3619103', E_USER_DEPRECATED);
  \Drupal::service(LocaleJs::class)->parseJsFile($filepath);
}

/**
 * Force the JavaScript translation file(s) to be refreshed.
 *
 * This function sets a refresh flag for a specified language, or all
 * languages except English, if none specified. JavaScript translation
 * files are rebuilt (with locale_update_js_files()) the next time a
 * request is served in that language.
 *
 * @param string|null $langcode
 *   (optional) The language code for which the file needs to be refreshed, or
 *   NULL to refresh all languages. Defaults to NULL.
 *
 * @return array
 *   New content of the 'system.javascript_parsed' variable.
 *
 * @deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. Use
 *   \Drupal::service(LocaleJs::class)->invalidate() instead.
 *
 * @see https://www.drupal.org/node/3619103
 */
function _locale_invalidate_js($langcode = NULL) {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. Use \\Drupal::service(LocaleJs::class)->invalidate() instead. See https://www.drupal.org/node/3619103', E_USER_DEPRECATED);
  return \Drupal::service(LocaleJs::class)->invalidate($langcode);
}

/**
 * Creates or recreates the JavaScript translation file for a language.
 *
 * @param string|null $langcode
 *   (optional) The language that the translation file should be (re)created
 *   for, or NULL for the current language. Defaults to NULL.
 *
 * @return bool
 *   TRUE if translation file exists, FALSE otherwise.
 *
 * @deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. Use
 *   \Drupal::service(LocaleJs::class)->rebuild() instead.
 *
 * @see https://www.drupal.org/node/3619103
 */
function _locale_rebuild_js($langcode = NULL) {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. Use \\Drupal::service(LocaleJs::class)->rebuild() instead. See https://www.drupal.org/node/3619103', E_USER_DEPRECATED);
  return \Drupal::service(LocaleJs::class)->rebuild($langcode);
}

/**
 * Form element callback: After build changes to the language update table.
 *
 * Adds labels to the languages and removes checkboxes from languages from which
 * translation files could not be found.
 *
 * @deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. There is no
 *   replacement.
 *
 * @see https://www.drupal.org/node/3616293
 */
function locale_translation_language_table($form_element) {
  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.5.0 and is removed from drupal:13.0.0. There is no replacement. See https://www.drupal.org/node/3616293', E_USER_DEPRECATED);
  // Remove checkboxes of languages without updates.
  if ($form_element['#not_found']) {
    foreach ($form_element['#not_found'] as $langcode) {
      $form_element[$langcode] = [];
    }
  }
  return $form_element;
}

Functions

Title Deprecated Summary
locale_form_language_admin_add_form_alter_submit

in drupal:11.5.0 and is removed from drupal:13.0.0. Use \Drupal::service(LocaleFormHooks::class) ->formLanguageAdminAddFormAlterSubmit() instead.

Form submission handler for language_admin_add_form().
locale_form_language_admin_edit_form_alter_submit

in drupal:11.5.0 and is removed from drupal:13.0.0. Use \Drupal::service(LocaleFormHooks::class) ->formLanguageAdminEditFormAlterSubmit() instead.

Form submission handler for language_admin_edit_form().
locale_get_plural Returns plural form index for a specific number.
locale_is_translatable

in drupal:11.5.0 and is removed from drupal:13.0.0. Use \Drupal::service(LocaleLanguages::class)->isTranslatable() instead.

Checks whether $langcode is a language supported as a locale target.
locale_js_translate

in drupal:11.5.0 and is removed from drupal:13.0.0. Use \Drupal::service(LocaleJs::class)->jsTranslate() instead.

Returns a list of translation files given a list of JavaScript files.
locale_string_is_safe

in drupal:11.5.0 and is removed from drupal:13.0.0. Use LocaleXss::stringIsSafe() instead.

Check that a string is safe to be added or imported as a translation.
locale_system_file_system_settings_submit

in drupal:11.4.0 and is removed from drupal:12.0.0. There is no replacement.

Submit handler for the file system settings form.
locale_system_remove

in drupal:11.5.0 and is removed from drupal:13.0.0. There is no replacement.

Delete translation history of modules and themes.
locale_system_set_config_langcodes

in drupal:11.5.0 and is removed from drupal:13.0.0. Use \Drupal::service('locale.config_manager')->updateDefaultConfigLangcodes() instead.

Updates default configuration when new modules or themes are installed.
locale_system_update

in drupal:11.5.0 and is removed from drupal:13.0.0. There is no replacement.

Imports translations when new modules or themes are installed.
locale_translatable_language_list

in drupal:11.5.0 and is removed from drupal:13.0.0. Use \Drupal::service(LocaleLanguages::class)->getTranslatableLanguages() instead.

Returns list of translatable languages.
locale_translation_clear_status

in drupal:11.4.0 and is removed from drupal:13.0.0. Use \Drupal::service(LocaleSource::class)->clearSources() instead.

Clear the translation status cache.
locale_translation_file_history_delete

in drupal:11.4.0 and is removed from drupal:13.0.0. Use \Drupal::service(CurrentImportStorage::class)->delete() instead.

Deletes the history of downloaded translations.
locale_translation_get_file_history

in drupal:11.4.0 and is removed from drupal:13.0.0. There is no direct replacement use \Drupal::service(CurrentImportStorage::class)->get() with the project and langcode instead.

Gets current translation status from the {locale_file} table.
locale_translation_get_status

in drupal:11.4.0 and is removed from drupal:13.0.0. Use \Drupal::service(LocaleSource::class)->loadSources() instead.

Gets the current translation status.
locale_translation_language_table

in drupal:11.5.0 and is removed from drupal:13.0.0. There is no replacement.

Form element callback: After build changes to the language update table.
locale_translation_status_delete_languages

in drupal:11.4.0 and is removed from drupal:13.0.0. Use \Drupal::service(LocaleSource::class)->deleteSourcesByLanguage() instead.

Delete language entries from the status cache.
locale_translation_status_delete_projects

in drupal:11.4.0 and is removed from drupal:13.0.0. Use \Drupal::service(LocaleSource::class)->deleteSources() instead.

Delete project entries from the status cache.
locale_translation_status_save

in drupal:11.4.0 and is removed from drupal:13.0.0. Use \Drupal::service(LocaleSource::class)->saveSource() instead.

Saves the status of translation sources in static cache.
locale_translation_update_file_history

in drupal:11.4.0 and is removed from drupal:13.0.0. Use \Drupal::service(CurrentImportStorage::class)->save() instead.

Updates the {locale_file} table.
locale_translation_use_remote_source

in drupal:11.5.0 and is removed from drupal:13.0.0. There is no replacement.

Checks whether remote translation sources are used.
_locale_invalidate_js

in drupal:11.5.0 and is removed from drupal:13.0.0. Use \Drupal::service(LocaleJs::class)->invalidate() instead.

Force the JavaScript translation file(s) to be refreshed.
_locale_parse_js_file

in drupal:11.5.0 and is removed from drupal:13.0.0. Use \Drupal::service(LocaleJs::class)->parseJsFile() instead.

Parses a JavaScript file, extracts translatable strings, and saves them.
_locale_rebuild_js

in drupal:11.5.0 and is removed from drupal:13.0.0. Use \Drupal::service(LocaleJs::class)->rebuild() instead.

Creates or recreates the JavaScript translation file for a language.
_locale_refresh_configuration

in drupal:11.5.0 and is removed from drupal:13.0.0. There is no replacement.

Refreshes configuration after string translations have been updated.
_locale_refresh_translations

in drupal:11.5.0 and is removed from drupal:13.0.0. Use \Drupal::service(LocaleJs::class)->refreshTranslations() instead.

Refresh related information after string translations have been updated.
_locale_strip_quotes

in drupal:11.5.0 and is removed from drupal:13.0.0. There is no replacement.

Removes the quotes and string concatenations from the string.

Constants

Title Deprecated Summary
LOCALE_CUSTOMIZED Flag for locally customized interface translation.
LOCALE_JS_OBJECT Regular expression pattern used to match simple JS object literal.
LOCALE_JS_OBJECT_CONTEXT Regular expression to match an object containing a key 'context'.
LOCALE_JS_STRING Regular expression pattern used to localize JavaScript strings.
LOCALE_NOT_CUSTOMIZED Flag for locally not customized interface translation.
LOCALE_TRANSLATION_CURRENT Translation source is the current translation.
LOCALE_TRANSLATION_LOCAL Translation source is a local file.
LOCALE_TRANSLATION_OVERWRITE_ALL UI option for override of existing translations. Override any translation.
LOCALE_TRANSLATION_OVERWRITE_NONE UI option for override of existing translations.
LOCALE_TRANSLATION_OVERWRITE_NON_CUSTOMIZED UI option for override of existing translations.
LOCALE_TRANSLATION_REMOTE Translation source is a remote file.
LOCALE_TRANSLATION_STATUS_TTL The number of seconds the translations status entry should be considered.
LOCALE_TRANSLATION_USE_SOURCE_LOCAL Translation update mode: Use local files only.
LOCALE_TRANSLATION_USE_SOURCE_REMOTE_AND_LOCAL Translation update mode: Use both remote and local files.

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