Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 25 additions & 21 deletions DependencyInjection/Compiler/RegisterMappingPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,45 +33,45 @@ public function process(ContainerBuilder $container): void
// Models now use PHP attributes, so we need to use AttributeDriver
// Create attribute driver if it doesn't exist (fallback if Extension didn't create it)
$attributeDriverId = 'lexik_translation.orm.metadata.attribute';

// Ensure attribute driver exists - create it if Extension didn't create it
if (!$container->hasDefinition($attributeDriverId)) {
// Calculate bundle path using ReflectionClass
$bundleReflection = new \ReflectionClass(\Lexik\Bundle\TranslationBundle\LexikTranslationBundle::class);
$bundleDir = dirname($bundleReflection->getFileName());
$modelPath = $bundleDir . '/Model';

// Try to get realpath
$realModelPath = realpath($modelPath);
if ($realModelPath) {
$modelPath = $realModelPath;
}

// Create AttributeDriver service
$driverDefinition = new Definition(AttributeDriver::class, [
[$modelPath]
]);
$driverDefinition->setPublic(false);
$container->setDefinition($attributeDriverId, $driverDefinition);
}

// Register attribute driver for models namespace
// IMPORTANT: We need to check if it's already registered to avoid duplicates
$ormDriver = $container->getDefinition($ormDriverId);
$methodCalls = $ormDriver->getMethodCalls();

