Passed
Push — master ( 8366d7...daf92e )
by Bruno
08:53
created

EventGenerator::generate()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

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