eZ\Publish\Core\Persistence\Legacy\Content\Location\Handler::copySubtree PHP Method

copySubtree() public method

Performs a deep copy of the location identified by $sourceId and all of its child locations, copying the most recent published content object for each location to a new content object without any additional version information. Relations are not copied. URLs are not touched at all.
public copySubtree ( mixed $sourceId, mixed $destinationParentId ) : eZ\Publish\SPI\Persistence\Content\Location
$sourceId mixed
$destinationParentId mixed
return eZ\Publish\SPI\Persistence\Content\Location the newly created Location.
    public function copySubtree($sourceId, $destinationParentId)
    {
        $children = $this->locationGateway->getSubtreeContent($sourceId);
        $destinationParentData = $this->locationGateway->getBasicNodeData($destinationParentId);
        $defaultObjectStates = $this->getDefaultContentStates();
        $contentMap = array();
        $locationMap = array($children[0]['parent_node_id'] => array('id' => $destinationParentId, 'hidden' => (bool) $destinationParentData['is_hidden'], 'invisible' => (bool) $destinationParentData['is_invisible'], 'path_identification_string' => $destinationParentData['path_identification_string']));
        $locations = array();
        foreach ($children as $child) {
            $locations[$child['contentobject_id']][$child['node_id']] = true;
        }
        $time = time();
        $mainLocations = array();
        $mainLocationsUpdate = array();
        foreach ($children as $index => $child) {
            // Copy content
            if (!isset($contentMap[$child['contentobject_id']])) {
                $content = $this->contentHandler->copy($child['contentobject_id'], $child['contentobject_version']);
                $this->setContentStates($content, $defaultObjectStates);
                $content = $this->contentHandler->publish($content->versionInfo->contentInfo->id, $content->versionInfo->contentInfo->currentVersionNo, new MetadataUpdateStruct(array('publicationDate' => $time, 'modificationDate' => $time)));
                $contentMap[$child['contentobject_id']] = $content->versionInfo->contentInfo->id;
            }
            $createStruct = $this->locationMapper->getLocationCreateStruct($child);
            $createStruct->contentId = $contentMap[$child['contentobject_id']];
            $parentData = $locationMap[$child['parent_node_id']];
            $createStruct->parentId = $parentData['id'];
            $createStruct->invisible = $createStruct->hidden || $parentData['hidden'] || $parentData['invisible'];
            $pathString = explode('/', $child['path_identification_string']);
            $pathString = end($pathString);
            $createStruct->pathIdentificationString = strlen($pathString) > 0 ? $parentData['path_identification_string'] . '/' . $pathString : null;
            // Use content main location if already set, otherwise create location as main
            if (isset($mainLocations[$child['contentobject_id']])) {
                $createStruct->mainLocationId = $locationMap[$mainLocations[$child['contentobject_id']]]['id'];
            } else {
                $createStruct->mainLocationId = true;
                $mainLocations[$child['contentobject_id']] = $child['node_id'];
                // If needed mark for update
                if (isset($locations[$child['contentobject_id']][$child['main_node_id']]) && count($locations[$child['contentobject_id']]) > 1 && $child['node_id'] !== $child['main_node_id']) {
                    $mainLocationsUpdate[$child['contentobject_id']] = $child['main_node_id'];
                }
            }
            $newLocation = $this->create($createStruct);
            $locationMap[$child['node_id']] = array('id' => $newLocation->id, 'hidden' => $newLocation->hidden, 'invisible' => $newLocation->invisible, 'path_identification_string' => $newLocation->pathIdentificationString);
            if ($index === 0) {
                $copiedSubtreeRootLocation = $newLocation;
            }
        }
        // Update main locations
        foreach ($mainLocationsUpdate as $contentId => $mainLocationId) {
            $this->changeMainLocation($contentMap[$contentId], $locationMap[$mainLocationId]['id']);
        }
        // If subtree root is main location for its content, update subtree section to the one of the
        // parent location content
        $subtreeRootContentInfo = $this->contentHandler->loadContentInfo($copiedSubtreeRootLocation->contentId);
        if ($subtreeRootContentInfo->mainLocationId === $copiedSubtreeRootLocation->id) {
            $this->setSectionForSubtree($copiedSubtreeRootLocation->id, $this->contentHandler->loadContentInfo($this->load($destinationParentId)->contentId)->sectionId);
        }
        return $copiedSubtreeRootLocation;
    }