75 lines
2.1 KiB
PHP
75 lines
2.1 KiB
PHP
<?php
|
|
|
|
namespace App\Node\UseCases;
|
|
|
|
use App\Exceptions\BadRequestException;
|
|
use App\Node\Node;
|
|
use App\Node\CreateNodeDto;
|
|
use App\Node\NodeRepository;
|
|
use App\Text\TextRepository;
|
|
use DomainException;
|
|
|
|
class CreateNode
|
|
{
|
|
public function __construct(
|
|
private NodeRepository $nodeRepo,
|
|
private TextRepository $textRepo,
|
|
) {}
|
|
|
|
/**
|
|
* @throws BadRequestException
|
|
* @throws DomainException
|
|
*/
|
|
public function execute(CreateNodeRequest $request): Node
|
|
{
|
|
if ($request->textId === null) {
|
|
throw new BadRequestException('textId is required');
|
|
}
|
|
|
|
if ($request->title === null) {
|
|
throw new BadRequestException('title is required');
|
|
}
|
|
|
|
$textId = $request->textId;
|
|
$text = $this->textRepo->find($textId);
|
|
if ($text === null) {
|
|
throw new DomainException("Text with id: $textId doesnt exist");
|
|
}
|
|
if ($request->parentNodeId === null) {
|
|
$this->validateNoOtherRootNodeExists($textId);
|
|
return $this->nodeRepo->create(new CreateNodeDto(
|
|
text: $text,
|
|
title: $request->title,
|
|
parentNode: null,
|
|
));
|
|
}
|
|
$parentNodeId = $request->parentNodeId;
|
|
$parentNode = $this->nodeRepo->find($parentNodeId);
|
|
if ($parentNode === null) {
|
|
throw new DomainException("Node with id: $parentNodeId doesnt exist");
|
|
}
|
|
|
|
return $this->nodeRepo->create(new CreateNodeDto(
|
|
text: $text,
|
|
title: $request->title,
|
|
parentNode: $parentNode,
|
|
));
|
|
}
|
|
|
|
/**
|
|
* @throws DomainException
|
|
*/
|
|
private function validateNoOtherRootNodeExists(int $textId): void
|
|
{
|
|
$nodesOfText = $this->nodeRepo->findByTextId($textId);
|
|
$exists = array_find(
|
|
$nodesOfText,
|
|
function (Node $node) {
|
|
return $node->getParentNode() === null;
|
|
}
|
|
);
|
|
if ($exists) {
|
|
throw new DomainException('A root node already exists for this text');
|
|
}
|
|
}
|
|
}
|