Issues (332)

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

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 ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
26
use Doctrine\Common\Persistence\ManagerRegistry;
27
use Doctrine\ODM\MongoDB\DocumentManager;
28
use Doctrine\ODM\MongoDB\Repository\DocumentRepository;
29
30
/**
31
 * Item data provider for the Doctrine MongoDB ODM.
32
 *
33
 * @experimental
34
 *
35
 * @author Alan Poulain <[email protected]>
36
 */
37
final class ItemDataProvider implements DenormalizedIdentifiersAwareItemDataProviderInterface, RestrictedDataProviderInterface
38
{
39
    use IdentifierManagerTrait;
40
41
    private $managerRegistry;
42
    private $resourceMetadataFactory;
43
    private $itemExtensions;
44
45
    /**
46
     * @param AggregationItemExtensionInterface[] $itemExtensions
47
     */
48
    public function __construct(ManagerRegistry $managerRegistry, ResourceMetadataFactoryInterface $resourceMetadataFactory, PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, iterable $itemExtensions = [])
49
    {
50
        $this->managerRegistry = $managerRegistry;
51
        $this->resourceMetadataFactory = $resourceMetadataFactory;
52
        $this->propertyNameCollectionFactory = $propertyNameCollectionFactory;
53
        $this->propertyMetadataFactory = $propertyMetadataFactory;
54
        $this->itemExtensions = $itemExtensions;
55
    }
56
57
    public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
58
    {
59
        return $this->managerRegistry->getManagerForClass($resourceClass) instanceof DocumentManager;
60
    }
61
62
    /**
63
     * {@inheritdoc}
64
     *
65
     * @throws RuntimeException
66
     */
67
    public function getItem(string $resourceClass, $id, string $operationName = null, array $context = [])
68
    {
69
        /** @var DocumentManager $manager */
70
        $manager = $this->managerRegistry->getManagerForClass($resourceClass);
71
72
        if (!\is_array($id) && !($context[IdentifierConverterInterface::HAS_IDENTIFIER_CONVERTER] ?? false)) {
73
            $id = $this->normalizeIdentifiers($id, $manager, $resourceClass);
0 ignored issues
show
$manager of type Doctrine\ODM\MongoDB\DocumentManager is incompatible with the type Doctrine\Common\Persistence\ObjectManager expected by parameter $manager of ApiPlatform\Core\Bridge\...:normalizeIdentifiers(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

73
            $id = $this->normalizeIdentifiers($id, /** @scrutinizer ignore-type */ $manager, $resourceClass);
Loading history...
74
        }
75
76
        $id = (array) $id;
77
78
        if (!($context['fetch_data'] ?? true)) {
79
            return $manager->getReference($resourceClass, reset($id));
80
        }
81
82
        $repository = $manager->getRepository($resourceClass);
83
        if (!$repository instanceof DocumentRepository) {
84
            throw new RuntimeException(sprintf('The repository for "%s" must be an instance of "%s".', $resourceClass, DocumentRepository::class));
85
        }
86
87
        $aggregationBuilder = $repository->createAggregationBuilder();
88
89
        foreach ($id as $propertyName => $value) {
90
            $aggregationBuilder->match()->field($propertyName)->equals($value);
91
        }
92
93
        foreach ($this->itemExtensions as $extension) {
94
            $extension->applyToItem($aggregationBuilder, $resourceClass, $id, $operationName, $context);
95
96
            if ($extension instanceof AggregationResultItemExtensionInterface && $extension->supportsResult($resourceClass, $operationName, $context)) {
97
                return $extension->getResult($aggregationBuilder, $resourceClass, $operationName, $context);
98
            }
99
        }
100
101
        $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass);
102
        $attribute = $resourceMetadata->getItemOperationAttribute($operationName, 'doctrine_mongodb', [], true);
103
        $executeOptions = $attribute['execute_options'] ?? [];
104
105
        return $aggregationBuilder->hydrate($resourceClass)->execute($executeOptions)->current() ?: null;
106
    }
107
}
108