Skip to content
This repository has been archived by the owner on Sep 16, 2021. It is now read-only.

Commit

Permalink
Refactored to support multiple nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
dantleech committed Jun 2, 2016
1 parent a938192 commit 10f0b7e
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 309 deletions.
88 changes: 43 additions & 45 deletions Repository/AbstractPhpcrRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,20 @@
namespace Symfony\Cmf\Component\Resource\Repository;

use DTL\Glob\FinderInterface;
use Puli\Repository\Api\ChangeStream\VersionList;
use Puli\Repository\Api\NoVersionFoundException;
use Puli\Repository\Api\ResourceNotFoundException;
use Puli\Repository\Api\ResourceRepository;
use Puli\Repository\Api\UnsupportedLanguageException;
use Puli\Repository\Resource\Collection\ArrayResourceCollection;
use Webmozart\Assert\Assert;
use Webmozart\PathUtil\Path;
use Puli\Repository\AbstractRepository;
use Symfony\Cmf\Component\Resource\Repository\Api\EditableRepository;

/**
* Abstract repository for both PHPCR and PHPCR-ODM repositories.
*
* @author Daniel Leech <[email protected]>
*/
abstract class AbstractPhpcrRepository implements ResourceRepository, CmfEditableRepository
abstract class AbstractPhpcrRepository extends AbstractRepository implements ResourceRepository, EditableRepository
{
/**
* Base path from which to serve nodes / nodes.
Expand Down Expand Up @@ -73,6 +72,39 @@ public function find($query, $language = 'glob')
return $this->buildCollection($nodes);
}

/**
* {@inheritdoc}
*/
public function remove($query, $language = 'glob')
{
$this->failUnlessGlob($language);
Assert::notEq('', trim($query, '/'), 'The root directory cannot be deleted.');
$nodes = $this->finder->find($this->resolvePath($query));

// delegate remove nodes to the implementation
$this->removeNodes($nodes);
}

/**
* {@inheritdoc}
*/
public function move($sourceQuery, $targetPath, $language = 'glob')
{
$this->failUnlessGlob($language);
Assert::notEq('', trim($sourceQuery, '/'), 'The root directory cannot be moved.');
$nodes = $this->finder->find($this->resolvePath($query));

$this->moveNodes($nodes, $sourceQuery, $targetPath);
}

/**
* {@inheritdoc}
*/
public function clear()
{
throw new \BadMethodCallException('Clear not supported');
}

/**
* Return the path with the basePath prefix
* if it has been set.
Expand All @@ -83,8 +115,7 @@ public function find($query, $language = 'glob')
*/
protected function resolvePath($path)
{
Assert::stringNotEmpty($path, 'The path must be a non-empty string. Got: %s');
Assert::startsWith($path, '/', 'The path %s is not absolute.');
$path = $this->sanitizePath($path);

if ($this->basePath) {
$path = $this->basePath.$path;
Expand Down Expand Up @@ -117,49 +148,16 @@ protected function unresolvePath($path)
abstract protected function buildCollection(array $nodes);

/**
* {@inheritdoc}
*/
public function getVersions($path)
{
try {
return new VersionList($path, [$this->get($path)]);
} catch (ResourceNotFoundException $e) {
throw NoVersionFoundException::forPath($path, $e);
}
}

/**
* {@inheritdoc}
*/
public function remove($query, $language = 'glob')
{
$this->failUnlessGlob($language);

Assert::startsWith($query, '/', 'The target path %s is not absolute.');
Assert::notEq('', trim($query, '/'), 'The root directory cannot be deleted.');
$resolvedPath = $this->resolvePath($query);

return $this->removeResource($resolvedPath);
}

/**
* Validate a language is usable to search in repositories.
* Rmeove the given nodes.
*
* @param string $language
* @param NodeInterface[]
*/
protected function failUnlessGlob($language)
{
if ('glob' !== $language) {
throw UnsupportedLanguageException::forLanguage($language);
}
}
abstract protected function removeNodes($nodes);

/**
* Will finally remove the resource.
*
* @param string $sourcePath
* Move the given nodes.
*
* @return int
* @param NodeInterface[]
*/
abstract protected function removeResource($sourcePath);
abstract protected function moveNodes($nodes, $sourceQuery, $targetPath);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,28 @@
* file that was distributed with this source code.
*/

namespace Symfony\Cmf\Component\Resource\Repository;
namespace Symfony\Cmf\Component\Resource\Repository\Api;

use InvalidArgumentException;
use Puli\Repository\Api\EditableRepository;
use Puli\Repository\Api\UnsupportedLanguageException;

/**
* CMF own interface to add the move() method.
* Extends the Puli editable repository to implement the as-of-yet not
* implemented features.
*
* @author Maximilian Berghoff <[email protected]>
*/
interface CmfEditableRepository extends EditableRepository
interface EditableRepository extends EditableRepository
{
/**
* Moves a resource inside the repository.
* Move all resources found by $sourceQuery to the target (parent) path.
*
* @param string $sourceQuery The Path of the current document.
* @param string $targetPath The parent path of the destination.
* @param string $sourceQuery
* @param string $targetPath
* @param string $language
*
* @return int
*
* @throws InvalidArgumentException If the sourceQuery is invalid.
* @throws InvalidArgumentException If the resource can not be moved to the targetPath.
* @throws UnsupportedLanguageException If the language is not supported.
*/
public function move($sourceQuery, $targetPath, $language = 'glob');
Expand Down
69 changes: 23 additions & 46 deletions Repository/PhpcrOdmRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,9 @@
use Doctrine\ODM\PHPCR\DocumentManagerInterface;
use DTL\Glob\Finder\PhpcrOdmTraversalFinder;
use DTL\Glob\FinderInterface;
use IteratorAggregate;
use Puli\Repository\Api\ResourceCollection;
use Puli\Repository\Api\ResourceNotFoundException;
use Puli\Repository\Resource\Collection\ArrayResourceCollection;
use Symfony\Cmf\Component\Resource\Repository\Resource\PhpcrOdmResource;
use Webmozart\Assert\Assert;

class PhpcrOdmRepository extends AbstractPhpcrRepository
{
Expand Down Expand Up @@ -89,7 +86,7 @@ public function contains($selector, $language = 'glob')
*/
public function findByTag($tag)
{
throw new \Exception('Get by tag not currently supported');
throw new \Exception('Find by tag not supported');
}

/**
Expand Down Expand Up @@ -127,61 +124,41 @@ protected function buildCollection(array $documents)
/**
* {@inheritdoc}
*/
public function add($path, $resource)
protected function removeNodes($nodes)
{
Assert::startsWith($path, '/', 'Target path %s must be absolute.');

$resolvedPath = $this->resolvePath($path);

/** @var PhpcrOdmResource[] $resources */
$resources = $resource instanceof IteratorAggregate ? $resource : new ArrayResourceCollection([$resource]);
Assert::isInstanceOf($resources, ResourceCollection::class, 'The list should be of instance "ResourceCollection".');

foreach ($resources as $resource) {
Assert::isInstanceOf($resource, PhpcrOdmResource::class);
Assert::same($resolvedPath, $this->resolvePath($resource->getPath()));

$this->getManager()->persist($resource->getPayload());
foreach ($nodes as $node) {
$document = $this->getDocumentForNode($node);
$this->getManager()->remove($document);
}

$this->getManager()->flush();
}

/**
* {@inheritdoc}
*/
public function move($sourceQuery, $targetPath, $language = 'glob')
protected function moveNodes($nodes, $sourceQuery, $targetPath)
{
$this->failUnlessGlob($language);
Assert::notEq('', trim($sourceQuery, '/'), 'The root directory cannot be moved.');

$targetPath = $this->resolvePath($targetPath);
$sourcePath = $this->resolvePath($sourceQuery);

$document = $this->getManager()->find(null, $sourcePath);
if (null === $document) {
throw new \InvalidArgumentException(sprintf('No document found at %s ', $sourcePath));
}

$this->getManager()->move($document, $targetPath);
$this->doMoveNodes($nodes, $sourceQuery, $targetPath);
$this->getManager()->flush();
}

/**
* {@inheritdoc}
*/
public function clear()
private function doMoveNodes($nodes, $sourceQuery, $targetPath)
{
throw new \BadMethodCallException('Clear currently not supported');
if (1 === count($nodes) && current($nodes)->getPath() === $sourceQuery) {
$document = $this->getDocumentForNode(current($nodes));

return $this->getManager()->move($document, $targetPath);
}

foreach ($nodes as $node) {
$document = $this->getDocumentForNode($node);
$this->getManager()->move($document, $targetPath.'/'.$node->getName());
}
}

/**
* {@inheritdoc}
*/
protected function removeResource($sourcePath)
private function getDocumentForNode(NodeInterface $node)
{
$document = $this->getManager()->find(null, $sourcePath);
$this->getManager()->remove($document);
$this->getManager()->flush();
// the PHPCR node is already loaded so the document should always
// be found, even if it is unmanaged (it will be a
// GenericDocument).
return $this->getManager()->find(null, $node->getPath());
}
}
75 changes: 14 additions & 61 deletions Repository/PhpcrRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,10 @@

use DTL\Glob\Finder\PhpcrTraversalFinder;
use DTL\Glob\FinderInterface;
use InvalidArgumentException;
use IteratorAggregate;
use PHPCR\PathNotFoundException;
use PHPCR\SessionInterface;
use Puli\Repository\Api\ResourceCollection;
use Puli\Repository\Api\ResourceNotFoundException;
use Puli\Repository\Resource\Collection\ArrayResourceCollection;
use Symfony\Cmf\Component\Resource\Repository\Resource\PhpcrResource;
use Webmozart\Assert\Assert;

/**
* Resource repository for PHPCR.
Expand All @@ -31,14 +26,14 @@
class PhpcrRepository extends AbstractPhpcrRepository
{
/**
* @var ManagerRegistry
* @var SessionInterface
*/
private $session;

/**
* @param SessionInterface $session
* @param FinderInterface $finder
* @param string $basePath
* @param FinderInterface $finder
*/
public function __construct(SessionInterface $session, $basePath = null, FinderInterface $finder = null)
{
Expand Down Expand Up @@ -128,25 +123,10 @@ protected function buildCollection(array $nodes)
/**
* {@inheritdoc}
*/
public function add($path, $resource)
protected function removeNodes($nodes)
{
Assert::startsWith($path, '/', 'Target path %s must be absolute.');
Assert::notEq('', trim($path, '/'), 'The root directory cannot be created.');

$resolvedPath = $this->resolvePath($path);
try {
$parentNode = $this->session->getNode($resolvedPath);
} catch (PathNotFoundException $e) {
throw new InvalidArgumentException(sprintf('Parent node for "%s" does not exist', $path), null, $e);
}

/** @var PhpcrResource[] $resources */
$resources = $resource instanceof IteratorAggregate ? $resource : new ArrayResourceCollection([$resource]);
Assert::isInstanceOf($resources, ResourceCollection::class, 'The list should be of instance "ResourceCollection".');

foreach ($resources as $resource) {
Assert::isInstanceOf($resource, PhpcrResource::class);
$parentNode->addNode($resource->getName(), $resource->getPayloadType());
foreach ($nodes as $node) {
$node->remove();
}

$this->session->save();
Expand All @@ -155,47 +135,20 @@ public function add($path, $resource)
/**
* {@inheritdoc}
*/
public function move($sourceQuery, $targetPath, $language = 'glob')
protected function moveNodes($nodes, $sourceQuery, $targetPath)
{
$this->failUnlessGlob($language);
Assert::notEq('', trim($sourceQuery, '/'), 'The root directory cannot be moved.');

$targetPath = $this->resolvePath($targetPath);
$sourcePath = $this->resolvePath($sourceQuery);

try {
$this->session->move($sourcePath, $targetPath);
} catch (PathNotFoundException $e) {
throw new \InvalidArgumentException(
sprintf('Could not move PHPCR resource from "%s" to "%s"', $sourcePath, $targetPath),
null,
$e
);
}
$this->doMoveNodes($nodes, $sourceQuery, $targetPath);
$this->session->save();
}

/**
* {@inheritdoc}
*/
public function clear()
private function doMoveNodes($nodes, $sourceQuery, $targetPath)
{
throw new \BadMethodCallException('Clear currently not supported');
}
if (count($nodes) === 1 && current($nodes)->getPath() === $sourceQuery) {
return $this->session->move(current($nodes)->getPath(), $targetPath);
}

/**
* {@inheritdoc}
*/
protected function removeResource($sourcePath)
{
try {
$this->session->removeItem($sourcePath);
} catch (PathNotFoundException $e) {
throw new \InvalidArgumentException(
sprintf('Could not remove PHPCR resource at "%s"', $sourcePath),
null,
$e
);
foreach ($nodes as $node) {
$this->session->move($node->getPath(), $targetPath.'/'.$node->getName());
}
$this->session->save();
}
}
Loading

0 comments on commit 10f0b7e

Please sign in to comment.