diff --git a/Classes/Package.php b/Classes/Package.php index 72fbcad..c50300d 100644 --- a/Classes/Package.php +++ b/Classes/Package.php @@ -12,6 +12,8 @@ */ class Package extends BasePackage { + private const NODE_TYPE_IDENTIFIER_MIXIN = 'Neos.Form.Builder:IdentifierMixin'; + /** * @param Bootstrap $bootstrap The current bootstrap * @return void @@ -20,24 +22,53 @@ public function boot(Bootstrap $bootstrap) { $dispatcher = $bootstrap->getSignalSlotDispatcher(); - $dispatcher->connect(Node::class, 'nodePropertyChanged', function (NodeInterface $node, $propertyName, $_, $newValue) use ($bootstrap) { - if ($propertyName !== 'identifier' || empty($newValue) || !$node->getNodeType()->isOfType('Neos.Form.Builder:IdentifierMixin')) { + $dispatcher->connect(Node::class, 'nodePropertyChanged', function (NodeInterface $node, $propertyName, $_, $newValue) { + if ($propertyName !== 'identifier' || empty($newValue) || !$node->getNodeType()->isOfType(self::NODE_TYPE_IDENTIFIER_MIXIN)) { return; } - /** @noinspection PhpUndefinedMethodInspection */ - $flowQuery = (new FlowQuery([$node]))->context(['invisibleContentShown' => true, 'removedContentShown' => true, 'inaccessibleContentShown' => true]); - $possibleIdentifier = $initialIdentifier = $newValue; - $i = 1; - /** @noinspection PhpUndefinedMethodInspection */ - while ($flowQuery - ->closest('[instanceof Neos.Form.Builder:NodeBasedForm]') - // [identifier=".."] matches the Form Element identifier, [_identiier!="..."] excludes the current node - ->find(sprintf('[instanceof Neos.Form.Builder:IdentifierMixin][identifier="%s"][_identifier!="%s"]', $possibleIdentifier, $node->getIdentifier())) - ->count() > 0) { - $possibleIdentifier = $initialIdentifier . '-' . $i++; + $this->setUniqueFormElementIdentifier($node, $newValue); + }); + + $dispatcher->connect(Node::class, 'nodeAdded', function (NodeInterface $node) { + try { + $identifier = $node->getProperty('identifier'); + + if (empty($identifier) || !$node->getNodeType()->isOfType(self::NODE_TYPE_IDENTIFIER_MIXIN)) { + return; + } + } catch (\Neos\ContentRepository\Exception\NodeException $e) { + return; } - $node->setProperty('identifier', $possibleIdentifier); + + $this->setUniqueFormElementIdentifier($node, $identifier); }); } + + /** + * @param NodeInterface $node + * @param string $identifier + * @throws \Neos\Eel\Exception + */ + private function setUniqueFormElementIdentifier(NodeInterface $node, string $identifier): void + { + /** @noinspection PhpUndefinedMethodInspection */ + $flowQuery = (new FlowQuery([$node]))->context([ + 'invisibleContentShown' => true, + 'removedContentShown' => true, + 'inaccessibleContentShown' => true + ]); + $possibleIdentifier = $identifier; + $i = 1; + /** @noinspection PhpUndefinedMethodInspection */ + while ($flowQuery + ->closest('[instanceof Neos.Form.Builder:NodeBasedForm]') + // [identifier=".."] matches the Form Element identifier, [_identiier!="..."] excludes the current node + ->find(sprintf('[instanceof %s][identifier="%s"][_identifier!="%s"]', + self::NODE_TYPE_IDENTIFIER_MIXIN ,$possibleIdentifier, $node->getIdentifier())) + ->count() > 0) { + $possibleIdentifier = $identifier . '-' . $i++; + } + $node->setProperty('identifier', $possibleIdentifier); + } }