CountTasksHandler   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 119
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 15

Importance

Changes 0
Metric Value
dl 0
loc 119
rs 9.1666
c 0
b 0
f 0
wmc 14
lcom 1
cbo 15

4 Methods

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