Added ability to scope RoutingContext.

This commit is contained in:
flash 2025-01-29 00:25:53 +00:00
parent 06d0413976
commit 33344541d6
10 changed files with 235 additions and 165 deletions

View file

@ -22,26 +22,26 @@ error_reporting(MSZ_DEBUG ? -1 : 0);
mb_internal_encoding('UTF-8'); mb_internal_encoding('UTF-8');
date_default_timezone_set('GMT'); date_default_timezone_set('GMT');
$cfg = FsConfig::fromFile(MSZ_CONFIG . '/config.cfg'); $env = FsConfig::fromFile(MSZ_CONFIG . '/config.cfg');
if($cfg->hasValues('sentry:dsn')) if($env->hasValues('sentry:dsn'))
(function($cfg) { (function($env) {
\Sentry\init([ \Sentry\init([
'dsn' => $cfg->getString('dsn'), 'dsn' => $env->getString('dsn'),
'traces_sample_rate' => $cfg->getFloat('tracesRate', 0.2), 'traces_sample_rate' => $env->getFloat('tracesRate', 0.2),
'profiles_sample_rate' => $cfg->getFloat('profilesRate', 0.2), 'profiles_sample_rate' => $env->getFloat('profilesRate', 0.2),
]); ]);
set_exception_handler(function(\Throwable $ex) { set_exception_handler(function(\Throwable $ex) {
\Sentry\captureException($ex); \Sentry\captureException($ex);
}); });
})($cfg->scopeTo('sentry')); })($env->scopeTo('sentry'));
$db = DbBackends::create($cfg->getString('database:dsn', 'null:')); $db = DbBackends::create($env->getString('database:dsn', 'null:'));
$db->execute('SET SESSION time_zone = \'+00:00\', sql_mode = \'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION\';'); $db->execute('SET SESSION time_zone = \'+00:00\', sql_mode = \'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION\';');
$cfg = new DbConfig($db, 'msz_config'); $cfg = new DbConfig($db, 'msz_config');
Mailer::init($cfg->scopeTo('mail')); Mailer::init($cfg->scopeTo('mail'));
$msz = new MisuzuContext($db, $cfg); $msz = new MisuzuContext($db, $cfg, $env);

View file

@ -126,9 +126,10 @@ CSRF::init(
); );
// order for these two currently matters i think: it shouldn't. // order for these two currently matters i think: it shouldn't.
$router = $msz->createRouting(); $router = $msz->createRouting($request);
$msz->startTemplating(); $msz->startTemplating();
if(in_array('main', $env->getArray(sprintf('domain:%s', $request->getHeaderLine('Host'))))) {
$mszRequestPath = substr($request->getPath(), 1); $mszRequestPath = substr($request->getPath(), 1);
$mszLegacyPathPrefix = MSZ_PUBLIC . '-legacy/'; $mszLegacyPathPrefix = MSZ_PUBLIC . '-legacy/';
$mszLegacyPath = $mszLegacyPathPrefix . $mszRequestPath; $mszLegacyPath = $mszLegacyPathPrefix . $mszRequestPath;
@ -148,5 +149,6 @@ if(str_starts_with($mszLegacyPath, $mszLegacyPathPrefix)) {
} }
} }
} }
}
$router->dispatch($request); $router->dispatch($request);

View file

