Goal-Calibration/app/Node/UseCases/CreateNode.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');
}
}
}