Skip to content

Commit

Permalink
Allow UpdateHandlerInterface object as a route action
Browse files Browse the repository at this point in the history
  • Loading branch information
viktorprogger committed Jul 15, 2024
1 parent dbf7660 commit c3fd083
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/Router/Route.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ final class Route
private array $middlewares = [];

/**
* @param callable|array|string|object $action
* @param callable|array|string|object|UpdateHandlerInterface $action
*/
public function __construct(
public readonly RuleStatic|RuleDynamic $rule,
Expand Down
37 changes: 33 additions & 4 deletions src/Router/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Botasis\Runtime\Router;

use Botasis\Runtime\InvalidCallableConfigurationException;
use Botasis\Runtime\Middleware\MiddlewareDispatcher;
use Botasis\Runtime\Response\Response;
use Botasis\Runtime\Response\ResponseInterface;
Expand Down Expand Up @@ -59,6 +60,7 @@ public function match(Update $update): UpdateHandlerInterface

foreach ($this->routes as $key => $route) {
if (!isset($this->compiledRules[$key])) {
// TODO domain exception with explanation (use yiisoft friendly exceptions) on callable not created
/** @psalm-suppress PossiblyUndefinedMethod The rule property is always a RuleDynamic */
$this->compiledRules[$key] = $this->callableResolver->resolve($route->rule->getCallbackDefinition());
}
Expand Down Expand Up @@ -122,10 +124,7 @@ private function getActionWrapped(Route|Group $route): Closure
}

return function(Update $update, UpdateHandlerInterface $handler) use($route): ResponseInterface {
/** @var callable(Update):mixed $action */
$action = $this->callableResolver->resolve($route->action);

$result = $action($update);
$result = $this->resolveAction($route)($update);
if ($result === null) {
$result = new Response($update);
}
Expand All @@ -152,4 +151,34 @@ public function handle(Update $update): ResponseInterface

return $this->emptyFallbackHandler;
}

/**
* @param Route $route
* @return Closure(Update):mixed
*/
private function resolveAction(Route $route): Closure
{
// TODO add tests for extended callables and update handlers as actions
// TODO also test exception text with route name chains
if ($route->action instanceof UpdateHandlerInterface) {
return [$route->action, 'handle'](...);
}

try {
return $this->callableResolver->resolve($route->action);
} catch (InvalidCallableConfigurationException $exception) {
if (is_string($route->action) && $this->container->has($route->action)) {
$action = $this->container->get($route->action);
if ($action instanceof UpdateHandlerInterface) {
return [$action, 'handle'](...);
}
}

// TODO domain exception with explanation (use yiisoft friendly exceptions)
throw new RuntimeException(
'Action must be an UpdateHandlerInterface or a callable definition.',
previous: $exception,
);
}
}
}

0 comments on commit c3fd083

Please sign in to comment.