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

ItemDataProvider   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 79
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 12
eloc 36
dl 0
loc 79
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A supports() 0 3 1
A __construct() 0 11 1
B getItem() 0 46 10
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\PHPCR;
15
16
use ApiPlatform\Core\Bridge\Doctrine\PHPCR\Extension\QueryItemExtensionInterface;
17
use ApiPlatform\Core\Bridge\Doctrine\PHPCR\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\PHPCR\DocumentManager;
26
27
/**
28
 * Item data provider for the Doctrine MongoDB ODM.
29
 */
30
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(
41
        ManagerRegistry $managerRegistry,
42
        PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory,
43
        PropertyMetadataFactoryInterface $propertyMetadataFactory,
44
        /* iterable */ $itemExtensions = [],
45
        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

45
        /** @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...
46
    ) {
47
        $this->managerRegistry = $managerRegistry;
48
        $this->propertyNameCollectionFactory = $propertyNameCollectionFactory;
49
        $this->propertyMetadataFactory = $propertyMetadataFactory;
50
        $this->itemExtensions = $itemExtensions;
51
    }
52
53
    public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
54
    {
55
        return null !== $this->managerRegistry->getManagerForClass($resourceClass);
56
    }
57
58
    /**
59
     * {@inheritdoc}
60
     *
61
     * @throws RuntimeException
62
     */
63
    public function getItem(string $resourceClass, $id, string $operationName = null, array $context = [])
64
    {
65
        $manager = $this->managerRegistry->getManagerForClass($resourceClass);
66
67
        $identifierValues = explode('-', (string) $id);
68
        $identifiers = [];
69
        $i = 0;
70
71
        foreach ($this->propertyNameCollectionFactory->create($resourceClass) as $propertyName) {
72
            $itemMetadata = $this->propertyMetadataFactory->create($resourceClass, $propertyName);
73
74
            $identifier = $itemMetadata->isIdentifier();
75
            if (null === $identifier || false === $identifier) {
76
                continue;
77
            }
78
79
            if (!isset($identifierValues[$i])) {
80
                throw new InvalidArgumentException(sprintf('Invalid identifier "%s".', $id));
81
            }
82
83
            $identifiers[$propertyName] = $identifierValues[$i];
84
            ++$i;
85
        }
86
87
        $fetchData = $context['fetch_data'] ?? true;
88
        if (!$fetchData && $manager instanceof DocumentManager) {
89
            return $manager->getReference($resourceClass, reset($identifiers));
90
        }
91
92
        $repository = $manager->getRepository($resourceClass);
93
        if (!method_exists($repository, 'createAggregationBuilder')) {
94
            throw new RuntimeException('The repository class must have a "createAggregationBuilder" method.');
95
        }
96
        /** @var Builder $aggregationBuilder */
97
        $aggregationBuilder = $repository->createAggregationBuilder();
98
        $queryNameGenerator = new QueryNameGenerator();
99
100
        foreach ($identifiers as $propertyName => $value) {
101
            $aggregationBuilder->match()->field($propertyName)->equals($value);
102
        }
103
104
        foreach ($this->itemExtensions as $extension) {
105
            $extension->applyToItem($aggregationBuilder, $queryNameGenerator, $resourceClass, $identifiers, $operationName);
106
        }
107
108
        return $aggregationBuilder->hydrate($resourceClass)->execute()->getSingleResult();
109
    }
110
}
111