Passed
Push — master ( c39fb6...9e9a0d )
by Rafael
04:42
created

Nodes   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 62
Duplicated Lines 0 %

Test Coverage

Coverage 89.66%

Importance

Changes 0
Metric Value
dl 0
loc 62
ccs 26
cts 29
cp 0.8966
rs 10
c 0
b 0
f 0
wmc 11

1 Method

Rating   Name   Duplication   Size   Complexity  
C __invoke() 0 53 11
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\Query\Node;
12
13
use Doctrine\Common\Util\Inflector;
14
use Ynlo\GraphQLBundle\Annotation as GraphQL;
15
use Ynlo\GraphQLBundle\Definition\ArgumentDefinition;
16
use Ynlo\GraphQLBundle\Model\ID;
17
use Ynlo\GraphQLBundle\Resolver\AbstractResolver;
18
19
/**
20
 * @GraphQL\Query(list=true)
21
 * @GraphQL\Argument(name="ids", type="[ID!]!")
22
 */
23
class Nodes extends AbstractResolver
24
{
25
    protected $fetchBy = 'id';
26
27
    /**
28
     * @param ID[]|mixed[] $ids
29
     *
30
     * @return mixed
31
     */
32 3
    public function __invoke($ids)
33
    {
34 3
        if (empty($ids)) {
35
            return [];
36
        }
37
38 3
        $types = [];
39 3
        $expectedResultsOrder = [];
40
41 3
        if (current($ids) instanceof ID) {
42 2
            foreach ($ids as $id) {
43 2
                $types[$id->getNodeType()][] = $id->getDatabaseId();
44 2
                $expectedResultsOrder[md5($id->getNodeType().$id->getDatabaseId())] = null;
45
            }
46
        } else {
47
            //when use a different field to fetch,
48
            //@see QueryGet::fetchBy
49 1
            $type = $this->getContext()->getDefinition()->getType();
50 1
            $objectDefinition = $this->getContext()->getEndpoint()->getType($type);
51
52
            /** @var ArgumentDefinition $arg */
53 1
            $arg = array_values($this->getContext()->getDefinition()->getArguments())[0];
54
55 1
            $field = null;
56 1
            if ($objectDefinition->hasField($arg->getName())) {
57
                $field = $objectDefinition->getField($arg->getName());
58 1
            } elseif ($objectDefinition->hasField(Inflector::singularize($arg->getName()))) { //by convention, singularize
59 1
                $field = $objectDefinition->getField(Inflector::singularize($arg->getName()));
60
            }
61
62 1
            if (null === $field) {
63
                throw new \RuntimeException(sprintf('Can`t resolve the field `%s` inside type `%s`', $arg->getName(), $type));
64
            }
65
66 1
            $types[$type] = $ids;
67 1
            foreach ($ids as $identifier) {
68 1
                $expectedResultsOrder[md5($type.$identifier)] = null;
69
            }
70
        }
71
72 3
        foreach ($types as $type => $searchValues) {
73 3
            if ($this->getContext()->getEndpoint()->hasType($type)) {
74 3
                foreach ($searchValues as $searchValue) {
75
                    //TODO: improve this to find all nodes in the same Repo with only one query, NOTE: the order and empty results are very IMPORTANT!
76
                    //The list of given id should match with the list of results including non-found nodes
77 3
                    $entity = $this->getContext()->getEndpoint()->getClassForType($type);
78 3
                    $result = $this->getManager()->getRepository($entity)->findOneBy([$this->fetchBy => $searchValue]);
79 3
                    $expectedResultsOrder[md5($type.$searchValue)] = $result;
80
                }
81
            }
82
        }
83
84 3
        return array_values($expectedResultsOrder);
85
    }
86
}
87