Passed
Push — master ( 1dbc05...713241 )
by Bruno
03:36
created

processMigrationRelationshipDirective()   C

Complexity

Conditions 12
Paths 146

Size

Total Lines 55
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 27
CRAP Score 12.0473

Importance

Changes 0
Metric Value
cc 12
eloc 31
c 0
b 0
f 0
nc 146
nop 4
dl 0
loc 55
ccs 27
cts 29
cp 0.931
crap 12.0473
rs 6.5833

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 = lcfirst($generator->getInflector()->singularize($field->name));
45 4
        $fieldName = $lowerName . '_id';
46
47 4
        list($type, $isRequired) = Parser::getUnwrappedType($field->getType());
48 4
        $typeName = $type->name;
49 4
        $tableName = MigrationGenerator::toTableName($typeName);
50
51 4
        $targetType = $generator->parser->getType($typeName);
52 4
        if (!$targetType) {
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
58
        // we don't know what is the reverse relationship name at this point. so let's guess all possibilities
59 4
        $targetField = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $targetField is dead and can be removed.
Loading history...
60
        try {
61 4
            $targetField = $targetType->getField($tableName);
62 4
        } catch (\GraphQL\Error\InvariantViolation $e) {
63
            // pass
64
        }
65 4
        if (!$targetField) {
0 ignored issues
show
introduced by
$targetField is of type GraphQL\Type\Definition\FieldDefinition, thus it always evaluated to true.
Loading history...
66
            try {
67
                // many to many
68 4
                $targetField = $targetType->getField($generator->getTableName());
69 3
            } catch (\GraphQL\Error\InvariantViolation $e) {
70
                // pass
71
            }
72
        }
73 4
        if (!$targetField) {
0 ignored issues
show
introduced by
$targetField is of type GraphQL\Type\Definition\FieldDefinition, thus it always evaluated to true.
Loading history...
74
            try {
75
                // one to many
76 3
                $targetField = $targetType->getField($generator->getLowerFirstLetterNamePlural());
77 3
            } catch (\GraphQL\Error\InvariantViolation $e) {
78
                // pass
79
            }
80
        }
81 4
        if (!$targetField) {
0 ignored issues
show
introduced by
$targetField is of type GraphQL\Type\Definition\FieldDefinition, thus it always evaluated to true.
Loading history...
82
            // one to one
83 3
            $targetField = $targetType->getField($generator->getLowerFirstLetterName());
84
        }
85
86 4
        $targetDirectives = $targetField->astNode->directives;
87 4
        foreach ($targetDirectives as $targetDirective) {
88 4
            switch ($targetDirective->name->value) {
89 4
                case 'hasOne':
90 1
                case 'hasMany':
91 4
                    $codeFragment->appendBase('->unsignedBigInteger("' . $fieldName . '")');
92 4
                break;
93
            }
94
        }
95 4
    }
96
97
    public static function processModelTypeDirective(
98
        ModelGenerator $generator,
99
        \GraphQL\Language\AST\DirectiveNode $directive
100
    ): void {
101
        // nothing
102
    }
103
104 4
    public static function processModelFieldDirective(
105
        ModelGenerator $generator,
106
        \GraphQL\Type\Definition\FieldDefinition $field,
107
        \Formularium\Field $fieldFormularium,
108
        \GraphQL\Language\AST\DirectiveNode $directive
109
    ): void {
110
        // nothing
111 4
    }
112
113 4
    public static function processModelRelationshipDirective(
114
        ModelGenerator $generator,
115
        \GraphQL\Type\Definition\FieldDefinition $field,
116
        \GraphQL\Language\AST\DirectiveNode $directive,
117
        \Formularium\Datatype $datatype = null
118
    ): ?\Formularium\Datatype {
119 4
        $fieldName = $generator->getInflector()->singularize($field->name);
120
121 4
        $sourceTypeName = $generator->getBaseName();
122 4
        $targetTypeName = $fieldName;
123 4
        $relationship = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $relationship is dead and can be removed.
Loading history...
124 4
        $isInverse = false;
0 ignored issues
show
Unused Code introduced by
The assignment to $isInverse is dead and can be removed.
Loading history...
125
126 4
        $targetClass = Str::studly($fieldName);
127 4
        $generateRandom = true; // TODO
0 ignored issues
show
Unused Code introduced by
The assignment to $generateRandom is dead and can be removed.
Loading history...
128 4
        $relationship = RelationshipFactory::RELATIONSHIP_ONE_TO_MANY;
129 4
        $isInverse = true;
130 4
        $generator->class->addMethod($fieldName)
131 4
            ->setPublic()
132 4
            ->setReturnType('\\Illuminate\\Database\\Eloquent\\Relations\\BelongsTo')
133 4
            ->setBody("return \$this->belongsTo($targetClass::class);");
134
135 4
        $datatypeName = $generator->getRelationshipDatatypeName(
136 4
            $relationship,
137
            $isInverse,
138
            $sourceTypeName,
139
            $targetTypeName
140
        );
141 4
        return DatatypeFactory::factory($datatypeName);
142
    }
143
144
    public static function processSeedTypeDirective(
145
        SeedGenerator $generator,
146
        \GraphQL\Language\AST\DirectiveNode $directive
147
    ): void {
148
        // empty
149
    }
150
151 4
    public static function processSeedFieldDirective(
152
        SeedGenerator $generator,
153
        \GraphQL\Type\Definition\FieldDefinition $field,
154
        \GraphQL\Language\AST\DirectiveNode $directive
155
    ): void {
156 4
        $type1 = $generator->getLowerFirstLetterName();
157 4
        $type2 = $generator->getInflector()->singularize($field->name);
158
159 4
        if (strcasecmp($type1, $type2) < 0) { // TODO: check this, might not work
160 4
            $relationship = $generator->getInflector()->pluralize($field->name);
161 4
            $generator->extraCode[] = self::makeManyToManySeed($type1, $type2, $relationship);
162
        }
163 4
    }
164
165 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

165
    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...
166
    {
167 4
        $className = Str::studly($targetModel);
168
        return <<<EOF
169
170
        try {
171 4
            \${$targetModel}Items = App\\Models\\$className::all();
172 4
            \$model->{$relationship}()->attach(
173 4
                \${$targetModel}Items->random(rand(1, 3))->pluck('id')->toArray()
174
            );
175
        }
176
        catch (\InvalidArgumentException \$e) {
177 4
            \$model->{$relationship}()->attach(
178 4
                \${$targetModel}Items->random(1)->pluck('id')->toArray()
179
            );
180
        }
181
EOF;
182
    }
183
}
184