Skip to content
Merged
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
3 changes: 3 additions & 0 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ jobs:
symfony-version:
- "5.4.x"
- "6.2.x"
- "6.3.x"
driver-version:
- "stable"
dependencies:
Expand All @@ -45,6 +46,8 @@ jobs:
exclude:
- php-version: "7.4"
symfony-version: "6.2.x"
- php-version: "7.4"
symfony-version: "6.3.x"

services:
mongodb:
Expand Down
24 changes: 24 additions & 0 deletions ArgumentResolver/DocumentValueResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace Doctrine\Bundle\MongoDBBundle\ArgumentResolver;

use Symfony\Bridge\Doctrine\ArgumentResolver\EntityValueResolver;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Controller\ValueResolverInterface;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;

/** @internal */
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why It's marked as @internal if the original EntityValueResolver is not @internal?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @pepeh, in this case we provide the feature of fetching objects from the controller automatically, I decided to mark this class as @internal since to me it was an implementation detail, if we could use the EntityValueResolver, we could remove this class.

Are you using this class directly?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@franmomu there is option to specify value resolver manually
#[ValueResolver(DocumentValueResolver::class)]
https://symfony.com/doc/current/controller/value_resolver.html#managing-value-resolvers
But if class is @internal IDE will show warning

final class DocumentValueResolver implements ValueResolverInterface
{
public function __construct(
private EntityValueResolver $entityValueResolver,
) {
}

public function resolve(Request $request, ArgumentMetadata $argument): array
{
return $this->entityValueResolver->resolve($request, $argument);
}
}
27 changes: 27 additions & 0 deletions Attribute/MapDocument.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace Doctrine\Bundle\MongoDBBundle\Attribute;

use Attribute;
use Doctrine\Bundle\MongoDBBundle\ArgumentResolver\DocumentValueResolver;
use Symfony\Bridge\Doctrine\Attribute\MapEntity;

#[Attribute(Attribute::TARGET_PARAMETER)]
class MapDocument extends MapEntity
{
public function __construct(
public ?string $class = null,
public ?string $objectManager = null,
public ?string $expr = null,
public ?array $mapping = null,
public ?array $exclude = null,
public ?bool $stripNull = null,
public array|string|null $id = null,
bool $disabled = false,
string $resolver = DocumentValueResolver::class,
) {
parent::__construct($class, $objectManager, $expr, $mapping, $exclude, $stripNull, $id, null, $disabled, $resolver);
}
}
77 changes: 43 additions & 34 deletions DependencyInjection/DoctrineMongoDBExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Doctrine\Bundle\MongoDBBundle\DependencyInjection;

use Doctrine\Bundle\MongoDBBundle\Attribute\AsDocumentListener;
use Doctrine\Bundle\MongoDBBundle\Attribute\MapDocument;
use Doctrine\Bundle\MongoDBBundle\DependencyInjection\Compiler\FixturesCompilerPass;
use Doctrine\Bundle\MongoDBBundle\DependencyInjection\Compiler\ServiceRepositoryCompilerPass;
use Doctrine\Bundle\MongoDBBundle\EventSubscriber\EventSubscriberInterface;
Expand All @@ -18,14 +19,14 @@
use InvalidArgumentException;
use Jean85\PrettyVersions;
use Symfony\Bridge\Doctrine\ArgumentResolver\EntityValueResolver;
use Symfony\Bridge\Doctrine\Attribute\MapEntity;
use Symfony\Bridge\Doctrine\DependencyInjection\AbstractDoctrineExtension;
use Symfony\Bridge\Doctrine\Messenger\DoctrineClearEntityManagerWorkerSubscriber;
use Symfony\Component\Cache\Adapter\ApcuAdapter;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\MemcachedAdapter;
use Symfony\Component\Cache\Adapter\RedisAdapter;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Config\Loader\FileLoader;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
Expand Down Expand Up @@ -149,39 +150,7 @@ public function load(array $configs, ContainerBuilder $container)

$this->loadMessengerServices($container);