@ -13,12 +13,14 @@ use Misuzu\Messages\MessagesContext;
use Misuzu\News\News; use Misuzu\News\News;
use Misuzu\Perms\Permissions; use Misuzu\Perms\Permissions;
use Misuzu\Profile\ProfileFields; use Misuzu\Profile\ProfileFields;
use Misuzu\Routing\{BackedRoutingContext,RoutingContext};
use Misuzu\Users\{UsersContext,UserInfo}; use Misuzu\Users\{UsersContext,UserInfo};
use RPCii\HmacVerificationProvider; use RPCii\HmacVerificationProvider;
use RPCii\Server\HttpRpcServer; use RPCii\Server\HttpRpcServer;
use Index\Config\Config; use Index\Config\Config;
use Index\Db\DbConnection; use Index\Db\DbConnection;
use Index\Db\Migration\{DbMigrationManager,DbMigrationRepo,FsDbMigrationRepo}; use Index\Db\Migration\{DbMigrationManager,DbMigrationRepo,FsDbMigrationRepo};
use Index\Http\HttpRequest;
use Index\Templating\TplEnvironment; use Index\Templating\TplEnvironment;
use Index\Urls\UrlRegistry; use Index\Urls\UrlRegistry;
@ -55,7 +57,8 @@ class MisuzuContext {
public function __construct( public function __construct(
public private(set) DbConnection $dbConn, public private(set) DbConnection $dbConn,
public private(set) Config $config public private(set) Config $config,
public private(set) Config $env
) { ) {
$this->perms = new Permissions($dbConn); $this->perms = new Permissions($dbConn);
$this->authInfo = new AuthInfo($this->perms); $this->authInfo = new AuthInfo($this->perms);
@ -144,11 +147,22 @@ class MisuzuContext {
Template::init($this->templating); Template::init($this->templating);
} }
public function createRouting(): RoutingContext { public function createRouting(HttpRequest $request): RoutingContext {
$routingCtx = new RoutingContext; $prefix = sprintf('domain:%s', $request->getHeaderLine('Host'));
$hostInfo = $this->env->scopeTo($prefix);
$purposes = $this->env->getArray($prefix);
$routingCtx = new BackedRoutingContext;
$this->urls = $routingCtx->urls; $this->urls = $routingCtx->urls;
$routingCtx->register(new \Misuzu\Home\HomeRoutes( if(in_array('main', $purposes)) {
$scopedInfo = $hostInfo->scopeTo('main');
$scopedCtx = $routingCtx->scopeTo(
$scopedInfo->getString('name'),
$scopedInfo->getString('path')
);
$scopedCtx->register(new \Misuzu\Home\HomeRoutes(
$this->config, $this->config,
$this->dbConn, $this->dbConn,
$this->siteInfo, $this->siteInfo,
@ -160,15 +174,15 @@ class MisuzuContext {
$this->usersCtx $this->usersCtx
)); ));
$routingCtx->register(new \Misuzu\Users\Assets\AssetsRoutes( $scopedCtx->register(new \Misuzu\Users\Assets\AssetsRoutes(
$this->authInfo, $this->authInfo,
$this->urls, $this->urls,
$this->usersCtx $this->usersCtx
)); ));
$routingCtx->register(new \Misuzu\Info\InfoRoutes); $scopedCtx->register(new \Misuzu\Info\InfoRoutes);
$routingCtx->register(new \Misuzu\News\NewsRoutes( $scopedCtx->register(new \Misuzu\News\NewsRoutes(
$this->siteInfo, $this->siteInfo,
$this->authInfo, $this->authInfo,
$this->urls, $this->urls,
@ -177,7 +191,7 @@ class MisuzuContext {
$this->comments $this->comments
)); ));
$routingCtx->register(new \Misuzu\Messages\MessagesRoutes( $scopedCtx->register(new \Misuzu\Messages\MessagesRoutes(
$this->config->scopeTo('messages'), $this->config->scopeTo('messages'),
$this->urls, $this->urls,
$this->authInfo, $this->authInfo,
@ -186,19 +200,19 @@ class MisuzuContext {
$this->perms $this->perms
)); ));
$routingCtx->register(new \Misuzu\Forum\ForumCategoriesRoutes( $scopedCtx->register(new \Misuzu\Forum\ForumCategoriesRoutes(
$this->forumCtx, $this->forumCtx,
$this->usersCtx, $this->usersCtx,
$this->authInfo, $this->authInfo,
)); ));
$routingCtx->register(new \Misuzu\Forum\ForumTopicsRoutes( $scopedCtx->register(new \Misuzu\Forum\ForumTopicsRoutes(
$this->urls, $this->urls,
$this->forumCtx, $this->forumCtx,
$this->usersCtx, $this->usersCtx,
$this->auditLog, $this->auditLog,
$this->authInfo, $this->authInfo,
)); ));
$routingCtx->register(new \Misuzu\Forum\ForumPostsRoutes( $scopedCtx->register(new \Misuzu\Forum\ForumPostsRoutes(
$this->urls, $this->urls,
$this->forumCtx, $this->forumCtx,
$this->usersCtx, $this->usersCtx,
@ -206,7 +220,7 @@ class MisuzuContext {
$this->authInfo, $this->authInfo,
)); ));
$routingCtx->register(new \Misuzu\Changelog\ChangelogRoutes( $scopedCtx->register(new \Misuzu\Changelog\ChangelogRoutes(
$this->siteInfo, $this->siteInfo,
$this->urls, $this->urls,
$this->changelog, $this->changelog,
@ -215,7 +229,7 @@ class MisuzuContext {
$this->comments $this->comments
)); ));
$routingCtx->register(new \Misuzu\SharpChat\SharpChatRoutes( $scopedCtx->register(new \Misuzu\SharpChat\SharpChatRoutes(
$this->config->scopeTo('sockChat'), $this->config->scopeTo('sockChat'),
$this->config->scopeTo('impersonate'), $this->config->scopeTo('impersonate'),
$this->urls, $this->urls,
@ -227,7 +241,7 @@ class MisuzuContext {
$this->counters $this->counters
)); ));
$routingCtx->register(new \Misuzu\Satori\SatoriRoutes( $scopedCtx->register(new \Misuzu\Satori\SatoriRoutes(
$this->config->scopeTo('satori'), $this->config->scopeTo('satori'),
$this->usersCtx, $this->usersCtx,
$this->forumCtx, $this->forumCtx,
@ -237,7 +251,7 @@ class MisuzuContext {
$routingCtx->register(new LegacyRoutes($this->urls)); $routingCtx->register(new LegacyRoutes($this->urls));
$rpcServer = new HttpRpcServer; $rpcServer = new HttpRpcServer;
$routingCtx->router->register($rpcServer->createRouteHandler( $scopedCtx->register($rpcServer->createRouteHandler(
new HmacVerificationProvider(fn() => $this->config->getString('aleister.secret')) new HmacVerificationProvider(fn() => $this->config->getString('aleister.secret'))
)); ));
@ -259,7 +273,7 @@ class MisuzuContext {
// This RPC server will eventually despawn when Hanyuu fully owns auth // This RPC server will eventually despawn when Hanyuu fully owns auth
$hanyuuRpcServer = new HttpRpcServer; $hanyuuRpcServer = new HttpRpcServer;
$routingCtx->router->scopeTo('/_hanyuu')->register($hanyuuRpcServer->createRouteHandler( $scopedCtx->scopeTo('', '/_hanyuu')->register($hanyuuRpcServer->createRouteHandler(
new HmacVerificationProvider(fn() => $this->config->getString('hanyuu.secret')) new HmacVerificationProvider(fn() => $this->config->getString('hanyuu.secret'))
)); ));
@ -270,6 +284,7 @@ class MisuzuContext {
$this->usersCtx, $this->usersCtx,
$this->authCtx $this->authCtx
)); ));
}
return $routingCtx; return $routingCtx;
} }

View file

@ -0,0 +1,39 @@
<?php
namespace Misuzu\Routing;
use Index\Http\HttpRequest;
use Index\Http\Routing\{HttpRouter,Router,RouteHandler};
use Index\Urls\{ArrayUrlRegistry,UrlRegistry,UrlSource};
class BackedRoutingContext implements RoutingContext {
public private(set) Router $router;
public private(set) UrlRegistry $urls;
public function __construct(
?Router $router = null,
?UrlRegistry $urls = null
) {
$this->urls = $urls ?? new ArrayUrlRegistry;
$this->router = $router ?? new HttpRouter(errorHandler: new RoutingErrorHandler);
$this->router->use('/', fn($resp) => $resp->setPoweredBy('Misuzu'));
}
public function register(RouteHandler|UrlSource $handler): void {
if($handler instanceof RouteHandler)
$this->router->register($handler);
if($handler instanceof UrlSource)
$this->urls->register($handler);
}
public function scopeTo(string $namePrefix, string $pathPrefix): RoutingContext {
return new ScopedRoutingContext(
$this->router->scopeTo($pathPrefix),
$this->urls->scopeTo($namePrefix, $pathPrefix)
);
}
/** @param mixed[] $args */
public function dispatch(?HttpRequest $request = null, array $args = []): void {
$this->router->dispatch($request, $args);
}
}

View file

@ -0,0 +1,12 @@
<?php
namespace Misuzu\Routing;
use Index\Http\HttpRequest;
use Index\Http\Routing\RouteHandler;
use Index\Urls\UrlSource;
interface RoutingContext {
public function register(RouteHandler|UrlSource $handler): void;
public function scopeTo(string $namePrefix, string $pathPrefix): RoutingContext;
public function dispatch(?HttpRequest $request = null, array $args = []): void;
}

View file

@ -1,7 +1,8 @@
<?php <?php
namespace Misuzu; namespace Misuzu\Routing;
use Index\Http\{HtmlHttpErrorHandler,HttpResponseBuilder,HttpRequest}; use Index\Http\{HtmlHttpErrorHandler,HttpResponseBuilder,HttpRequest};
use Misuzu\Template;
class RoutingErrorHandler extends HtmlHttpErrorHandler { class RoutingErrorHandler extends HtmlHttpErrorHandler {
public function handle(HttpResponseBuilder $response, HttpRequest $request, int $code, string $message): void { public function handle(HttpResponseBuilder $response, HttpRequest $request, int $code, string $message): void {

View file

@ -0,0 +1,32 @@
<?php
namespace Misuzu\Routing;
use Index\Http\HttpRequest;
use Index\Http\Routing\{RouteHandler,Router};
use Index\Urls\{UrlRegistry,UrlSource};
class ScopedRoutingContext implements RoutingContext {
public function __construct(
private Router $router,
private UrlRegistry $urls
) {}
public function register(RouteHandler|UrlSource $handler): void {
if($handler instanceof RouteHandler)
$this->router->register($handler);
if($handler instanceof UrlSource)
$this->urls->register($handler);
}
public function scopeTo(string $namePrefix, string $pathPrefix): RoutingContext {
return new ScopedRoutingContext(
$this->router->scopeTo($pathPrefix),
$this->urls->scopeTo($namePrefix, $pathPrefix)
);
}
/** @param mixed[] $args */
public function dispatch(?HttpRequest $request = null, array $args = []): void {
$this->router->dispatch($request, $args);
}
}

View file

@ -1,29 +0,0 @@
<?php
namespace Misuzu;
use Index\Http\HttpRequest;
use Index\Http\Routing\{HttpRouter,Router,RouteHandler};
use Index\Urls\{ArrayUrlRegistry,UrlFormat,UrlRegistry,UrlSource};
class RoutingContext {
public private(set) UrlRegistry $urls;
public private(set) HttpRouter $router;
public function __construct() {
$this->urls = new ArrayUrlRegistry;
$this->router = new HttpRouter(errorHandler: new RoutingErrorHandler);
$this->router->use('/', fn($resp) => $resp->setPoweredBy('Misuzu'));
}
public function register(RouteHandler|UrlSource $handler): void {
if($handler instanceof RouteHandler)
$this->router->register($handler);
if($handler instanceof UrlSource)
$this->urls->register($handler);
}
/** @param mixed[] $args */
public function dispatch(?HttpRequest $request = null, array $args = []): void {
$this->router->dispatch($request, $args);
}
}

View file

@ -7,7 +7,6 @@ use Index\Config\Config;
use Index\Http\{HttpRequest,HttpResponseBuilder}; use Index\Http\{HttpRequest,HttpResponseBuilder};
use Index\Http\Routing\{HttpGet,HttpMiddleware,RouteHandler,RouteHandlerTrait}; use Index\Http\Routing\{HttpGet,HttpMiddleware,RouteHandler,RouteHandlerTrait};
use Misuzu\Pagination; use Misuzu\Pagination;
use Misuzu\RoutingContext;
use Misuzu\Forum\ForumContext; use Misuzu\Forum\ForumContext;
use Misuzu\Profile\ProfileFields; use Misuzu\Profile\ProfileFields;
use Misuzu\Users\UsersContext; use Misuzu\Users\UsersContext;

View file

@ -2,7 +2,6 @@
namespace Misuzu\SharpChat; namespace Misuzu\SharpChat;
use RuntimeException; use RuntimeException;
use Misuzu\RoutingContext;
use Misuzu\Auth\{AuthContext,AuthInfo,Sessions}; use Misuzu\Auth\{AuthContext,AuthInfo,Sessions};
use Misuzu\Counters\Counters; use Misuzu\Counters\Counters;
use Misuzu\Emoticons\Emotes; use Misuzu\Emoticons\Emotes;