Passed
Push — master ( 9fdafe...783d3e )
by Martin
02:30
created

Command::completeTask()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 20
rs 9.4285
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\Specification\TaskNameIsNotEmptySpecification;
12
use Todo\Domain\Specification\TaskNameIsUniqueSpecification;
13
use Todo\Domain\Task;
14
15
/**
16
 * Class Command
17
 *
18
 * @category None
19
 * @package  Todo\Application\Task
20
 * @author   Martin Pham <[email protected]>
21
 * @license  None http://
22
 * @link     None
23
 */
24
class Command
25
{
26
    /**
27
     * TaskRepository
28
     *
29
     * @var TaskRepositoryInterface
30
     */
31
    protected $taskRepository;
32
33
    /**
34
     * TaskFactory
35
     *
36
     * @var TaskFactory
37
     */
38
    protected $taskFactory;
39
40
    /**
41
     * Command constructor
42
     *
43
     * @param TaskRepositoryInterface $taskRepository Task Repository
44
     * @param TaskFactory             $taskFactory    Task Factory
45
     */
46
    public function __construct(
47
        TaskRepositoryInterface $taskRepository,
48
        TaskFactory $taskFactory
49
    ) {
50
        $this->taskRepository = $taskRepository;
51
        $this->taskFactory = $taskFactory;
52
    }
53
54
55
    /**
56
     * Add New Task
57
     *
58
     * @param string $name Name
59
     *
60
     * @return Task
61
     * @throws TaskCannotBeSavedException
62
     * @throws TaskNameIsAlreadyExistedException
63
     * @throws TaskNameIsEmptyException
64
     */
65
    public function addNewTask(string $name) : Task
66
    {
67
        try {
68
            $task = $this->taskFactory->createFromName($name);
69
        } catch (TaskNameIsEmptyException | TaskNameIsAlreadyExistedException $e) {
70
            throw $e;
71
        }
72
73
        $result = $this->taskRepository->save($task);
74
75
        if (!$result) {
76
            throw new TaskCannotBeSavedException(
77
                'Cannot save task into repository.'
78
            );
79
        }
80
81
        return $task;
82
    }
83
84
    /**
85
     * Complete Task
86
     *
87
     * @param string $taskId Task ID
88
     *
89
     * @return Task
90
     * @throws TaskNotFoundException
91
     * @throws TaskCannotBeSavedException
92
     */
93
    public function completeTask($taskId) : Task
94
    {
95
        try {
96
            $task = $this->taskRepository->find($taskId);
97
        } catch (TaskNotFoundException $e) {
98
            throw $e;
99
        }
100
101
        $task->setStatus(Task::STATUS_COMPLETED);
102
103
        $result = $this->taskRepository->save($task);
104
105
        if (!$result) {
106
            throw new TaskCannotBeSavedException(
107
                'Cannot save task into repository.'
108
            );
109
        }
110
111
        return $task;
112
    }
113
114
    /**
115
     * Redo Task
116
     *
117
     * @param string $taskId Task ID
118
     *
119
     * @return Task
120
     * @throws TaskNotFoundException
121
     * @throws TaskCannotBeSavedException
122
     */
123
    public function redoTask(string $taskId) : Task
124
    {
125
        try {
126
            $task = $this->taskRepository->find($taskId);
127
        } catch (TaskNotFoundException $e) {
128
            throw $e;
129
        }
130
131
        $task->setStatus(Task::STATUS_REMAINING);
132
133
        $result = $this->taskRepository->save($task);
134
135
        if (!$result) {
136
            throw new TaskCannotBeSavedException(
137
                'Cannot save task into repository.'
138
            );
139
        }
140
141
        return $task;
142
    }
143
144
    /**
145
     * EditTask
146
     *
147
     * @param string $taskId ID
148
     * @param array  $data   Field
149
     *
150
     * @return Task
151
     * @throws TaskCannotBeSavedException
152
     * @throws TaskNotFoundException
153
     * @throws TaskNameIsAlreadyExistedException
154
     * @throws TaskNameIsEmptyException
155
     */
156
    public function editTask(string $taskId, array $data) : Task
157
    {
158
        try {
159
            $task = $this->taskRepository->find($taskId);
160
        } catch (TaskNotFoundException $e) {
161
            throw $e;
162
        }
163
164
        if (isset($data['name'])) {
165
            $emptyNameValidator = new TaskNameIsNotEmptySpecification();
166
            if (!$emptyNameValidator->isSatisfiedBy($data['name'])) {
167
                throw new TaskNameIsEmptyException("Task's name should not be empty.");
168
            }
169
170
            $uniqueNameValidator = new TaskNameIsUniqueSpecification(
171
                $this->taskRepository
172
            );
173
            if (!$uniqueNameValidator->isSatisfiedBy($data['name'], $taskId)) {
174
                throw new TaskNameIsAlreadyExistedException(
175
                    "Task's name {$data['name']} is already existed"
176
                );
177
            }
178
179
180
            $task->setName($data['name']);
181
        }
182
183
184
185
        if (isset($data['status'])) {
186
            $task->setStatus($data['status']);
187
        }
188
189
        $result = $this->taskRepository->save($task);
190
191
        if (!$result) {
192
            throw new TaskCannotBeSavedException(
193
                'Cannot save task into repository.'
194
            );
195
        }
196
197
        return $task;
198
    }
199
200
201
    /**
202
     * RemoveTask
203
     *
204
     * @param string $taskId ID
205
     *
206
     * @return void
207
     * @throws TaskCannotBeRemovedException
208
     * @throws TaskNotFoundException
209
     */
210
    public function removeTask($taskId)
211
    {
212
        try {
213
            $task = $this->taskRepository->find($taskId);
214
        } catch (TaskNotFoundException $e) {
215
            throw $e;
216
        }
217
218
        $result = $this->taskRepository->remove($task);
219
220
        if (!$result) {
221
            throw new TaskCannotBeRemovedException(
222
                'Cannot remove task(s) from repository.'
223
            );
224
        }
225
    }
226
227
    /**
228
     * CleanAllCompletedTasks
229
     *
230
     * @return void
231
     * @throws TaskCannotBeRemovedException
232
     */
233
    public function cleanAllCompletedTasks()
234
    {
235
        $result = $this->taskRepository->removeByStatus(Task::STATUS_COMPLETED);
236
237
        if (!$result) {
238
            throw new TaskCannotBeRemovedException(
239
                'Cannot remove task(s) from repository.'
240
            );
241
        }
242
    }
243
}
244