summaryrefslogtreecommitdiff
path: root/src/DTS/TodoRepository.php
diff options
context:
space:
mode:
Diffstat (limited to 'src/DTS/TodoRepository.php')
-rw-r--r--src/DTS/TodoRepository.php162
1 files changed, 162 insertions, 0 deletions
diff --git a/src/DTS/TodoRepository.php b/src/DTS/TodoRepository.php
new file mode 100644
index 0000000..5ec759f
--- /dev/null
+++ b/src/DTS/TodoRepository.php
@@ -0,0 +1,162 @@
+<?php
+
+declare(strict_types=1);
+
+namespace DTS;
+
+use DTS\Todo;
+
+class TodoRepository implements \Iterator
+{
+ private string $pathToRepository;
+
+ private array $repository = [];
+
+ private array $tags = [];
+
+ private int $position = 0;
+
+ function __construct(string $pathToRepository)
+ {
+ $this->pathToRepository = $pathToRepository;
+
+ $this->load();
+ }
+
+ public function sort(bool $asc = true): TodoRepository
+ {
+ usort($this->repository, function ($a, $b) use ($asc) {
+ return $asc ? $a->task <=> $b->task
+ : $b->task <=> $a->task;
+ });
+
+ return $this;
+ }
+
+ public function filter(string $tag): TodoRepository
+ {
+ $this->repository = array_filter(
+ $this->repository,
+ fn($todo) => $todo->tag === $tag
+ );
+
+ return $this;
+ }
+
+ public function find(string $id): ?Todo
+ {
+ return $this->repository[$id] ?? null;
+ }
+
+ public function add(Todo $todo): bool
+ {
+ $this->repository[] = $todo;
+
+ return $this->save();
+ }
+
+ public function update(Todo $todo): bool
+ {
+ if (array_key_exists($todo->id, $this->repository)) {
+ $this->repository[$todo->id] = $todo;
+
+ return $this->save();
+ }
+
+ return false;
+ }
+
+ public function delete(Todo $todo): bool
+ {
+ if (array_key_exists($todo->id, $this->repository)) {
+ unset($this->repository[$todo->id]);
+
+ return $this->save();
+ }
+
+ return false;
+ }
+
+ public function tags(): array
+ {
+ return $this->tags;
+ }
+
+ public function current()
+ {
+ return $this->repository[$this->position];
+ }
+
+ public function key()
+ {
+ return $this->position;
+ }
+
+ public function next(): void
+ {
+ ++$this->position;
+ }
+
+ public function rewind(): void
+ {
+ $this->position = 0;
+ }
+
+ public function valid(): bool
+ {
+ return isset($this->repository[$this->position]);
+ }
+
+ private function load(): void
+ {
+ if (!is_file($this->pathToRepository) || !is_readable($this->pathToRepository)) {
+ throw new \Exception("Unable to locate repository {$this->pathToRepository}");
+ }
+
+ if (($fp = fopen($this->pathToRepository, 'r')) === FALSE) {
+ throw new \Exception("Unable to read from repository {$this->pathToRepository}");
+ }
+
+ $id = 0;
+
+ while (($data = fgetcsv($fp)) !== FALSE) {
+ $todo = new Todo();
+
+ $todo->id = $id++;
+ $todo->task = $data[0];
+ $todo->tag = $data[1];
+ $todo->addedAt = $data[2];
+
+ $this->repository[] = $todo;
+
+ $this->tags[] = $todo->tag;
+ }
+
+ $this->tags = array_filter(array_unique($this->tags));
+
+ sort($this->tags);
+
+ fclose($fp);
+ }
+
+ private function save(): bool
+ {
+ if (($fp = fopen($this->pathToRepository, 'w')) === FALSE) {
+ throw new \Exception("Unable to open repository {$this->pathToRepository}");
+ }
+
+ $success = true;
+
+ foreach ($this->repository as $todo) {
+ $success = $success && fputcsv($fp, [
+ $todo->task,
+ $todo->tag,
+ $todo->addedAt,
+ ]) !== false;
+ }
+
+ fclose($fp);
+
+ return $success;
+ }
+}