Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a context resource #134

Merged
merged 1 commit into from
Mar 9, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions docs/04. Controllers.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,28 @@ where setting `autoHydrate` to false makes sense, it is not recommended to set `
you will receive potentially malicious data. It's therefore up to you to manually validate and filter your data
if you turn off this option!

## Context resource

When dealing with requests such as POST `/users/1/tweets`, you will receive a Tweet instance as the parameter
of the POST method in the tweet controller. However, you may need to have the context that was used to match
this resource. In this case, the user n°1.

Because the router traverses the whole path, it keeps track of all the matched resources. ZfrRest controllers offer
a simple way to retrieve the previous matched resource (aka. the context) through the use of the `getContextResource`
method:

```php
class TweetListController extends AbstractRestfulController
{
public function post(Tweet $tweet)
{
$userResource = $this->getContextResource(); // $userResource is a ResourceInterface object
}
}
```

ZfrRest only supports going back one level in the hierarchy.

### Navigation

* Continue to [**Built-in listeners**](/docs/05. Built-in listeners.md)
Expand Down
8 changes: 8 additions & 0 deletions src/ZfrRest/Mvc/Controller/AbstractRestfulController.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,14 @@ public function getMatchedResource()
return $this->getEvent()->getRouteMatch()->getParam('resource', null);
}

/**
* @return ResourceInterface|null
*/
public function getContextResource()
{
return $this->getEvent()->getRouteMatch()->getParam('context', null);
}

/**
* Get the method handler plugin manager
*
Expand Down
13 changes: 9 additions & 4 deletions src/ZfrRest/Router/Http/ResourceGraphRoute.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
use ZfrRest\Resource\ResourceInterface;
use ZfrRest\Router\Exception\RuntimeException;
use ZfrRest\Router\Http\Matcher\BaseSubPathMatcher;
use ZfrRest\Router\Http\Matcher\SubPathMatch;

/**
* @license MIT
Expand Down Expand Up @@ -169,19 +170,20 @@ public function match(RequestInterface $request, $pathOffset = 0)
], strlen($path));
}

return $this->buildRouteMatch($match->getMatchedResource(), strlen($path));
return $this->buildRouteMatch($match, strlen($path));
}

/**
* Build a route match
*
* @param ResourceInterface $resource
* @param int $pathLength
* @param SubPathMatch $match
* @param int $pathLength
* @throws RuntimeException
* @return RouteMatch
*/
protected function buildRouteMatch(ResourceInterface $resource, $pathLength)
protected function buildRouteMatch(SubPathMatch $match, $pathLength)
{
$resource = $match->getMatchedResource();
$metadata = $resource->getMetadata();

// If returned $data is a collection, then we use the controller specified in Collection mapping
Expand All @@ -196,9 +198,12 @@ protected function buildRouteMatch(ResourceInterface $resource, $pathLength)
$controllerName = $metadata->getControllerName();
}

$previousMatch = $match->getPreviousMatch();

return new RouteMatch(
[
'resource' => $resource,
'context' => $previousMatch ? $previousMatch->getMatchedResource() : null,
'controller' => $controllerName
],
$pathLength
Expand Down