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

processModelRelationshipDirective()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 28
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 18
nc 1
nop 4
dl 0
loc 28
ccs 16
cts 16
cp 1
crap 1
rs 9.6666
c 1
b 0
f 0
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\Factory\DatatypeFactory;
8
use Formularium\Field;
9
use GraphQL\Type\Definition\ObjectType;
10
use GraphQL\Type\Definition\UnionType;
11
use Illuminate\Support\Str;
12
use Modelarium\Exception\Exception;
13
use Modelarium\Parser;
14
use Modelarium\Datatypes\RelationshipFactory;
15
use Modelarium\Exception\DirectiveException;
16
use Modelarium\Laravel\Targets\Interfaces\MigrationDirectiveInterface;
17
use Modelarium\Laravel\Targets\ModelGenerator;
18
use Modelarium\Laravel\Targets\SeedGenerator;
19
use Modelarium\Laravel\Targets\Interfaces\ModelDirectiveInterface;
20
use Modelarium\Laravel\Targets\Interfaces\SeedDirectiveInterface;
21
use Modelarium\Laravel\Targets\MigrationCodeFragment;
22
use Modelarium\Laravel\Targets\MigrationGenerator;
23
24
class MorphToDirective implements MigrationDirectiveInterface, ModelDirectiveInterface, SeedDirectiveInterface
25
{
26
    public static function processMigrationTypeDirective(
27
        MigrationGenerator $generator,
28
        \GraphQL\Language\AST\DirectiveNode $directive
29
    ): void {
30
        throw new DirectiveException("Directive not supported here");
31
    }
32
33
    public static function processMigrationFieldDirective(
34
        MigrationGenerator $generator,
35
        \GraphQL\Type\Definition\FieldDefinition $field,
36
        \GraphQL\Language\AST\DirectiveNode $directive,
37
        MigrationCodeFragment $code
38
    ): void {
39
        throw new DirectiveException("Directive not supported here");
40
    }
41
42 2
    public static function processMigrationRelationshipDirective(
43
        MigrationGenerator $generator,
44
        \GraphQL\Type\Definition\FieldDefinition $field,
45
        \GraphQL\Language\AST\DirectiveNode $directive,
46
        MigrationCodeFragment $codeFragment
47
    ): void {
48 2
        $lowerName = mb_strtolower($generator->getInflector()->singularize($field->name));
49 2
        list($type, $isRequired) = Parser::getUnwrappedType($field->type);
50 2
        $relation = Parser::getDirectiveArgumentByName($directive, 'relation', $lowerName);
51 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

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

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