Passed
Push — master ( 7a0761...b9ca99 )
by Bruno
03:45
created

processMigrationFieldDirective()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 4
dl 0
loc 7
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Modelarium\Laravel\Directives;
4
5
use Formularium\Datatype;
6
use Formularium\Factory\DatatypeFactory;
7
use GraphQL\Type\Definition\ObjectType;
8
use Illuminate\Support\Str;
9
use Modelarium\Datatypes\RelationshipFactory;
10
use Modelarium\Exception\DirectiveException;
11
use Modelarium\Laravel\Targets\Interfaces\MigrationDirectiveInterface;
12
use Modelarium\Laravel\Targets\ModelGenerator;
13
use Modelarium\Laravel\Targets\SeedGenerator;
14
use Modelarium\Laravel\Targets\Interfaces\ModelDirectiveInterface;
15
use Modelarium\Laravel\Targets\Interfaces\SeedDirectiveInterface;
16
use Modelarium\Laravel\Targets\MigrationCodeFragment;
17
use Modelarium\Laravel\Targets\MigrationGenerator;
18
use Modelarium\Parser;
19
20
class BelongsToDirective implements MigrationDirectiveInterface, ModelDirectiveInterface, SeedDirectiveInterface
21
{
22
    public static function processMigrationTypeDirective(
23
        MigrationGenerator $generator,
24
        \GraphQL\Language\AST\DirectiveNode $directive
25
    ): void {
26
        throw new DirectiveException("Directive not supported here");
27
    }
28
29
    public static function processMigrationFieldDirective(
30
        MigrationGenerator $generator,
31
        \GraphQL\Type\Definition\FieldDefinition $field,
32
        \GraphQL\Language\AST\DirectiveNode $directive,
33
        MigrationCodeFragment $code
34
    ): void {
35
        throw new DirectiveException("Directive not supported here");
36
    }
37
38 4
    public static function processMigrationRelationshipDirective(
39
        MigrationGenerator $generator,
40
        \GraphQL\Type\Definition\FieldDefinition $field,
41
        \GraphQL\Language\AST\DirectiveNode $directive,
42
        MigrationCodeFragment $codeFragment
43
    ): void {
44 4
        $lowerName = mb_strtolower($generator->getInflector()->singularize($field->name));
45 4
        $fieldName = $lowerName . '_id';
46
47 4
        list($type, $isRequired) = Parser::getUnwrappedType($field->type);
48 4
        $typeName = $type->name;
49 4
        $tableName = MigrationGenerator::toTableName($typeName);
50
51 4
        $targetType = $generator->parser->getType($typeName);
52 4
        if (!$targetType) {
0 ignored issues
show
introduced by
$targetType is of type GraphQL\Type\Definition\Type, thus it always evaluated to true.
Loading history...
53
            throw new DirectiveException("Cannot get type {$typeName} as a relationship to {$generator->getBaseName()}");
54 4
        } elseif (!($targetType instanceof ObjectType)) {
55
            throw new DirectiveException("{$typeName} is not a type for a relationship to {$generator->getBaseName()}");
56
        }
57
        // we don't know what is the reverse relationship name at this point. so let's guess all possibilities
58
        try {
59 4
            $targetField = $targetType->getField($tableName);
60 4
        } catch (\GraphQL\Error\InvariantViolation $e) {
61
            try {
62 4
                $targetField = $targetType->getField($generator->getTableName());
63 3
            } catch (\GraphQL\Error\InvariantViolation $e) {
64
                // one to one
65 3
                $targetField = $targetType->getField($generator->getLowerName());
66
            }
67
        }
68
69 4
        $targetDirectives = $targetField->astNode->directives;
70 4
        foreach ($targetDirectives as $targetDirective) {
71 4
            switch ($targetDirective->name->value) {
72 4
                case 'hasOne':
73 1
                case 'hasMany':
74 4
                    $codeFragment->appendBase('->unsignedBigInteger("' . $fieldName . '")');
75 4
                break;
76
            }
77
        }
78 4
    }
79
80
    public static function processModelTypeDirective(
81
        ModelGenerator $generator,
82
        \GraphQL\Language\AST\DirectiveNode $directive
83
    ): void {
84
        // nothing
85
    }
86
87 4
    public static function processModelFieldDirective(
88
        ModelGenerator $generator,
89
        \GraphQL\Type\Definition\FieldDefinition $field,
90
        \Formularium\Field $fieldFormularium,
91
        \GraphQL\Language\AST\DirectiveNode $directive
92
    ): void {
93
        // nothing
94 4
    }
95
96 4
    public static function processModelRelationshipDirective(
97
        ModelGenerator $generator,
98
        \GraphQL\Type\Definition\FieldDefinition $field,
99
        \GraphQL\Language\AST\DirectiveNode $directive,
100
        \Formularium\Datatype $datatype = null
101
    ): ?\Formularium\Datatype {
102 4
        $lowerName = mb_strtolower($generator->getInflector()->singularize($field->name));
103 4
        $lowerNamePlural = $generator->getInflector()->pluralize($lowerName);
0 ignored issues
show
Unused Code introduced by
The assignment to $lowerNamePlural is dead and can be removed.
Loading history...
104
105 4
        $sourceTypeName = $generator->getLowerName();
106 4
        $targetTypeName = $lowerName;
107 4
        $relationship = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $relationship is dead and can be removed.
Loading history...
108 4
        $isInverse = false;
0 ignored issues
show
Unused Code introduced by
The assignment to $isInverse is dead and can be removed.
Loading history...
109
110 4
        $targetClass = Str::studly($generator->getInflector()->singularize($field->name));
111 4
        $generateRandom = true; // TODO
0 ignored issues
show
Unused Code introduced by
The assignment to $generateRandom is dead and can be removed.
Loading history...
112 4
        $relationship = RelationshipFactory::RELATIONSHIP_ONE_TO_MANY;
113 4
        $isInverse = true;
114 4
        $generator->class->addMethod($lowerName)
115 4
            ->setPublic()
116 4
            ->setReturnType('\\Illuminate\\Database\\Eloquent\\Relations\\BelongsTo')
117 4
            ->setBody("return \$this->belongsTo($targetClass::class);");
118
119 4
        $datatypeName = $generator->getRelationshipDatatypeName(
120 4
            $relationship,
121
            $isInverse,
122
            $sourceTypeName,
123
            $targetTypeName
124
        );
125 4
        return DatatypeFactory::factory($datatypeName);
126
    }
127
128
    public static function processSeedTypeDirective(
129
        SeedGenerator $generator,
130
        \GraphQL\Language\AST\DirectiveNode $directive
131
    ): void {
132
        // empty
133
    }
134
135 4
    public static function processSeedFieldDirective(
136
        SeedGenerator $generator,
137
        \GraphQL\Type\Definition\FieldDefinition $field,
138
        \GraphQL\Language\AST\DirectiveNode $directive
139
    ): void {
140 4
        $type1 = $generator->getLowerName();
141 4
        $type2 = mb_strtolower($generator->getInflector()->singularize($field->name));
142
143 4
        if (strcasecmp($type1, $type2) < 0) { // TODO: check this, might not work
144 4
            $relationship = mb_strtolower($generator->getInflector()->pluralize($field->name));
145 4
            $generator->extraCode[] = self::makeManyToManySeed($type1, $type2, $relationship);
146
        }
147 4
    }
148
149 4
    protected static function makeManyToManySeed(string $sourceModel, string $targetModel, string $relationship): string
0 ignored issues
show
Unused Code introduced by
The parameter $sourceModel is not used and could be removed. ( Ignorable by Annotation )

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

149
    protected static function makeManyToManySeed(/** @scrutinizer ignore-unused */ string $sourceModel, string $targetModel, string $relationship): string

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
150
    {
151
        return <<<EOF
152
153
        try {
154 4
            \${$targetModel}Items = App\\Models\\$targetModel::all();
155 4
            \$model->{$relationship}()->attach(
156 4
                \${$targetModel}Items->random(rand(1, 3))->pluck('id')->toArray()
157
            );
158
        }
159
        catch (\InvalidArgumentException \$e) {
160 4
            \$model->{$relationship}()->attach(
161 4
                \${$targetModel}Items->random(1)->pluck('id')->toArray()
162
            );
163
        }
164
EOF;
165
    }
166
}
167