Passed
Pull Request — master (#2162)
by Maximilian
03:14
created

ItemDataProvider::getItem()   B

Complexity

Conditions 10
Paths 19

Size

Total Lines 46
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 26
dl 0
loc 46
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\Bridge\Doctrine\MongoDB\Util\QueryNameGenerator;
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
class ItemDataProvider implements ItemDataProviderInterface, RestrictedDataProviderInterface
32
{
33
    private $managerRegistry;
34
    private $propertyNameCollectionFactory;
35
    private $propertyMetadataFactory;
36
    private $itemExtensions;
37
38
    /**
39
     * @param QueryItemExtensionInterface[] $itemExtensions
40
     */
41
    public function __construct(ManagerRegistry $managerRegistry, PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, /* iterable */ $itemExtensions = [], ItemDataProviderInterface $decorated = null)
0 ignored issues
show
Unused Code introduced by
The parameter $decorated is not used and could be removed. ( Ignorable by Annotation )

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

41
    public function __construct(ManagerRegistry $managerRegistry, PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, /* iterable */ $itemExtensions = [], /** @scrutinizer ignore-unused */ ItemDataProviderInterface $decorated = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
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
        $queryNameGenerator = new QueryNameGenerator();
95
96
        foreach ($identifiers as $propertyName => $value) {
97
            $aggregationBuilder->match()->field($propertyName)->equals($value);
98
        }
99
100
        foreach ($this->itemExtensions as $extension) {
101
            $extension->applyToItem($aggregationBuilder, $queryNameGenerator, $resourceClass, $identifiers, $operationName);
102
        }
103
104
        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...
105
    }
106
}
107