Passed
Pull Request — master (#2144)
by Alan
07:23
created

ItemDataProvider   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 77
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 13
eloc 41
dl 0
loc 77
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
C getItem() 0 54 12
A __construct() 0 7 1
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
 * This file is part of the API Platform project.
15
 *
16
 * (c) Kévin Dunglas <[email protected]>
17
 *
18
 * For the full copyright and license information, please view the LICENSE
19
 * file that was distributed with this source code.
20
 */
21
22
namespace ApiPlatform\Core\Bridge\Doctrine\MongoDB;
23
24
use ApiPlatform\Core\Bridge\Doctrine\MongoDB\Extension\QueryItemExtensionInterface;
25
use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
26
use ApiPlatform\Core\Exception\InvalidArgumentException;
27
use ApiPlatform\Core\Exception\ResourceClassNotSupportedException;
28
use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
29
use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
30
use Doctrine\Common\Persistence\ManagerRegistry;
31
use Doctrine\ODM\MongoDB\DocumentManager;
32
use Doctrine\ODM\MongoDB\DocumentRepository;
33
34
/**
35
 * Item data provider for the Doctrine MongoDB ODM.
36
 */
37
class ItemDataProvider implements ItemDataProviderInterface
38
{
39
    private $managerRegistry;
40
    private $propertyNameCollectionFactory;
41
    private $propertyMetadataFactory;
42
    private $itemExtensions;
43
    private $decorated;
44
45
    /**
46
     * @param QueryItemExtensionInterface[] $itemExtensions
47
     */
48
    public function __construct(ManagerRegistry $managerRegistry, PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, /* iterable */ $itemExtensions = [], ItemDataProviderInterface $decorated = null)
49
    {
50
        $this->managerRegistry = $managerRegistry;
51
        $this->propertyNameCollectionFactory = $propertyNameCollectionFactory;
52
        $this->propertyMetadataFactory = $propertyMetadataFactory;
53
        $this->itemExtensions = $itemExtensions;
54
        $this->decorated = $decorated;
55
    }
56
57
    /**
58
     * {@inheritdoc}
59
     */
60
    public function getItem(string $resourceClass, $id, string $operationName = null, array $context = [])
61
    {
62
        if ($this->decorated) {
63
            try {
64
                return $this->decorated->getItem($resourceClass, $id, $operationName, $context);
65
            } catch (ResourceClassNotSupportedException $resourceClassNotSupportedException) {
66
                // Ignore it
67
            }
68
        }
69
70
        $manager = $this->managerRegistry->getManagerForClass($resourceClass);
71
        if (null === $manager) {
72
            throw new ResourceClassNotSupportedException();
73
        }
74
75
        $identifierValues = explode('-', (string) $id);
76
        $identifiers = [];
77
        $i = 0;
78
79
        foreach ($this->propertyNameCollectionFactory->create($resourceClass) as $propertyName) {
80
            $itemMetadata = $this->propertyMetadataFactory->create($resourceClass, $propertyName);
81
82
            $identifier = $itemMetadata->isIdentifier();
83
            if (null === $identifier || false === $identifier) {
84
                continue;
85
            }
86
87
            if (!isset($identifierValues[$i])) {
88
                throw new InvalidArgumentException(sprintf('Invalid identifier "%s".', $id));
89
            }
90
91
            $identifiers[$propertyName] = $identifierValues[$i];
92
            ++$i;
93
        }
94
95
        $fetchData = $context['fetch_data'] ?? true;
96
        if (!$fetchData && $manager instanceof DocumentManager) {
97
            return $manager->getReference($resourceClass, reset($identifiers));
98
        }
99
100
        /** @var DocumentRepository $repository */
101
        $repository = $manager->getRepository($resourceClass);
102
        $queryBuilder = $repository->createQueryBuilder();
103
104
        foreach ($identifiers as $propertyName => $value) {
105
            $queryBuilder
106
                ->field($propertyName)->equals($value);
107
        }
108
109
        foreach ($this->itemExtensions as $extension) {
110
            $extension->applyToItem($queryBuilder, $resourceClass, $identifiers, $operationName);
111
        }
112
113
        return $queryBuilder->getQuery()->getSingleResult();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $queryBuilder->ge...ry()->getSingleResult() also could return the type array which is incompatible with the return type mandated by ApiPlatform\Core\DataPro...derInterface::getItem() of object|null.
Loading history...
114
    }
115
}
116