diff --git a/composer.json b/composer.json index 1f4a6ee..a3219b7 100644 --- a/composer.json +++ b/composer.json @@ -41,7 +41,8 @@ "require-dev": { "phpunit/phpunit": ">=3.7.0", "squizlabs/php_codesniffer": "1.5.*", - "zendframework/zend-loader": "~2.3" + "zendframework/zend-loader": "~2.3", + "zendframework/zend-i18n": "~2.3" }, "autoload": { "psr-4": { diff --git a/src/ContentValidationListener.php b/src/ContentValidationListener.php index 0f3deb4..5cdb1bf 100644 --- a/src/ContentValidationListener.php +++ b/src/ContentValidationListener.php @@ -213,8 +213,20 @@ public function onRoute(MvcEvent $e) } $inputFilter->setData($data); - if ($inputFilter->isValid()) { - return; + /** + * A specific Filter may throw an Exception if an invalid value is given. + * Convert any Exception to return a failed validation response + */ + try { + if ($inputFilter->isValid()) { + return; + } + } catch (FilterInvalidArgumentException $ex) { + return new ApiProblemResponse( + new ApiProblem(422, 'Invalid value supplied to filter', null, null, array( + 'validation_messages' => array($ex->getMessage()), + )) + ); } return new ApiProblemResponse( diff --git a/test/ContentValidationListenerTest.php b/test/ContentValidationListenerTest.php index e4f9ac2..a47b237 100644 --- a/test/ContentValidationListenerTest.php +++ b/test/ContentValidationListenerTest.php @@ -280,6 +280,42 @@ public function testApiProblemResponseFromInvalidContentContainsValidationErrorM $this->assertInternalType('array', $asArray['validation_messages']['bar']); } + public function testReturnsApiProblemResponseIfAnInputFilterThrowsAnException() + { + $services = new ServiceManager(); + $factory = new InputFilterFactory(); + $services->setService('FooValidator', $factory->createInputFilter(array( + 'foo' => array( + 'name' => 'foo', + 'validators' => array( + array('name' => 'DateTime'), + ), + ), + ))); + $listener = new ContentValidationListener(array( + 'Foo' => array('input_filter' => 'FooValidator'), + ), $services); + + $request = new HttpRequest(); + $request->setMethod('POST'); + + $matches = new RouteMatch(array('controller' => 'Foo')); + + $dataParams = new ParameterDataContainer(); + $dataParams->setBodyParams(array( + 'foo' => '12314', + )); + + $event = new MvcEvent(); + $event->setRequest($request); + $event->setRouteMatch($matches); + $event->setParam('ZFContentNegotiationParameterData', $dataParams); + + $response = $listener->onRoute($event); + $this->assertInstanceOf('ZF\ApiProblem\ApiProblemResponse', $response); + return $response; + } + public function testReturnsApiProblemResponseIfParametersAreMissing() { $services = new ServiceManager();