Commit 65afac9f authored by RJ Garcia's avatar RJ Garcia

Added support for callables in CallbackResolver

- Added the ability for the callback resolver to support any callable instead
of just the object and method callable type.
- Updated the service_controller documentation to note about all callables
Signed-off-by: default avatarRJ Garcia <rj@bighead.net>
parent 5f0fc5c1
......@@ -114,3 +114,29 @@ followed by a single colon (:), followed by the method name.
};
$app->get('/posts.json', "posts.controller:indexJsonAction");
In addition to using classes for service controllers, you can define any
callable as a service in the application to be used for a route.
.. code-block:: php
namespace Demo\Controller;
use Demo\Repository\PostRepository;
use Symfony\Component\HttpFoundation\JsonResponse;
function postIndexJson(PostRepository $repo) {
return function() use ($repo) {
return new JsonResponse($repo->findAll());
};
}
And when defining your route, the code would look like the following:
.. code-block:: php
$app['posts.controller'] = function($app) {
return Demo\Controller\postIndexJson($app['posts.repository']);
};
$app->get('/posts.json', 'posts.controller');
......@@ -33,7 +33,7 @@ class CallbackResolver
*/
public function isValid($name)
{
return is_string($name) && preg_match(static::SERVICE_PATTERN, $name);
return is_string($name) && (preg_match(static::SERVICE_PATTERN, $name) || isset($this->app[$name]));
}
/**
......@@ -41,19 +41,25 @@ class CallbackResolver
*
* @param string $name
*
* @return array A callable array
* @return callable A callable value
*
* @throws \InvalidArgumentException In case the method does not exist.
*/
public function convertCallback($name)
{
if (preg_match(static::SERVICE_PATTERN, $name)) {
list($service, $method) = explode(':', $name, 2);
$callback = array($this->app[$service], $method);
} else {
$service = $name;
$callback = $this->app[$name];
}
if (!isset($this->app[$service])) {
throw new \InvalidArgumentException(sprintf('Service "%s" does not exist.', $service));
if (!is_callable($callback)) {
throw new \InvalidArgumentException(sprintf('Service "%s" is not callable.', $service));
}
return array($this->app[$service], $method);
return $callback;
}
/**
......@@ -61,7 +67,7 @@ class CallbackResolver
*
* @param string $name
*
* @return array A callable array
* @return string|callable A callable value or the string passed in
*
* @throws \InvalidArgumentException In case the method does not exist.
*/
......
......@@ -27,27 +27,55 @@ class CallbackResolverTest extends \PHPUnit_Framework_Testcase
public function testShouldResolveCallback()
{
$this->app['some_service'] = function () { return new \stdClass(); };
$callable = function () {};
$this->app['some_service'] = function () { return new \ArrayObject(); };
$this->app['callable_service'] = function () use ($callable) {
return $callable;
};
$this->assertTrue($this->resolver->isValid('some_service:methodName'));
$this->assertTrue($this->resolver->isValid('callable_service'));
$this->assertEquals(
array($this->app['some_service'], 'methodName'),
$this->resolver->convertCallback('some_service:methodName')
array($this->app['some_service'], 'append'),
$this->resolver->convertCallback('some_service:append')
);
$this->assertSame($callable, $this->resolver->convertCallback('callable_service'));
}
public function testNonStringsAreNotValid()
/**
* @dataProvider nonStringsAreNotValidProvider
*/
public function testNonStringsAreNotValid($name)
{
$this->assertFalse($this->resolver->isValid($name));
}
public function nonStringsAreNotValidProvider()
{
$this->assertFalse($this->resolver->isValid(null));
$this->assertFalse($this->resolver->isValid('some_service::methodName'));
return array(
array(null),
array('some_service::methodName'),
array('missing_service'),
);
}
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Service "some_service" does not exist.
* @expectedExceptionMessageRegExp /Service "[a-z_]+" is not callable./
* @dataProvider shouldThrowAnExceptionIfServiceIsNotCallableProvider
*/
public function testShouldThrowAnExceptionIfServiceIsMissing()
public function testShouldThrowAnExceptionIfServiceIsNotCallable($name)
{
$this->resolver->convertCallback('some_service:methodName');
$this->app['non_callable_obj'] = function () { return new \stdClass(); };
$this->app['non_callable'] = function () { return array(); };
$this->resolver->convertCallback($name);
}
public function shouldThrowAnExceptionIfServiceIsNotCallableProvider()
{
return array(
array('non_callable_obj:methodA'),
array('non_callable'),
);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment