Permalink
Browse files

Adjust condition annotations to all be represented as 2 dimensional a…

…rray of annotations and items so they are all trested the same way.

Adjust Resource::exec() to handle multiple condition annotations of the same name/method correctly.
  • Loading branch information...
1 parent cd7a0e9 commit a1fcbd91046c610c643804dd79fd798f02ff3b99 @peej committed Aug 27, 2012
View
2 features/annotation-cache.feature
@@ -13,7 +13,7 @@ Feature: Caching of annotation information
"uri": "|^/cache$|",
"methods": {
"method1": {
- "method": "GET"
+ "method": ["GET"]
}
}
}
View
2 features/bootstrap/FeatureContext.php
@@ -424,7 +424,7 @@ public function theResourceShouldHaveTheConditionWithTheParameters($className, $
{
$metadata = $this->app->getResourceMetadata($className);
if ($parameters) {
- if ($parameters != join(',', $metadata['methods']['test'][$conditionName])) throw new Exception('Condition method not found');
+ if ($parameters != join(',', $metadata['methods']['test'][$conditionName][0])) throw new Exception('Condition method not found');
$resource = new $className($this->app, new Request, array());
$condition = call_user_func_array(array($resource, $conditionName), explode(',', $parameters));
View
2 features/bootstrap/env.php
@@ -16,7 +16,7 @@ class MyResource extends Tonic\Resource {
* @accepts application/x-www-form-urlencoded
* @accepts application/multipart
* @provides text/html
- * @condition myCondition
+ * @myCondition
* @param str $name
* @return Response
*/
View
16 src/Tonic/Application.php
@@ -12,14 +12,20 @@ class Application
*/
private $options = array();
+ private $baseUri= '';
+
/**
* Metadata of the loaded resources
*/
private $resources = array();
public function __construct($options = array())
{
- $this->baseUri = dirname($_SERVER['SCRIPT_NAME']);
+ if (isset($options['baseUri'])) {
+ $this->baseUri = $options['baseUri'];
+ } elseif (isset($_SERVER['DOCUMENT_URI'])) {
+ $this->baseUri = dirname($_SERVER['DOCUMENT_URI']);
+ }
$this->options = $options;
// load resource metadata passed in via options array
@@ -69,7 +75,7 @@ private function loadResourceFiles($filenames)
* Load the metadata for all loaded resource classes
* @param str $uriSpace Optional URI-space to mount the resources into
*/
- public function loadResourceMetadata($uriSpace = NULL)
+ private function loadResourceMetadata($uriSpace = NULL)
{
foreach (get_declared_classes() as $className) {
if (
@@ -260,7 +266,7 @@ private function uriTemplateToRegex($uri)
return $return;
}
- public function readMethodAnnotations($className)
+ private function readMethodAnnotations($className)
{
if (isset($this->resources[$className]) && isset($this->resources[$className]['methods'])) {
return $this->resources[$className]['methods'];
@@ -278,7 +284,9 @@ public function readMethodAnnotations($className)
foreach ($docComment as $annotationName => $value) {
$methodName = substr($annotationName, 1);
if (method_exists($className, $methodName)) {
- $methodMetadata[$methodName] = $value[0];
+ foreach ($value as $v) {
+ $methodMetadata[$methodName][] = $v;
+ }
}
}
$metadata[$methodReflector->getName()] = $methodMetadata;
View
2 src/Tonic/Request.php
@@ -9,7 +9,7 @@ class Request
{
public $uri;
public $method;
- public $contentType = 'application/x-www-form-urlencoded';
+ public $contentType;
public $data;
public $accept = array();
public $acceptLanguage = array();
View
63 src/Tonic/Resource.php
@@ -33,24 +33,24 @@ public function __get($name)
* Execute the resource, that is, find the correct resource method to call
* based upon the request and then call it.
*
- * @param str methodName Optional name of method to execute, bypasing annotations, useful for debugging
* @return Tonic\Response
*/
- final public function exec($methodName = NULL)
+ final public function exec()
{
// get the annotation metadata for this resource
$resourceMetadata = $this->app->getResourceMetadata($this);
- $error = new NotAcceptableException;
$methodPriorities = array();
if (isset($resourceMetadata['methods'])) {
foreach ($resourceMetadata['methods'] as $key => $methodMetadata) {
- if (!$methodName || $methodName == $key) {
- $methodPriorities[$key] = 0;
- foreach ($methodMetadata as $conditionName => $params) { // process each method condition
- if (method_exists($this, $conditionName)) {
- $this->currentMethodName = $key;
+ foreach ($methodMetadata as $conditionName => $conditions) { // process each method condition
+ if (method_exists($this, $conditionName)) {
+ $this->currentMethodName = $key;
+ $methodPriorities[$key] = 0;
+ $conditionValue = -1;
+ $error = null;
+ foreach ($conditions as $params) {
try {
if (is_array($params)) {
$condition = call_user_func_array(array($this, $conditionName), $params);
@@ -59,25 +59,30 @@ public function __get($name)
}
if (!$condition) $condition = 0;
if (is_numeric($condition)) {
- $methodPriorities[$key] += $condition;
+ if ($condition > $conditionValue) {
+ $conditionValue = $condition;
+ }
} elseif ($condition) {
$resourceMetadata['methods'][$key]['response'] = $condition;
}
+ $error = null;
} catch (Exception $e) {
- unset($methodPriorities[$key]);
$error = $e;
- break;
}
- } else {
- throw new \Exception(sprintf(
- 'Condition method "%s" not found in Resource class "%s"',
- $conditionName,
- get_class($this)
- ));
}
+ if ($conditionValue > -1) {
+ $methodPriorities[$key] += $conditionValue;
+ } elseif ($error) {
+ unset($methodPriorities[$key]);
+ break;
+ }
+ } else {
+ throw new \Exception(sprintf(
+ 'Condition method "%s" not found in Resource class "%s"',
+ $conditionName,
+ get_class($this)
+ ));
}
- } else {
- unset($methodPriorities[$key]);
}
}
}
@@ -138,13 +143,10 @@ public function __get($name)
* HTTP method condition must match request method
* @param str $method
*/
- final protected function method()
+ final protected function method($method)
{
- $methods = func_get_args();
- foreach ($methods as $method) {
- if (strtolower($this->request->method) == strtolower($method)) return;
- }
- throw new MethodNotAllowedException('No matching method for HTTP method "'.$this->request->method.'"');
+ if (strtolower($this->request->method) != strtolower($method))
+ throw new MethodNotAllowedException('No matching method for HTTP method "'.$this->request->method.'"');
}
/**
@@ -174,19 +176,20 @@ protected function accepts($mimetype)
*/
protected function provides($mimetype)
{
+ if (count($this->request->accept) == 0) return 0;
$pos = array_search($mimetype, $this->request->accept);
if ($pos === FALSE) {
if (in_array('*/*', $this->request->accept)) {
return 0;
} else {
throw new NotAcceptableException('No matching method for response type "'.join(', ', $this->request->accept).'"');
}
+ } else {
+ $this->after(function ($response) use ($mimetype) {
+ $response->contentType = $mimetype;
+ });
+ return count($this->request->accept) - $pos;
}
- $this->after(function ($response) use ($mimetype) {
- $response->contentType = $mimetype;
- });
-
- return count($this->request->accept) - $pos;
}
/**

0 comments on commit a1fcbd9

Please sign in to comment.