// available in Symfony 6.2 and higher
if (! class_exists(EntityValueResolver::class)) {
$container->removeDefinition('doctrine_mongodb.odm.entity_value_resolver');
$container->removeDefinition('doctrine_mongodb.odm.entity_value_resolver.expression_language');
} else {
if (! class_exists(ExpressionLanguage::class)) {
$container->removeDefinition('doctrine_mongodb.odm.entity_value_resolver.expression_language');
}

$controllerResolverDefaults = [];

if (! $config['controller_resolver']['enabled']) {
$controllerResolverDefaults['disabled'] = true;
}

if (! $config['controller_resolver']['auto_mapping']) {
$controllerResolverDefaults['mapping'] = [];
}

if ($controllerResolverDefaults) {
$container->getDefinition('doctrine_mongodb.odm.entity_value_resolver')->setArgument(2, (new Definition(MapEntity::class))->setArguments([
null,
null,
null,
$controllerResolverDefaults['mapping'] ?? null,
null,
null,
null,
null,
$controllerResolverDefaults['disabled'] ?? false,
]));
}
}
$this->loadEntityValueResolverServices($container, $loader, $config);
}

/**
Expand Down Expand Up @@ -432,6 +401,46 @@ private function loadMessengerServices(ContainerBuilder $container): void
$loader->load('messenger.xml');
}

/** @param array<string, mixed> $config */
private function loadEntityValueResolverServices(ContainerBuilder $container, FileLoader $loader, array $config): void
{
// available in Symfony 6.2 and higher
if (! class_exists(EntityValueResolver::class)) {
return;
}

$loader->load('value_resolver.xml');

if (! class_exists(ExpressionLanguage::class)) {
$container->removeDefinition('doctrine_mongodb.odm.document_value_resolver.expression_language');
}

$controllerResolverDefaults = [];

if (! $config['controller_resolver']['enabled']) {
$controllerResolverDefaults['disabled'] = true;
}

if (! $config['controller_resolver']['auto_mapping']) {
$controllerResolverDefaults['mapping'] = [];
}

if ($controllerResolverDefaults === []) {
return;
}

$container->getDefinition('doctrine_mongodb.odm.entity_value_resolver')->setArgument(2, (new Definition(MapDocument::class))->setArguments([
null,
null,
null,
$controllerResolverDefaults['mapping'] ?? null,
null,
null,
null,
$controllerResolverDefaults['disabled'] ?? false,
]));
}

/**
* Normalizes the driver options array
*
Expand Down
8 changes: 0 additions & 8 deletions Resources/config/mongodb.xml
Original file line number Diff line number Diff line change
Expand Up @@ -208,13 +208,5 @@
<service id="doctrine_mongodb.odm.symfony.fixtures.loader" class="Doctrine\Bundle\MongoDBBundle\Loader\SymfonyFixturesLoader" public="false">
<argument type="service" id="service_container" />
</service>

<service id="doctrine_mongodb.odm.entity_value_resolver" class="Symfony\Bridge\Doctrine\ArgumentResolver\EntityValueResolver">
Copy link
Member

@GromNaN GromNaN Jun 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like a breaking change if someone is already using the MapEntity attribute with the ODM. Not a big deal but it must be documented in the UPGRADE file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmm not sure about the BC break, these services were added in 4.6.x and never been released, so if someone is using it is because EntityValueResolver was registered as a service manually, in that case I guess it will continue working fine.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and never been released

We're fine changing logic given this argument :)

<argument type="service" id="doctrine_mongodb" />
<argument type="service" id="doctrine_mongodb.odm.entity_value_resolver.expression_language" on-invalid="ignore" />
<tag name="controller.argument_value_resolver" priority="110" />
</service>

<service id="doctrine_mongodb.odm.entity_value_resolver.expression_language" class="Symfony\Component\ExpressionLanguage\ExpressionLanguage" />
</services>
</container>
20 changes: 20 additions & 0 deletions Resources/config/value_resolver.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

<services>
<service id="doctrine_mongodb.odm.entity_value_resolver" class="Symfony\Bridge\Doctrine\ArgumentResolver\EntityValueResolver">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this and other services use document instead of entity?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed the other ones, but not sure about this one since it's for the EntityValueResolver

<argument type="service" id="doctrine_mongodb" />
<argument type="service" id="doctrine_mongodb.odm.document_value_resolver.expression_language" on-invalid="ignore" />
</service>

<service id="doctrine_mongodb.odm.document_value_resolver.expression_language" class="Symfony\Component\ExpressionLanguage\ExpressionLanguage" />

<service id="doctrine_mongodb.odm.document_value_resolver" class="Doctrine\Bundle\MongoDBBundle\ArgumentResolver\DocumentValueResolver">
<argument type="service" id="doctrine_mongodb.odm.entity_value_resolver" />
<tag name="Doctrine\Bundle\MongoDBBundle\ArgumentResolver\DocumentValueResolver" priority="110">controller.argument_value_resolver</tag>
</service>
</services>
</container>
Loading