From 711af58dcdcf5e8a543ba882e9418acbf25ae724 Mon Sep 17 00:00:00 2001 From: Hugo Sales Date: Fri, 5 Jun 2020 23:04:49 +0000 Subject: [PATCH] [I18N] Added ability to call `_m_dynamic` from any class, allowing it to define translations for dynamic-valued calls to `_m` --- src/Core/DB/DefaultSettings.php | 15 ++++++++ src/Core/I18n/I18nHelper.php | 4 +- src/Core/I18n/TransExtractor.php | 64 +++++++++++++++++++++++++------- 3 files changed, 68 insertions(+), 15 deletions(-) diff --git a/src/Core/DB/DefaultSettings.php b/src/Core/DB/DefaultSettings.php index 6c889cf9b3..2bbe4a044d 100644 --- a/src/Core/DB/DefaultSettings.php +++ b/src/Core/DB/DefaultSettings.php @@ -32,6 +32,7 @@ namespace App\Core\DB; +use function App\Core\I18n\_m; use App\Core\I18n\I18nHelper; use App\Util\Common; @@ -304,4 +305,18 @@ abstract class DefaultSettings DB::getConnection()->executeQuery($sql); } } + + public static function _m_dynamic(): array + { + self::setDefaults(); + $m = []; + $m['domain'] = 'core'; + foreach (self::$defaults as $key => $inner) { + $m[] = _m($key); + foreach (array_keys($inner) as $inner_key) { + $m[] = _m($inner_key); + } + } + return $m; + } } diff --git a/src/Core/I18n/I18nHelper.php b/src/Core/I18n/I18nHelper.php index 72570c5c20..568d0d93bc 100644 --- a/src/Core/I18n/I18nHelper.php +++ b/src/Core/I18n/I18nHelper.php @@ -47,7 +47,7 @@ abstract class I18nHelper /** * Looks for which plugin we've been called from to get the gettext domain; - * if not in a plugin subdirectory, we'll use the default 'Core'. + * if not in a plugin subdirectory, we'll use the default 'core'. * * @return string */ @@ -68,7 +68,7 @@ abstract class I18nHelper $path = Formatting::normalizePath($path); $cached[$path] = Formatting::pluginFromPath($path); } - return $cached[$path] ?? 'Core'; + return $cached[$path] ?? 'core'; } /** diff --git a/src/Core/I18n/TransExtractor.php b/src/Core/I18n/TransExtractor.php index 5e595381dc..b0097ee8e0 100644 --- a/src/Core/I18n/TransExtractor.php +++ b/src/Core/I18n/TransExtractor.php @@ -34,6 +34,7 @@ namespace App\Core\I18n; +use App\Util\Formatting; use Symfony\Component\Finder\Finder; use Symfony\Component\Translation\Extractor\AbstractFileExtractor; use Symfony\Component\Translation\Extractor\ExtractorInterface; @@ -51,19 +52,26 @@ class TransExtractor extends AbstractFileExtractor implements ExtractorInterface * @var array */ protected $sequences = [ + // [ + // '_m', + // '(', + // self::MESSAGE_TOKEN, + // ',', + // self::METHOD_ARGUMENTS_TOKEN, + // ',', + // self::DOMAIN_TOKEN, + // ], [ '_m', '(', self::MESSAGE_TOKEN, - ',', - self::METHOD_ARGUMENTS_TOKEN, - ',', - self::DOMAIN_TOKEN, ], [ - '_m', - '(', - self::MESSAGE_TOKEN, + // Special case: when we have calls to _m with a dynamic + // value, we need to handle them seperately + 'function', + '_m_dynamic', + self::M_DYNAMIC, ], ]; @@ -72,6 +80,7 @@ class TransExtractor extends AbstractFileExtractor implements ExtractorInterface const MESSAGE_TOKEN = 300; const METHOD_ARGUMENTS_TOKEN = 1000; const DOMAIN_TOKEN = 1001; + const M_DYNAMIC = 1002; /** * Prefix for new found message. @@ -258,22 +267,51 @@ class TransExtractor extends AbstractFileExtractor implements ExtractorInterface if ('' !== $domainToken) { $domain = $domainToken; } - break; + } elseif (self::M_DYNAMIC === $item) { + // Special case + self::storeDynamic($catalog, $filename); } else { break; } } if ($message) { - $catalog->set($message, $this->prefix . $message, $domain); - $metadata = $catalog->getMetadata($message, $domain) ?? []; - $normalizedFilename = preg_replace('{[\\\\/]+}', '/', $filename); - $metadata['sources'][] = $normalizedFilename . ':' . $tokens[$key][2]; - $catalog->setMetadata($message, $metadata, $domain); + self::store($catalog, $message, $domain, $filename, $tokens[$key][2]); // Line no. break; } } } } + + private function store(MessageCatalogue $mc, string $message, + string $domain, string $filename, ?int $line_no = null) + { + $mc->set($message, $this->prefix . $message, $domain); + $metadata = $mc->getMetadata($message, $domain) ?? []; + $metadata['sources'][] = Formatting::normalizePath($filename) . (!empty($line_no) ? ":{$line_no}" : ''); + $mc->setMetadata($message, $metadata, $domain); + } + + private function storeDynamic(MessageCatalogue $mc, string $filename) + { + require_once $filename; + $class = preg_replace('/.*\/([A-Za-z]*)\.php/', '\1', $filename); + $classes = get_declared_classes(); + + // Find FQCN of $class + foreach ($classes as $c) { + if (strstr($c, $class) !== false) { + $class = $c; + break; + } + } + + $messages = $class::_m_dynamic(); + $domain = $messages['domain']; + unset($messages['domain']); + foreach ($messages as $m) { + self::store($mc, $m, $domain, $filename); + } + } }