New_Micro_Learning/backend/app/Modules/Taxonomy/Application/TaxonomyHierarchy.php

49 خطوط
1.5 KiB
PHP

<?php
namespace App\Modules\Taxonomy\Application;
use App\Modules\Taxonomy\Domain\TaxonomyNode;
use Illuminate\Validation\ValidationException;
final class TaxonomyHierarchy
{
public function assertValidParent(string $organizationId, string $taxonomyTypeId, ?string $parentId, ?string $movingNodeId = null): void
{
if ($parentId === null) {
return;
}
if ($parentId === $movingNodeId) {
$this->invalidParent();
}
$parent = TaxonomyNode::query()
->where('organization_id', $organizationId)
->where('taxonomy_type_id', $taxonomyTypeId)
->find($parentId);
if (! $parent) {
$this->invalidParent('The selected parent does not belong to this taxonomy.');
}
$visited = [];
$cursor = $parent;
while ($cursor !== null) {
if (isset($visited[$cursor->getKey()]) || $cursor->getKey() === $movingNodeId) {
$this->invalidParent('The selected parent would create a circular hierarchy.');
}
$visited[$cursor->getKey()] = true;
$cursor = $cursor->parent_id
? TaxonomyNode::query()->where('organization_id', $organizationId)->find($cursor->parent_id)
: null;
}
}
private function invalidParent(string $message = 'A taxonomy node cannot be its own parent.'): never
{
throw ValidationException::withMessages(['parentId' => [$message]]);
}
}