Passed
Push — master ( 2bb6f9...3a8224 )
by Kévin
06:14 queued 02:58
created

Bridge/Doctrine/MongoDbOdm/ItemDataProvider.php (1 issue)

Severity
1
<?php
2
3
/*
4
 * This file is part of the API Platform project.
5
 *
6
 * (c) Kévin Dunglas <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace ApiPlatform\Core\Bridge\Doctrine\MongoDbOdm;
15
16
use ApiPlatform\Core\Bridge\Doctrine\Common\Util\IdentifierManagerTrait;
17
use ApiPlatform\Core\Bridge\Doctrine\MongoDbOdm\Extension\AggregationItemExtensionInterface;
18
use ApiPlatform\Core\Bridge\Doctrine\MongoDbOdm\Extension\AggregationResultItemExtensionInterface;
19
use ApiPlatform\Core\DataProvider\DenormalizedIdentifiersAwareItemDataProviderInterface;
20
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
21
use ApiPlatform\Core\Exception\RuntimeException;
22
use ApiPlatform\Core\Identifier\IdentifierConverterInterface;
23
use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
24
use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
25
use Doctrine\Common\Persistence\ManagerRegistry;
26
use Doctrine\ODM\MongoDB\DocumentManager;
27
use Doctrine\ODM\MongoDB\Repository\DocumentRepository;
28
29
/**
30
 * Item data provider for the Doctrine MongoDB ODM.
31
 *
32
 * @experimental
33
 *
34
 * @author Alan Poulain <[email protected]>
35
 */
36
final class ItemDataProvider implements DenormalizedIdentifiersAwareItemDataProviderInterface, RestrictedDataProviderInterface
37
{
38
    use IdentifierManagerTrait;
39
40
    private $managerRegistry;
41
    private $itemExtensions;
42
43
    /**
44
     * @param AggregationItemExtensionInterface[] $itemExtensions
45
     */
46
    public function __construct(ManagerRegistry $managerRegistry, PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, iterable $itemExtensions = [])
47
    {
48
        $this->managerRegistry = $managerRegistry;
49
        $this->propertyNameCollectionFactory = $propertyNameCollectionFactory;
50
        $this->propertyMetadataFactory = $propertyMetadataFactory;
51
        $this->itemExtensions = $itemExtensions;
52
    }
53
54
    public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
55
    {
56
        return $this->managerRegistry->getManagerForClass($resourceClass) instanceof DocumentManager;
57
    }
58
59
    /**
60
     * {@inheritdoc}
61
     *
62
     * @throws RuntimeException
63
     */
64
    public function getItem(string $resourceClass, $id, string $operationName = null, array $context = [])
65
    {
66
        /** @var DocumentManager $manager */
67
        $manager = $this->managerRegistry->getManagerForClass($resourceClass);
68
69
        if (!\is_array($id) && !($context[IdentifierConverterInterface::HAS_IDENTIFIER_CONVERTER] ?? false)) {
70
            $id = $this->normalizeIdentifiers($id, $manager, $resourceClass);
71
        }
72
73
        $id = (array) $id;
74
75
        if (!$fetchData = $context['fetch_data'] ?? true) {
0 ignored issues
show
The assignment to $fetchData is dead and can be removed.
Loading history...
76
            return $manager->getReference($resourceClass, reset($id));
77
        }
78
79
        $repository = $manager->getRepository($resourceClass);
80
        if (!$repository instanceof DocumentRepository) {
81
            throw new RuntimeException(sprintf('The repository for "%s" must be an instance of "%s".', $resourceClass, DocumentRepository::class));
82
        }
83
84
        $aggregationBuilder = $repository->createAggregationBuilder();
85
86
        foreach ($id as $propertyName => $value) {
87
            $aggregationBuilder->match()->field($propertyName)->equals($value);
88
        }
89
90
        foreach ($this->itemExtensions as $extension) {
91
            $extension->applyToItem($aggregationBuilder, $resourceClass, $id, $operationName, $context);
92
93
            if ($extension instanceof AggregationResultItemExtensionInterface && $extension->supportsResult($resourceClass, $operationName, $context)) {
94
                return $extension->getResult($aggregationBuilder, $resourceClass, $operationName, $context);
95
            }
96
        }
97
98
        return $aggregationBuilder->hydrate($resourceClass)->execute()->current() ?: null;
99
    }
100
}
101