Passed
Pull Request — master (#2144)
by Alan
06:21
created

ItemDataProvider::getItem()   B

Complexity

Conditions 10
Paths 19

Size

Total Lines 45
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 25
dl 0
loc 45
rs 7.6666
c 0
b 0
f 0
cc 10
nc 19
nop 4

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\MongoDB;
15
16
use ApiPlatform\Core\Bridge\Doctrine\MongoDB\Extension\QueryItemExtensionInterface;
17
use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
18
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
19
use ApiPlatform\Core\Exception\InvalidArgumentException;
20
use ApiPlatform\Core\Exception\RuntimeException;
21
use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
22
use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
23
use Doctrine\Common\Persistence\ManagerRegistry;
24
use Doctrine\ODM\MongoDB\Aggregation\Builder;
25
use Doctrine\ODM\MongoDB\DocumentManager;
26
27
/**
28
 * Item data provider for the Doctrine MongoDB ODM.
29
 */
30
final class ItemDataProvider implements ItemDataProviderInterface, RestrictedDataProviderInterface
31
{
32
    private $managerRegistry;
33
    private $propertyNameCollectionFactory;
34
    private $propertyMetadataFactory;
35
    private $itemExtensions;
36
37
    /**
38
     * @param QueryItemExtensionInterface[] $itemExtensions
39
     */
40
    public function __construct(ManagerRegistry $managerRegistry, PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, iterable $itemExtensions = [])
41
    {
42
        $this->managerRegistry = $managerRegistry;
43
        $this->propertyNameCollectionFactory = $propertyNameCollectionFactory;
44
        $this->propertyMetadataFactory = $propertyMetadataFactory;
45
        $this->itemExtensions = $itemExtensions;
46
    }
47
48
    public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
49
    {
50
        return null !== $this->managerRegistry->getManagerForClass($resourceClass);
51
    }
52
53
    /**
54
     * {@inheritdoc}
55
     *
56
     * @throws RuntimeException
57
     */
58
    public function getItem(string $resourceClass, $id, string $operationName = null, array $context = [])
59
    {
60
        $manager = $this->managerRegistry->getManagerForClass($resourceClass);
61
62
        $identifierValues = explode('-', (string) $id);
63
        $identifiers = [];
64
        $i = 0;
65
66
        foreach ($this->propertyNameCollectionFactory->create($resourceClass) as $propertyName) {
67
            $itemMetadata = $this->propertyMetadataFactory->create($resourceClass, $propertyName);
68
69
            $identifier = $itemMetadata->isIdentifier();
70
            if (null === $identifier || false === $identifier) {
71
                continue;
72
            }
73
74
            if (!isset($identifierValues[$i])) {
75
                throw new InvalidArgumentException(sprintf('Invalid identifier "%s".', $id));
76
            }
77
78
            $identifiers[$propertyName] = $identifierValues[$i];
79
            ++$i;
80
        }
81
82
        $fetchData = $context['fetch_data'] ?? true;
83
        if (!$fetchData && $manager instanceof DocumentManager) {
84
            return $manager->getReference($resourceClass, reset($identifiers));
85
        }
86
87
        $repository = $manager->getRepository($resourceClass);
88
        if (!method_exists($repository, 'createAggregationBuilder')) {
89
            throw new RuntimeException('The repository class must have a "createAggregationBuilder" method.');
90
        }
91
        /** @var Builder $aggregationBuilder */
92
        $aggregationBuilder = $repository->createAggregationBuilder();
93
94
        foreach ($identifiers as $propertyName => $value) {
95
            $aggregationBuilder->match()->field($propertyName)->equals($value);
96
        }
97
98
        foreach ($this->itemExtensions as $extension) {
99
            $extension->applyToItem($aggregationBuilder, $resourceClass, $identifiers, $operationName);
100
        }
101
102
        return $aggregationBuilder->hydrate($resourceClass)->execute()->getSingleResult();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $aggregationBuild...te()->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...
103
    }
104
}
105