Passed
Push — master ( 1d70e3...37a26d )
by Bruno
03:13
created

EventGenerator   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 96
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 46
dl 0
loc 96
ccs 44
cts 44
cp 1
rs 10
c 1
b 0
f 0
wmc 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A processFieldDirectives() 0 22 4
A makeEventClass() 0 32 1
A generate() 0 9 2
A getGenerateFilename() 0 7 3
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 3
    public function generate(): GeneratedCollection
32
    {
33 3
        $this->events = new GeneratedCollection();
34
35 3
        foreach ($this->type->getFields() as $field) {
36 3
            $directives = $field->astNode->directives;
37 3
            $this->processFieldDirectives($field, $directives, 'Event');
38
        }
39 3
        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 3
    public function processFieldDirectives(
78
        \GraphQL\Type\Definition\FieldDefinition $field,
79
        \GraphQL\Language\AST\NodeList $directives,
80
        string $type
81
    ): void {
82
        // TODO: there's probably no need to override this
83 3
        if ($field->type instanceof NonNull) {
84 1
            $type = $field->type->getWrappedType();
85
        } else {
86 3
            $type = $field->type;
87
        }
88 3
        $typeName = $type->name; /** @phpstan-ignore-line */
89
        
90 3
        foreach ($directives as $directive) {
91 3
            $name = $directive->name->value;
92 3
            switch ($name) {
93 3
            case 'event':
94 2
                $dispatch = Parser::getDirectiveArgumentByName($directive, 'dispatch');
95 2
                $e = $this->makeEventClass($dispatch, $typeName);
0 ignored issues
show
Bug introduced by
It seems like $dispatch can also be of type array and array and null; however, parameter $name of Modelarium\Laravel\Targe...rator::makeEventClass() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

95
                $e = $this->makeEventClass(/** @scrutinizer ignore-type */ $dispatch, $typeName);
Loading history...
96 2
                $this->events->push($e);
97 2
                break;
98
            default:
99
            }
100
        }
101 3
    }
102
103 2
    public function getGenerateFilename(string $relativePath, string $name): string
104
    {
105
        // fix App -> app
106 2
        if (mb_substr($relativePath, 0, 3) === 'App' && !is_dir($this->getBasePath($relativePath))) {
107 2
            $relativePath[0] = 'a';
108
        }
109 2
        return $this->getBasePath($relativePath . '/' . $name . '.php');
110
    }
111
}
112