Test Setup Failed
Push — master ( 435315...25317c )
by Kirill
02:05
created

ObjectTypeBuilder::callAction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 0
cts 0
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 2
crap 2
1
<?php
2
/**
3
 * This file is part of Railt package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
declare(strict_types=1);
9
10
namespace Railt\Adapters\Webonyx\Builder;
11
12
use GraphQL\Type\Definition\ObjectType;
13
use GraphQL\Type\Definition\ResolveInfo;
14
use Railt\Adapters\InputInterface;
15
use Railt\Adapters\Webonyx\Input;
16
use Railt\Adapters\Webonyx\Output;
17
use Railt\Reflection\Abstraction\ObjectTypeInterface;
18
use Railt\Routing\Action;
19
20
/**
21
 * Class ObjectTypeBuilder
22
 *
23
 * @package Railt\Adapters\Webonyx\Builder
24
 * @property-read ObjectTypeInterface $type
25
 */
26
class ObjectTypeBuilder extends Builder
27
{
28
    /**
29
     * @return ObjectType
30
     * @throws \LogicException
31
     * @throws \ReflectionException
32
     * @throws \Railt\Routing\Exceptions\RouteCompilationException
33
     * @throws \Psr\Container\NotFoundExceptionInterface
34
     * @throws \Psr\Container\ContainerExceptionInterface
35
     * @throws \InvalidArgumentException
36
     */
37
    public function build(): ObjectType
38
    {
39
        return new ObjectType([
40
            'name'         => $this->type->getName(),
41
            'description'  => $this->type->getDescription(),
0 ignored issues
show
Bug introduced by
The method getDescription() does not seem to exist on object<Railt\Reflection\...on\ObjectTypeInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
42
            'fields'       => function (): array {
43
                return iterator_to_array($this->getObjectFields());
44
            },
45
            'resolveField' => function ($value, array $args = [], $context, ResolveInfo $info) {
46
                $input = new Input($args, $info);
47
48
                $this->events->dispatch('request:' . $input->getPath(), $input);
49
50
                $value = $this->fetchData($input, $value);
51
52
                $this->events->dispatch('response:' . $input->getPath(), $value, $input);
53
54
                return $value;
55
            },
56
        ]);
57
    }
58
59
    /**
60
     * @return \Traversable
61
     * @throws \LogicException
62
     */
63
    private function getObjectFields(): \Traversable
64
    {
65
        foreach ($this->type->getFields() as $field) {
66
            yield $field->getName() => $this->make($field, FieldBuilder::class);
67
        }
68
    }
69
70
    /**
71
     * @param InputInterface $input
72
     * @param mixed $value
73
     * @return mixed|null
74
     * @throws \InvalidArgumentException
75
     * @throws \Psr\Container\ContainerExceptionInterface
76
     * @throws \Psr\Container\NotFoundExceptionInterface
77
     * @throws \Railt\Routing\Exceptions\RouteCompilationException
78
     * @throws \ReflectionException
79
     */
80
    private function fetchData(InputInterface $input, $value)
81
    {
82
        if ($value instanceof \Traversable) {
83
            $value = iterator_to_array($value);
84
        }
85
86
        // When route allowed
87
        if ($this->router->has($input->getPath())) {
88
            return $this->resolveResponder($input, $value);
89
        }
90
91
        return $this->getFieldValue($input, $value);
92
    }
93
94
    /**
95
     * @param InputInterface $input
96
     * @param mixed $value
97
     * @return mixed
98
     * @throws \Railt\Routing\Exceptions\RouteCompilationException
99
     */
100
    private function resolveResponder(InputInterface $input, $value)
101
    {
102
        $parent = $value;
103
104
        $value = $this->getFieldValue($input, $value, $value);
105
106
        foreach ($this->router->resolve($input->getPath()) as $responder) {
107
            $value = $this->callAction($responder, [
108
                'input'  => $input,
109
                'value'  => $value,
110
                'parent' => $parent,
111
                'output' => new Output($value, $parent),
112
            ]);
113
        }
114
115
        return $value;
116
    }
117
118
    /**
119
     * @param InputInterface $input
120
     * @param mixed $value
121
     * @param null $default
122
     * @return mixed|null
123
     */
124
    private function getFieldValue(InputInterface $input, $value, $default = null)
125
    {
126
        if (is_array($value) || $value instanceof \ArrayAccess) {
127
            return $value[$input->getFieldName()] ?? $default;
128
        }
129
130
        return $default;
131
    }
132
133
    /**
134
     * @param Action $action
135
     * @param array $params
136
     * @return mixed
137
     */
138
    private function callAction(Action $action, array $params = [])
139
    {
140
        return $action->invoke(array_merge([
141
            'field' => $this->type,
142
        ], $params));
143
    }
144
}
145