mvc: partially fix container field cloning, closes https://github.com/opnsense/core/issues/7521

While cloning model fields, the identifier for these new fields should also be set, which is currently being arranged in the ArrayField->add() method.
This commit makes sure we set the identifiers for one level below the array field type, which is good enough for current implementations, eventually this should be a recursive action or needs a way to push the identifiers directly on clone.

re-arrange the code a bit as well to remove the need for the $new_record array.
This commit is contained in:
Ad Schellevis 2024-06-22 11:16:54 +02:00
parent de1f9a0852
commit cfd7dca5ec

View File

@ -118,8 +118,17 @@ class ArrayField extends BaseField
*/
public function add()
{
$new_record = array();
$nodeUUID = $this->generateUUID();
$container_node = $this->newContainerField($this->__reference . "." . $nodeUUID, $this->internalXMLTagName);
$template_ref = $this->internalTemplateNode->__reference;
foreach ($this->internalTemplateNode->iterateItems() as $key => $node) {
$new_node = clone $node;
$new_node->setInternalReference($container_node->__reference . "." . $key);
$new_node->applyDefault();
$new_node->setChanged();
$container_node->addChildNode($key, $new_node);
if ($node->isContainer()) {
foreach ($node->iterateRecursiveItems() as $subnode) {
if (is_a($subnode, "OPNsense\\Base\\FieldTypes\\ArrayField")) {
@ -127,18 +136,19 @@ class ArrayField extends BaseField
throw new \Exception("Unsupported copy, Array doesn't support nesting.");
}
}
}
$new_record[$key] = clone $node;
}
$nodeUUID = $this->generateUUID();
$container_node = $this->newContainerField($this->__reference . "." . $nodeUUID, $this->internalXMLTagName);
foreach ($new_record as $key => $node) {
// initialize field with new internal id and defined default value
$node->setInternalReference($container_node->__reference . "." . $key);
$node->applyDefault();
$node->setChanged();
$container_node->addChildNode($key, $node);
/**
* XXX: incomplete, only supports one nesting level of container fields. In the long run we probably
* should refactor the add() function to push identifiers differently.
*/
foreach ($node->iterateItems() as $subkey => $subnode) {
$new_subnode = clone $subnode;
$new_subnode->setInternalReference($new_node->__reference . "." . $subkey);
$new_subnode->applyDefault();
$new_subnode->setChanged();
$new_node->addChildNode($subkey, $new_subnode);
}
}
}
// make sure we have a UUID on repeating child items