Skip to content

Commit

Permalink
Minor code cleanups, adding query-params based filtering
Browse files Browse the repository at this point in the history
  • Loading branch information
Ocramius committed Jun 11, 2013
1 parent 4b22b51 commit 6aa7319
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 26 deletions.
23 changes: 18 additions & 5 deletions src/ZfrRest/Mvc/Router/Http/Matcher/BaseSubPathMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,30 @@
*/
class BaseSubPathMatcher implements SubPathMatcherInterface
{
/**
* @var CollectionSubPathMatcher
*/
private $collectionMatcher;

/**
* @var AssociationSubPathMatcher
*/
private $associationMatcher;

/**
* Constructor.
*/
public function __construct()
{
$this->collectionMatcher = new CollectionSubPathMatcher();
$this->associationMatcher = new AssociationSubPathMatcher();
}

public function matchSubPath(
ResourceInterface $resource,
$subPath,
Request $request
) {
/**
* {@inheritDoc}
*/
public function matchSubPath(ResourceInterface $resource, $subPath, Request $request)
{
$path = trim($subPath, '/');

if (empty($path)) {
Expand Down
71 changes: 52 additions & 19 deletions src/ZfrRest/Mvc/Router/Http/Matcher/CollectionSubPathMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\Selectable;
use Traversable;
use Zend\Http\Request;
use Zend\Stdlib\ArrayUtils;
use ZfrRest\Mvc\Exception;
Expand All @@ -36,11 +37,11 @@
*/
class CollectionSubPathMatcher implements SubPathMatcherInterface
{
public function matchSubPath(
ResourceInterface $resource,
$subPath,
Request $request
) {
/**
* {@inheritDoc}
*/
public function matchSubPath(ResourceInterface $resource, $subPath, Request $request)
{
if (! $resource->isCollection()) {
return null;
}
Expand All @@ -66,35 +67,67 @@ public function matchSubPath(
);
}

/**
* Retrieves a single item in the collection by its identifier
*
* @param mixed $data
* @param array $identifierNames
* @param mixed $identifier
*
* @return mixed|null
*
* @throws \ZfrRest\Mvc\Exception\RuntimeException on composite identifiers (not yet supported)
*/
protected function findItem($data, array $identifierNames, $identifier)
{
if (count($identifierNames) > 1) {
// @todo Cannot match multiple identifiers for now
return null;
throw new RuntimeException(get_class($this) . ' is not able to handle composite identifiers');
}

if (!$data instanceof Selectable) {
if (! ($data instanceof \Traversable || is_array($data))) {
// @todo cannot match on non-selectables?
if (! $data instanceof Selectable) {
if (! ($data instanceof Traversable || is_array($data))) {
// Can only match selectable resources
return null;
}

$data = new ArrayCollection(ArrayUtils::iteratorToArray($data));
}

if (! $data instanceof Selectable) {
// @todo should probably also handle repositories with no Selectable API
return null;
}
$found = $data->matching(new Criteria(Criteria::expr()->eq(current($identifierNames), $identifier)));

return $data->matching(
new Criteria(Criteria::expr()->eq(current($identifierNames), $identifier))
)->first();
return $found->isEmpty() ? null : $found->first();
}

/**
* Filters the given resource by using the request object, then return the filtered subset
*
* @param ResourceInterface $resource
* @param Request $request
*
* @return ResourceInterface
*/
protected function filterAssociation(ResourceInterface $resource, Request $request)
{
// @todo add collection filtering via GET parameters
return $resource;
if (! $resource->isCollection()) {
// can only filter collections
return $resource;
}

$data = $resource->getMetadata();

if (! $data instanceof Selectable) {
return $resource;
}

$criteria = new Criteria();

// @todo do we really need this part? This filtering is not safe.
foreach ($request->getQuery() as $parameterName => $parameterValue) {
if ($resource->getMetadata()->getClassMetadata()->hasField($parameterName)) {
$criteria->expr()->eq($parameterName, $parameterValue);
}
}

return new Resource($data->matching($criteria), $resource->getMetadata());
}
}
25 changes: 23 additions & 2 deletions src/ZfrRest/Mvc/Router/Http/Matcher/SubPathMatch.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,33 @@
*/
class SubPathMatch
{
/**
* @var string|null
*/
public $matchedPath;

/**
* @var ResourceInterface|null
*/
public $matchedResource;

public function __construct(ResourceInterface $matchedResource = null, $matchedPath = null)
{
/**
* @var SubPathMatch|null
*/
public $previousMatch;

/**
* @param ResourceInterface|null $matchedResource
* @param string|null $matchedPath
* @param SubPathMatch|null $previousMatch
*/
public function __construct(
ResourceInterface $matchedResource = null,
$matchedPath = null,
SubPathMatch $previousMatch = null
) {
$this->matchedResource = $matchedResource;
$this->matchedPath = $matchedPath;
$this->previousMatch = $previousMatch;
}
}

0 comments on commit 6aa7319

Please sign in to comment.