src/Sulu/Component/DocumentManager/Subscriber/Behavior/VersionSubscriber.php
private function restoreNode(
        NodeInterface $node,
        NodeInterface $frozenNode,
        $contentPropertyPrefix,
        $systemPropertyPrefix
    ) {
        // remove the properties for the given language, so that values being added since the last version are removed
        foreach ($node->getProperties() as $property) {
            if ($this->isRestoreProperty($property->getName(), $contentPropertyPrefix, $systemPropertyPrefix)) {
                $property->remove();
            }
        }

        // set all the properties from the saved version to the node
        foreach ($frozenNode->getPropertiesValues() as $name => $value) {
            if ($this->isRestoreProperty($name, $contentPropertyPrefix, $systemPropertyPrefix)) {
                $node->setProperty($name, $value);
            }
        }

        /** @var NodeInterface $childNode */
        foreach ($frozenNode->getNodes() as $childNode) {
            // create new node if it not exists
            if (!$node->hasNode($childNode->getName())) {
                $newNode = $node->addNode($childNode->getName());
                $newNode->setMixins($childNode->getPropertyValueWithDefault('jcr:frozenMixinTypes', []));
            }

            $this->restoreNode(
                $node->getNode($childNode->getName()),
                $childNode,
                $contentPropertyPrefix,
                $systemPropertyPrefix
            );
        }

        // remove child-nodes which do not exists in frozen-node
        foreach ($node->getNodes() as $childNode) {
            if (OnParentVersionAction::COPY !== $childNode->getDefinition()->getOnParentVersion()
                || $frozenNode->hasNode($childNode->getName())
            ) {
                continue;
            }

            $childNode->remove();
        }
    }
private function restoreNode(
        NodeInterface $node,
        NodeInterface $frozenNode,
        $contentPropertyPrefix,
        $systemPropertyPrefix
    ) {
        // remove the properties for the given language, so that values being added since the last version are removed
        foreach ($node->getProperties() as $property) {
            if ($this->isRestoreProperty($property->getName(), $contentPropertyPrefix, $systemPropertyPrefix)) {
                $property->remove();
            }
        }

        // set all the properties from the saved version to the node
        foreach ($frozenNode->getPropertiesValues() as $name => $value) {
            if ($this->isRestoreProperty($name, $contentPropertyPrefix, $systemPropertyPrefix)) {
                $node->setProperty($name, $value);
            }
        }

        /** @var NodeInterface $childNode */
        foreach ($frozenNode->getNodes() as $childNode) {
            // create new node if it not exists
            if (!$node->hasNode($childNode->getName())) {
                $newNode = $node->addNode($childNode->getName());
                $newNode->setMixins($childNode->getPropertyValueWithDefault('jcr:frozenMixinTypes', []));
            }

            $this->restoreNode(
                $node->getNode($childNode->getName()),
                $childNode,
                $contentPropertyPrefix,
                $systemPropertyPrefix
            );
        }

        // remove child-nodes which do not exists in frozen-node
        foreach ($node->getNodes() as $childNode) {
            if (OnParentVersionAction::COPY !== $childNode->getDefinition()->getOnParentVersion()
                || $frozenNode->hasNode($childNode->getName())
            ) {
                continue;
            }

            $childNode->remove();
        }
    }
private function restoreNode ( NodeInterface $ node , NodeInterface $ frozenNode , $ contentPropertyPrefix , $ systemPropertyPrefix ) { // remove the properties for the given language, so that values being added since the last version are removed foreach ( $ node -> getProperties ( ) as $ property ) { if ( $ this -> isRestoreProperty ( $ property -> getName ( ) , $ contentPropertyPrefix , $ systemPropertyPrefix ) ) { $ property -> remove ( ) ; } } // set all the properties from the saved version to the node foreach ( $ frozenNode -> getPropertiesValues ( ) as $ name => $ value ) { if ( $ this -> isRestoreProperty ( $ name , $ contentPropertyPrefix , $ systemPropertyPrefix ) ) { $ node -> setProperty ( $ name , $ value ) ; } } /** @var NodeInterface $childNode */ foreach ( $ frozenNode -> getNodes ( ) as $ childNode ) { // create new node if it not exists if ( ! $ node -> hasNode ( $ childNode -> getName ( ) ) ) { $ newNode = $ node -> addNode ( $ childNode -> getName ( ) ) ; $ newNode -> setMixins ( $ childNode -> getPropertyValueWithDefault ( 'jcr:frozenMixinTypes' , [ ] ) ) ; } $ this -> restoreNode ( $ node -> getNode ( $ childNode -> getName ( ) ) , $ childNode , $ contentPropertyPrefix , $ systemPropertyPrefix ) ; } // remove child-nodes which do not exists in frozen-node foreach ( $ node -> getNodes ( ) as $ childNode ) { if ( OnParentVersionAction :: COPY !== $ childNode -> getDefinition ( ) -> getOnParentVersion ( ) || $ frozenNode -> hasNode ( $ childNode -> getName ( ) ) ) { continue ; } $ childNode -> remove ( ) ; } }
Restore given node with properties given from frozen-node.
Will be called recursive.

@param NodeInterface $node
@param NodeInterface $frozenNode
@param string $contentPropertyPrefix
@param string $systemPropertyPrefix
Restore given node with properties given from frozen - node . Will be called recursive .