Closed chrisvanpatten closed 8 years ago
Hi @chrisvanpatten
Well, it is not a Cortex feature and I think it's out of the scope of a router to make middlewares available.
With a little bit of code you can use Cortex with external libraries that provide middlewares.
To give you some directions, I think you can create you custom route class that accepts middlewares.
For example:
namespace Chris;
class MiddlewareQueryRoute extends \Brain\Cortex\Route\QueryRoute {
private $middlewares = [];
public function __construct($path, $queryBuilder, array $options = []) {
// store a "before" callback if it was already there
$before = empty($options['before']) ? null : $options['before'];
// then set before option to a function that 1st runs middlewares and
// after that runs the "before" callback if there was one
$options['before'] = function($vars, $wp, $template, $matches) use($before) {
$this->runMiddlewares($vars, $wp, $template, $matches);
is_callable($before) and $before($vars, $wp, $template, $matches);
};
parent::__construct($path, $queryBuilder, $options);
}
public function addMiddleware(callable $middleware) {
$this->middlewares[] = $middlewares;
return $this;
}
private function runMiddlewares($vars, $wp, $template, $matches) {
array_walk(
$this->middlewares,
function(callable $middleware) use($vars, $wp, $template, $matches) {
$middleware($vars, $wp, $template, $matches);
}
);
}
}
Having this class in place, you can create an instance of your route instead of Cortex QueryRoute
and use it to add middlewares, something like:
use Brain\Cortex\Route\RouteCollectionInterface as Routes;
use Chris\MiddlewareQueryRoute;
add_action('cortex.routes', function(Routes $routes) {
$path = '{type:[a-z]+}/latest';
$querybuilder = function(array $matches) {
return [ 'post_type' => $matches['type'] ];
};
$before = function($vars, $wp, $template, $matches) {
/* do something */
};
$route = new MiddlewareQueryRoute($path, $querybuilder, ['before' => $before])
->addMiddleware(function($vars, $wp, $template, $matches) {
/* do something */
})->addMiddleware(function($vars, $wp, $template, $matches) {
/* do something */
});
$routes->addRoute($route);
});
The "before" callback, if given, will be called after all the middleware callables have been ran.
Note that move from a code like this to a more sophisticated middleware implementation that makes use of, for example, "Relay" or any other middleware library out there, will not be that hard.
Brilliant, thank you!
Is it possible to register route middleware? I know it's possible to add the 'before' callback, but can these be chained?
I'd like to add an auth check (if user is logged out, redirect to login page) to a big group of routes, but still need to be able to use the 'before' callback for other purposes on some routes.
Thanks!