Command::completeTask()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 9.2
c 0
b 0
f 0
cc 3
eloc 11
nc 3
nop 1
1
<?php
2
3
namespace Todo\Application\Task;
4
use Todo\Application\Task\Exception\TaskCannotBeRemovedException;
5
use Todo\Application\Task\Exception\TaskCannotBeSavedException;
6
use Todo\Domain\Exception\TaskNameIsAlreadyExistedException;
7
use Todo\Domain\Exception\TaskNameIsEmptyException;
8
use Todo\Domain\Exception\TaskNotFoundException;
9
use Todo\Domain\Factory\TaskFactory;
10
use Todo\Domain\Repository\TaskRepositoryInterface;
11
use Todo\Domain\Service\TaskValidationService;
12
use Todo\Domain\Specification\TaskNameIsNotEmptySpecification;
13
use Todo\Domain\Specification\TaskNameIsUniqueSpecification;
14
use Todo\Domain\Task;
15
16
/**
17
 * Class Command
18
 *
19
 * Executes Task's commands to update/remove Task object from repository
20
 *
21
 * @category None
22
 * @package  Todo\Application\Task
23
 * @author   Martin Pham <[email protected]>
24
 * @license  None http://
25
 * @link     None
26
 */
27
class Command
28
{
29
    /**
30
     * TaskRepository
31
     *
32
     * @var TaskRepositoryInterface
33
     */
34
    protected $taskRepository;
35
36
    /**
37
     * TaskValidationService
38
     *
39
     * @var TaskValidationService
40
     */
41
    protected $taskValidationService;
42
43
    /**
44
     * TaskFactory
45
     *
46
     * @var TaskFactory
47
     */
48
    protected $taskFactory;
49
50
    /**
51
     * Command constructor
52
     *
53
     * @param TaskRepositoryInterface $taskRepository Task Repository
54
     */
55
    public function __construct(
56
        TaskRepositoryInterface $taskRepository
57
    ) {
58
        // Inject Task repository
59
        $this->taskRepository = $taskRepository;
60
61
        // Init Task factory
62
        $this->taskFactory = new TaskFactory($this->taskRepository);
63
64
        // Init Task validation service
65
        $this->taskValidationService = new TaskValidationService(
66
            $this->taskRepository
67
        );
68
    }
69
70
71
    /**
72
     * Add new Task into repository
73
     *
74
     * @param string $name Name
75
     *
76
     * @return Task
77
     * @throws TaskCannotBeSavedException
78
     * @throws TaskNameIsAlreadyExistedException
79
     * @throws TaskNameIsEmptyException
80
     */
81
    public function addNewTask(string $name) : Task
82
    {
83
        // Try to init Task object from given name
84
        // Trigger exceptions when Task's name is empty or already existed
85
        try {
86
            $task = $this->taskFactory->createFromName($name);
87
        } catch (TaskNameIsEmptyException | TaskNameIsAlreadyExistedException $e) {
88
            throw $e;
89
        }
90
91
        // Persist Task object into repository
92
        try {
93
            $this->taskRepository->save($task);
94
        } catch (TaskCannotBeSavedException $e) {
95
            throw $e;
96
        }
97
98
        // Return Task object
99
        return $task;
100
    }
101
102
    /**
103
     * Update Task's status to completed
104
     *
105
     * @param string $taskId Task ID
106
     *
107
     * @return Task
108
     * @throws TaskNotFoundException
109
     * @throws TaskCannotBeSavedException
110
     */
111
    public function completeTask($taskId) : Task
112
    {
113
        // Try to find Task object from repository, from given ID
114
        try {
115
            $task = $this->taskRepository->find($taskId);
116
        } catch (TaskNotFoundException $e) {
117
            throw $e;
118
        }
119
120
        // Update Task's status to completed
121
        $task->setStatus(Task::STATUS_COMPLETED);
122
123
        // Try to save Task object into repository
124
        try {
125
            $this->taskRepository->save($task);
126
        } catch (TaskCannotBeSavedException $e) {
127
            throw $e;
128
        }
129
130
        // Return Task object
131
        return $task;
132
    }
133
134
    /**
135
     * Update Task's status to remaining
136
     *
137
     * @param string $taskId Task ID
138
     *
139
     * @return Task
140
     * @throws TaskNotFoundException
141
     * @throws TaskCannotBeSavedException
142
     */
143
    public function redoTask(string $taskId) : Task
144
    {
145
        // Try to find Task object from repository
146
        try {
147
            $task = $this->taskRepository->find($taskId);
148
        } catch (TaskNotFoundException $e) {
149
            throw $e;
150
        }
151
152
        // Set Task's status to remaining
153
        $task->setStatus(Task::STATUS_REMAINING);
154
155
        // Then try to save Task object into repository
156
        try {
157
            $this->taskRepository->save($task);
158
        } catch (TaskCannotBeSavedException $e) {
159
            throw $e;
160
        }
161
162
        // Return Task object
163
        return $task;
164
    }
165
166
    /**
167
     * Update Task's data
168
     *
169
     * @param string $taskId Task ID
170
     * @param array  $data   Fields (name, status)
171
     *
172
     * @return Task
173
     * @throws TaskCannotBeSavedException
174
     * @throws TaskNotFoundException
175
     * @throws TaskNameIsAlreadyExistedException
176
     * @throws TaskNameIsEmptyException
177
     */
178
    public function editTask(string $taskId, array $data) : Task
179
    {
180
        // Try to find Task object from repository
181
        try {
182
            $task = $this->taskRepository->find($taskId);
183
        } catch (TaskNotFoundException $e) {
184
            throw $e;
185
        }
186
187
        // Update Task's name
188
        if (isset($data['name'])) {
189
            // Wait, we want to validate the name before set new Task's name
190
            try {
191
                $this->taskValidationService->validateName($data['name'], $taskId);
192
            } catch (TaskNameIsEmptyException | TaskNameIsAlreadyExistedException $e) {
193
                throw $e;
194
            }
195
196
            // It's ok, we set new name
197
            $task->setName($data['name']);
198
        }
199
200
201
        // Update Task's status
202
        if (isset($data['status'])) {
203
            $task->setStatus($data['status']);
204
        }
205
206
        // Save Task object into repository
207
        try {
208
            $this->taskRepository->save($task);
209
        } catch (TaskCannotBeSavedException $e) {
210
            throw $e;
211
        }
212
213
        // Return Task object
214
        return $task;
215
    }
216
217
218
    /**
219
     * Remove Task out of repository
220
     *
221
     * @param string $taskId Task ID
222
     *
223
     * @return void
224
     * @throws TaskCannotBeRemovedException
225
     * @throws TaskNotFoundException
226
     */
227
    public function removeTask($taskId)
228
    {
229
        // First we need to find the Task object
230
        try {
231
            $task = $this->taskRepository->find($taskId);
232
        } catch (TaskNotFoundException $e) {
233
            throw $e;
234
        }
235
236
        // Now we try to remove this Task out of repository
237
        try {
238
            $this->taskRepository->remove($task);
239
        } catch (TaskCannotBeRemovedException $e) {
240
            throw $e;
241
        }
242
    }
243
244
    /**
245
     * Remove all completed tasks from repository
246
     *
247
     * @return void
248
     * @throws TaskCannotBeRemovedException
249
     */
250
    public function cleanAllCompletedTasks()
251
    {
252
        try {
253
            $this->taskRepository->removeByStatus(Task::STATUS_COMPLETED);
254
        } catch (TaskCannotBeRemovedException $e) {
255
            throw $e;
256
        }
257
    }
258
}
259