Passed
Push — master ( 605481...12e50c )
by Rafael
05:00
created

SimpleIDEncoder::decode()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 30
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 5.0488

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 15
c 2
b 1
f 0
dl 0
loc 30
ccs 14
cts 16
cp 0.875
rs 9.4555
cc 5
nc 5
nop 1
crap 5.0488
1
<?php
2
/*******************************************************************************
3
 *  This file is part of the GraphQL Bundle package.
4
 *
5
 *  (c) YnloUltratech <[email protected]>
6
 *
7
 *  For the full copyright and license information, please view the LICENSE
8
 *  file that was distributed with this source code.
9
 ******************************************************************************/
10
11
namespace Ynlo\GraphQLBundle\Encoder;
12
13
use Doctrine\Bundle\DoctrineBundle\Registry;
14
use Doctrine\ORM\EntityManagerInterface;
15
use Ynlo\GraphQLBundle\Definition\Registry\DefinitionRegistry;
16
use Ynlo\GraphQLBundle\Model\NodeInterface;
17
use Ynlo\GraphQLBundle\Util\TypeUtil;
18
19
class SimpleIDEncoder implements IDEncoderInterface
20
{
21
    private const DIVIDER = ':';
22
23
    /**
24
     * @var Registry
25
     */
26
    protected $doctrine;
27
28
    /**
29
     * @var DefinitionRegistry
30
     */
31
    protected $definitionRegistry;
32
33
34 7
    public function __construct(DefinitionRegistry $definitionRegistry, Registry $registry)
35
    {
36 7
        $this->doctrine = $registry;
37 7
        $this->definitionRegistry = $definitionRegistry;
38 7
    }
39
40
    /**
41
     * {@inheritDoc}
42
     */
43 4
    public function encode(NodeInterface $node): ?string
44
    {
45 4
        $nodeType = TypeUtil::resolveObjectType($this->definitionRegistry->getEndpoint(), $node);
46
47 4
        return sprintf('%s%s%s', $nodeType, self::DIVIDER, $node->getId());
48
    }
49
50
    /**
51
     * {@inheritDoc}
52
     */
53 6
    public function decode($globalId): ?NodeInterface
54
    {
55 6
        if (strpos($globalId, self::DIVIDER) > 1) {
56 5
            $divider = self::DIVIDER;
57 5
            [$nodeType, $databaseId] = preg_split("/$divider/", $globalId, 2);
58
59 5
            $class = $this->definitionRegistry->getEndpoint()->getClassForType($nodeType);
60 5
            if (!class_exists($class)) {
61 1
                return null;
62
            }
63
64 4
            $manager = $this->doctrine->getManager();
65 4
            if ($manager instanceof EntityManagerInterface) {
66 4
                $reference = $manager->getReference($class, $databaseId);
67 4
                $resolvedType = TypeUtil::resolveObjectType($this->definitionRegistry->getEndpoint(), $reference);
68
69
                //compare the given type encoded in the globalID with the type resolved by the object instance
70
                //This is important to avoid get a node using different type when use the same entity class
71
                //e.g. 'AdminUser:1' => resolve to type 'AdminUser' and should not be possible get using 'CommonUser:1' as globalId
72 4
                if ($resolvedType !== $nodeType) {
73
                    return null;
74
                }
75
76 4
                return $reference;
77
            }
78
79
            throw new \UnexpectedValueException('Not supported doctrine manager.');
80
        }
81
82 1
        return null;
83
    }
84
}
85