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

processSeedFieldDirective()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
nc 2
nop 3
dl 0
loc 11
ccs 6
cts 6
cp 1
crap 2
rs 10
c 1
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Modelarium\Laravel\Directives;
4
5
use Formularium\Factory\DatatypeFactory;
6
use GraphQL\Type\Definition\ObjectType;
7
use Illuminate\Support\Str;
8
use Modelarium\Exception\Exception;
9
use Modelarium\Parser;
10
use Modelarium\Datatypes\RelationshipFactory;
11
use Modelarium\Exception\DirectiveException;
12
use Modelarium\Laravel\Targets\Interfaces\MigrationDirectiveInterface;
13
use Modelarium\Laravel\Targets\ModelGenerator;
14
use Modelarium\Laravel\Targets\SeedGenerator;
15
use Modelarium\Laravel\Targets\Interfaces\ModelDirectiveInterface;
16
use Modelarium\Laravel\Targets\Interfaces\SeedDirectiveInterface;
17
use Modelarium\Laravel\Targets\MigrationCodeFragment;
18
use Modelarium\Laravel\Targets\MigrationGenerator;
19
20
class MorphedByManyDirective 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 1
    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 1
        $lowerName = mb_strtolower($generator->getInflector()->singularize($field->name));
45 1
        $relation = Parser::getDirectiveArgumentByName($directive, 'relation', $lowerName);
46 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

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

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