Completed
Push — master ( edb9ee...b465c5 )
by
unknown
10:14
created

TranslationDirective::manipulateFieldDefinition()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.7998
c 0
b 0
f 0
cc 3
nc 3
nop 3
1
<?php
2
3
namespace BBSLab\NovaTranslation\GraphQL\Directives;
4
5
use GraphQL\Language\AST\ArgumentNode;
6
use GraphQL\Language\AST\DirectiveNode;
7
use GraphQL\Language\AST\FieldDefinitionNode;
8
use GraphQL\Language\AST\NamedTypeNode;
9
use GraphQL\Language\AST\NameNode;
10
use GraphQL\Language\AST\NodeList;
11
use GraphQL\Language\AST\NonNullTypeNode;
12
use GraphQL\Language\AST\ObjectTypeDefinitionNode;
13
use GraphQL\Language\AST\StringValueNode;
14
use GraphQL\Type\Definition\ResolveInfo;
15
use Nuwave\Lighthouse\Schema\AST\ASTHelper;
16
use Nuwave\Lighthouse\Schema\AST\DocumentAST;
17
use Nuwave\Lighthouse\Schema\Directives\BaseDirective;
18
use Nuwave\Lighthouse\Schema\Values\FieldValue;
19
use Nuwave\Lighthouse\Support\Contracts\DefinedDirective;
20
use Nuwave\Lighthouse\Support\Contracts\FieldManipulator;
21
use Nuwave\Lighthouse\Support\Contracts\FieldResolver;
22
use Nuwave\Lighthouse\Support\Contracts\GraphQLContext;
23
24
class TranslationDirective extends BaseDirective implements FieldResolver, FieldManipulator, DefinedDirective
25
{
26
    /**
27
     * {@inheritdoc}
28
     */
29
    public function name(): string
30
    {
31
        return 'translation';
32
    }
33
34
    /**
35
     * {@inheritdoc}
36
     */
37
    public static function definition(): string
38
    {
39
        return /* @lang GraphQL */ <<<'SDL'
40
directive @translation(
41
  "Specify the class name of the model to use."
42
  model: String
43
  "Specify the GraphQL type to add the 'locale' field."
44
  type: String
45
) on ARGUMENT_DEFINITION
46
SDL;
47
    }
48
49
    /**
50
     * {@inheritdoc}
51
     */
52
    public function manipulateFieldDefinition(DocumentAST &$documentAST, FieldDefinitionNode &$fieldDefinition, ObjectTypeDefinitionNode &$parentType): void
53
    {
54
        $typeToAddLocaleField = $this->directiveArgValue('type', class_basename($this->getModelClass()));
55
56
        foreach ($documentAST->types as &$type) {
57
            if ($type->name->value === $typeToAddLocaleField) {
58
                /** @var \GraphQL\Language\AST\ObjectTypeDefinitionNode $type */
59
                $type->fields = ASTHelper::mergeNodeList($type->fields, [
60
                    $this->defineLocaleField(),
61
                    $this->defineTranslationIdField(),
62
                ]);
63
            }
64
        }
65
    }
66
67
    /**
68
     * {@inheritdoc}
69
     */
70
    public function resolveField(FieldValue $fieldValue): FieldValue
71
    {
72
        return $fieldValue->setResolver(
73
            function ($root, array $args, GraphQLContext $context, ResolveInfo $resolveInfo) {
0 ignored issues
show
Unused Code introduced by
The parameter $context is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $resolveInfo is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
74
                $modelClass = $this->getModelClass();
75
76
                $isos = [];
77
                if (isset($args['localeFilters'])) {
78
                    if (isset($args['localeFilters']['locale'])) {
79
                        $isos[] = $args['localeFilters']['locale'];
80
                    }
81
                    if (isset($args['localeFilters']['locales'])) {
82
                        $isos = array_merge($isos, $args['localeFilters']['locales']);
83
                    }
84
                }
85
86
                $table = (new $modelClass)->getTable();
87
                $query = $modelClass::query()
88
                    ->select($table.'.*', 'locales.iso AS locale', 'translations.translation_id')
89
                    ->join('translations', $table.'.id', '=', 'translations.translatable_id')
90
                    ->join('locales', 'translations.locale_id', '=', 'locales.id')
91
                    ->where('translations.translatable_type', '=', $modelClass)
92
                    ->where('locales.available_in_api', '=', true);
93
94
                if (! empty($isos)) {
95
                    $query = $query->whereIn('locales.iso', $isos);
96
                }
97
98
                return $query->get();
99
            }
100
        );
101
    }
102
103
    /**
104
     * Setup "locale" field definition.
105
     *
106
     * @return \GraphQL\Language\AST\FieldDefinitionNode
107
     */
108
    protected function defineLocaleField()
109
    {
110
        return new FieldDefinitionNode([
111
            'name' => new NameNode(['value' => 'locale']),
112
            'type' => new NonNullTypeNode(['type' => new NamedTypeNode(['name' => new NameNode(['value' => 'String'])])]),
113
            'arguments' => new NodeList([]),
114
            'directives' => new NodeList([]),
115
            'description' => new StringValueNode(['value' => 'Locale ISO', 'block' => false]),
116
        ]);
117
    }
118
119
    /**
120
     * Setup "translationId" field definition.
121
     *
122
     * @return \GraphQL\Language\AST\FieldDefinitionNode
123
     */
124
    protected function defineTranslationIdField()
125
    {
126
        return new FieldDefinitionNode([
127
            'name' => new NameNode(['value' => 'translationId']),
128
            'type' => new NonNullTypeNode(['type' => new NamedTypeNode(['name' => new NameNode(['value' => 'Int'])])]),
129
            'arguments' => new NodeList([]),
130
            'directives' => new NodeList([
131
                new DirectiveNode([
132
                    'name' => new NameNode(['value' => 'rename']),
133
                    'arguments' => new NodeList([
134
                        new ArgumentNode([
135
                            'name' => new NameNode(['value' => 'attribute']),
136
                            'value' => new StringValueNode(['value' => 'translation_id', 'block' => false]),
137
                        ]),
138
                    ]),
139
                ]),
140
            ]),
141
            'description' => new StringValueNode(['value' => 'Item translation ID', 'block' => false]),
142
        ]);
143
    }
144
}
145