Skip to content

Commit

Permalink
Merge pull request #3069 from ddrv-fork/array-routes
Browse files Browse the repository at this point in the history
Classname/Method Callable Arrays
  • Loading branch information
l0gicgate committed Apr 19, 2021
2 parents 090498e + 2b8774e commit 8294d20
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 6 deletions.
23 changes: 23 additions & 0 deletions Slim/CallableResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public function __construct(?ContainerInterface $container = null)
*/
public function resolve($toResolve): callable
{
$toResolve = $this->prepareToResolve($toResolve);
if (is_callable($toResolve)) {
return $this->bindToContainer($toResolve);
}
Expand Down Expand Up @@ -90,6 +91,7 @@ public function resolveMiddleware($toResolve): callable
*/
private function resolveByPredicate($toResolve, callable $predicate, string $defaultMethod): callable
{
$toResolve = $this->prepareToResolve($toResolve);
if (is_callable($toResolve)) {
return $this->bindToContainer($toResolve);
}
Expand Down Expand Up @@ -144,6 +146,9 @@ private function resolveSlimNotation(string $toResolve): array
$instance = $this->container->get($class);
} else {
if (!class_exists($class)) {
if ($method) {
$class .= '::' . $method . '()';
}
throw new RuntimeException(sprintf('Callable %s does not exist', $class));
}
$instance = new $class($this->container);
Expand Down Expand Up @@ -187,4 +192,22 @@ private function bindToContainer(callable $callable): callable
}
return $callable;
}

/**
* @param string|callable $toResolve
* @return string|callable
*/
private function prepareToResolve($toResolve)
{
if (!is_array($toResolve)) {
return $toResolve;
}
$candidate = $toResolve;
$class = array_shift($candidate);
$method = array_shift($candidate);
if (is_string($class) && is_string($method)) {
return $class . ':' . $method;
}
return $toResolve;
}
}
46 changes: 40 additions & 6 deletions tests/CallableResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,23 @@ public function testSlimCallable()
$this->assertEquals(3, CallableTest::$CalledCount);
}

public function testSlimCallableAsArray()
{
$resolver = new CallableResolver(); // No container injected
$callable = $resolver->resolve([CallableTest::class, 'toCall']);
$callableRoute = $resolver->resolveRoute([CallableTest::class, 'toCall']);
$callableMiddleware = $resolver->resolveMiddleware([CallableTest::class, 'toCall']);

$callable();
$this->assertEquals(1, CallableTest::$CalledCount);

$callableRoute();
$this->assertEquals(2, CallableTest::$CalledCount);

$callableMiddleware();
$this->assertEquals(3, CallableTest::$CalledCount);
}

public function testSlimCallableContainer()
{
/** @var ContainerInterface $container */
Expand All @@ -150,6 +167,23 @@ public function testSlimCallableContainer()
$this->assertEquals($container, CallableTest::$CalledContainer);
}

public function testSlimCallableAsArrayContainer()
{
/** @var ContainerInterface $container */
$container = $this->containerProphecy->reveal();
$resolver = new CallableResolver($container);
$resolver->resolve([CallableTest::class, 'toCall']);
$this->assertEquals($container, CallableTest::$CalledContainer);

CallableTest::$CalledContainer = null;
$resolver->resolveRoute([CallableTest::class, 'toCall']);
$this->assertEquals($container, CallableTest::$CalledContainer);

CallableTest::$CalledContainer = null;
$resolver->resolveMiddleware([CallableTest::class ,'toCall']);
$this->assertEquals($container, CallableTest::$CalledContainer);
}

public function testContainer()
{
$this->containerProphecy->has('callable_service')->willReturn(true);
Expand Down Expand Up @@ -441,7 +475,7 @@ public function testMiddlewareFunctionNotFoundThrowException()
public function testClassNotFoundThrowException()
{
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('Callable Unknown does not exist');
$this->expectExceptionMessage('Callable Unknown::notFound() does not exist');

/** @var ContainerInterface $container */
$container = $this->containerProphecy->reveal();
Expand All @@ -452,7 +486,7 @@ public function testClassNotFoundThrowException()
public function testRouteClassNotFoundThrowException()
{
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('Callable Unknown does not exist');
$this->expectExceptionMessage('Callable Unknown::notFound() does not exist');

/** @var ContainerInterface $container */
$container = $this->containerProphecy->reveal();
Expand All @@ -463,7 +497,7 @@ public function testRouteClassNotFoundThrowException()
public function testMiddlewareClassNotFoundThrowException()
{
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('Callable Unknown does not exist');
$this->expectExceptionMessage('Callable Unknown::notFound() does not exist');

/** @var ContainerInterface $container */
$container = $this->containerProphecy->reveal();
Expand All @@ -474,7 +508,7 @@ public function testMiddlewareClassNotFoundThrowException()
public function testCallableClassNotFoundThrowException()
{
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('is not resolvable');
$this->expectExceptionMessage('Callable Unknown::notFound() does not exist');

/** @var ContainerInterface $container */
$container = $this->containerProphecy->reveal();
Expand All @@ -485,7 +519,7 @@ public function testCallableClassNotFoundThrowException()
public function testRouteCallableClassNotFoundThrowException()
{
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('is not resolvable');
$this->expectExceptionMessage('Callable Unknown::notFound() does not exist');

/** @var ContainerInterface $container */
$container = $this->containerProphecy->reveal();
Expand All @@ -496,7 +530,7 @@ public function testRouteCallableClassNotFoundThrowException()
public function testMiddlewareCallableClassNotFoundThrowException()
{
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('is not resolvable');
$this->expectExceptionMessage('Callable Unknown::notFound() does not exist');

/** @var ContainerInterface $container */
$container = $this->containerProphecy->reveal();
Expand Down

0 comments on commit 8294d20

Please sign in to comment.