TasksResolver::buildPagination()   B
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 44
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 44
rs 8.439
c 0
b 0
f 0
cc 5
eloc 32
nc 4
nop 1
1
<?php
2
3
/*
4
 * This file is part of the Kreta package.
5
 *
6
 * (c) Beñat Espiña <[email protected]>
7
 * (c) Gorka Laucirica <[email protected]>
8
 *
9
 * For the full copyright and license information, please view the LICENSE
10
 * file that was distributed with this source code.
11
 */
12
13
declare(strict_types=1);
14
15
namespace Kreta\TaskManager\Infrastructure\Symfony\GraphQl\Query\Project\Task;
16
17
use Kreta\SharedKernel\Application\QueryBus;
18
use Kreta\SharedKernel\Http\GraphQl\Relay\ConnectionBuilder;
19
use Kreta\SharedKernel\Http\GraphQl\Resolver;
20
use Kreta\TaskManager\Application\Query\Project\Task\CountTasksQuery;
21
use Kreta\TaskManager\Application\Query\Project\Task\FilterTasksQuery;
22
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
23
24
class TasksResolver implements Resolver
25
{
26
    private $connectionBuilder;
27
    private $queryBus;
28
    private $currentUser;
29
    private $taskBuilderResolver;
30
31
    public function __construct(
32
        TokenStorageInterface $tokenStorage,
33
        ConnectionBuilder $connectionBuilder,
34
        QueryBus $queryBus,
35
        TaskBuilderResolver $taskBuilderResolver
36
    ) {
37
        $this->connectionBuilder = $connectionBuilder;
38
        $this->queryBus = $queryBus;
39
        $this->currentUser = $tokenStorage->getToken()->getUser()->getUsername();
40
        $this->taskBuilderResolver = $taskBuilderResolver;
41
    }
42
43
    public function resolveByProject($projectId, $args)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
44
    {
45
        $args['projectId'] = $projectId;
46
47
        return $this->resolve($args);
48
    }
49
50
    public function resolveByParent($parentId, $args)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
51
    {
52
        $args['parentId'] = $parentId;
53
54
        return $this->resolve($args);
55
    }
56
57
    public function resolve($args)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
58
    {
59
        if (isset($args['taskConnectionInput'])) {
60
            $args = $args['taskConnectionInput'];
61
        }
62
63
        if (!isset($args['title'])) {
64
            $args['title'] = null;
65
        }
66
        if (!isset($args['projectId'])) {
67
            $args['projectId'] = null;
68
        }
69
        if (!isset($args['parentId'])) {
70
            $args['parentId'] = null;
71
        }
72
        if (!isset($args['priority'])) {
73
            $args['priority'] = null;
74
        }
75
        if (!isset($args['progress'])) {
76
            $args['progress'] = null;
77
        }
78
        if (!isset($args['assigneeId'])) {
79
            $args['assigneeId'] = null;
80
        }
81
        if (!isset($args['reporterId'])) {
82
            $args['reporterId'] = null;
83
        }
84
85
        list($offset, $limit, $total) = $this->buildPagination($args);
86
87
        $this->queryBus->handle(
88
            new FilterTasksQuery(
89
                $this->currentUser,
90
                $offset,
91
                $limit,
92
                $args['parentId'],
93
                $args['projectId'],
94
                $args['title'],
95
                $args['priority'],
96
                $args['progress'],
97
                $args['assigneeId'],
98
                $args['reporterId']
99
            ),
100
            $result
101
        );
102
103
        foreach ($result as $key => $task) {
104
            $result[$key] = $this->taskBuilderResolver->resolve($task);
105
        }
106
107
        $connection = $this->connectionBuilder->fromArraySlice(
108
            $result,
109
            $args,
110
            [
111
                'sliceStart'  => $offset,
112
                'arrayLength' => $total,
113
            ]
114
        );
115
        $connection->totalCount = count($result);
116
117
        return $connection;
118
    }
119
120
    private function buildPagination($args) : array
121
    {
122
        $this->queryBus->handle(
123
            new CountTasksQuery(
124
                $this->currentUser,
125
                $args['parentId'],
126
                $args['projectId'],
127
                $args['title'],
128
                $args['priority'],
129
                $args['progress'],
130
                $args['assigneeId'],
131
                $args['reporterId']
132
            ),
133
            $total
134
        );
135
136
        $beforeOffset = $this->connectionBuilder->getOffsetWithDefault(
137
            $args['before']
138
                ?? null,
139
            $total
140
        );
141
        $afterOffset = $this->connectionBuilder->getOffsetWithDefault(
142
            $args['after']
143
                ?? null,
144
            -1
145
        );
146
        $startOffset = max($afterOffset, -1) + 1;
147
        $endOffset = min($beforeOffset, $total);
148
149
        if (isset($args['first']) && is_numeric($args['first'])) {
150
            $endOffset = min($endOffset, $startOffset + $args['first']);
151
        }
152
        if (isset($args['last']) && is_numeric($args['last'])) {
153
            $startOffset = max($startOffset, $endOffset - $args['last']);
154
        }
155
        $offset = max($startOffset, 0);
156
        $limit = $endOffset - $startOffset;
157
158
        return [
159
            $offset,
160
            $limit,
161
            $total,
162
        ];
163
    }
164
}
165