Just to be clear: I dont want to pass middleware to the middleware. I just want to pass a simple class that i can use inside the middleware to:
- extract specific expected values from the request.
- throw an error if its not what i expect.
- Use those values to build my object from the class passed to the middleware.
- And finally pass my new shiny shaped data object (which my IDE can understand) along to the controller.
but you say there is no way to pass a simple class to the middleware when adding middleware to a route. This means I will need to have a different middleware class for each and every route i want to use this on.
Something like this (as simplified/pseudo code for now):
The Midlleware
class LoginRequestMiddleware
{
public function __construct(
protected Profiler $profiler,
protected System $system
) {}
public function __invoke(Request $request, RequestHandler $handler): Response
{
$data = LoginData::fromRequest($request);
$request = $request->withAttribute("data", $data);
return $handler->handle($request);
}
}
The Data class
class LoginData
{
public function __construct(
public string $email,
public string $password,
) {}
public static function fromRequest(Request $request)
{
$parsedBody = $request->getParsedBody();
if (!in_array('email', $parsedBody) || !in_array('password', $parsedBody)) {
throw new \Exception("Invalid request");
}
return new self(
$request->getParsedBody()['email'],
$request->getParsedBody()['password'],
);
}
}
The Controller
class LoginController
{
public function __invoke(
Request $request,
ResponseInterface $response,
LoginData $data,
): ResponseInterface
{
$email = $data->email; // IDE knows this property exists and is a string
}
}
But maybe there is another way to simplify the middleware, so i dont need to write a new one for every route i want my custom data in? Preferably i only want to write a simple class like LoginData
for every route i want to use this setup in.
ps. I am already using the DI-PHP bridge
EDIT:
ooor maybe something more basic like this:
class LoginController
{
public function __invoke(
Request $request,
ResponseInterface $response,
): ResponseInterface
{
$parsedBody = $request->getParsedBody();
$data = LoginData::fromRequest($request);
$email = $data->email; // IDE knows this exists and is a string
}
}