json node repo

This commit is contained in:
Yisroel Baum 2026-04-17 11:30:17 +03:00
parent 38d06fce43
commit a092ee8840
Signed by: yisroelbaum
GPG key ID: 0FA60884F75520A9

View file

@ -0,0 +1,129 @@
<?php
namespace App\Node;
use App\Node\Node;
use App\Node\CreateNodeDto;
use App\Node\NodeRepository;
use App\Text\TextRepository;
class JsonNodeRepository implements NodeRepository
{
private string $filePath;
public function __construct(
private TextRepository $textRepository,
) {
$this->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;
}
}