[I18N] Added ability to call `_m_dynamic` from any class, allowing it to define translations for dynamic-valued calls to `_m`

This commit is contained in:
Hugo Sales 2020-06-05 23:04:49 +00:00 committed by Hugo Sales
parent 5be901f9ce
commit 711af58dcd
Signed by: someonewithpc
GPG Key ID: 7D0C7EAFC9D835A0
3 changed files with 68 additions and 15 deletions

View File

@ -32,6 +32,7 @@
namespace App\Core\DB; namespace App\Core\DB;
use function App\Core\I18n\_m;
use App\Core\I18n\I18nHelper; use App\Core\I18n\I18nHelper;
use App\Util\Common; use App\Util\Common;
@ -304,4 +305,18 @@ abstract class DefaultSettings
DB::getConnection()->executeQuery($sql); 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;
}
} }

View File

@ -47,7 +47,7 @@ abstract class I18nHelper
/** /**
* Looks for which plugin we've been called from to get the gettext domain; * 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 * @return string
*/ */
@ -68,7 +68,7 @@ abstract class I18nHelper
$path = Formatting::normalizePath($path); $path = Formatting::normalizePath($path);
$cached[$path] = Formatting::pluginFromPath($path); $cached[$path] = Formatting::pluginFromPath($path);
} }
return $cached[$path] ?? 'Core'; return $cached[$path] ?? 'core';
} }
/** /**

View File

@ -34,6 +34,7 @@
namespace App\Core\I18n; namespace App\Core\I18n;
use App\Util\Formatting;
use Symfony\Component\Finder\Finder; use Symfony\Component\Finder\Finder;
use Symfony\Component\Translation\Extractor\AbstractFileExtractor; use Symfony\Component\Translation\Extractor\AbstractFileExtractor;
use Symfony\Component\Translation\Extractor\ExtractorInterface; use Symfony\Component\Translation\Extractor\ExtractorInterface;
@ -51,19 +52,26 @@ class TransExtractor extends AbstractFileExtractor implements ExtractorInterface
* @var array * @var array
*/ */
protected $sequences = [ protected $sequences = [
// [
// '_m',
// '(',
// self::MESSAGE_TOKEN,
// ',',
// self::METHOD_ARGUMENTS_TOKEN,
// ',',
// self::DOMAIN_TOKEN,
// ],
[ [
'_m', '_m',
'(', '(',
self::MESSAGE_TOKEN, self::MESSAGE_TOKEN,
',',
self::METHOD_ARGUMENTS_TOKEN,
',',
self::DOMAIN_TOKEN,
], ],
[ [
'_m', // Special case: when we have calls to _m with a dynamic
'(', // value, we need to handle them seperately
self::MESSAGE_TOKEN, 'function',
'_m_dynamic',
self::M_DYNAMIC,
], ],
]; ];
@ -72,6 +80,7 @@ class TransExtractor extends AbstractFileExtractor implements ExtractorInterface
const MESSAGE_TOKEN = 300; const MESSAGE_TOKEN = 300;
const METHOD_ARGUMENTS_TOKEN = 1000; const METHOD_ARGUMENTS_TOKEN = 1000;
const DOMAIN_TOKEN = 1001; const DOMAIN_TOKEN = 1001;
const M_DYNAMIC = 1002;
/** /**
* Prefix for new found message. * Prefix for new found message.
@ -258,22 +267,51 @@ class TransExtractor extends AbstractFileExtractor implements ExtractorInterface
if ('' !== $domainToken) { if ('' !== $domainToken) {
$domain = $domainToken; $domain = $domainToken;
} }
break; break;
} elseif (self::M_DYNAMIC === $item) {
// Special case
self::storeDynamic($catalog, $filename);
} else { } else {
break; break;
} }
} }
if ($message) { if ($message) {
$catalog->set($message, $this->prefix . $message, $domain); self::store($catalog, $message, $domain, $filename, $tokens[$key][2]); // Line no.
$metadata = $catalog->getMetadata($message, $domain) ?? [];
$normalizedFilename = preg_replace('{[\\\\/]+}', '/', $filename);
$metadata['sources'][] = $normalizedFilename . ':' . $tokens[$key][2];
$catalog->setMetadata($message, $metadata, $domain);
break; 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);
}
}
} }