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]]); } }