From f8a70b3cfcee5471b61a377a0b3303a54ec7223b Mon Sep 17 00:00:00 2001 From: Davide Pastore Date: Fri, 16 Dec 2016 18:15:06 +0100 Subject: [PATCH] Route parameter support (#19) Closed #18 --- README.md | 42 ++++++++++++++++++++ src/Validation.php | 1 + tests/ValidationTest.php | 82 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+) diff --git a/README.md b/README.md index b5a8432..c0f08ce 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,44 @@ $app->post('/bar', function ($req, $res, $args) { $app->run(); ``` + +## Route parameters + +```php +use Respect\Validation\Validator as v; + +$app = new \Slim\App(); + +//Create the validators +$routeParamValidator = v::numeric()->positive(); +$validators = array( + 'param' => $routeParamValidator, +); + +$app->get('/foo/{param}', function ($req, $res, $args) { + //Here you expect 'param' route parameter + if($req->getAttribute('has_errors')){ + //There are errors, read them + $errors = $req->getAttribute('errors'); + + /* $errors contain: + array( + 'param' => array( + '"wrong" must be numeric', + ), + ); + */ + } else { + //No errors + } +})->add(new \DavidePastore\Slim\Validation\Validation($validators)); + +$app->run(); +``` + +Note that requests parameters take priority over route parameters, so if you use the same name for a route and request parameter, the last will win and it will be considered for validation. + + ## JSON requests You can also validate a JSON request. Let's say your body request is: @@ -176,6 +214,7 @@ Array */ ``` + ## XML requests You can also validate a XML request. Let's say your body request is: @@ -268,16 +307,19 @@ $middleware = new \DavidePastore\Slim\Validation\Validation($validators, $transl $app->run(); ``` + ## Testing ``` bash $ phpunit ``` + ## Contributing Please see [CONTRIBUTING](CONTRIBUTING.md) for details. + ## Credits - [Davide Pastore](https://github.com/davidepastore) diff --git a/src/Validation.php b/src/Validation.php index 2210275..8ec2764 100644 --- a/src/Validation.php +++ b/src/Validation.php @@ -88,6 +88,7 @@ public function __invoke($request, $response, $next) { $this->errors = []; $params = $request->getParams(); + $params = array_merge((array) $request->getAttribute('routeInfo')[2], $params); $this->validate($params, $this->validators); $request = $request->withAttribute($this->errors_name, $this->getErrors()); diff --git a/tests/ValidationTest.php b/tests/ValidationTest.php index 8d836ec..8015ab8 100644 --- a/tests/ValidationTest.php +++ b/tests/ValidationTest.php @@ -2,6 +2,8 @@ namespace DavidePastore\Slim\Validation\Tests; +use ReflectionProperty; +use Slim\Collection; use Slim\Http\Body; use Slim\Http\Environment; use Slim\Http\Headers; @@ -634,4 +636,84 @@ public function testSetTranslator() $this->assertEquals($expectedValidators, $validators); $this->assertEquals($newTranslator, $translator); } + + public function requestFactory($envData = []) + { + $env = Environment::mock($envData); + $uri = Uri::createFromString('https://example.com:443/foo/bar?abc=123'); + $headers = Headers::createFromEnvironment($env); + $cookies = []; + $serverParams = $env->all(); + $body = new RequestBody(); + $request = new Request('GET', $uri, $headers, $cookies, $serverParams, $body); + + return $request; + } + + /** + * Test for validation. + * + * @dataProvider routeParamValidationProvider + */ + public function testRouteParamValidation($expectedValidators, $expectedHasErrors, $expectedErrors, $attributes) + { + $this->setupGet(); + $attrProp = new ReflectionProperty($this->request, 'attributes'); + $attrProp->setAccessible(true); + $attrProp->setValue($this->request, new Collection(array('routeInfo' => array( + 0, + 1, + $attributes, + )))); + + $mw = new Validation($expectedValidators); + + $errors = null; + $hasErrors = null; + $validators = []; + $next = function ($req, $res) use (&$errors, &$hasErrors, &$validators) { + $errors = $req->getAttribute('errors'); + $hasErrors = $req->getAttribute('has_errors'); + $validators = $req->getAttribute('validators'); + + return $res; + }; + + $response = $mw($this->request, $this->response, $next); + + $this->assertEquals($expectedValidators, $validators); + $this->assertEquals($expectedHasErrors, $hasErrors); + $this->assertEquals($expectedErrors, $errors); + } + + /** + * The validation provider for the route parameters. + */ + public function routeParamValidationProvider() + { + return array( + //Validation without errors + array( + array( + 'routeParam' => v::alnum()->noWhitespace()->length(1, 5), + ), + false, + [], + ['routeParam' => 'test'], + ), + //Validation with errors + array( + array( + 'routeParam' => v::alnum()->noWhitespace()->length(1, 5), + ), + true, + array( + 'routeParam' => array( + '"davidepastore" must have a length between 1 and 5', + ), + ), + ['routeParam' => 'davidepastore'], + ), + ); + } }