> */ public function all(): array { $items = $this->read(); usort( $items, static fn (array $left, array $right): int => strcmp( (string) ($right['created_at'] ?? ''), (string) ($left['created_at'] ?? '') ) ); return $items; } /** * @return array|null */ public function find(string $id): ?array { foreach ($this->read() as $item) { if ((string) ($item['id'] ?? '') === $id) { return $item; } } return null; } /** * @return array|null */ public function findConflict(string $username, string $email): ?array { $username = strtolower(trim($username)); $email = strtolower(trim($email)); foreach ($this->read() as $item) { $status = (string) ($item['status'] ?? 'pending'); if ($status === 'rejected') { continue; } if (strtolower((string) ($item['username'] ?? '')) === $username) { return $item; } if (strtolower((string) ($item['email'] ?? '')) === $email) { return $item; } } return null; } /** * @param array $payload * @return array */ public function create(array $payload): array { $items = $this->read(); $items[] = $payload; $this->write($items); return $payload; } /** * @param callable(array): array $mutator * @return array|null */ public function update(string $id, callable $mutator): ?array { $items = $this->read(); $updated = null; foreach ($items as $index => $item) { if ((string) ($item['id'] ?? '') !== $id) { continue; } $items[$index] = $mutator($item); $updated = $items[$index]; break; } if ($updated === null) { return null; } $this->write($items); return $updated; } /** * @return array> */ private function read(): array { if (!is_file($this->storagePath)) { return []; } $raw = file_get_contents($this->storagePath); if ($raw === false || trim($raw) === '') { return []; } $decoded = json_decode($raw, true); return is_array($decoded) ? array_values(array_filter($decoded, 'is_array')) : []; } /** * @param array> $items */ private function write(array $items): void { $directory = dirname($this->storagePath); if (!is_dir($directory)) { mkdir($directory, 0775, true); } file_put_contents( $this->storagePath, json_encode($items, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . PHP_EOL, LOCK_EX ); } }