Skip to content

Commit

Permalink
Allow configuration of placeholder overriding attributes
Browse files Browse the repository at this point in the history
Fixes PHP-DI#86
  • Loading branch information
andrewnicols committed Jun 19, 2024
1 parent dedf7f5 commit 7c85b1d
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 7 deletions.
11 changes: 7 additions & 4 deletions src/Bridge.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@
*/
class Bridge
{
public static function create(?ContainerInterface $container = null): App
public static function create(
?ContainerInterface $container = null,
bool $prioritiseAttributesOverParams = false
): App
{

Check failure on line 29 in src/Bridge.php

View workflow job for this annotation

GitHub Actions / Coding standards

The closing parenthesis and the opening brace of a multi-line function declaration must be on the same line
$container = $container ?: new Container;

Expand All @@ -33,7 +36,7 @@ public static function create(?ContainerInterface $container = null): App

$container->set(App::class, $app);

$controllerInvoker = static::createControllerInvoker($container);
$controllerInvoker = static::createControllerInvoker($container, $prioritiseAttributesOverParams);
$app->getRouteCollector()->setDefaultInvocationStrategy($controllerInvoker);

return $app;
Expand All @@ -59,8 +62,8 @@ protected static function createInvoker(ContainerInterface $container): Invoker
/**
* Create a controller invoker with the default resolvers.
*/
protected static function createControllerInvoker(ContainerInterface $container): ControllerInvoker
protected static function createControllerInvoker(ContainerInterface $container, bool $prioritiseAttributesOverParams): ControllerInvoker
{
return new ControllerInvoker(self::createInvoker($container));
return new ControllerInvoker(self::createInvoker($container), $prioritiseAttributesOverParams);
}
}
17 changes: 14 additions & 3 deletions src/ControllerInvoker.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@ class ControllerInvoker implements InvocationStrategyInterface
/** @var InvokerInterface */
private $invoker;

public function __construct(InvokerInterface $invoker)
/** @var bool Whether attributes should override parameters */
protected $prioritiseAttributesOverParams;

public function __construct(InvokerInterface $invoker, bool $prioritiseAttributesOverParams)
{
$this->invoker = $invoker;
$this->prioritiseAttributesOverParams = $prioritiseAttributesOverParams;
}

/**
Expand All @@ -33,7 +37,7 @@ public function __invoke(
): ResponseInterface {
// Inject the request and response by parameter name
$parameters = [
'request' => self::injectRouteArguments($request, $routeArguments),
'request' => self::injectRouteArguments($request, $routeArguments, $this->prioritiseAttributesOverParams),
'response' => $response,
];
// Inject the route arguments by name
Expand All @@ -60,10 +64,17 @@ protected function processResponse($response)
*
* @param array $routeArguments
*/
protected static function injectRouteArguments(ServerRequestInterface $request, array $routeArguments): ServerRequestInterface
protected static function injectRouteArguments(
ServerRequestInterface $request,
array $routeArguments,
bool $prioritiseAttributesOverParams
): ServerRequestInterface
{

Check failure on line 72 in src/ControllerInvoker.php

View workflow job for this annotation

GitHub Actions / Coding standards

The closing parenthesis and the opening brace of a multi-line function declaration must be on the same line
$requestWithArgs = $request;
foreach ($routeArguments as $key => $value) {
if ($prioritiseAttributesOverParams && $request->getAttribute($key) !== null) {
continue;
}
$requestWithArgs = $requestWithArgs->withAttribute($key, $value);
}
return $requestWithArgs;
Expand Down
20 changes: 20 additions & 0 deletions tests/RoutingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,26 @@ public function injects_route_placeholder_over_request_attribute()
$this->assertEquals('Hello matt', (string) $response->getBody());
}

/**
* @test
*/
public function prefers_request_attribute_over_route_placeholder_if_configured()
{
$app = Bridge::create(null, true);
$app->add(function (ServerRequestInterface $request, RequestHandlerInterface $next) {
return $next->handle($request->withAttribute('name', 'Bob'));
});
$app->get('/{name}', function ($name, $request, $response) {
$response->getBody()->write('Hello ' . $name . ', from ' . $request->getAttribute('name'));
return $response;
});

$response = $app->handle(RequestFactory::create('/matt'));

// The route placeholder does not override the request attribute but the placeholder is still provided to the controller
$this->assertEquals('Hello matt, from Bob', (string) $response->getBody());
}

/**
* @test
*/
Expand Down

0 comments on commit 7c85b1d

Please sign in to comment.