commit 7c2b0f735326b0e11ea3ce86ff3221a6e6c4603e Author: Erik Stielstra Date: Mon Sep 8 21:04:25 2014 +0200 #25 diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index 27e8c5d..2606240 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -1609,14 +1609,17 @@ function _install_prepare_import($langcode) { if ($info['major']) { $core = $info['major'] . '.x'; $data = array( - 'name' => 'drupal', + 'id' => 'drupal', + 'name' => 'Drupal core', 'project_type' => 'module', 'core' => $core, 'version' => $version, 'server_pattern' => $install_state['server_pattern'], 'status' => 1, ); - \Drupal::service('locale.project')->set($data['name'], $data); + $project = new \Drupal\locale\LocaleTranslatableProject($data); + $project->setLangcode($langcode); + \Drupal::service('locale.project')->set($project); module_load_include('compare.inc', 'locale'); locale_translation_check_projects_local(array('drupal'), array($install_state['parameters']['langcode'])); } diff --git a/core/modules/locale/locale.batch.inc b/core/modules/locale/locale.batch.inc index 7bea448..a76b5e9 100644 --- a/core/modules/locale/locale.batch.inc +++ b/core/modules/locale/locale.batch.inc @@ -183,7 +183,7 @@ function locale_translation_batch_fetch_import($project_id, $langcode, $options, if ($project) { $project->setLangcode($langcode); - if ($project->localIsAvailable() && $local = $project->getLocalSource()) { + if ($project->localIsLatest() && $local = $project->getLocalSource()) { $local->langcode = $langcode; module_load_include('bulk.inc', 'locale'); $options += array( diff --git a/core/modules/locale/locale.install b/core/modules/locale/locale.install index a6bdb24..8211a1a 100644 --- a/core/modules/locale/locale.install +++ b/core/modules/locale/locale.install @@ -243,7 +243,7 @@ function locale_requirements($phase) { if ($languages) { // Determine the status of the translation updates per language. - $projects = locale_translation_get_status(); + $projects = \Drupal::service('locale.project')->getAll(); if ($projects) { /** @var \Drupal\locale\LocaleTranslatableProjectInterface $project */ foreach ($projects as $project) { diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module index 1eeebd4..90e3d18 100644 --- a/core/modules/locale/locale.module +++ b/core/modules/locale/locale.module @@ -463,11 +463,12 @@ function locale_system_update(array $components) { // built-in support for translation imports in the installer. if (!drupal_installation_attempted() && locale_translatable_language_list() && \Drupal::config('locale.settings')->get('translation.import_enabled')) { module_load_include('compare.inc', 'locale'); + locale_translation_build_projects(); // 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(locale_translation_build_projects()); + $projects = array_keys(locale_translation_get_projects()); if ($list = array_intersect($list, $projects)) { module_load_include('fetch.inc', 'locale'); // Get translation status of the projects, download and update @@ -514,12 +515,7 @@ function locale_system_remove($components) { locale_translate_delete_translation_files($list, array()); // Remove translatable projects. - // Followup issue http://drupal.org/node/1842362 to replace the - // {locale_project} table. Then change this to a function call. \Drupal::service('locale.project')->deleteMultiple($list); - - // Clear the translation status. - locale_translation_status_delete_projects($list); } } @@ -831,7 +827,7 @@ function locale_translation_get_file_history() { // Get file history from the database. $result = db_query('SELECT project, langcode, filename, version, uri, timestamp, last_checked FROM {locale_file}'); foreach ($result as $file) { - $file->type = $file->timestamp ? LOCALE_TRANSLATION_CURRENT : ''; + $file->type = $file->timestamp ? 'current' : ''; $history[$file->project][$file->langcode] = $file; } } @@ -860,7 +856,6 @@ function locale_translation_update_file_history($file) { )) ->execute(); // The file history has changed, flush the static cache now. - // @todo Can we make this more fine grained? drupal_static_reset('locale_translation_get_file_history'); return $status; } @@ -883,6 +878,9 @@ function locale_translation_file_history_delete($projects = array(), $langcodes $query->condition('langcode', $langcodes); } $query->execute(); + + // The file history has changed, flush the static cache now. + drupal_static_reset('locale_translation_get_file_history'); } /** @@ -898,8 +896,7 @@ function locale_translation_file_history_delete($projects = array(), $langcodes * @return array * Array of translatable project objects. */ -// @todo deprecate/remove this function? -// @todo Is $langcode param needed? +// @todo deprecate ? function locale_translation_get_status($project_names = NULL, $langcodes = NULL) { if ($project_names) { @@ -917,11 +914,11 @@ function locale_translation_get_status($project_names = NULL, $langcodes = NULL) * Language code(s) to be deleted from the cache. */ function locale_translation_status_delete_languages($langcodes) { - $projects = locale_translation_get_projects(); - /** @var \Drupal\locale\LocaleTranslatableProject $project */ - foreach ($projects as $key => $project) { + + $projects = \Drupal::service('locale.project')->getAll(); + foreach (array_keys($projects) as $name) { foreach ($langcodes as $langcode) { - $projects[$key]->removeLangcode($langcode); + $projects[$name]->removeLangcode($langcode); } } \Drupal::service('locale.project')->setMultiple($projects); @@ -933,6 +930,7 @@ function locale_translation_status_delete_languages($langcodes) { * @param array $projects * Project name(s) to be deleted from the cache. */ +// @todo Deprecate ? function locale_translation_status_delete_projects($projects) { \Drupal::service('locale.project')->deleteMultiple($projects); @@ -941,9 +939,14 @@ function locale_translation_status_delete_projects($projects) { /** * Clear the translation status cache. */ -// @todo Deprecate function locale_translation_clear_status() { - \Drupal::service('locale.project')->disableAll(); + + $projects = \Drupal::service('locale.project')->getAll(); + foreach (array_keys($projects) as $name) { + $projects[$name]->clearTranslationStates(); + } + \Drupal::service('locale.project')->setMultiple($projects); + \Drupal::state()->delete('locale.translation_last_checked'); } /** diff --git a/core/modules/locale/locale.translation.inc b/core/modules/locale/locale.translation.inc index 911c15f..48a8b26 100644 --- a/core/modules/locale/locale.translation.inc +++ b/core/modules/locale/locale.translation.inc @@ -29,7 +29,7 @@ function locale_translation_get_projects($project_names = array()) { $projects = &drupal_static(__FUNCTION__, array()); if (empty($projects)) { - // Get project data from the database. + // Get project data from the key value store. $row_count = \Drupal::service('locale.project')->countProjects(); // http://drupal.org/node/1777106 is a follow-up issue to make the check for // possible out-of-date project information more robust. diff --git a/core/modules/locale/src/Form/TranslationStatusForm.php b/core/modules/locale/src/Form/TranslationStatusForm.php index 7d6e63d..725f063 100644 --- a/core/modules/locale/src/Form/TranslationStatusForm.php +++ b/core/modules/locale/src/Form/TranslationStatusForm.php @@ -4,7 +4,6 @@ * @file * Contains \Drupal\locale\Form\TranslationStatusForm. */ - namespace Drupal\locale\Form; use Drupal\Component\Utility\String; @@ -70,7 +69,7 @@ public function getFormID() { */ public function buildForm(array $form, FormStateInterface $form_state) { $languages = locale_translatable_language_list(); - $projects = locale_translation_get_status(); + $projects = \Drupal::service('locale.project')->getAll(); $options = array(); $languages_update = array(); $languages_not_found = array(); diff --git a/core/modules/locale/src/LocaleProjectStorage.php b/core/modules/locale/src/LocaleProjectStorage.php index d37dc07..7cbf8cf 100644 --- a/core/modules/locale/src/LocaleProjectStorage.php +++ b/core/modules/locale/src/LocaleProjectStorage.php @@ -147,7 +147,7 @@ public function deleteAll() { public function disableAll() { $projects = $this->getAll(); foreach (array_keys($projects) as $key) { - $projects[$key]->setStatus(0); + $projects[$key]->setStatus(FALSE); if (isset($cache[$key])) { $cache[$key] = $projects[$key]; } diff --git a/core/modules/locale/src/LocaleTranslatableProject.php b/core/modules/locale/src/LocaleTranslatableProject.php index 3a5ae70..6b2a08b 100644 --- a/core/modules/locale/src/LocaleTranslatableProject.php +++ b/core/modules/locale/src/LocaleTranslatableProject.php @@ -8,9 +8,9 @@ namespace Drupal\locale; /** - * @todo + * Provides a translatable project that contains the interface translation + * status of an extension. */ -// @todo Add interface? class LocaleTranslatableProject implements LocaleTranslatableProjectInterface { /** @@ -34,9 +34,9 @@ class LocaleTranslatableProject implements LocaleTranslatableProjectInterface { protected $projectCore = ''; /** - * Project status. 0: disabled, 1: enabled" + * Project status. FALSE: disabled, TRUE: enabled" */ - protected $status = 0; + protected $status = FALSE; /** * Translation file uri pattern. May contain placeholders. @@ -170,25 +170,25 @@ public function initLangcodeMultiple(array $langcodes) { /** * @inheritdoc */ - public function getStatus() { + public function removeLangcode($langcode) { - return $this->status; + unset($this->stateByLanguage[$langcode]); } /** * @inheritdoc */ - public function setStatus($status) { + public function getStatus() { - $this->status = $status ? 1 : 0; + return $this->status; } /** * @inheritdoc */ - public function removeLangcode($langcode) { + public function setStatus($status) { - unset($this->stateByLanguage[$langcode]); + $this->status = (bool) $status; } /** @@ -196,7 +196,7 @@ public function removeLangcode($langcode) { */ public function clearTranslationStates() { - foreach ($this->stateByLanguage as $langcode => $data) { + foreach (array_keys($this->stateByLanguage) as $langcode) { $this->stateByLanguage[$langcode]->localSource = NULL; $this->stateByLanguage[$langcode]->remoteSource = NULL; } @@ -206,24 +206,26 @@ public function clearTranslationStates() { * @inheritdoc */ public function getLocalSource() { + $source = NULL; if (!empty($this->localSource)) { - return $this->localSource; + $source = $this->localSource; } - return FALSE; + return $source; } /** * @inheritdoc */ public function getRemoteSource() { + $source = NULL; if (!empty($this->remoteSource)) { - return $this->remoteSource; + $source = $this->remoteSource; } - return FALSE; + return $source; } /** @@ -237,14 +239,6 @@ public function getLatestSourceTimestamp() { /** * @inheritdoc */ - public function getLatestSourceType() { - - return $this->latestSource; - } - - /** - * @inheritdoc - */ public function getVersion() { return $this->projectVersion; @@ -263,7 +257,7 @@ public function setVersion($version) { */ public function remoteIsValid() { - // @todo Return FALSE if file was not found (404) less than x time ago. + // Development release translations are not supported for remote sources. if ($this->projectVersion && strpos('dev', $this->projectVersion) !== FALSE) { return FALSE; } @@ -282,14 +276,6 @@ public function remoteIsAvailable() { /** * @inheritdoc */ - public function localIsAvailable() { - - return $this->latestSource == 'local'; - } - - /** - * @inheritdoc - */ public function remoteIsLatest() { return $this->latestSource == 'remote'; @@ -378,6 +364,14 @@ public function hasNoTranslation() { return $this->latestSource == ''; } + /** + * @inheritdoc + */ + public function isUpToDate() { + + return $this->latestSource == 'current'; + } + /* * Initializes the translation state by loading from cache or building a new one. * @@ -502,11 +496,14 @@ protected function buildServerPattern($template, $langcode) { } /** - * @todo + * Returns whether the file URI is at a remote translation source. * * @param $uri + * File URI. May include a scheme. * * @return bool + * Returns TRUE if the file scheme indicates a remote file. FALSE if no + * scheme is supplied or files are stored at the local file system. */ protected function fileIsRemote($uri) { diff --git a/core/modules/locale/src/LocaleTranslatableProjectInterface.php b/core/modules/locale/src/LocaleTranslatableProjectInterface.php index 25d6a3f..b4bb214 100644 --- a/core/modules/locale/src/LocaleTranslatableProjectInterface.php +++ b/core/modules/locale/src/LocaleTranslatableProjectInterface.php @@ -8,23 +8,31 @@ namespace Drupal\locale; /** - * @todo + * Defines the locale translatable project interface. */ interface LocaleTranslatableProjectInterface { /** - * @todo - * @param $data + * Initializes the translation project. + * + * @param array $data + * Array of project data. */ public function __construct($data); /** * Returns the machine name of the project. + * + * @return string + * The unique project machine name. */ public function id(); /** * Returns the human readable name of the project. + * + * @return string + * The human readable project name. */ public function getName(); @@ -32,84 +40,100 @@ public function getName(); * Serialize the project to an array * * @return array + * Project properties to be stored. */ public function toArray(); /** * Sets the language this project is translated to. * - * @param $langcode + * @param string $langcode + * Language code. */ public function setLangcode($langcode); /** * Initializes the project for a language. + * + * @param string $langcode + * Language code. */ public function initLangcode($langcode); /** * Initializes the project for multiple languages. + * + * @param array $langcodes + * Array of language codes. */ public function initLangcodeMultiple(array $langcodes); + /** + * Deletes stored data of specified language. + * + * @param string $langcode + * Language code. + */ + public function removeLangcode($langcode); /** * Returns the project status. * * @return bool + * Returns TRUE if the project is enabled, FALSE otherwise. */ public function getStatus(); /** * Sets the project status. * - * @param $status + * @param bool $status + * A flag indicating the project status. TRUE: enabled, FALSE: disabled. */ public function setStatus($status); /** - * Deletes stored data of specified language. - * - * @param $langcode - */ - public function removeLangcode($langcode); - - /** * Deletes translations states of the project for all languages. */ public function clearTranslationStates(); /** - * Returns the local source state. + * Returns the local translation source. + * + * @return \stdClass|NULL + * Remote local object or NULL if no remote translation source is available. */ public function getLocalSource(); /** - * Returns the remote source state. + * Returns the remote translation source. + * + * @return \stdClass|NULL + * Remote source object or NULL if no remote source is available. */ public function getRemoteSource(); /** - * @todo + * Returns the timestamp of the most recent translation source. + * + * @return integer + * Timestamp of a translation source. 0 if no source is available. */ public function getLatestSourceTimestamp(); /** - * @todo + * Returns the version of the project. * * @return string - * 'current', 'local', 'remote' or empty string. - * @todo Better not expose these internal strings. Currently only use for tests. - */ - public function getLatestSourceType(); - - /** - * @todo + * Project release version string. */ public function getVersion(); /** - * @todo + * Overrides the project version. + * + * @param string $version + * Project release version string. */ public function setVersion($version); @@ -132,49 +156,53 @@ public function remoteIsValid(); public function remoteIsAvailable(); /** - * Whether the local source is available and can be imported. + * Returns whether the remote source is the latest translation source. * * @return bool - * Returns FALSE if the project version is a dev release. No translations - * are available for dev releases. - */ - public function localIsAvailable(); - - /** - * @todo - * @return bool + * Returns TRUE if the remote translation source is the latest or the only + * available source. FALSE if no remote source is available, the remote + * source is older or the current translation is up to date. */ public function remoteIsLatest(); /** - * @todo + * Returns whether the local source is the latest translation source. + * * @return bool + * Returns TRUE if the local translation source is the latest or the only + * available source. FALSE if no local source is available, the local + * source is older or the current translation is up to date. */ public function localIsLatest(); /** * Updates the translation state with local source data. * - * @param $data + * @param \stdClass $data + * Local translation source data. */ public function updateLocalSource($data); /** * Updates the translation state with remote source data. * - * @param $data + * @param \stdClass $data + * Remote translation source data. */ public function updateRemoteSource($data); /** - * Updates the translation state with the timestamp of a newly imported translation. + * Updates the current translation state timestamp. * - * @param $timestamp + * @param int $timestamp + * Timestamp of a newly imported translation. */ public function updateTimestamp($timestamp); /** - * Whether this project is translated in language $langcode. + * Whether this project is translated. + * + * The language the project is translated in, is set using setLanguage(). * * @return bool * Returns TRUE if this project is translated. @@ -184,16 +212,32 @@ public function isTranslated(); /** * Whether translation updates are available for this language. * + * The language the project is translated in, is set using setLanguage(). + * * @return bool * Returns TRUE if a local or remote translation update is available. */ public function hasUpdates(); /** - * Whether the project is not translated and no translation updates are - * available. + * Whether the project was translated ever. + * + * The language the project is translated in, is set using setLanguage(). + * + * @return bool + * Returns TRUE if the project was not translated before and no translation + * sources are available. */ public function hasNoTranslation(); + /** + * Whether the project translation is up to date. + * + * @return bool + * Returns TRUE if the project is translated and the translation is of the + * latest version. Returns FALSE if more recent local or remote translations + * are available or the project has never been translated before. + */ + public function isUpToDate(); } diff --git a/core/modules/locale/src/Tests/LocaleUpdateTest.php b/core/modules/locale/src/Tests/LocaleUpdateTest.php index db42b52..9b6df18 100644 --- a/core/modules/locale/src/Tests/LocaleUpdateTest.php +++ b/core/modules/locale/src/Tests/LocaleUpdateTest.php @@ -97,21 +97,21 @@ public function testUpdateCheckStatus() { /** @var \Drupal\locale\LocaleTranslatableProjectInterface $project */ $project = \Drupal::service('locale.project')->get('contrib_module_one'); $project->setLangcode('de'); - $this->assertEqual($project->getLatestSourceType(), 'local', 'Translation of contrib_module_one found'); + $this->assertTrue($project->localIsLatest(), 'Translation of contrib_module_one found'); $this->assertEqual($project->getLatestSourceTimestamp(), $this->timestampOld, 'Translation timestamp found'); $project = \Drupal::service('locale.project')->get('contrib_module_two'); $project->setLangcode('de'); - $this->assertEqual($project->getLatestSourceType(), 'local', 'Translation of contrib_module_two found'); + $this->assertTrue($project->localIsLatest(), 'Translation of contrib_module_two found'); $this->assertEqual($project->getLatestSourceTimestamp(), $this->timestampNew, 'Translation timestamp found'); $project = \Drupal::service('locale.project')->get('locale_test'); $project->setLangcode('de'); - $this->assertEqual($project->getLatestSourceType(), 'local', 'Translation of locale_test found'); + $this->assertTrue($project->localIsLatest(), 'Translation of locale_test found'); $project = \Drupal::service('locale.project')->get('custom_module_one'); $project->setLangcode('de'); - $this->assertEqual($project->getLatestSourceType(), 'local', 'Translation of custom_module_one found'); + $this->assertTrue($project->localIsLatest(), 'Translation of custom_module_one found'); // Set the test conditions. $edit = array( @@ -124,26 +124,26 @@ public function testUpdateCheckStatus() { /** @var \Drupal\locale\LocaleTranslatableProjectInterface $project */ $project = \Drupal::service('locale.project')->get('contrib_module_one'); $project->setLangcode('de'); - $this->assertEqual($project->getLatestSourceType(), 'remote', 'Translation of contrib_module_one found'); + $this->assertTrue($project->remoteIsLatest(), 'Translation of contrib_module_one found'); $this->assertEqual($project->getLatestSourceTimestamp(), $this->timestampNew, 'Translation timestamp found'); $project = \Drupal::service('locale.project')->get('contrib_module_two'); $project->setLangcode('de'); - $this->assertEqual($project->getLatestSourceType(), 'local', 'Translation of contrib_module_two found'); + $this->assertTrue($project->localIsLatest(), 'Translation of contrib_module_two found'); $this->assertEqual($project->getLatestSourceTimestamp(), $this->timestampNew, 'Translation timestamp found'); $project = \Drupal::service('locale.project')->get('contrib_module_three'); $project->setLangcode('de'); - $this->assertEqual($project->getLatestSourceType(), 'local', 'Translation of contrib_module_three found'); + $this->assertTrue($project->localIsLatest(), 'Translation of contrib_module_three found'); $this->assertEqual($project->getLatestSourceTimestamp(), $this->timestampOld, 'Translation timestamp found'); $project = \Drupal::service('locale.project')->get('locale_test'); $project->setLangcode('de'); - $this->assertEqual($project->getLatestSourceType(), 'local', 'Translation of locale_test found'); + $this->assertTrue($project->localIsLatest(), 'Translation of locale_test found'); $project = \Drupal::service('locale.project')->get('custom_module_one'); $project->setLangcode('de'); - $this->assertEqual($project->getLatestSourceType(), 'local', 'Translation of custom_module_one found'); + $this->assertTrue($project->localIsLatest(), 'Translation of custom_module_one found'); } /** @@ -184,15 +184,15 @@ public function testUpdateImportSourceRemote() { /** @var \Drupal\locale\LocaleTranslatableProjectInterface $project */ $project = \Drupal::service('locale.project')->get('contrib_module_one'); $project->setLangcode('de'); - $this->assertEqual($project->getLatestSourceType(), 'current', 'Translation of contrib_module_one found'); + $this->assertTrue($project->isUpToDate(), 'Translation of contrib_module_one found'); $project = \Drupal::service('locale.project')->get('contrib_module_two'); $project->setLangcode('de'); - $this->assertEqual($project->getLatestSourceType(), 'current', 'Translation of contrib_module_two found'); + $this->assertTrue($project->isUpToDate(), 'Translation of contrib_module_two found'); $project = \Drupal::service('locale.project')->get('contrib_module_three'); $project->setLangcode('de'); - $this->assertEqual($project->getLatestSourceType(), 'current', 'Translation of contrib_module_three found'); + $this->assertTrue($project->isUpToDate(), 'Translation of contrib_module_three found'); // Check the new translation status. // The static cache needs to be flushed first to get the most recent data @@ -246,15 +246,15 @@ public function testUpdateImportSourceLocal() { /** @var \Drupal\locale\LocaleTranslatableProjectInterface $project */ $project = \Drupal::service('locale.project')->get('contrib_module_one'); $project->setLangcode('de'); - $this->assertEqual($project->getLatestSourceType(), 'current', 'Translation of contrib_module_one found'); + $this->assertTrue($project->isUpToDate(), 'Translation of contrib_module_one found'); $project = \Drupal::service('locale.project')->get('contrib_module_two'); $project->setLangcode('de'); - $this->assertEqual($project->getLatestSourceType(), 'current', 'Translation of contrib_module_two found'); + $this->assertTrue($project->isUpToDate(), 'Translation of contrib_module_two found'); $project = \Drupal::service('locale.project')->get('contrib_module_three'); $project->setLangcode('de'); - $this->assertEqual($project->getLatestSourceType(), 'current', 'Translation of contrib_module_three found'); + $this->assertTrue($project->isUpToDate(), 'Translation of contrib_module_three found'); // Check the new translation status. // The static cache needs to be flushed first to get the most recent data