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

MorphedByManyDirective   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 139
Duplicated Lines 0 %

Test Coverage

Coverage 86.44%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 53
dl 0
loc 139
ccs 51
cts 59
cp 0.8644
rs 10
c 1
b 0
f 0
wmc 18

9 Methods

Rating   Name   Duplication   Size   Complexity  
A processMigrationFieldDirective() 0 7 1
B processModelRelationshipDirective() 0 57 9
A processMigrationRelationshipDirective() 0 9 1
A processMigrationTypeDirective() 0 5 1
A processModelTypeDirective() 0 4 1
A processModelFieldDirective() 0 6 1
A processSeedFieldDirective() 0 11 2
A processSeedTypeDirective() 0 4 1
A makeManyToManySeed() 0 13 1
1
<?php declare(strict_types=1);
2
3
namespace Modelarium\Laravel\Directives;
4
5
use GraphQL\Type\Definition\ObjectType;
6
use Illuminate\Support\Str;
7
use Modelarium\Exception\Exception;
8
use Modelarium\Parser;
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
19
class MorphedByManyDirective implements MigrationDirectiveInterface, ModelDirectiveInterface, SeedDirectiveInterface
20
{
21
    public static function processMigrationTypeDirective(
22
        MigrationGenerator $generator,
23
        \GraphQL\Language\AST\DirectiveNode $directive
24
    ): void {
25
        throw new DirectiveException("Directive not supported here");
26
    }
27
28
    public static function processMigrationFieldDirective(
29
        MigrationGenerator $generator,
30
        \GraphQL\Type\Definition\FieldDefinition $field,
31
        \GraphQL\Language\AST\DirectiveNode $directive,
32
        MigrationCodeFragment $code
33
    ): void {
34
        throw new DirectiveException("Directive not supported here");
35
    }
36
37 1
    public static function processMigrationRelationshipDirective(
38
        MigrationGenerator $generator,
39
        \GraphQL\Type\Definition\FieldDefinition $field,
40
        \GraphQL\Language\AST\DirectiveNode $directive,
41
        MigrationCodeFragment $codeFragment
42
    ): void {
43 1
        $lowerName = mb_strtolower($generator->getInflector()->singularize($field->name));
44 1
        $relation = Parser::getDirectiveArgumentByName($directive, 'relation', $lowerName);
45 1
        $generator->generateManyToManyMorphTable($generator->getLowerName(), $relation);
0 ignored issues
show
Bug introduced by
It seems like $relation can also be of type array and array; however, parameter $relation of Modelarium\Laravel\Targe...eManyToManyMorphTable() 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

45
        $generator->generateManyToManyMorphTable($generator->getLowerName(), /** @scrutinizer ignore-type */ $relation);
Loading history...
46 1
    }
47
48
    public static function processModelTypeDirective(
49
        ModelGenerator $generator,
50
        \GraphQL\Language\AST\DirectiveNode $directive
51
    ): void {
52
        // nothing
53
    }
54
55 1
    public static function processModelFieldDirective(
56
        ModelGenerator $generator,
57
        \GraphQL\Type\Definition\FieldDefinition $field,
58
        \Formularium\Field $fieldFormularium,
59
        \GraphQL\Language\AST\DirectiveNode $directive
60
    ): void {
61
        // nothing
62 1
    }
63
64 1
    public static function processModelRelationshipDirective(
65
        ModelGenerator $generator,
66
        \GraphQL\Type\Definition\FieldDefinition $field,
67
        \GraphQL\Language\AST\DirectiveNode $directive
68
    ): string {
69 1
        $name = $directive->name->value;
0 ignored issues
show
Unused Code introduced by
The assignment to $name is dead and can be removed.
Loading history...
70 1
        list($type, $isRequired) = Parser::getUnwrappedType($field->type);
71 1
        $typeName = $type->name;
0 ignored issues
show
Unused Code introduced by
The assignment to $typeName is dead and can be removed.
Loading history...
72
73 1
        $lowerName = mb_strtolower($generator->getInflector()->singularize($field->name));
74 1
        $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...
75
76 1
        $sourceTypeName = $generator->getLowerName();
77 1
        $targetTypeName = $lowerName;
78 1
        $relationship = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $relationship is dead and can be removed.
Loading history...
79 1
        $isInverse = false;
0 ignored issues
show
Unused Code introduced by
The assignment to $isInverse is dead and can be removed.
Loading history...
80 1
        $targetClass = '\\App\\Models\\' . Str::studly($generator->getInflector()->singularize($field->name));
0 ignored issues
show
Unused Code introduced by
The assignment to $targetClass is dead and can be removed.
Loading history...
81 1
        $generateRandom = true; // TODO
0 ignored issues
show
Unused Code introduced by
The assignment to $generateRandom is dead and can be removed.
Loading history...
82
83 1
        $relationship = RelationshipFactory::MORPH_MANY_TO_MANY; // TODO
84 1
        $isInverse = true;
85 1
        $typeMap = $generator->parser->getSchema()->getTypeMap();
86
87 1
        foreach ($typeMap as $name => $object) {
88 1
            if (!($object instanceof ObjectType) || $name === 'Query' || $name === 'Mutation' || $name === 'Subscription') {
89 1
                continue;
90
            }
91
92
            /**
93
             * @var ObjectType $object
94
             */
95
96 1
            if (str_starts_with((string)$name, '__')) {
97
                // internal type
98 1
                continue;
99
            }
100
101 1
            foreach ($object->getFields() as $subField) {
102 1
                $subDirectives = Parser::getDirectives($subField->astNode->directives);
103
104 1
                if (!array_key_exists('morphToMany', $subDirectives)) {
105 1
                    continue;
106
                }
107
108 1
                $methodName = $generator->getInflector()->pluralize(mb_strtolower((string)$name));
109 1
                $generator->class->addMethod($methodName)
110 1
                        ->setReturnType('\\Illuminate\\Database\\Eloquent\\Relations\\MorphToMany')
111 1
                        ->setPublic()
112 1
                        ->setBody("return \$this->morphedByMany($name::class, '$lowerName');");
113
            }
114
        }
115
116 1
        return $generator->getRelationshipDatatypeName(
117 1
            $relationship,
118
            $isInverse,
119
            $sourceTypeName,
120
            $targetTypeName
121
        );
122
    }
123
124
    public static function processSeedTypeDirective(
125
        SeedGenerator $generator,
126
        \GraphQL\Language\AST\DirectiveNode $directive
127
    ): void {
128
        // empty
129
    }
130
131 1
    public static function processSeedFieldDirective(
132
        SeedGenerator $generator,
133
        \GraphQL\Type\Definition\FieldDefinition $field,
134
        \GraphQL\Language\AST\DirectiveNode $directive
135
    ): void {
136 1
        $type1 = $generator->getLowerName();
137 1
        $type2 = mb_strtolower($generator->getInflector()->singularize($field->name));
138
139 1
        if (strcasecmp($type1, $type2) < 0) { // TODO: check this, might not work
140 1
            $relationship = mb_strtolower($generator->getInflector()->pluralize($field->name));
141 1
            $generator->extraCode[] = self::makeManyToManySeed($type1, $type2, $relationship);
142
        }
143 1
    }
144
145 1
    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 1
            \${$targetModel}Items = App\\Models\\$targetModel::all();
151 1
            \$model->{$relationship}()->attach(
152 1
                \${$targetModel}Items->random(rand(1, 3))->pluck('id')->toArray()
153
            );
154
        }
155
        catch (\InvalidArgumentException \$e) {
156 1
            \$model->{$relationship}()->attach(
157 1
                \${$targetModel}Items->random(1)->pluck('id')->toArray()
158
            );
159
        }
160
EOF;
161
    }
162
}
163