public function moveSubtreeNodes(array $sourceNodeData, array $destinationNodeData)
{
$fromPathString = $sourceNodeData['path_string'];
/** @var $query \eZ\Publish\Core\Persistence\Database\SelectQuery */
$query = $this->handler->createSelectQuery();
$query->select($this->handler->quoteColumn('node_id'), $this->handler->quoteColumn('parent_node_id'), $this->handler->quoteColumn('path_string'), $this->handler->quoteColumn('path_identification_string'))->from($this->handler->quoteTable('ezcontentobject_tree'))->where($query->expr->like($this->handler->quoteColumn('path_string'), $query->bindValue($fromPathString . '%')));
$statement = $query->prepare();
$statement->execute();
$rows = $statement->fetchAll();
$oldParentPathString = implode('/', array_slice(explode('/', $fromPathString), 0, -2)) . '/';
$oldParentPathIdentificationString = implode('/', array_slice(explode('/', $sourceNodeData['path_identification_string']), 0, -1));
foreach ($rows as $row) {
// Prefixing ensures correct replacement when old parent is root node
$newPathString = str_replace('prefix' . $oldParentPathString, $destinationNodeData['path_string'], 'prefix' . $row['path_string']);
$newPathIdentificationString = str_replace('prefix' . $oldParentPathIdentificationString, $destinationNodeData['path_identification_string'] . '/', 'prefix' . $row['path_identification_string']);
$newParentId = $row['parent_node_id'];
if ($row['path_string'] === $fromPathString) {
$newParentId = (int) implode('', array_slice(explode('/', $newPathString), -3, 1));
}
/** @var $query \eZ\Publish\Core\Persistence\Database\UpdateQuery */
$query = $this->handler->createUpdateQuery();
$query->update($this->handler->quoteTable('ezcontentobject_tree'))->set($this->handler->quoteColumn('path_string'), $query->bindValue($newPathString))->set($this->handler->quoteColumn('path_identification_string'), $query->bindValue($newPathIdentificationString))->set($this->handler->quoteColumn('depth'), $query->bindValue(substr_count($newPathString, '/') - 2))->set($this->handler->quoteColumn('parent_node_id'), $query->bindValue($newParentId));
if ($destinationNodeData['is_hidden'] || $destinationNodeData['is_invisible']) {
// CASE 1: Mark whole tree as invisible if destination is invisible and/or hidden
$query->set($this->handler->quoteColumn('is_invisible'), $query->bindValue(1));
} elseif (!$sourceNodeData['is_hidden'] && $sourceNodeData['is_invisible']) {
// CASE 2: source is only invisible, we will need to re-calculate whole moved tree visibility
$query->set($this->handler->quoteColumn('is_invisible'), $query->bindValue($this->isHiddenByParent($newPathString, $rows) ? 1 : 0));
} else {
// CASE 3: keep invisible flags as is (source is either hidden or not hidden/invisible at all)
}
$query->where($query->expr->eq($this->handler->quoteColumn('node_id'), $query->bindValue($row['node_id'])));
$query->prepare()->execute();
}
}