Passed
Push — master ( cab6b5...845ff4 )
by Bruno
04:13 queued 01:09
created

MorphToDirective   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 132
Duplicated Lines 0 %

Test Coverage

Coverage 83.05%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 53
dl 0
loc 132
ccs 49
cts 59
cp 0.8305
rs 10
c 1
b 0
f 0
wmc 14

9 Methods

Rating   Name   Duplication   Size   Complexity  
A processModelRelationshipDirective() 0 25 1
A processMigrationRelationshipDirective() 0 13 2
A processMigrationTypeDirective() 0 5 1
A processModelTypeDirective() 0 4 1
A processMigrationFieldDirective() 0 7 1
A processModelFieldDirective() 0 27 4
A processSeedTypeDirective() 0 4 1
A processSeedFieldDirective() 0 11 2
A makeManyToManySeed() 0 13 1
1
<?php declare(strict_types=1);
2
3
namespace Modelarium\Laravel\Directives;
4
5
use Faker\Provider\File;
6
use Formularium\ExtradataParameter;
7
use Formularium\Field;
8
use GraphQL\Type\Definition\ObjectType;
9
use GraphQL\Type\Definition\UnionType;
10
use Illuminate\Support\Str;
11
use Modelarium\Exception\Exception;
12
use Modelarium\Parser;
13
use Modelarium\Datatypes\RelationshipFactory;
14
use Modelarium\Exception\DirectiveException;
15
use Modelarium\Laravel\Targets\Interfaces\MigrationDirectiveInterface;
16
use Modelarium\Laravel\Targets\ModelGenerator;
17
use Modelarium\Laravel\Targets\SeedGenerator;
18
use Modelarium\Laravel\Targets\Interfaces\ModelDirectiveInterface;
19
use Modelarium\Laravel\Targets\Interfaces\SeedDirectiveInterface;
20
use Modelarium\Laravel\Targets\MigrationCodeFragment;
21
use Modelarium\Laravel\Targets\MigrationGenerator;
22
23
class MorphToDirective implements MigrationDirectiveInterface, ModelDirectiveInterface, SeedDirectiveInterface
24
{
25
    public static function processMigrationTypeDirective(
26
        MigrationGenerator $generator,
27
        \GraphQL\Language\AST\DirectiveNode $directive
28
    ): void {
29
        throw new DirectiveException("Directive not supported here");
30
    }
31
32
    public static function processMigrationFieldDirective(
33
        MigrationGenerator $generator,
34
        \GraphQL\Type\Definition\FieldDefinition $field,
35
        \GraphQL\Language\AST\DirectiveNode $directive,
36
        MigrationCodeFragment $code
37
    ): void {
38
        throw new DirectiveException("Directive not supported here");
39
    }
40
41 2
    public static function processMigrationRelationshipDirective(
42
        MigrationGenerator $generator,
43
        \GraphQL\Type\Definition\FieldDefinition $field,
44
        \GraphQL\Language\AST\DirectiveNode $directive,
45
        MigrationCodeFragment $codeFragment
46
    ): void {
47 2
        $lowerName = mb_strtolower($generator->getInflector()->singularize($field->name));
48 2
        list($type, $isRequired) = Parser::getUnwrappedType($field->type);
49 2
        $relation = Parser::getDirectiveArgumentByName($directive, 'relation', $lowerName);
50 2
        $codeFragment->appendBase('->unsignedBigInteger("' . $relation . '_id")');
0 ignored issues
show
Bug introduced by
Are you sure $relation of type array|mixed|string can be used in concatenation? ( Ignorable by Annotation )

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

50
        $codeFragment->appendBase('->unsignedBigInteger("' . /** @scrutinizer ignore-type */ $relation . '_id")');
Loading history...
51 2
        $codeFragment->appendExtraLine(
52 2
            '$table->string("' . $relation . '_type")' .
53 2
            ($isRequired ? '' : '->nullable()') . ';'
54
        );
55 2
    }
56
    
57
    public static function processModelTypeDirective(
58
        ModelGenerator $generator,
59
        \GraphQL\Language\AST\DirectiveNode $directive
60
    ): void {
61
        // nothing
62
    }
63
64 2
    public static function processModelFieldDirective(
65
        ModelGenerator $generator,
66
        \GraphQL\Type\Definition\FieldDefinition $field,
67
        \Formularium\Field $fieldFormularium,
68
        \GraphQL\Language\AST\DirectiveNode $directive
69
    ): void {
70 2
        list($type, $isRequired) = Parser::getUnwrappedType($field->type);
71 2
        $typeName = $type->name;
72
73 2
        if (!($type instanceof UnionType)) {
74
            throw new Exception("$typeName is declared as @morphTo target but it is not a union type.");
75
        }
76 2
        $unionTypes = $type->getTypes();
77 2
        $morphableTargets = [];
78 2
        foreach ($unionTypes as $t) {
79 2
            if (!($t instanceof ObjectType)) {
80
                throw new Exception("$typeName is declared in a @morphTo union but it's not an object type.");
81
            }
82
83
            /**
84
             * @var ObjectType $t
85
             */
86 2
            $morphableTargets[] = $t->name;
87
        }
88
89 2
        $fieldFormularium->getExtradata('morphTo')
90 2
            ->appendParameter(new ExtradataParameter('targetModels', implode(',', $morphableTargets)));
91 2
    }
92
93 2
    public static function processModelRelationshipDirective(
94
        ModelGenerator $generator,
95
        \GraphQL\Type\Definition\FieldDefinition $field,
96
        \GraphQL\Language\AST\DirectiveNode $directive
97
    ): string {
98 2
        $lowerName = mb_strtolower($generator->getInflector()->singularize($field->name));
99
100 2
        $sourceTypeName = $generator->getLowerName();
101 2
        $targetTypeName = $lowerName;
102 2
        $relationship = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $relationship is dead and can be removed.
Loading history...
103 2
        $isInverse = false;
0 ignored issues
show
Unused Code introduced by
The assignment to $isInverse is dead and can be removed.
Loading history...
104 2
        $generateRandom = true; // TODO
0 ignored issues
show
Unused Code introduced by
The assignment to $generateRandom is dead and can be removed.
Loading history...
105
106 2
        $relationship = RelationshipFactory::MORPH_ONE_TO_MANY; // TODO
107 2
        $isInverse = true;
108 2
        $generator->class->addMethod($field->name)
109 2
            ->setReturnType('\\Illuminate\\Database\\Eloquent\\Relations\\MorphTo')
110 2
            ->setPublic()
111 2
            ->setBody("return \$this->morphTo();");
112
113 2
        return $generator->getRelationshipDatatypeName(
114 2
            $relationship,
115
            $isInverse,
116
            $sourceTypeName,
117
            $targetTypeName
118
        );
119
    }
120
121
    public static function processSeedTypeDirective(
122
        SeedGenerator $generator,
123
        \GraphQL\Language\AST\DirectiveNode $directive
124
    ): void {
125
        // empty
126
    }
127
128 2
    public static function processSeedFieldDirective(
129
        SeedGenerator $generator,
130
        \GraphQL\Type\Definition\FieldDefinition $field,
131
        \GraphQL\Language\AST\DirectiveNode $directive
132
    ): void {
133 2
        $type1 = $generator->getLowerName();
134 2
        $type2 = mb_strtolower($generator->getInflector()->singularize($field->name));
135
136 2
        if (strcasecmp($type1, $type2) < 0) { // TODO: check this, might not work
137 2
            $relationship = mb_strtolower($generator->getInflector()->pluralize($field->name));
138 2
            $generator->extraCode[] = self::makeManyToManySeed($type1, $type2, $relationship);
139
        }
140 2
    }
141
142 2
    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

142
    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...
143
    {
144
        return <<<EOF
145
146
        try {
147 2
            \${$targetModel}Items = App\\Models\\$targetModel::all();
148 2
            \$model->{$relationship}()->attach(
149 2
                \${$targetModel}Items->random(rand(1, 3))->pluck('id')->toArray()
150
            );
151
        }
152
        catch (\InvalidArgumentException \$e) {
153 2
            \$model->{$relationship}()->attach(
154 2
                \${$targetModel}Items->random(1)->pluck('id')->toArray()
155
            );
156
        }
157
EOF;
158
    }
159
}
160