Passed
Push — master ( 73a53e...f91dab )
by Bruno
07:25 queued 04:03
created

BelongsToDirective::makeManyToManySeed()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 9
c 1
b 0
f 0
dl 0
loc 13
ccs 6
cts 6
cp 1
rs 9.9666
cc 1
nc 1
nop 3
crap 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\Datatypes\RelationshipFactory;
8
use Modelarium\Exception\DirectiveException;
9
use Modelarium\Laravel\Targets\Interfaces\MigrationDirectiveInterface;
10
use Modelarium\Laravel\Targets\ModelGenerator;
11
use Modelarium\Laravel\Targets\SeedGenerator;
12
use Modelarium\Laravel\Targets\Interfaces\ModelDirectiveInterface;
13
use Modelarium\Laravel\Targets\Interfaces\SeedDirectiveInterface;
14
use Modelarium\Laravel\Targets\MigrationCodeFragment;
15
use Modelarium\Laravel\Targets\MigrationGenerator;
16
use Modelarium\Parser;
17
18
class BelongsToDirective implements MigrationDirectiveInterface, ModelDirectiveInterface, SeedDirectiveInterface
19
{
20
    public static function processMigrationTypeDirective(
21
        MigrationGenerator $generator,
22
        \GraphQL\Language\AST\DirectiveNode $directive
23
    ): void {
24
        throw new DirectiveException("Directive not supported here");
25
    }
26
27
    public static function processMigrationFieldDirective(
28
        MigrationGenerator $generator,
29
        \GraphQL\Type\Definition\FieldDefinition $field,
30
        \GraphQL\Language\AST\DirectiveNode $directive,
31
        MigrationCodeFragment $code
32
    ): void {
33
        throw new DirectiveException("Directive not supported here");
34
    }
35
36 4
    public static function processMigrationRelationshipDirective(
37
        MigrationGenerator $generator,
38
        \GraphQL\Type\Definition\FieldDefinition $field,
39
        \GraphQL\Language\AST\DirectiveNode $directive,
40
        MigrationCodeFragment $codeFragment
41
    ): void {
42 4
        $lowerName = mb_strtolower($generator->getInflector()->singularize($field->name));
43 4
        $fieldName = $lowerName . '_id';
44
45 4
        list($type, $isRequired) = Parser::getUnwrappedType($field->type);
46 4
        $typeName = $type->name;
47 4
        $tableName = MigrationGenerator::toTableName($typeName);
48
49 4
        $targetType = $generator->parser->getType($typeName);
50 4
        if (!$targetType) {
0 ignored issues
show
introduced by
$targetType is of type GraphQL\Type\Definition\Type, thus it always evaluated to true.
Loading history...
51
            throw new DirectiveException("Cannot get type {$typeName} as a relationship to {$generator->getBaseName()}");
52 4
        } elseif (!($targetType instanceof ObjectType)) {
53
            throw new DirectiveException("{$typeName} is not a type for a relationship to {$generator->getBaseName()}");
54
        }
55
        // we don't know what is the reverse relationship name at this point. so let's guess all possibilities
56
        try {
57 4
            $targetField = $targetType->getField($tableName);
58 4
        } catch (\GraphQL\Error\InvariantViolation $e) {
59
            try {
60 4
                $targetField = $targetType->getField($generator->getTableName());
61 3
            } catch (\GraphQL\Error\InvariantViolation $e) {
62
                // one to one
63 3
                $targetField = $targetType->getField($generator->getLowerName());
64
            }
65
        }
66
67 4
        $targetDirectives = $targetField->astNode->directives;
68 4
        foreach ($targetDirectives as $targetDirective) {
69 4
            switch ($targetDirective->name->value) {
70 4
                case 'hasOne':
71 1
                case 'hasMany':
72 4
                    $codeFragment->appendBase('->unsignedBigInteger("' . $fieldName . '")');
73 4
                break;
74
            }
75
        }
76 4
    }
77
78
    public static function processModelTypeDirective(
79
        ModelGenerator $generator,
80
        \GraphQL\Language\AST\DirectiveNode $directive
81
    ): void {
82
        // nothing
83
    }
84
85 4
    public static function processModelFieldDirective(
86
        ModelGenerator $generator,
87
        \GraphQL\Type\Definition\FieldDefinition $field,
88
        \Formularium\Field $fieldFormularium,
89
        \GraphQL\Language\AST\DirectiveNode $directive
90
    ): void {
91
        // nothing
92 4
    }
93
94 4
    public static function processModelRelationshipDirective(
95
        ModelGenerator $generator,
96
        \GraphQL\Type\Definition\FieldDefinition $field,
97
        \GraphQL\Language\AST\DirectiveNode $directive
98
    ): string {
99 4
        $lowerName = mb_strtolower($generator->getInflector()->singularize($field->name));
100 4
        $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...
101
102 4
        $sourceTypeName = $generator->getLowerName();
103 4
        $targetTypeName = $lowerName;
104 4
        $relationship = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $relationship is dead and can be removed.
Loading history...
105 4
        $isInverse = false;
0 ignored issues
show
Unused Code introduced by
The assignment to $isInverse is dead and can be removed.
Loading history...
106
107 4
        $targetClass = Str::studly($generator->getInflector()->singularize($field->name));
108 4
        $generateRandom = true; // TODO
0 ignored issues
show
Unused Code introduced by
The assignment to $generateRandom is dead and can be removed.
Loading history...
109 4
        $relationship = RelationshipFactory::RELATIONSHIP_ONE_TO_MANY;
110 4
        $isInverse = true;
111 4
        $generator->class->addMethod($lowerName)
112 4
            ->setPublic()
113 4
            ->setReturnType('\\Illuminate\\Database\\Eloquent\\Relations\\BelongsTo')
114 4
            ->setBody("return \$this->belongsTo($targetClass::class);");
115
116 4
        return $generator->getRelationshipDatatypeName(
117 4
            $relationship,
118
            $isInverse,
119
            $sourceTypeName,
120
            $targetTypeName
121
        );
122
    }
123
124 4
    public static function processSeedFieldDirective(
125
        SeedGenerator $generator,
126
        \GraphQL\Type\Definition\FieldDefinition $field,
127
        \GraphQL\Language\AST\DirectiveNode $directive
128
    ): void {
129 4
        $type1 = $generator->getLowerName();
130 4
        $type2 = mb_strtolower($generator->getInflector()->singularize($field->name));
131
132 4
        if (strcasecmp($type1, $type2) < 0) { // TODO: check this, might not work
133 4
            $relationship = mb_strtolower($generator->getInflector()->pluralize($field->name));
134 4
            $generator->extraCode[] = self::makeManyToManySeed($type1, $type2, $relationship);
135
        }
136 4
    }
137
138 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

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