EventGenerator::generate()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

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