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; } }