. namespace core\router; use Invoker\InvokerInterface; use Psr\Container\ContainerInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; /** * Controller Invoker for the Moodle Router. * * This class handles invocation of the route callable, and the conversion of the response into an appropriate format. * * @package core * @copyright Andrew Lyons * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class controller_invoker implements \Slim\Interfaces\InvocationStrategyInterface { /** * Create a new controller invoker. * * @param ContainerInterface $container * @param InvokerInterface $invoker */ public function __construct( /** @var ContainerInterface The DI container */ protected ContainerInterface $container, /** @var InvokerInterface The invoker */ protected InvokerInterface $invoker, ) { } #[\Override] public function __invoke( callable $callable, ServerRequestInterface $request, ResponseInterface $response, array $routeArguments, // phpcs:ignore moodle.NamingConventions.ValidVariableName.VariableNameLowerCase ): ResponseInterface { // Inject the request and response by parameter name. $parameters = [ 'request' => self::inject_route_arguments( $request, $routeArguments, // phpcs:ignore moodle.NamingConventions.ValidVariableName.VariableNameLowerCase ), 'response' => $response, ]; // Inject the route arguments by name. $parameters += $routeArguments; // phpcs:ignore moodle.NamingConventions.ValidVariableName.VariableNameLowerCase // Inject the attributes defined on the request. $parameters += $request->getAttributes(); $result = $this->invoker->call($callable, $parameters); return $this->container->get(response_handler::class)->standardise_response($result); } /** * Helper to inject route arguments. * * This is based on the ControllerInvoker. * * @param ServerRequestInterface $request * @param array $routeargs * @return ServerRequestInterface */ private static function inject_route_arguments( ServerRequestInterface $request, array $routeargs, ): ServerRequestInterface { $args = $request; foreach ($routeargs as $key => $value) { // Note: This differs to upstream where route args always override attributes. // We apply mapped parameters via route attributes and must therefore override the route args. if (!$args->getAttribute($key)) { $args = $args->withAttribute($key, $value); } } return $args; } }