129 lines
2.9 KiB
PHP
129 lines
2.9 KiB
PHP
<?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;
|
|
}
|
|
}
|