add loading of automatic ORM field labels to i18nTextCollector

This commit is contained in:
Florian Thoma 2023-02-13 16:56:59 +11:00
parent 2c874a1e94
commit c0722308af
2 changed files with 89 additions and 2 deletions

View File

@ -5,6 +5,9 @@ namespace SilverStripe\i18n\TextCollection;
use Exception;
use LogicException;
use SilverStripe\Core\ClassInfo;
use SilverStripe\Core\Config\Config;
use SilverStripe\Core\Config\Configurable;
use SilverStripe\Core\Extension;
use SilverStripe\Core\Injector\Injectable;
use SilverStripe\Core\Manifest\ClassLoader;
use SilverStripe\Core\Manifest\Module;
@ -12,10 +15,12 @@ use SilverStripe\Core\Manifest\ModuleLoader;
use SilverStripe\Dev\Debug;
use SilverStripe\Control\Director;
use ReflectionClass;
use SilverStripe\Forms\FormField;
use SilverStripe\i18n\i18n;
use SilverStripe\i18n\i18nEntityProvider;
use SilverStripe\i18n\Messages\Reader;
use SilverStripe\i18n\Messages\Writer;
use SilverStripe\ORM\DataObject;
/**
* SilverStripe-variant of the "gettext" tool:
@ -482,6 +487,7 @@ class i18nTextCollector
if ($extension === 'php') {
$entities = array_merge(
$entities,
$this->collectFromORM($filePath),
$this->collectFromCode($content, $filePath, $module),
$this->collectFromEntityProviders($filePath, $module)
);
@ -881,7 +887,7 @@ class i18nTextCollector
$classes = ClassInfo::classes_for_file($filePath);
foreach ($classes as $class) {
// Skip non-implementing classes
if (!class_exists($class ?? '') || !is_a($class, i18nEntityProvider::class, true)) {
if (!class_exists($class) || !is_a($class, i18nEntityProvider::class, true)) {
continue;
}
@ -907,6 +913,47 @@ class i18nTextCollector
return $entities;
}
/**
* Extracts translations for ORM fields
*
* @param string $filePath
* @return array
*/
public function collectFromORM($filePath)
{
$entities = [];
$classes = ClassInfo::classes_for_file($filePath);
foreach ($classes as $class) {
// Skip non-implementing classes
if (!class_exists($class)) {
continue;
}
// Skip abstract classes
$reflectionClass = new ReflectionClass($class);
if ($reflectionClass->isAbstract()) {
continue;
}
$provided = [];
// add labels for ORM fields
if (is_a($class, DataObject::class, true) || is_a($class, Extension::class, true)) {
foreach (['db', 'has_one', 'has_many', 'belongs_to', 'many_many', 'belongs_many_many'] as $type) {
if ($config = Config::inst()->get($class, $type, Config::UNINHERITED)) {
foreach ($config as $name => $spec) {
// add type in translation identifier as used in DataObject::fieldLabels()
$provided["{$class}.{$type}_{$name}"] = FormField::name_to_label($name);
}
}
}
}
$entities = array_merge($entities, $provided);
}
ksort($entities);
return $entities;
}
/**
* Normalizes entities with namespaces.
*

View File

@ -3,12 +3,15 @@
namespace SilverStripe\i18n\Tests;
use SilverStripe\Assets\Filesystem;
use SilverStripe\Core\Config\Config;
use SilverStripe\Core\Manifest\ModuleLoader;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\i18n\i18n;
use SilverStripe\i18n\TextCollection\i18nTextCollector;
use SilverStripe\i18n\Messages\YamlWriter;
use SilverStripe\i18n\Tests\i18nTest\TestDataObject;
use SilverStripe\i18n\Tests\i18nTextCollectorTest\Collector;
use SilverStripe\i18n\TextCollection\i18nTextCollector;
use SilverStripe\Security\Member;
class i18nTextCollectorTest extends SapphireTest
{
@ -709,6 +712,43 @@ PHP;
);
}
public function testCollectFromORM()
{
// note: Disable _fakewebroot manifest for this test
$this->popManifests();
// update config because test can't load config from actual class
Config::inst()->update(TestDataObject::class, 'db', [
'MyProperty' => 'Varchar',
'MyUntranslatedProperty' => 'Text'
]);
Config::inst()->update(TestDataObject::class, 'has_one', [
'HasOneRelation' => Member::class
]);
Config::inst()->update(TestDataObject::class, 'has_many', [
'HasManyRelation' => Member::class
]);
Config::inst()->update(TestDataObject::class, 'many_many', [
'ManyManyRelation' => Member::class
]);
$c = i18nTextCollector::create();
// Collect from MyObject.php
$filePath = __DIR__ . '/i18nTest/TestDataObject.php';
$matches = $c->collectFromORM($filePath);
$this->assertEquals(
[
'SilverStripe\i18n\Tests\i18nTest\TestDataObject.db_MyProperty' => 'My property',
'SilverStripe\i18n\Tests\i18nTest\TestDataObject.db_MyUntranslatedProperty' => 'My untranslated property',
'SilverStripe\i18n\Tests\i18nTest\TestDataObject.has_one_HasOneRelation' => 'Has one relation',
'SilverStripe\i18n\Tests\i18nTest\TestDataObject.has_many_HasManyRelation' => 'Has many relation',
'SilverStripe\i18n\Tests\i18nTest\TestDataObject.many_many_ManyManyRelation' => 'Many many relation',
],
$matches
);
}
/**
* Test that duplicate keys are resolved to the appropriate modules
*/