FilterTasksHandler   B
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 131
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 16

Importance

Changes 0
Metric Value
dl 0
loc 131
rs 8.4614
c 0
b 0
f 0
wmc 14
lcom 1
cbo 16

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 17 1
B __invoke() 0 67 7
A addUserId() 0 8 2
B parentTask() 0 25 4
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\Application\Query\Project\Task;
16
17
use Kreta\TaskManager\Application\DataTransformer\Project\Task\TaskDataTransformer;
18
use Kreta\TaskManager\Domain\Model\Organization\Organization;
19
use Kreta\TaskManager\Domain\Model\Organization\OrganizationRepository;
20
use Kreta\TaskManager\Domain\Model\Organization\OrganizationSpecificationFactory;
21
use Kreta\TaskManager\Domain\Model\Project\Project;
22
use Kreta\TaskManager\Domain\Model\Project\ProjectId;
23
use Kreta\TaskManager\Domain\Model\Project\ProjectRepository;
24
use Kreta\TaskManager\Domain\Model\Project\ProjectSpecificationFactory;
25
use Kreta\TaskManager\Domain\Model\Project\Task\Task;
26
use Kreta\TaskManager\Domain\Model\Project\Task\TaskId;
27
use Kreta\TaskManager\Domain\Model\Project\Task\TaskPriority;
28
use Kreta\TaskManager\Domain\Model\Project\Task\TaskProgress;
29
use Kreta\TaskManager\Domain\Model\Project\Task\TaskRepository;
30
use Kreta\TaskManager\Domain\Model\Project\Task\TaskSpecificationFactory;
31
use Kreta\TaskManager\Domain\Model\Project\Task\UnauthorizedTaskResourceException;
32
use Kreta\TaskManager\Domain\Model\User\UserId;
33
34
class FilterTasksHandler
35
{
36
    private $repository;
37
    private $specificationFactory;
38
    private $dataTransformer;
39
    private $projectRepository;
40
    private $projectSpecificationFactory;
41
    private $organizationRepository;
42
    private $organizationSpecificationFactory;
43
44
    public function __construct(
45
        OrganizationRepository $organizationRepository,
46
        OrganizationSpecificationFactory $organizationSpecificationFactory,
47
        ProjectRepository $projectRepository,
48
        ProjectSpecificationFactory $projectSpecificationFactory,
49
        TaskRepository $repository,
50
        TaskSpecificationFactory $specificationFactory,
51
        TaskDataTransformer $dataTransformer
52
    ) {
53
        $this->repository = $repository;
54
        $this->specificationFactory = $specificationFactory;
55
        $this->dataTransformer = $dataTransformer;
56
        $this->organizationRepository = $organizationRepository;
57
        $this->organizationSpecificationFactory = $organizationSpecificationFactory;
58
        $this->projectRepository = $projectRepository;
59
        $this->projectSpecificationFactory = $projectSpecificationFactory;
60
    }
61
62
    public function __invoke(FilterTasksQuery $query)
63
    {
64
        $userId = UserId::generate($query->userId());
65
        $projectIds = [ProjectId::generate($query->projectId())];
66
        $assigneeIds = [];
67
        $reporterIds = [];
68
69
        $project = $this->projectRepository->projectOfId($projectIds[0]);
70
        if ($project instanceof Project) {
71
            $organization = $this->organizationRepository->organizationOfId(
72
                $project->organizationId()
73
            );
74
            $assigneeIds = $this->addUserId($assigneeIds, $organization, $query->assigneeId());
75
            $reporterIds = $this->addUserId($reporterIds, $organization, $query->reporterId());
76
77
            if (!$organization->isOrganizationMember($userId)) {
78
                throw new UnauthorizedTaskResourceException();
79
            }
80
        } else {
81
            $organizations = $this->organizationRepository->query(
82
                $this->organizationSpecificationFactory->buildFilterableSpecification(
83
                    null,
84
                    $userId
85
                )
86
            );
87
88
            $organizationIds = [];
89
            foreach ($organizations as $organization) {
90
                $assigneeIds = $this->addUserId($assigneeIds, $organization, $query->assigneeId());
91
                $reporterIds = $this->addUserId($reporterIds, $organization, $query->reporterId());
92
93
                $organizationIds[] = $organization->id();
94
            }
95
            $projects = $this->projectRepository->query(
96
                $this->projectSpecificationFactory->buildFilterableSpecification(
97
                    $organizationIds,
98
                    null
99
                )
100
            );
101
            $projectIds = array_map(function (Project $project) {
102
                return $project->id();
103
            }, $projects);
104
        }
105
        if (empty($projectIds)) {
106
            return [];
107
        }
108
109
        $tasks = $this->repository->query(
110
            $this->specificationFactory->buildFilterableSpecification(
111
                $projectIds,
112
                $query->title(),
113
                $this->parentTask($query->parentId(), $userId),
114
                null === $query->priority() ? null : new TaskPriority($query->priority()),
115
                null === $query->progress() ? null : new TaskProgress($query->progress()),
116
                $assigneeIds,
117
                $reporterIds,
118
                $query->offset(),
119
                $query->limit()
120
            )
121
        );
122
123
        return array_map(function (Task $task) {
124
            $this->dataTransformer->write($task);
125
126
            return $this->dataTransformer->read();
127
        }, $tasks);
128
    }
129
130
    private function addUserId($userIds, Organization $organization, ? string $userId)
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...
131
    {
132
        if (null !== $userId) {
133
            $userIds[] = $organization->organizationMember(UserId::generate($userId));
134
        }
135
136
        return $userIds;
137
    }
138
139
    private function parentTask(? string $parentId, UserId $userId) : ? TaskId
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...
140
    {
141
        if (null === $parentId) {
142
            return null;
143
        }
144
145
        $parent = $this->repository->taskOfId(
146
            TaskId::generate($parentId)
147
        );
148
        if (null === $parent) {
149
            return TaskId::generate();
150
        }
151
152
        $project = $this->projectRepository->projectOfId(
153
            $parent->projectId()
154
        );
155
        $organization = $this->organizationRepository->organizationOfId(
156
            $project->organizationId()
157
        );
158
        if (!$organization->isOrganizationMember($userId)) {
159
            throw new UnauthorizedTaskResourceException();
160
        }
161
162
        return $parent->id();
163
    }
164
}
165