public function execute(InputInterface $input, OutputInterface $output) { $session = $this->get('phpcr.session'); $file = $input->getArgument('file'); $pretty = $input->getOption('pretty'); $exportDocument = $input->getOption('document'); $dialog = $this->get('helper.question'); if (file_exists($file)) { $confirmed = true; if (false === $input->getOption('no-interaction')) { $confirmed = $dialog->ask($input, $output, new ConfirmationQuestion('File already exists, overwrite?')); } if (false === $confirmed) { return; } } $stream = fopen($file, 'w'); $absPath = $input->getArgument('absPath'); PathHelper::assertValidAbsolutePath($absPath); if (true === $exportDocument) { $session->exportDocumentView($absPath, $stream, $input->getOption('skip-binary'), $input->getOption('no-recurse')); } else { $session->exportSystemView($absPath, $stream, $input->getOption('skip-binary'), $input->getOption('no-recurse')); } fclose($stream); if ($pretty) { $xml = new \DOMDocument(1.0); $xml->load($file); $xml->preserveWhitespace = true; $xml->formatOutput = true; $xml->save($file); } }
public function execute(InputInterface $input, OutputInterface $output) { $session = $this->get('phpcr.session'); $file = $input->getArgument('file'); $parentAbsPath = $input->getArgument('parentAbsPath'); $uuidBehavior = $input->getOption('uuid-behavior'); if (!in_array($uuidBehavior, $this->uuidBehaviors)) { throw new \Exception(sprintf("The specified uuid behavior \"%s\" is invalid, you should use one of:\n%s", $uuidBehavior, ' - ' . implode("\n - ", $this->uuidBehaviors))); } if (!file_exists($file)) { throw new \InvalidArgumentException(sprintf('The file "%s" does not exist', $file)); } PathHelper::assertValidAbsolutePath($parentAbsPath); $uuidBehavior = constant('\\PHPCR\\ImportUUIDBehaviorInterface::IMPORT_UUID_' . strtoupper(str_replace('-', '_', $uuidBehavior))); $session->importXml($parentAbsPath, $file, $uuidBehavior); }
/** * Execute moving a single node */ 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); }
/** * {@inheritDoc} */ public function getNodes($paths) { $this->assertLoggedIn(); if (empty($paths)) { return array(); } $identifiers = array(); foreach ($paths as $path) { PathHelper::assertValidAbsolutePath($path); $identifiers[] = $this->getNodeIdentifierForPath($path); } return $this->getNodesByIdentifier($identifiers); }
/** * {@inheritDoc} */ public function getCandidates(Request $request) { $candidates = array(); $url = $request->getPathInfo(); foreach ($this->getPrefixes() as $prefix) { $candidates = array_unique(array_merge($candidates, $this->getCandidatesFor($url, $prefix))); } $locale = $this->determineLocale($url); if ($locale) { $url = substr($url, strlen($locale) + 1); foreach ($this->getPrefixes() as $prefix) { $candidates = array_unique(array_merge($candidates, $this->getCandidatesFor($url, $prefix))); } } // filter out things like double // or trailing / - this would trigger an exception on the document manager. foreach ($candidates as $key => $candidate) { if (!PathHelper::assertValidAbsolutePath($candidate, false, false)) { unset($candidates[$key]); } } return $candidates; }
/** * @dataProvider dataproviderInvalidAbsolutePaths */ public function testAssertInvalidAbsolutePathNoThrow($path, $destination = false) { $this->assertFalse(PathHelper::assertValidAbsolutePath($path, $destination, false)); }
/** * Checks if the path is absolute and valid, and properly urlencodes special characters * * This is to be used in the Davex headers. The XML requests can cope with unencoded stuff * * @param string $path to check * * @return string the cleaned path * * @throws RepositoryException If path is not absolute or invalid */ protected function encodeAndValidatePathForDavex($path) { PathHelper::assertValidAbsolutePath($path); $path = rawurlencode($path); // we encoded the whole path, need to rebuild slashes and parenthesis // this will not collide with %2F as % was encoded by rawurlencode $path = str_replace(array('%2F', '%5B', '%5D'), array('/', '[', ']'), $path); return $path; }
/** * @param string $name Name of the menu to load * @param array $options * @param bool $throw Whether to throw an exception if the menu is not * found or no valid menu. Returns false if $throw is false and there * is no menu at $name * * @return object|bool The menu root found with $name or false if $throw * is false and the menu was not found * * @throws \InvalidArgumentException Only if $throw is true throws this * exception if the name is empty or no menu found */ protected function find($name, array $options, $throw) { if (empty($name)) { if ($throw) { throw new \InvalidArgumentException('The menu name may not be empty'); } return false; } $dm = $this->getObjectManager(); $session = $dm->getPhpcrSession(); try { $path = PathHelper::absolutizePath($name, $this->getMenuRoot()); PathHelper::assertValidAbsolutePath($path, false, true, $session->getNamespacePrefixes()); } catch (RepositoryException $e) { if ($throw) { throw $e; } return false; } if ($this->getPrefetch() > 0) { try { if ($session instanceof Session && 0 < $session->getSessionOption(Session::OPTION_FETCH_DEPTH) && 0 === strncmp($path, $this->getMenuRoot(), strlen($this->getMenuRoot()))) { // we have jackalope with a fetch depth. prefetch all menu // nodes of all menues. $session->getNode($this->getMenuRoot(), $this->getPrefetch() + 1); } else { $session->getNode($path, $this->getPrefetch()); } } catch (PathNotFoundException $e) { if ($throw) { throw new \InvalidArgumentException(sprintf('The menu root "%s" does not exist.', $this->getMenuRoot())); } return false; } } $menu = $dm->find(null, $path); if (null === $menu) { if ($throw) { throw new \InvalidArgumentException(sprintf('The menu "%s" is not defined.', $name)); } return false; } if (!$menu instanceof NodeInterface) { if ($throw) { throw new \InvalidArgumentException("Menu at '{$name}' is not a valid menu node"); } return false; } return $menu; }