Completed
Pull Request — master (#904)
by Antoine
21:03
created

IdentifiersHelper   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 61
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
wmc 9
lcom 1
cbo 5
dl 0
loc 61
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
C normalizeIdentifiers() 0 39 8
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
namespace ApiPlatform\Core\Bridge\Doctrine\Orm\Util;
13
14
use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
15
use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
16
use Doctrine\Common\Persistence\ObjectManager;
17
use Doctrine\ORM\QueryBuilder;
18
19
/**
20
 * Tools that helps managing Identifiers (composite or regular) and related where clauses 
21
 */
22
class IdentifiersHelper
23
{
24
    private $propertyNameCollectionFactory;
25
    private $propertyMetadataFactory;
26
27
    function __construct(PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
28
        $this->propertyNameCollectionFactory = $propertyNameCollectionFactory;
29
        $this->propertyMetadataFactory = $propertyMetadataFactory;
30
    }
31
32
    /**
33
     * Transform and check the identifier, composite or not.
34
     *
35
     * @param int|string    $id
36
     * @param ObjectManager $manager
37
     * @param string        $resourceClass
38
     *
39
     * @throws PropertyNotFoundException
40
     *
41
     * @return array
42
     */
43
    public function normalizeIdentifiers($id, ObjectManager $manager, string $resourceClass): array
44
    {
45
        $identifierValues = [$id];
46
        $doctrineMetadataIdentifier = $manager->getClassMetadata($resourceClass)->getIdentifier();
47
48
        if (count($doctrineMetadataIdentifier) >= 2) {
49
            $identifiers = explode(';', $id);
50
            $identifiersMap = [];
51
52
            // first transform identifiers to a proper key/value array
53
            foreach ($identifiers as $identifier) {
54
                $keyValue = explode('=', $identifier);
55
                $identifiersMap[$keyValue[0]] = $keyValue[1];
56
            }
57
        }
58
59
        $identifiers = [];
60
        $i = 0;
61
62
        foreach ($this->propertyNameCollectionFactory->create($resourceClass) as $propertyName) {
63
            $propertyMetadata = $this->propertyMetadataFactory->create($resourceClass, $propertyName);
64
65
            $identifier = $propertyMetadata->isIdentifier();
66
            if (null === $identifier || false === $identifier) {
67
                continue;
68
            }
69
70
            $identifier = !isset($identifiersMap) ? $identifierValues[$i] ?? null : $identifiersMap[$propertyName] ?? null;
71
72
            if (null === $identifier) {
73
                throw new PropertyNotFoundException(sprintf('Invalid identifier "%s", "%s" has not been found.', $id, $propertyName));
74
            }
75
76
            $identifiers[$propertyName] = $identifier;
77
            ++$i;
78
        }
79
80
        return $identifiers;
81
    }
82
}