pathToRepository = $pathToRepository; $this->load(); } public function sort(bool $asc = true): BookmarkRepository { usort($this->repository, function ($a, $b) use ($asc) { return $asc ? $a->addedAt <=> $b->addedAt : $b->addedAt <=> $a->addedAt; }); return $this; } public function filter(string $tag): BookmarkRepository { $this->repository = array_filter( $this->repository, fn($bookmark) => $bookmark->tag === $tag ); return $this; } public function find(string $id): ?Bookmark { $index = $this->findBookmarkIndex($id); return $this->repository[$index] ?? null; } public function add(Bookmark $bookmark): bool { $this->repository[] = $bookmark; return $this->save(); } public function update(Bookmark $bookmark): bool { $index = $this->findBookmarkIndex($bookmark->id); if ($index !== null) { $this->repository[$index] = $bookmark; return $this->save(); } return false; } public function delete(Bookmark $bookmark): bool { $index = $this->findBookmarkIndex($bookmark->id); if ($index !== null) { unset($this->repository[$index]); return $this->save(); } return false; } public function current(): mixed { return $this->repository[$this->position]; } public function key(): mixed { 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 findBookmarkIndex(string $id): ?int { foreach ($this->repository as $index => $bookmark) { if ($bookmark->id == $id) { return $index; } } return null; } 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}"); } while (($data = fgetcsv($fp)) !== FALSE) { $bookmark = new Bookmark(); $bookmark->id = $data[0]; $bookmark->url = $data[1]; $bookmark->title = $data[2]; $bookmark->tag = $data[3]; $bookmark->addedAt = $data[4]; $this->repository[] = $bookmark; } 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 $bookmark) { $success = $success && fputcsv($fp, [ $bookmark->id, $bookmark->url, $bookmark->title, $bookmark->tag, $bookmark->addedAt, ]) !== false; } fclose($fp); return $success; } }