private function bootRouteTarget($actions) : array
{
$middlewares = [];
$applications = [];
$booted = [];
$monitors = [];
foreach ($actions as $key => $action) {
if ($action instanceof Bootable) {
/* don't ever boot a Bootable twice */
$hash = spl_object_hash($action);
if (!array_key_exists($hash, $booted)) {
$booted[$hash] = ($this->bootLoader)($action);
}
$action = $booted[$hash];
} elseif (is_array($action) && $action[0] instanceof Bootable) {
/* don't ever boot a Bootable twice */
$hash = spl_object_hash($action[0]);
if (!array_key_exists($hash, $booted)) {
$booted[$hash] = ($this->bootLoader)($action[0]);
}
}
if ($action instanceof Middleware) {
$middlewares[] = [$action, "do"];
} elseif (is_array($action) && $action[0] instanceof Middleware) {
$middlewares[] = [$action[0], "do"];
}
if ($action instanceof Monitor) {
$monitors[get_class($action)][] = $action;
} elseif (is_array($action) && $action[0] instanceof Monitor) {
$monitors[get_class($action[0])][] = $action[0];
}
if (is_callable($action)) {
$applications[] = $action;
}
}
if (empty($applications[1])) {
if (empty($applications[0])) {
// in order to specify only middlewares (in combination with e.g. a fallback handler)
return [[function () {
}, $middlewares], $monitors];
} else {
return [[$applications[0], $middlewares], $monitors];
}
}
return [[static function (Request $request, Response $response, array $args) use($applications) {
foreach ($applications as $application) {
$result = $application($request, $response, $args);
if ($result instanceof \Generator) {
yield from $result;
}
if ($response->state() & Response::STARTED) {
return;
}
}
}, $middlewares], $monitors];
}