PaginationManipulator   A
last analyzed

Complexity

Total Complexity 5

Size/Duplication

Total Lines 113
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 0
Metric Value
wmc 5
lcom 1
cbo 7
dl 0
loc 113
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A transformToPaginatedField() 0 14 2
B registerConnection() 0 57 2
A addCursorPaginationInfoType() 0 22 1
1
<?php
2
3
namespace DutchCodingCompany\CursorPagination\Pagination;
4
5
use GraphQL\Language\AST\FieldDefinitionNode;
6
use GraphQL\Language\AST\ObjectTypeDefinitionNode;
7
use Nuwave\Lighthouse\Pagination\PaginationType;
8
use Nuwave\Lighthouse\Schema\AST\ASTHelper;
9
use Nuwave\Lighthouse\Schema\AST\PartialParser;
10
11
class PaginationManipulator extends \Nuwave\Lighthouse\Pagination\PaginationManipulator
12
{
13
14
    /**
15
     * Transform the definition for a field to a field with pagination.
16
     *
17
     * This makes either an offset-based Paginator or a cursor-based Connection.
18
     * The types in between are automatically generated and applied to the schema.
19
     *
20
     * @param  \Nuwave\Lighthouse\Pagination\PaginationType  $paginationType
21
     */
22
    public function transformToPaginatedField(
23
        PaginationType $paginationType,
24
        FieldDefinitionNode &$fieldDefinition,
25
        ObjectTypeDefinitionNode &$parentType,
26
        ?int $defaultCount = null,
27
        ?int $maxCount = null,
28
        ?ObjectTypeDefinitionNode $edgeType = null
29
    ): void {
30
        if ($paginationType->isConnection()) {
31
            $this->registerConnection($fieldDefinition, $parentType, $defaultCount, $maxCount, $edgeType);
32
        } else {
33
            $this->registerPaginator($fieldDefinition, $parentType, $defaultCount, $maxCount);
34
        }
35
    }
36
37
    /**
38
     * Register connection with schema.
39
     */
40
    protected function registerConnection(
41
        FieldDefinitionNode &$fieldDefinition,
42
        ObjectTypeDefinitionNode &$parentType,
43
        ?int $defaultCount = null,
44
        ?int $maxCount = null,
45
        ?ObjectTypeDefinitionNode $edgeType = null
46
    ): void {
47
        // Register cursor specific pagination type
48
        $this->addCursorPaginationInfoType();
49
50
        $fieldTypeName = ASTHelper::getUnderlyingTypeName($fieldDefinition);
51
52
        if ($edgeType) {
53
            $connectionEdgeName = $edgeType->name->value;
54
            $connectionTypeName = "{$connectionEdgeName}Connection";
55
        } else {
56
            $connectionEdgeName = "{$fieldTypeName}Edge";
57
            $connectionTypeName = "{$fieldTypeName}Connection";
58
        }
59
60
        $connectionFieldName = addslashes(ConnectionField::class);
61
        $connectionType = PartialParser::objectTypeDefinition(/** @lang GraphQL */ <<<GRAPHQL
62
            "A paginated list of $fieldTypeName edges."
63
            type $connectionTypeName {
64
                "Pagination information about the list of edges."
65
                pageInfo: CursorPageInfo! @field(resolver: "{$connectionFieldName}@pageInfoResolver")
66
67
                "A list of $fieldTypeName edges."
68
                edges: [$connectionEdgeName] @field(resolver: "{$connectionFieldName}@edgeResolver")
69
            }
70
GRAPHQL
71
        );
72
        $this->addPaginationWrapperType($connectionType);
73
74
        $connectionEdge = $edgeType
75
            ?? $this->documentAST->types[$connectionEdgeName]
76
            ?? PartialParser::objectTypeDefinition(/** @lang GraphQL */ <<<GRAPHQL
77
                "An edge that contains a node of type $fieldTypeName and a cursor."
78
                type $connectionEdgeName {
79
                    "The $fieldTypeName node."
80
                    node: $fieldTypeName
81
                }
82
GRAPHQL
83
            );
84
        $this->documentAST->setTypeDefinition($connectionEdge);
85
86
        $inputValueDefinitions = [
87
            self::countArgument('first', $defaultCount, $maxCount),
88
            "\"A cursor after which elements are returned.\"\nafter: String",
89
        ];
90
91
        $connectionArguments = PartialParser::inputValueDefinitions($inputValueDefinitions);
92
93
        $fieldDefinition->arguments = ASTHelper::mergeNodeList($fieldDefinition->arguments, $connectionArguments);
94
        $fieldDefinition->type = PartialParser::namedType($connectionTypeName);
95
        $parentType->fields = ASTHelper::mergeNodeList($parentType->fields, [$fieldDefinition]);
0 ignored issues
show
Documentation Bug introduced by
It seems like \Nuwave\Lighthouse\Schem...rray($fieldDefinition)) of type object<GraphQL\Language\AST\NodeList> is incompatible with the declared type array<integer,object<Gra...ldDefinitionNode>>|null of property $fields.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
96
    }
97
98
    /**
99
     * Add the types required for pagination.
100
     */
101
    protected function addCursorPaginationInfoType(): void
102
    {
103
        $this->documentAST->setTypeDefinition(
104
            PartialParser::objectTypeDefinition(/** @lang GraphQL */ '
105
                "Pagination information about the corresponding list of items."
106
                type CursorPageInfo {
107
                  "When paginating forwards, the cursor to continue."
108
                  after: String
109
110
                  "When paginating forwards, are there more items?"
111
                  hasAfter: Boolean!
112
113
                  "Total number of node in connection."
114
                  total: Int
115
116
                  "Count of nodes in current request."
117
                  count: Int
118
119
                }
120
            ')
121
        );
122
    }
123
}
124