// Check if attribute driver is already registered
$attributeDriverRegistered = false;
foreach ($methodCalls as $call) {
if ($call[0] === 'addDriver' &&
isset($call[1][0]) &&
if ($call[0] === 'addDriver' &&
isset($call[1][0]) &&
$call[1][0] instanceof Reference &&
(string)$call[1][0] === $attributeDriverId) {
$attributeDriverRegistered = true;
break;
}
}

// Register XML driver for Entity namespace FIRST (entities use XML mapping)
// This must be registered before Model namespace to ensure entities are recognized
// Create XML driver for entities if it doesn't exist
Expand All @@ -81,14 +81,18 @@ public function process(ContainerBuilder $container): void
$bundleReflection = new \ReflectionClass(\Lexik\Bundle\TranslationBundle\LexikTranslationBundle::class);
$bundleDir = dirname($bundleReflection->getFileName());
$doctrinePath = $bundleDir . '/Resources/config/doctrine';

$realDoctrinePath = realpath($doctrinePath);
if ($realDoctrinePath) {
$doctrinePath = $realDoctrinePath;
}

// Create XML driver for entities using the same class as the model XML driver
$xmlDriverClass = $container->getParameter('doctrine.orm.metadata.xml.class');

// Create XML driver for entities using SimplifiedXmlDriver
if (class_exists(SimplifiedXmlDriver::class)) {
$xmlDriverClass = SimplifiedXmlDriver::class;
} else {
$xmlDriverClass = $container->getParameter('doctrine.orm.metadata.xml.class');
}
$entityDriverDefinition = new Definition($xmlDriverClass, [
[$doctrinePath => 'Lexik\Bundle\TranslationBundle\Entity'],
SimplifiedXmlDriver::DEFAULT_FILE_EXTENSION,
Expand All @@ -97,18 +101,18 @@ public function process(ContainerBuilder $container): void
$entityDriverDefinition->setPublic(false);
$container->setDefinition($entityXmlDriverId, $entityDriverDefinition);
}

// Register XML driver for Entity namespace FIRST
$entityDriverRegistered = false;
foreach ($methodCalls as $call) {
if ($call[0] === 'addDriver' &&
isset($call[1][1]) &&
if ($call[0] === 'addDriver' &&
isset($call[1][1]) &&
$call[1][1] === 'Lexik\Bundle\TranslationBundle\Entity') {
$entityDriverRegistered = true;
break;
}
}

if (!$entityDriverRegistered && $container->hasDefinition($entityXmlDriverId)) {
// Insert at the beginning to ensure Entity namespace is processed first
$newMethodCalls = [[
Expand All @@ -121,15 +125,15 @@ public function process(ContainerBuilder $container): void
$ormDriver->setMethodCalls($newMethodCalls);
$methodCalls = $newMethodCalls; // Update for next checks
}

// Register attribute driver if not already registered
if (!$attributeDriverRegistered && $container->hasDefinition($attributeDriverId)) {
// Remove any existing registration for the Model namespace (XML driver)
$newMethodCalls = [];
foreach ($methodCalls as $call) {
// Skip XML driver registration for Model namespace
if ($call[0] === 'addDriver' &&
isset($call[1][1]) &&
if ($call[0] === 'addDriver' &&
isset($call[1][1]) &&
$call[1][1] === 'Lexik\Bundle\TranslationBundle\Model' &&
isset($call[1][0]) &&
$call[1][0] instanceof Reference &&
Expand All @@ -139,13 +143,13 @@ public function process(ContainerBuilder $container): void
}
$newMethodCalls[] = $call;
}

// Add attribute driver for Model namespace
$newMethodCalls[] = [
'addDriver',
[new Reference($attributeDriverId), 'Lexik\Bundle\TranslationBundle\Model']
];

// Update method calls
$ormDriver->setMethodCalls($newMethodCalls);
} elseif (!$container->hasDefinition($attributeDriverId) && $container->hasDefinition('lexik_translation.orm.metadata.xml')) {
Expand Down
25 changes: 15 additions & 10 deletions DependencyInjection/LexikTranslationExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,13 @@ protected function buildTranslationStorageDefinition(ContainerBuilder $container
$args = [new Reference('doctrine'), $objectManager ?? 'default'];

// Create XML driver for backward compatibility
$this->createDoctrineMappingDriver($container, 'lexik_translation.orm.metadata.xml', '%doctrine.orm.metadata.xml.class%');

if (class_exists(SimplifiedXmlDriver::class)) {
$xmlDriverClass = SimplifiedXmlDriver::class;
} else {
$xmlDriverClass = $container->getParameter('doctrine.orm.metadata.xml.class');
}
$this->createDoctrineMappingDriver($container, 'lexik_translation.orm.metadata.xml', $xmlDriverClass);

// Create attribute driver for models (MappedSuperclass) that now use PHP attributes
$this->createDoctrineAttributeDriver($container, 'lexik_translation.orm.metadata.attribute');

Expand All @@ -186,8 +191,8 @@ protected function buildTranslationStorageDefinition(ContainerBuilder $container
}

$args[] = [
'trans_unit' => new Parameter(sprintf('lexik_translation.%s.trans_unit.class', $storage)),
'translation' => new Parameter(sprintf('lexik_translation.%s.translation.class', $storage)),
'trans_unit' => new Parameter(sprintf('lexik_translation.%s.trans_unit.class', $storage)),
'translation' => new Parameter(sprintf('lexik_translation.%s.translation.class', $storage)),
'file' => new Parameter(sprintf('lexik_translation.%s.file.class', $storage))
];

Expand All @@ -208,7 +213,7 @@ protected function buildTranslationStorageDefinition(ContainerBuilder $container
protected function createDoctrineMappingDriver(ContainerBuilder $container, $driverId, $driverClass)
{
$driverDefinition = new Definition($driverClass, [
[realpath(__DIR__.'/../Resources/config/model') => 'Lexik\Bundle\TranslationBundle\Model'],
[realpath(__DIR__.'/../Resources/config/model') => 'Lexik\Bundle\TranslationBundle\Model'],
SimplifiedXmlDriver::DEFAULT_FILE_EXTENSION, true
]);
$driverDefinition->setPublic(false);
Expand All @@ -229,20 +234,20 @@ protected function createDoctrineAttributeDriver(ContainerBuilder $container, $d
$bundleReflection = new \ReflectionClass(\Lexik\Bundle\TranslationBundle\LexikTranslationBundle::class);
$bundleDir = dirname($bundleReflection->getFileName());
$modelPath = $bundleDir . '/Model';

// Try to get realpath, but use the calculated path if it fails
$realModelPath = realpath($modelPath);
if ($realModelPath) {
$modelPath = $realModelPath;
}

// AttributeDriver constructor expects an array of paths (directories to scan)
// It will automatically detect classes with #[ORM\MappedSuperclass] or #[ORM\Entity] attributes
$driverDefinition = new Definition(AttributeDriver::class, [
[$modelPath]
]);
$driverDefinition->setPublic(false);

// Always set/override the definition to ensure it exists with correct arguments
$container->setDefinition($driverId, $driverDefinition);
}
Expand Down Expand Up @@ -280,9 +285,9 @@ protected function registerTranslatorConfiguration(array $config, ContainerBuild
$innerTranslator = $container->hasDefinition('lexik_translation.translator.inner')
? $container->findDefinition('lexik_translation.translator.inner')
: $container->findDefinition('translator');

$innerTranslator->addMethodCall('setFallbackLocales', [$config['fallback_locale']]);

// For adding file resources, we'll add them to the inner translator
$translator = $innerTranslator;

Expand Down
22 changes: 11 additions & 11 deletions Tests/Unit/Translation/TranslatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ public function testAddDatabaseResources(): void
$expected = [
'de' => [
['database', 'DB', 'superTranslations']
],
],
'en' => [
['database', 'DB', 'messages'],
['database', 'DB', 'messages'],
['database', 'DB', 'superTranslations']
],
],
'fr' => [
['database', 'DB', 'messages'],
['database', 'DB', 'messages'],
['database', 'DB', 'superTranslations'],
]
];
Expand Down Expand Up @@ -140,10 +140,10 @@ protected function createTranslator($em, $cacheDir): TranslatorMock
];

return new TranslatorMock(
container: $container,
formatter: new MessageFormatter(),
defaultLocale: 'en',
loaderIds: $loaderIds,
container: $container,
formatter: new MessageFormatter(),
defaultLocale: 'en',
loaderIds: $loaderIds,
options: $options
);
}
Expand All @@ -170,9 +170,9 @@ protected function createFakeCacheFiles($cacheDir): void

class TranslatorMock extends Translator
{
public $dbResources = [];
public array $dbResources = [];
public array $options = [
'cache_dir' => '',
'cache_dir' => '',
'debug' => false,
'resource_files' => [],
'cache_vary' => [],
Expand All @@ -197,4 +197,4 @@ public function addResource(string $format, mixed $resource, string $locale, ?st

parent::addResource($format, $resource, $locale, $domain);
}
}
}
1 change: 0 additions & 1 deletion Tests/Unit/Util/DataGrid/DataGridRequestHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ private function getReflectionMethod($name)
{
$class = new \ReflectionClass(DataGridRequestHandler::class);
$method = $class->getMethod($name);
$method->setAccessible(true);

return $method;
}
Expand Down
Loading
Loading