Passed
Push — master ( 625be7...d965a1 )
by Bruno
08:58
created

ModelGenerator::formulariumModel()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 13
c 0
b 0
f 0
dl 0
loc 17
rs 9.8333
ccs 12
cts 12
cp 1
cc 2
nc 2
nop 0
crap 2
1
<?php declare(strict_types=1);
2
3
namespace Modelarium\Laravel\Targets;
4
5
use Formularium\Datatype;
0 ignored issues
show
Bug introduced by
The type Formularium\Datatype was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use GraphQL\Type\Definition\ListOfType;
7
use GraphQL\Type\Definition\NonNull;
8
use GraphQL\Type\Definition\ObjectType;
9
use Illuminate\Support\Str;
10
use GraphQL\Type\Definition\Type;
11
use Modelarium\Exception\Exception;
12
use Modelarium\GeneratedCollection;
13
use Modelarium\GeneratedItem;
14
15
class ModelGenerator extends BaseGenerator
16
{
17
    /**
18
     * @var ObjectType
19
     */
20
    protected $type = null;
21
22
    /**
23
     * fillable attributes
24
     *
25
     * @var array
26
     */
27
    protected $fillable = [];
28
29
    /**
30
     * fillable attributes
31
     *
32
     * @var array
33
     */
34
    protected $hidden = [];
35
36
    /**
37
     *
38
     * @var string
39
     */
40
    protected $parentClassName = 'Model';
41
42
    /**
43
     *
44
     * @var array
45
     */
46
    protected $traits = [];
47 5
48
    public function generate(): GeneratedCollection
49 5
    {
50 5
        $x = new GeneratedCollection([
51 5
            new GeneratedItem(
52 5
                GeneratedItem::TYPE_MODEL,
53 5
                $this->generateString(),
54
                $this->getGenerateFilename()
55 5
            ),
56 5
            new GeneratedItem(
57 5
                GeneratedItem::TYPE_MODEL,
58 5
                $this->stubToString('model'),
59 5
                $this->getGenerateFilename(false),
60
                true
61
            )
62 5
        ]);
63
        return $x;
64
    }
65
66
    protected function processBasetype(
67
        \GraphQL\Type\Definition\FieldDefinition $field,
68
        \GraphQL\Language\AST\NodeList $directives
69
    ): void {
70
        $fieldName = $field->name;
0 ignored issues
show
Unused Code introduced by
The assignment to $fieldName is dead and can be removed.
Loading history...
71
        $extra = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $extra is dead and can be removed.
Loading history...
72
73
        $isRequired = false;
74
75
        if ($field->type instanceof NonNull) {
76
            $isRequired = true;
77
            $type = $field->type->getWrappedType();
78
        } else {
79
            $type = $field->type;
80
        }
81
82
        $validators = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $validators is dead and can be removed.
Loading history...
83
        if ($isRequired) {
84
            $validators = [
85
                Datatype::REQUIRED => true
86
            ];
87
        }
88
89
        foreach ($directives as $directive) {
90
            $name = $directive->name->value;
91
            switch ($name) {
92
            case 'fillableAPI':
93 5
                $this->fillable[] = $name;
94
                break;
95
            case 'hiddenAPI':
96
                $this->hidden[] = $name;
97 5
                break;
98 5
            }
99
        }
100 5
101 5
        $typeName = $type->name; /** @phpstan-ignore-line */
102
        switch ($typeName) {
103 1
        case 'ID':
104
        case 'String':
105
        case 'Integer':
106 5
        case 'Float':
107 5
        case 'Boolean':
108
        }
109 5
    
110 5
        $scalarType = $this->parser->getScalarType($typeName);
111 5
112 5
        if ($scalarType) {
113 4
            // TODO
114 4
            $validDirectives = $scalarType->getDatatype()->getValidatorMetadata();
115
            foreach ($directives as $directive) {
116 4
                $name = $directive->name->value;
117
                if (array_key_exists($name, $validDirectives)) {
118
                }
119 4
            }
120
        }
121 5
    }
122 1
123 1
    protected function processRelationship(
124
        \GraphQL\Type\Definition\FieldDefinition $field,
125 1
        \GraphQL\Language\AST\NodeList $directives
126
    ): array {
127
        $lowerName = mb_strtolower($this->inflector->singularize($field->name));
128 1
        $lowerNamePlural = $this->inflector->pluralize($lowerName);
129
130 4
        if ($field->type instanceof NonNull) {
131 3
            $type = $field->type->getWrappedType();
0 ignored issues
show
Unused Code introduced by
The assignment to $type is dead and can be removed.
Loading history...
132 3
        } else {
133
            $type = $field->type;
134 3
        }
135
136
        $extra = [];
137 3
        $targetClass = 'App\\\\' . Str::studly($this->inflector->singularize($field->name));
138 4
139 1
        foreach ($directives as $directive) {
140 1
            $name = $directive->name->value;
141 1
            switch ($name) {
142
            case 'belongsTo':
143 1
                $extra[] = <<<EOF
144
    public function $lowerName()
145
    {
146 1
        return \$this->belongsTo($targetClass::class);
147
    }
148 4
EOF;
149
                break;
150
151
            case 'belongsToMany':
152 5
                $extra[] = <<<EOF
153
    public function $lowerNamePlural()
154
    {
155 7
        return \$this->belongsToMany($targetClass::class);
156
    }
157
EOF;
158 7
                break;
159 1
    
160
            case 'hasOne':
161 1
                $extra[] = <<<EOF
162 1
    public function $lowerName()
163 1
    {
164
        return \$this->hasOne($targetClass::class);
165
    }
166 7
EOF;
167
                break;
168
            case 'hasMany':
169 7
                $targetClass = $this->inflector->singularize($targetClass);
170
                $extra[] = <<<EOF
171
    public function $lowerNamePlural()
172 7
    {
173
        return \$this->hasMany($targetClass::class);
174 7
    }
175
EOF;
176
                break;
177 7
            default:
178
                break;
179 7
            }
180 7
        }
181 7
182 7
        return $extra;
183
    }
184
185
    protected function processDirectives(
186 5
        \GraphQL\Language\AST\NodeList $directives
187
    ): array {
188
        foreach ($directives as $directive) {
189
            $name = $directive->name->value;
190
            switch ($name) {
191
            case 'softDeletesDB':
192
                $this->traits[] = '\Illuminate\Database\Eloquent\SoftDeletes';
193
                break;
194
            }
195 7
        }
196 7
        return [];
197 7
    }
198
199
    protected function formulariumModel(
200 7
201 7
    ): string {
202 7
        $fields = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $fields is dead and can be removed.
Loading history...
203 7
        foreach ($this->fields as $f) {
0 ignored issues
show
Bug Best Practice introduced by
The property fields does not exist on Modelarium\Laravel\Targets\ModelGenerator. Did you maybe forget to declare it?
Loading history...
204
            $string = <<<EOF
0 ignored issues
show
Unused Code introduced by
The assignment to $string is dead and can be removed.
Loading history...
205
            new \Formularium\Field(
206 7
                'name',
207 7
                'datatype',
208 7
                [ // extensions
209 7
                ],
210
                [ // validators
211
                ]
212 7
            ),
213 7
EOF;
214 7
        }
215 7
        return '';
216
    }
217
218 7
    public function generateString(): string
219 7
    {
220 7
        return $this->stubToString('modelbase', function ($stub) {
221 7
            $db = [];
222
223
            foreach ($this->type->getFields() as $field) {
224 7
                // TODO if (NonNull)
225 7
226 7
                $directives = $field->astNode->directives;
227 7
                if (
228
                    ($field->type instanceof ObjectType) ||
229
                    ($field->type instanceof NonNull) && (
230 7
                        ($field->type->getWrappedType() instanceof ObjectType) ||
231 7
                        ($field->type->getWrappedType() instanceof ListOfType)
232
                    )
233
                ) {
234 5
                    // relationship
235
                    $db = array_merge($db, $this->processRelationship($field, $directives));
236 5
                } else {
237
                    $this->processBasetype($field, $directives);
238
                }
239
            }
240
241
            /**
242
             * @var \GraphQL\Language\AST\NodeList|null
243
             */
244
            $directives = $this->type->astNode->directives;
245
            if ($directives) {
246
                $db = array_merge($db, $this->processDirectives($directives));
0 ignored issues
show
Bug introduced by
$directives of type GraphQL\Language\AST\DirectiveNode[] is incompatible with the type GraphQL\Language\AST\NodeList expected by parameter $directives of Modelarium\Laravel\Targe...or::processDirectives(). ( Ignorable by Annotation )

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

246
                $db = array_merge($db, $this->processDirectives(/** @scrutinizer ignore-type */ $directives));
Loading history...
247
            }
248
249
            $stub = str_replace(
250
                '{{traitsCode}}',
251
                $this->traits ? 'use ' . join(', ', $this->traits) . ';' : '',
252
                $stub
253
            );
254
255
            $stub = str_replace(
256
                '{{dummyMethods}}',
257
                join("\n            ", $db),
258
                $stub
259
            );
260
261
            $stub = str_replace(
262
                '{{dummyFillable}}',
263
                var_export($this->fillable, true),
264
                $stub
265
            );
266
267
            $stub = str_replace(
268
                '{{dummyHidden}}',
269
                var_export($this->hidden, true),
270
                $stub
271
            );
272
273
            $stub = str_replace(
274
                '{{ParentDummyModel}}',
275
                $this->parentClassName,
276
                $stub
277
            );
278
279
            return $stub;
280
        });
281
    }
282
283
    public function getGenerateFilename(bool $base = true): string
284
    {
285
        return $this->getBasePath('app/' . ($base ? 'Base' : '') . $this->studlyName . '.php');
286
    }
287
}
288