Passed
Push — master ( 09030e...cab6b5 )
by Bruno
08:31
created

EventGenerator::processFieldDirectives()   B

Complexity

Conditions 6
Paths 10

Size

Total Lines 36
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 6.0052

Importance

Changes 0
Metric Value
cc 6
eloc 20
nc 10
nop 3
dl 0
loc 36
ccs 18
cts 19
cp 0.9474
crap 6.0052
rs 8.9777
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Modelarium\Laravel\Targets;
4
5
use GraphQL\Type\Definition\NonNull;
6
use GraphQL\Type\Definition\ObjectType;
7
use GraphQL\Type\Definition\Type;
8
use Modelarium\BaseGenerator;
9
use Modelarium\GeneratedCollection;
10
use Modelarium\GeneratedItem;
11
use Nette\PhpGenerator\ClassType;
12
13
class EventGenerator extends BaseGenerator
14
{
15
    /**
16
     * @var string
17
     */
18
    protected $stubDir = __DIR__ . "/stubs/";
19
20
    /**
21
     * @var ObjectType
22
     */
23
    protected $type = null;
24
25
    /**
26
     * @var GeneratedCollection
27
     */
28
    protected $events;
29
30 2
    public function generate(): GeneratedCollection
31
    {
32 2
        $this->events = new GeneratedCollection();
33
34 2
        foreach ($this->type->getFields() as $field) {
35 1
            $directives = $field->astNode->directives;
36 1
            $this->processFieldDirectives($field, $directives, 'Event');
37
        }
38 2
        return $this->events;
39
    }
40
41 1
    protected function makeEventClass(string $name, string $model): GeneratedItem
42
    {
43 1
        list($eventNamespace, $eventClassName, $relativePath) = $this->splitClassName($name);
44
45 1
        $namespace = new \Nette\PhpGenerator\PhpNamespace($eventNamespace);
46
47
        /**
48
         * @var ClassType $class
49
         */
50 1
        $class = $namespace->addClass($eventClassName);
51
        $class
52 1
            ->addComment("This file was automatically generated by Modelarium.")
53 1
            ->setTraits(['Illuminate\Queue\SerializesModels']);
54
        
55 1
        $class->addProperty('target')
56 1
            ->setPublic()
57 1
            ->setComment("@var $model");
58 1
        $printer = new \Nette\PhpGenerator\PsrPrinter;
59
    
60 1
        $constructor = $class->addMethod('__construct');
61 1
        $constructor->setPublic()
62 1
            ->addParameter('target')
63 1
            ->setType('App\\Models\\' . $model);
64
65 1
        $constructor->addBody(
66 1
            '$this->target = $target;'
67
        );
68
69 1
        return new GeneratedItem(
70 1
            $name,
71 1
            "<?php declare(strict_types=1);\n\n" . $printer->printNamespace($namespace),
72 1
            $this->getGenerateFilename($relativePath, $eventClassName)
73
        );
74
    }
75
76 1
    public function processFieldDirectives(
77
        \GraphQL\Type\Definition\FieldDefinition $field,
78
        \GraphQL\Language\AST\NodeList $directives,
79
        string $type
80 1
    ): void {
81
        // TODO: there's probably no need to override this
82
        if ($field->type instanceof NonNull) {
83 1
            $type = $field->type->getWrappedType();
84
        } else {
85 1
            $type = $field->type;
86
        }
87 1
        $typeName = $type->name; /** @phpstan-ignore-line */
88 1
        
89 1
        foreach ($directives as $directive) {
90 1
            $name = $directive->name->value;
91 1
            switch ($name) {
92
            case 'event':
93 1
                $dispatch = '';
94
                
95
                foreach ($directive->arguments as $arg) {
96
                    /**
97
                     * @var \GraphQL\Language\AST\ArgumentNode $arg
98 1
                     */
99
100 1
                    $value = $arg->value->value;
0 ignored issues
show
Bug introduced by
Accessing value on the interface GraphQL\Language\AST\ValueNode suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
101 1
102 1
                    switch ($arg->name->value) {
103 1
                    case 'dispatch':
104
                        $dispatch = $value;
105
                    break;
106 1
                    }
107 1
                }
108 1
                $e = $this->makeEventClass($dispatch, $typeName);
109
                $this->events->push($e);
110
                break;
111
            default:
112 1
            }
113
        }
114 1
    }
115
116
    public function getGenerateFilename(string $relativePath, string $name): string
117 1
    {
118 1
        // fix App -> app
119
        if (mb_substr($relativePath, 0, 3) === 'App' && !is_dir($this->getBasePath($relativePath))) {
120 1
            $relativePath[0] = 'a';
121
        }
122
        return $this->getBasePath($relativePath . '/' . $name . '.php');
123
    }
124
}
125