Skip to content

Commit

Permalink
Add DocumentValueResolver and MapDocument (#774)
Browse files Browse the repository at this point in the history
* Add Symfony 6.3 to the test matrix

* Introduce DocumentValueResolver and MapDocument
  • Loading branch information
franmomu authored Jul 26, 2023
1 parent a14aee5 commit 294b0fb
Show file tree
Hide file tree
Showing 14 changed files with 560 additions and 51 deletions.
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 */
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">
<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">
<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

0 comments on commit 294b0fb

Please sign in to comment.