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 d3353e3
Show file tree
Hide file tree
Showing 6 changed files with 193 additions and 140 deletions.
85 changes: 43 additions & 42 deletions Repository/AbstractPhpcrRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@
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 +75,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 +118,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 +151,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,30 @@
* 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
* @return void
*
* @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
87 changes: 87 additions & 0 deletions Repository/CompositeRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

use Puli\Repository\Api\ResourceRepository;
use Puli\Repository\Resource\Collection\ArrayResourceCollection;
use Puli\Repository\AbstractRepository;

class CompositeRepository extends AbstractRepository implements ResourceRepository
{
private $children = [];

public function mount($name, ResourceRepository $repository)
{
if (isset($this->children[$name])) {
throw new \InvalidArgumentException(sprintf(
'Repository of class "%s" has already been mounted at "%s"',
get_class($this->children[$path]),
$path
));
}

$this->children[$name] = $repository;
}

/**
* {@inheritDoc}
*/
public function get($path)
{
$path = $this->sanitizePath($path);
$child = substr($path, 1);
$child = substr($path, 0, strpos($path, '/'));

if (!isset($thos->children[$child])) {
throw new ResourceNotFoundException(sprintf(
'No repository mounted in composite repository with name "%s"',
$child
));
}

$path = substr($path, strlen($child) + 2);

return $this->children[$child]->get($path);
}

/**
* {@inheritDoc}
*/
public function getVersions($path)
{
}

/**
* {@inheritDoc}
*/
public function find($query, $language = 'glob')
{
}

/**
* {@inheritDoc}
*/
public function contains($query, $language = 'glob')
{
}
}

/**
* {@inheritDoc}
*/
public function hasChildren($path)
{
return false === empty($this->children);
}

/**
* {@inheritDoc}
*/
public function listChildren($path)
{
PathUtil::assertAht
if ($path === '/') {
return new ArrayResourceCollection($this->children);
}


}
}
66 changes: 23 additions & 43 deletions Repository/PhpcrOdmRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Puli\Repository\Resource\Collection\ArrayResourceCollection;
use Symfony\Cmf\Component\Resource\Repository\Resource\PhpcrOdmResource;
use Webmozart\Assert\Assert;
use PHPCR\Util\PathHelper;

class PhpcrOdmRepository extends AbstractPhpcrRepository
{
Expand Down Expand Up @@ -89,7 +90,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 +128,40 @@ 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());
}
}
Loading

0 comments on commit d3353e3

Please sign in to comment.