doctrine / DoctrineMongoDBBundle

Integrates Doctrine MongoDB ODM with Symfony
http://symfony.com/doc/current/bundles/DoctrineMongoDBBundle/index.html
MIT License
377 stars 231 forks source link

Configuration with non bundled mapping and xml mapping is broken in 5.0 #841

Closed frenchcomp closed 5 months ago

frenchcomp commented 5 months ago

Hi,

I have a project, with persisted document are not in bundle and use a xml mapping. The configuration is

doctrine_mongodb:
    document_managers:
        default:
            auto_mapping: true
            mappings:
                TeknooEastCommon:
                    type: 'xml'
                    dir: '%kernel.project_dir%/vendor/teknoo/east-common/infrastructures/doctrine/config/universal'
                    is_bundle: false
                    prefix: 'Teknoo\East\Common\Object'

It's work with the bundle under v4.7 (With Symfony 6.4 or 7.0) but not with v5.0 I have this error :

PHP Fatal error: Uncaught TypeError: is_dir(): Argument #1 ($filename) must be of type string, int given in /home/richard/Prog/teknoo/websites/website-deloge-io/appliance/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/SymfonyFileLocator.php:180

After debug, the compiled DI for the document manager is different, The error come from the XmlDriver configuration and the Symfony DoctrineBridge and this bunde.

With 4.7, the generated code is :

$c = new \Doctrine\Bundle\MongoDBBundle\Mapping\Driver\XmlDriver([(\dirname(__DIR__, 4).'/vendor/teknoo/east-common/infrastructures/doctrine/config/universal') => 'Teknoo\\East\\Common\\Object', (\dirname(__DIR__, 4).'/vendor/teknoo/east-common/infrastructures/doctrine/config/doctrine') => 'Teknoo\\East\\Common\\Doctrine\\Object', (\dirname(__DIR__, 4).'/vendor/teknoo/east-website/infrastructures/doctrine/config/universal') => 'Teknoo\\East\\Website\\Object', (\dirname(__DIR__, 4).'/vendor/teknoo/east-website/infrastructures/doctrine/config/doctrine') => 'Teknoo\\East\\Website\\Doctrine\\Object']);
        $c->setGlobalBasename('mapping');

But with 5.0

$c = new \Doctrine\Bundle\MongoDBBundle\Mapping\Driver\XmlDriver([(\dirname(__DIR__, 4).'/vendor/teknoo/east-common/infrastructures/doctrine/config/universal'), (\dirname(__DIR__, 4).'/vendor/teknoo/east-common/infrastructures/doctrine/config/doctrine'), (\dirname(__DIR__, 4).'/vendor/teknoo/east-website/infrastructures/doctrine/config/universal'), (\dirname(__DIR__, 4).'/vendor/teknoo/east-website/infrastructures/doctrine/config/doctrine')]);

The first argument of XmlDriver has only array's values wihout keys.

It come from the 'vendor/symfony/doctrine-bridge/DependencyInjection/AbstractDoctrineExtension.php', line 218

if (str_contains($mappingDriverDef->getClass(), 'yml') || str_contains($mappingDriverDef->getClass(), 'xml')) {
    $mappingDriverDef->setArguments([array_flip($driverPaths)]);
    $mappingDriverDef->addMethodCall('setGlobalBasename', ['mapping']);
}

The mappingDriverDef->getClass() return %doctrine_mongodb.odm.metadata.xml.class% and the condition will be true But it 5.0 Doctrine\Bundle\MongoDBBundle\Mapping\Driver\XmlDriver and because the condition is sensible to the case, it will never be true.

Thanks.

MatthieuPoudevigne-cnic commented 5 months ago

I confirm i have the same problem when i try to update symfony 6.4 to 7.0 with the update of this bundle

GromNaN commented 5 months ago

Thanks for the reminder, I'm checking.

GromNaN commented 5 months ago

We use SimplifiedXmlDriver to parse the mapping with type: xml. This class accepts a list of strings string[] as $prefixes. (see SimplifiedXmlDriver::__construct())

But the SymfonyFileLocator that is used, only keep the "keys" from this array of paths. That's why we get 0 instead of the actual file path. https://github.com/doctrine/persistence/blob/e7cf418cafe83a75f7a7096cc9fa890b201d28f1/src/Persistence/Mapping/Driver/SymfonyFileLocator.php#L95

GromNaN commented 5 months ago

The issue is caused by #821 See the fix in Symfony DoctrineBridge: https://github.com/symfony/symfony/pull/53681