Jackalope\Transport\DoctrineDBAL\Client::moveNode PHP Method

moveNode() protected method

Execute moving a single node
protected moveNode ( $srcAbsPath, $dstAbsPath )
    protected function moveNode($srcAbsPath, $dstAbsPath)
    {
        $this->assertLoggedIn();
        PathHelper::assertValidAbsolutePath($srcAbsPath, false, true, $this->getNamespacePrefixes());
        PathHelper::assertValidAbsolutePath($dstAbsPath, true, true, $this->getNamespacePrefixes());
        if (!$this->pathExists($srcAbsPath)) {
            throw new PathNotFoundException("Source path '{$srcAbsPath}' not found");
        }
        if ($this->getSystemIdForNode($dstAbsPath)) {
            throw new ItemExistsException("Cannot move '{$srcAbsPath}' to '{$dstAbsPath}' because destination node already exists.");
        }
        if (!$this->getSystemIdForNode(PathHelper::getParentPath($dstAbsPath))) {
            throw new PathNotFoundException("Parent of the destination path '" . $dstAbsPath . "' has to exist.");
        }
        $query = 'SELECT path, id FROM phpcr_nodes WHERE path LIKE ? OR path = ? AND workspace_name = ? ' . $this->getConnection()->getDatabasePlatform()->getForUpdateSQL();
        $stmt = $this->getConnection()->executeQuery($query, array($srcAbsPath . '/%', $srcAbsPath, $this->workspaceName));
        /*
         * TODO: https://github.com/jackalope/jackalope-doctrine-dbal/pull/26/files#L0R1057
         * the other thing i wonder: can't you do the replacement inside sql instead of loading and then storing
         * the node? this will be extremely slow for a large set of nodes. i think you should use query builder here
         * rather than raw sql, to make it work on a maximum of platforms.
         *
         * can you try to do this please? if we don't figure out how to do it, at least fix the where criteria, and
         * we can ask the doctrine community how to do the substring operation.
         * http://stackoverflow.com/questions/8619421/correct-syntax-for-doctrine2s-query-builder-substring-helper-method
         */
        $query = "UPDATE phpcr_nodes SET ";
        $updatePathCase = "path = CASE ";
        $updateParentCase = "parent = CASE ";
        $updateLocalNameCase = "local_name = CASE ";
        $updateSortOrderCase = "sort_order = CASE ";
        $updateDepthCase = "depth = CASE ";
        // TODO: Find a better way to do this
        // Calculate CAST type for CASE statement
        switch ($this->getConnection()->getDatabasePlatform()->getName()) {
            case 'pgsql':
                $intType = 'integer';
                break;
            case 'mysql':
                $intType = 'unsigned';
                break;
            default:
                $intType = 'integer';
        }
        $i = 0;
        $values = $ids = array();
        $srcAbsPathPattern = '/^' . preg_quote($srcAbsPath, '/') . '/';
        while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
            $values[':id' . $i] = $row['id'];
            $values[':path' . $i] = preg_replace($srcAbsPathPattern, $dstAbsPath, $row['path'], 1);
            $values[':parent' . $i] = PathHelper::getParentPath($values[':path' . $i]);
            $values[':depth' . $i] = PathHelper::getPathDepth($values[':path' . $i]);
            $updatePathCase .= "WHEN id = :id" . $i . " THEN :path" . $i . " ";
            $updateParentCase .= "WHEN id = :id" . $i . " THEN :parent" . $i . " ";
            $updateDepthCase .= "WHEN id = :id" . $i . " THEN CAST(:depth" . $i . " AS " . $intType . ") ";
            if ($srcAbsPath === $row['path']) {
                $values[':localname' . $i] = PathHelper::getNodeName($values[':path' . $i]);
                $updateLocalNameCase .= "WHEN id = :id" . $i . " THEN :localname" . $i . " ";
                $updateSortOrderCase .= "WHEN id = :id" . $i . " THEN (SELECT * FROM ( SELECT MAX(x.sort_order) + 1 FROM phpcr_nodes x WHERE x.parent = :parent" . $i . ") y) ";
            }
            $ids[] = $row['id'];
            $i++;
        }
        if (!$i) {
            return;
        }
        $ids = implode($ids, ',');
        $updateLocalNameCase .= "ELSE local_name END, ";
        $updateSortOrderCase .= "ELSE sort_order END ";
        $query .= $updatePathCase . "END, " . $updateParentCase . "END, " . $updateDepthCase . "END, " . $updateLocalNameCase . $updateSortOrderCase;
        $query .= "WHERE id IN (" . $ids . ")";
        try {
            $this->getConnection()->executeUpdate($query, $values);
        } catch (DBALException $e) {
            throw new RepositoryException("Unexpected exception while moving node from {$srcAbsPath} to {$dstAbsPath}", $e->getCode(), $e);
        }
        $this->cleanIdentifierCache($srcAbsPath);
    }