diff --git a/app/Node/JsonNodeRepository.php b/app/Node/JsonNodeRepository.php new file mode 100644 index 0000000..a466bc0 --- /dev/null +++ b/app/Node/JsonNodeRepository.php @@ -0,0 +1,129 @@ +filePath = __DIR__.'/../../data/nodes.json'; + } + + public function create(CreateNodeDto $dto): Node + { + $nodes = $this->readNodes(); + $id = $this->getNextId($nodes); + + $nodes[] = [ + 'id' => $id, + 'title' => $dto->title, + 'textId' => $dto->text->getId(), + 'parentNodeId' => $dto->parentNode?->getId(), + ]; + + $this->writeNodes($nodes); + + return new Node( + id: $id, + title: $dto->title, + text: $dto->text, + parentNode: $dto->parentNode, + ); + } + + public function find(int $id): ?Node + { + $nodes = $this->readNodes(); + + foreach ($nodes as $data) { + if ($data['id'] === $id) { + return $this->hydrateNode($data, $nodes); + } + } + + return null; + } + + /** + * @return Node[] + */ + public function findByTextId(int $id): array + { + $nodes = $this->readNodes(); + + $matching = array_filter( + $nodes, + fn(array $data) => $data['textId'] === $id + ); + + return array_values(array_map( + fn(array $data) => $this->hydrateNode($data, $nodes), + $matching + )); + } + + private function hydrateNode(array $data, array $allNodes): Node + { + $text = $this->textRepository->find($data['textId']); + + $parentNode = null; + if ($data['parentNodeId'] !== null) { + foreach ($allNodes as $parentData) { + if ($parentData['id'] === $data['parentNodeId']) { + $parentNode = $this->hydrateNode($parentData, $allNodes); + break; + } + } + } + + return new Node( + id: $data['id'], + title: $data['title'], + text: $text, + parentNode: $parentNode, + ); + } + + private function readNodes(): array + { + if (!file_exists($this->filePath)) { + return []; + } + + $content = file_get_contents($this->filePath); + + return json_decode($content, true) ?? []; + } + + private function writeNodes(array $nodes): void + { + file_put_contents( + $this->filePath, + json_encode($nodes, JSON_PRETTY_PRINT) + ); + } + + private function getNextId(array $nodes): int + { + if (empty($nodes)) { + return 1; + } + + $maxId = 0; + foreach ($nodes as $node) { + if ($node['id'] > $maxId) { + $maxId = $node['id']; + } + } + + return $maxId + 1; + } +}