Completed
Pull Request — master (#29)
by
unknown
01:39
created

MutationBuilder::generateMutationArguments()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 17
ccs 9
cts 9
cp 1
rs 9.7
c 0
b 0
f 0
cc 3
nc 3
nop 2
crap 3
1
<?php
2
3
namespace Softonic\GraphQL;
4
5
use Softonic\GraphQL\Config\MutationTypeConfig;
6
use Softonic\GraphQL\Mutation\Collection as MutationCollection;
7
use Softonic\GraphQL\Mutation\Item as MutationItem;
8
use Softonic\GraphQL\Mutation\MutationObject;
9
use Softonic\GraphQL\Query\Collection as QueryCollection;
10
use Softonic\GraphQL\Query\Item as QueryItem;
11
use Softonic\GraphQL\Query\ReadObject;
12
13
class MutationBuilder
14
{
15
    const SOURCE_ROOT_PATH = '.';
16
17
    /**
18
     * @var array
19
     */
20
    private $config;
21
22
    /**
23
     * @var ReadObject
24
     */
25
    private $source;
26
27
    /**
28
     * @var MutationTypeConfig
29
     */
30
    private $mutationTypeConfig;
31
32
    /**
33
     * @param array<MutationTypeConfig> $config
34
     */
35 66
    public function __construct(array $config, ReadObject $source)
36
    {
37 66
        $this->config = $config;
38 66
        $this->source = $source;
39 66
    }
40
41 66
    public function build(): MutationObject
42
    {
43 66
        $mutationVariables = [];
44 66
        foreach ($this->config as $variableName => $mutationTypeConfig) {
45 66
            $this->mutationTypeConfig = $mutationTypeConfig;
46 66
            $path                     = self::SOURCE_ROOT_PATH;
47 66
            $config                   = $this->mutationTypeConfig->get($path);
48 66
            if ($config->type === MutationCollection::class) {
49 6
                $arguments = [];
50 6
                foreach ($this->source as $sourceItem) {
0 ignored issues
show
Bug introduced by
The expression $this->source of type object<Softonic\GraphQL\Query\ReadObject> is not traversable.
Loading history...
51 6
                    $mutationItemArguments = $this->generateMutationArguments($sourceItem, $path);
52
53 6
                    $arguments[] = new MutationItem($mutationItemArguments, $config->children);
54
                }
55
56 6
                $mutationVariables[$variableName] = new $config->type($arguments, $config->children);
57
            } else {
58 60
                $arguments = $this->generateMutationArguments($this->source, $path);
0 ignored issues
show
Compatibility introduced by
$this->source of type object<Softonic\GraphQL\Query\ReadObject> is not a sub-type of object<Softonic\GraphQL\Query\Item>. It seems like you assume a concrete implementation of the interface Softonic\GraphQL\Query\ReadObject to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
59
60 63
                $mutationVariables[$variableName] = new $config->type($arguments, $config->children);
61
            }
62
        }
63
64 66
        return new MutationItem($mutationVariables, $this->config);
65
    }
66
67 66
    private function generateMutationArguments(QueryItem $source, string $path): array
68
    {
69 66
        $arguments = [];
70 66
        foreach ($source as $sourceKey => $sourceValue) {
71
            // Having a property that is an item is not handled.
72 66
            if ($sourceValue instanceof QueryCollection) {
73 48
                $childPath   = $this->createPathFromParent($path, $sourceKey);
74 48
                $childConfig = $this->mutationTypeConfig->get($childPath);
75
76 48
                $arguments[$sourceKey] = $this->mutateChild($childConfig, $sourceValue, $childPath);
77
            } else {
78 66
                $arguments[$sourceKey] = $sourceValue;
79
            }
80
        }
81
82 66
        return $arguments;
83
    }
84
85 48
    private function createPathFromParent(string $parent, string $child): string
86
    {
87 48
        return ('.' === $parent) ? ".{$child}" : "{$parent}.{$child}";
88
    }
89
90 48
    private function mutateChild(
91
        MutationTypeConfig $config,
92
        QueryCollection $sourceCollection,
93
        string $path
94
    ): MutationObject {
95 48
        $arguments = [];
96 48
        if (is_null($config->linksTo)) {
97 42
            foreach ($config->children as $key => $childConfig) {
98 42
                $childPath       = $this->createPathFromParent($path, $key);
99 42
                $arguments[$key] = $this->mutateChild($childConfig, $sourceCollection, $childPath);
100
            }
101
        } else {
102 48
            foreach ($sourceCollection as $sourceItem) {
103 46
                $itemArguments = $this->generateMutationArguments($sourceItem, $path);
104
105 46
                $arguments[] = new MutationItem($itemArguments, $config->children);
106
            }
107
        }
108
109 48
        return new $config->type($arguments, $config->children);
110
    }
111
}
112