From 63ed9cf3a4997e80147fe8144ded3c13ddcf3d44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Garc=C3=ADa=20Crespo?= Date: Wed, 13 May 2026 10:11:11 +0200 Subject: [PATCH] Speed up install fixture loading Avoid recomputing access warning translations for every rights basis term during install/purge. Translate the warning strings in one batched pass and reuse the results for each generated access-statement setting. Keep QubitI18N::getTranslations() as a fresh lookup for compatibility, and add a batched helper for callers that need multiple strings translated across all languages. Also fix a stray leading '-' before the fixture loader object reference check. Measured tools:purge --demo improving from about 54s before this optimization pass to about 10s after it. --- lib/arInstall.class.php | 14 ++++--- lib/i18n/QubitI18N.class.php | 39 +++++++++++++------ .../lib/addon/sfPropelData.class.php | 2 +- 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/lib/arInstall.class.php b/lib/arInstall.class.php index fdac5291d1..2f00baaab4 100644 --- a/lib/arInstall.class.php +++ b/lib/arInstall.class.php @@ -387,6 +387,12 @@ public static function loadData($dispatcher, $formatter) $accessConditionalWarning = $i18n->__( 'This record has not yet been reviewed for personal or confidential information. Please contact the Reference Archivist to request access and initiate an access review.' ); + $translations = QubitI18N::getTranslationsForStrings([ + $accessDisallowWarning, + $accessConditionalWarning, + ]); + $accessDisallowWarningTranslations = $translations[$accessDisallowWarning]; + $accessConditionalWarningTranslations = $translations[$accessConditionalWarning]; foreach ( QubitTaxonomy::getTermsById(QubitTaxonomy::RIGHT_BASIS_ID) as $item @@ -396,9 +402,7 @@ public static function loadData($dispatcher, $formatter) $setting->scope = 'access_statement'; $setting->setValue($accessDisallowWarning, ['culture' => 'en']); - foreach ( - QubitI18N::getTranslations($accessDisallowWarning) as $langCode => $message - ) { + foreach ($accessDisallowWarningTranslations as $langCode => $message) { $setting->setValue($message, ['culture' => $langCode]); } @@ -409,9 +413,7 @@ public static function loadData($dispatcher, $formatter) $setting->scope = 'access_statement'; $setting->setValue($accessConditionalWarning, ['culture' => 'en']); - foreach ( - QubitI18N::getTranslations($accessConditionalWarning) as $langCode => $message - ) { + foreach ($accessConditionalWarningTranslations as $langCode => $message) { $setting->setValue($message, ['culture' => $langCode]); } diff --git a/lib/i18n/QubitI18N.class.php b/lib/i18n/QubitI18N.class.php index 37115efc06..2113a0a44a 100644 --- a/lib/i18n/QubitI18N.class.php +++ b/lib/i18n/QubitI18N.class.php @@ -31,32 +31,49 @@ class QubitI18N * @param mixed $string */ public static function getTranslations($string) + { + $translations = self::getTranslationsForStrings([$string]); + + return $translations[$string]; + } + + /** + * Return translations for several source strings in one pass over the + * configured application languages. This keeps getTranslations() compatible + * while allowing install tasks to avoid rebuilding i18n state for each + * string. + */ + public static function getTranslationsForStrings(array $strings) { $translations = []; + foreach ($strings as $string) { + $translations[$string] = []; + } - // Index the array with all the language codes available in the application + // Index the language codes available in the application. + $languageCodes = []; foreach (new DirectoryIterator(sfConfig::get('sf_app_i18n_dir')) as $fileInfo) { if ($fileInfo->isDot()) { continue; } - $translations[$fileInfo->getBasename()] = ''; + $languageCodes[] = $fileInfo->getBasename(); } $configuration = sfContext::getInstance()->getConfiguration(); - $cache = new sfNoCache(); - foreach ($translations as $langCode => &$value) { - $i18n = new sfI18N($configuration, $cache, ['culture' => $langCode]); + foreach ($languageCodes as $langCode) { + $i18n = new sfI18N($configuration, new sfNoCache(), ['culture' => $langCode]); - // Mark untranslated messages + // Mark untranslated messages so they can be omitted below. $i18n->getMessageFormat()->setUntranslatedPS(['[T]', '[/T]']); - // Update the value of this language in the dictionary - $value = $i18n->__($string); + foreach ($strings as $string) { + $value = $i18n->__($string); - // But discard the message if it's untranslated - if (empty($value) || 0 === strpos($value, '[T]', 0)) { - unset($translations[$langCode]); + // Discard empty and untranslated messages. + if (!empty($value) && 0 !== strpos($value, '[T]', 0)) { + $translations[$string][$langCode] = $value; + } } } diff --git a/vendor/symfony/lib/plugins/sfPropelPlugin/lib/addon/sfPropelData.class.php b/vendor/symfony/lib/plugins/sfPropelPlugin/lib/addon/sfPropelData.class.php index 986559b818..d0417fbbf0 100644 --- a/vendor/symfony/lib/plugins/sfPropelPlugin/lib/addon/sfPropelData.class.php +++ b/vendor/symfony/lib/plugins/sfPropelPlugin/lib/addon/sfPropelData.class.php @@ -115,7 +115,7 @@ public function loadDataFromArray($data) // foreign key? $columnCheck = !empty($column) && (isset($column) ? true : false); -- $objectCheck = !empty($value) && is_string($value) && (isset($this->object_references[$value]) ? true : false); + $objectCheck = !empty($value) && is_string($value) && (isset($this->object_references[$value]) ? true : false); if ($columnCheck && $column->isForeignKey() && $objectCheck) { $value = $this->object_references[$value]->getPrimaryKey();