Passed
Pull Request — master (#2144)
by Alan
03:00
created

ItemDataProvider::getItem()   C

Complexity

Conditions 12
Paths 25

Size

Total Lines 49
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

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