Completed
Pull Request — master (#29)
by
unknown
06:10
created

MutationBuilder   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 92
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 2
dl 0
loc 92
ccs 40
cts 40
cp 1
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A build() 0 16 2
A getMutationTypeClass() 0 4 2
A generateMutationArguments() 0 15 3
A createPathFromParent() 0 4 2
A mutateChild() 0 26 4
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 MUTATION_TYPE_MAP = [
16
        QueryItem::class       => MutationItem::class,
17
        QueryCollection::class => MutationCollection::class,
18
    ];
19
20
    const DEFAULT_MUTATION_TYPE = MutationItem::class;
21
22
    private $config;
23
24
    private $source;
25
26
    /**
27
     * @param array<MutationTypeConfig> $config
28
     */
29 46
    public function __construct(array $config, QueryItem $source)
30
    {
31 46
        $this->config = $config;
32 46
        $this->source = $source;
33 46
    }
34
35 46
    public function build(): MutationItem
36
    {
37 46
        $mutationVariables = [];
38
39 46
        foreach ($this->config as $variableName => $configObject) {
40 46
            $path   = $configObject->linksTo;
41 46
            $config = $configObject->get($path);
42
43 46
            $mutationTypeClass = $this->getMutationTypeClass($config, $this->source);
44 46
            $arguments         = $this->generateMutationArguments($config, $this->source, $path);
45
46 46
            $mutationVariables[$variableName] = new $mutationTypeClass($arguments, $config->children);
47
        }
48
49 46
        return new MutationItem($mutationVariables, $this->config);
50
    }
51
52 46
    private function getMutationTypeClass(MutationTypeConfig $config, ReadObject $source): string
53
    {
54 46
        return !empty($config->linksTo) ? self::MUTATION_TYPE_MAP[get_class($source)] : self::DEFAULT_MUTATION_TYPE;
55
    }
56
57 46
    private function generateMutationArguments(MutationTypeConfig $config, ReadObject $source, string $path): array
58
    {
59 46
        $arguments = [];
60 46
        foreach ($source as $sourceKey => $sourceValue) {
0 ignored issues
show
Bug introduced by
The expression $source of type object<Softonic\GraphQL\Query\ReadObject> is not traversable.
Loading history...
61 46
            if ($sourceValue instanceof ReadObject) {
62 38
                $childPath = $this->createPathFromParent($path, $sourceKey);
63
64 38
                $arguments[$sourceKey] = $this->mutateChild($config->children[$sourceKey], $sourceValue, $childPath);
65
            } else {
66 46
                $arguments[$sourceKey] = $sourceValue;
67
            }
68
        }
69
70 46
        return $arguments;
71
    }
72
73 38
    private function createPathFromParent(string $parent, string $child): string
74
    {
75 38
        return ('.' === $parent) ? ".{$child}" : "{$parent}.{$child}";
76
    }
77
78 38
    private function mutateChild(MutationTypeConfig $config, ReadObject $source, string $path): MutationObject
79
    {
80 38
        if (is_null($config->linksTo)) {
81 38
            $arguments = [];
82 38
            foreach ($config->children as $key => $childConfig) {
83 38
                $childArguments = [];
84 38
                foreach ($source as $sourceKey => $sourceValue) {
0 ignored issues
show
Bug introduced by
The expression $source of type object<Softonic\GraphQL\Query\ReadObject> is not traversable.
Loading history...
85 36
                    $childChildrenType      = $this->getMutationTypeClass($childConfig, $sourceValue);
86 36
                    $childChildrenArguments = $this->generateMutationArguments($childConfig, $sourceValue, $path);
87
88 36
                    $childArguments[$sourceKey] = new $childChildrenType(
89 36
                        $childChildrenArguments,
90 36
                        $childConfig->children
91
                    );
92
                }
93
94 38
                $childType = $this->getMutationTypeClass($childConfig, $source);
95
96 38
                $arguments[$key] = new $childType($childArguments, $childConfig->children);
97
            }
98
        }
99
100 38
        $type = $this->getMutationTypeClass($config, $source);
101
102 38
        return new $type($arguments, $config->children);
0 ignored issues
show
Bug introduced by
The variable $arguments does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
103
    }
104
}
105