mirror of
https://github.com/flarum/core.git
synced 2025-08-28 18:40:46 +02:00
chore: adapt extenders
This commit is contained in:
@@ -16,7 +16,7 @@ use Flarum\Foundation\ContainerUtil;
|
|||||||
use Illuminate\Contracts\Container\Container;
|
use Illuminate\Contracts\Container\Container;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\Relations\Relation;
|
use Illuminate\Database\Eloquent\Relations\Relation;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Illuminate\Http\Request;
|
||||||
use Tobscure\JsonApi\Document;
|
use Tobscure\JsonApi\Document;
|
||||||
|
|
||||||
class ApiController implements ExtenderInterface
|
class ApiController implements ExtenderInterface
|
||||||
@@ -63,12 +63,12 @@ class ApiController implements ExtenderInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @template S of AbstractSerializeController
|
* @template S of AbstractSerializeController
|
||||||
* @param (callable(S $controller, mixed $data, ServerRequestInterface $request, Document $document): array)|class-string $callback
|
* @param (callable(S $controller, mixed $data, Request $request, Document $document): array)|class-string $callback
|
||||||
*
|
*
|
||||||
* The callback can be a closure or an invokable class, and should accept:
|
* The callback can be a closure or an invokable class, and should accept:
|
||||||
* - $controller: An instance of this controller.
|
* - $controller: An instance of this controller.
|
||||||
* - $data: Mixed, can be an array of data or an object (like an instance of Collection or AbstractModel).
|
* - $data: Mixed, can be an array of data or an object (like an instance of Collection or AbstractModel).
|
||||||
* - $request: An instance of \Psr\Http\Message\ServerRequestInterface.
|
* - $request: An instance of \Illuminate\Http\Request.
|
||||||
* - $document: An instance of \Tobscure\JsonApi\Document.
|
* - $document: An instance of \Tobscure\JsonApi\Document.
|
||||||
*
|
*
|
||||||
* The callable should return:
|
* The callable should return:
|
||||||
@@ -330,11 +330,11 @@ class ApiController implements ExtenderInterface
|
|||||||
*
|
*
|
||||||
* @param string $relation: Relationship name, see load method description.
|
* @param string $relation: Relationship name, see load method description.
|
||||||
* @template R of Relation
|
* @template R of Relation
|
||||||
* @param (callable(Builder|R, \Psr\Http\Message\ServerRequestInterface|null, array): void) $callback
|
* @param (callable(Builder|R, \Illuminate\Http\Request|null, array): void) $callback
|
||||||
*
|
*
|
||||||
* The callback to modify the query, should accept:
|
* The callback to modify the query, should accept:
|
||||||
* - \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Relations\Relation $query: A query object.
|
* - \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Relations\Relation $query: A query object.
|
||||||
* - \Psr\Http\Message\ServerRequestInterface|null $request: An instance of the request.
|
* - \Illuminate\Http\Request|null $request: An instance of the request.
|
||||||
* - array $relations: An array of relations that are to be loaded.
|
* - array $relations: An array of relations that are to be loaded.
|
||||||
*
|
*
|
||||||
* @return self
|
* @return self
|
||||||
|
51
framework/core/src/Extend/Concerns/ExtendsRoutes.php
Normal file
51
framework/core/src/Extend/Concerns/ExtendsRoutes.php
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Flarum\Extend\Concerns;
|
||||||
|
|
||||||
|
use Flarum\Foundation\Config;
|
||||||
|
use Flarum\Http\RouteHandlerFactory;
|
||||||
|
use Flarum\Http\Router;
|
||||||
|
use Illuminate\Contracts\Container\Container;
|
||||||
|
use Illuminate\Contracts\Foundation\Application;
|
||||||
|
|
||||||
|
trait ExtendsRoutes
|
||||||
|
{
|
||||||
|
private array $routes = [];
|
||||||
|
private array $removedRoutes = [];
|
||||||
|
|
||||||
|
protected function registerRoutes(Container $container): void
|
||||||
|
{
|
||||||
|
if (empty($this->routes) && empty($this->removedRoutes)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$container->make(Application::class)->booted(
|
||||||
|
function (Container $container) {
|
||||||
|
/** @var RouteHandlerFactory $factory */
|
||||||
|
$factory = $container->make(RouteHandlerFactory::class);
|
||||||
|
/** @var Router $router */
|
||||||
|
$router = $container->make(Router::class);
|
||||||
|
/** @var Config $config */
|
||||||
|
|
||||||
|
foreach ($this->removedRoutes as $routeName) {
|
||||||
|
$router->forgetRoute($routeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->routes as $route) {
|
||||||
|
if ($router->has($route['name'])) {
|
||||||
|
throw new \RuntimeException("Route name '{$route['name']}' is already in use.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$action = isset($route['handler'])
|
||||||
|
? $factory->toController($route['handler'])
|
||||||
|
: $factory->toFrontend($this->frontend, $route['content']);
|
||||||
|
|
||||||
|
$router
|
||||||
|
->addRoute($route['method'], $route['path'], $action)
|
||||||
|
->prefix($config->path($this->frontend))
|
||||||
|
->name($route['name']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@@ -13,7 +13,7 @@ use Flarum\Extension\Extension;
|
|||||||
use Flarum\Formatter\Formatter as ActualFormatter;
|
use Flarum\Formatter\Formatter as ActualFormatter;
|
||||||
use Flarum\Foundation\ContainerUtil;
|
use Flarum\Foundation\ContainerUtil;
|
||||||
use Illuminate\Contracts\Container\Container;
|
use Illuminate\Contracts\Container\Container;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Illuminate\Http\Request;
|
||||||
use s9e\TextFormatter\Configurator;
|
use s9e\TextFormatter\Configurator;
|
||||||
use s9e\TextFormatter\Parser;
|
use s9e\TextFormatter\Parser;
|
||||||
use s9e\TextFormatter\Renderer;
|
use s9e\TextFormatter\Renderer;
|
||||||
@@ -96,13 +96,13 @@ class Formatter implements ExtenderInterface, LifecycleInterface
|
|||||||
* Prepare the system for rendering. This can be used to modify the xml that will be rendered, or to modify the renderer.
|
* Prepare the system for rendering. This can be used to modify the xml that will be rendered, or to modify the renderer.
|
||||||
* Please note that the xml to be rendered must be returned, regardless of whether it's changed.
|
* Please note that the xml to be rendered must be returned, regardless of whether it's changed.
|
||||||
*
|
*
|
||||||
* @param (callable(Renderer $renderer, mixed $context, string $xml, ServerRequestInterface $request): string)|class-string $callback
|
* @param (callable(Renderer $renderer, mixed $context, string $xml, Request $request): string)|class-string $callback
|
||||||
*
|
*
|
||||||
* The callback can be a closure or invokable class, and should accept:
|
* The callback can be a closure or invokable class, and should accept:
|
||||||
* - \s9e\TextFormatter\Renderer $renderer
|
* - \s9e\TextFormatter\Renderer $renderer
|
||||||
* - mixed $context
|
* - mixed $context
|
||||||
* - string $xml: The xml to be rendered.
|
* - string $xml: The xml to be rendered.
|
||||||
* - ServerRequestInterface $request. This argument MUST either be nullable, or omitted entirely.
|
* - Request $request. This argument MUST either be nullable, or omitted entirely.
|
||||||
*
|
*
|
||||||
* The callback should return:
|
* The callback should return:
|
||||||
* - string $xml: The xml to be rendered.
|
* - string $xml: The xml to be rendered.
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
namespace Flarum\Extend;
|
namespace Flarum\Extend;
|
||||||
|
|
||||||
|
use Flarum\Extend\Concerns\ExtendsRoutes;
|
||||||
use Flarum\Extension\Event\Disabled;
|
use Flarum\Extension\Event\Disabled;
|
||||||
use Flarum\Extension\Event\Enabled;
|
use Flarum\Extension\Event\Enabled;
|
||||||
use Flarum\Extension\Extension;
|
use Flarum\Extension\Extension;
|
||||||
@@ -20,19 +21,17 @@ use Flarum\Frontend\Document;
|
|||||||
use Flarum\Frontend\Driver\TitleDriverInterface;
|
use Flarum\Frontend\Driver\TitleDriverInterface;
|
||||||
use Flarum\Frontend\Frontend as ActualFrontend;
|
use Flarum\Frontend\Frontend as ActualFrontend;
|
||||||
use Flarum\Frontend\RecompileFrontendAssets;
|
use Flarum\Frontend\RecompileFrontendAssets;
|
||||||
use Flarum\Http\RouteCollection;
|
|
||||||
use Flarum\Http\RouteHandlerFactory;
|
|
||||||
use Flarum\Locale\LocaleManager;
|
use Flarum\Locale\LocaleManager;
|
||||||
use Flarum\Settings\Event\Saved;
|
use Flarum\Settings\Event\Saved;
|
||||||
use Illuminate\Contracts\Container\Container;
|
use Illuminate\Contracts\Container\Container;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class Frontend implements ExtenderInterface
|
class Frontend implements ExtenderInterface
|
||||||
{
|
{
|
||||||
|
use ExtendsRoutes;
|
||||||
|
|
||||||
private array $css = [];
|
private array $css = [];
|
||||||
private ?string $js = null;
|
private ?string $js = null;
|
||||||
private array $routes = [];
|
|
||||||
private array $removedRoutes = [];
|
|
||||||
private array $content = [];
|
private array $content = [];
|
||||||
private array $preloadArrs = [];
|
private array $preloadArrs = [];
|
||||||
private ?string $titleDriver = null;
|
private ?string $titleDriver = null;
|
||||||
@@ -91,11 +90,11 @@ class Frontend implements ExtenderInterface
|
|||||||
*
|
*
|
||||||
* @param string $path: The path of the route.
|
* @param string $path: The path of the route.
|
||||||
* @param string $name: The name of the route, must be unique.
|
* @param string $name: The name of the route, must be unique.
|
||||||
* @param (callable(Document $document, ServerRequestInterface $request): void)|class-string|null $content
|
* @param (callable(Document $document, Request $request): void)|class-string|null $content
|
||||||
*
|
*
|
||||||
* The content can be a closure or an invokable class, and should accept:
|
* The content can be a closure or an invokable class, and should accept:
|
||||||
* - \Flarum\Frontend\Document $document
|
* - \Flarum\Frontend\Document $document
|
||||||
* - \Psr\Http\Message\ServerRequestInterface $request
|
* - \Illuminate\Http\Request $request
|
||||||
*
|
*
|
||||||
* The callable should return void.
|
* The callable should return void.
|
||||||
*
|
*
|
||||||
@@ -103,7 +102,9 @@ class Frontend implements ExtenderInterface
|
|||||||
*/
|
*/
|
||||||
public function route(string $path, string $name, callable|string $content = null): self
|
public function route(string $path, string $name, callable|string $content = null): self
|
||||||
{
|
{
|
||||||
$this->routes[] = compact('path', 'name', 'content');
|
$method = 'GET';
|
||||||
|
|
||||||
|
$this->routes[] = compact('method', 'path', 'name', 'content');
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@@ -125,11 +126,11 @@ class Frontend implements ExtenderInterface
|
|||||||
/**
|
/**
|
||||||
* Modify the content of the frontend.
|
* Modify the content of the frontend.
|
||||||
*
|
*
|
||||||
* @param (callable(Document $document, ServerRequestInterface $request): void)|class-string|null $callback
|
* @param (callable(Document $document, Request $request): void)|class-string|null $callback
|
||||||
*
|
*
|
||||||
* The content can be a closure or an invokable class, and should accept:
|
* The content can be a closure or an invokable class, and should accept:
|
||||||
* - \Flarum\Frontend\Document $document
|
* - \Flarum\Frontend\Document $document
|
||||||
* - \Psr\Http\Message\ServerRequestInterface $request
|
* - \Illuminate\Http\Request $request
|
||||||
*
|
*
|
||||||
* The callable should return void.
|
* The callable should return void.
|
||||||
*
|
*
|
||||||
@@ -266,33 +267,6 @@ class Frontend implements ExtenderInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function registerRoutes(Container $container): void
|
|
||||||
{
|
|
||||||
if (empty($this->routes) && empty($this->removedRoutes)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$container->resolving(
|
|
||||||
"flarum.{$this->frontend}.routes",
|
|
||||||
function (RouteCollection $collection, Container $container) {
|
|
||||||
/** @var RouteHandlerFactory $factory */
|
|
||||||
$factory = $container->make(RouteHandlerFactory::class);
|
|
||||||
|
|
||||||
foreach ($this->removedRoutes as $routeName) {
|
|
||||||
$collection->removeRoute($routeName);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($this->routes as $route) {
|
|
||||||
$collection->get(
|
|
||||||
$route['path'],
|
|
||||||
$route['name'],
|
|
||||||
$factory->toFrontend($this->frontend, $route['content'])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function registerContent(Container $container): void
|
private function registerContent(Container $container): void
|
||||||
{
|
{
|
||||||
if (empty($this->content)) {
|
if (empty($this->content)) {
|
||||||
|
@@ -9,22 +9,20 @@
|
|||||||
|
|
||||||
namespace Flarum\Extend;
|
namespace Flarum\Extend;
|
||||||
|
|
||||||
|
use Flarum\Extend\Concerns\ExtendsRoutes;
|
||||||
use Flarum\Extension\Extension;
|
use Flarum\Extension\Extension;
|
||||||
use Flarum\Http\RouteCollection;
|
use Flarum\Http\Controller\AbstractController;
|
||||||
use Flarum\Http\RouteHandlerFactory;
|
|
||||||
use Illuminate\Contracts\Container\Container;
|
use Illuminate\Contracts\Container\Container;
|
||||||
use Psr\Http\Server\RequestHandlerInterface;
|
|
||||||
|
|
||||||
class Routes implements ExtenderInterface
|
class Routes implements ExtenderInterface
|
||||||
{
|
{
|
||||||
private array $routes = [];
|
use ExtendsRoutes;
|
||||||
private array $removedRoutes = [];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $appName: Name of the app (api, forum, admin).
|
* @param string $frontend: Name of the app (api, forum, admin).
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly string $appName
|
private readonly string $frontend
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,9 +31,9 @@ class Routes implements ExtenderInterface
|
|||||||
*
|
*
|
||||||
* @param string $path: The path of the route
|
* @param string $path: The path of the route
|
||||||
* @param string $name: The name of the route, must be unique.
|
* @param string $name: The name of the route, must be unique.
|
||||||
* @param callable|class-string<RequestHandlerInterface> $handler: ::class attribute of the controller class, or a closure.
|
* @param callable|class-string<AbstractController> $handler: ::class attribute of the controller class, or a closure.
|
||||||
*
|
*
|
||||||
* If the handler is a controller class, it should implement \Psr\Http\Server\RequestHandlerInterface,
|
* If the handler is a controller class, it should extend \Flarum\Http\Controller,
|
||||||
* or extend one of the Flarum Api controllers within \Flarum\Api\Controller.
|
* or extend one of the Flarum Api controllers within \Flarum\Api\Controller.
|
||||||
*
|
*
|
||||||
* The handler should accept:
|
* The handler should accept:
|
||||||
@@ -57,9 +55,9 @@ class Routes implements ExtenderInterface
|
|||||||
*
|
*
|
||||||
* @param string $path: The path of the route
|
* @param string $path: The path of the route
|
||||||
* @param string $name: The name of the route, must be unique.
|
* @param string $name: The name of the route, must be unique.
|
||||||
* @param callable|class-string<RequestHandlerInterface> $handler: ::class attribute of the controller class, or a closure.
|
* @param callable|class-string<AbstractController> $handler: ::class attribute of the controller class, or a closure.
|
||||||
*
|
*
|
||||||
* If the handler is a controller class, it should implement \Psr\Http\Server\RequestHandlerInterface,
|
* If the handler is a controller class, it should extend \Flarum\Http\Controller,
|
||||||
* or extend one of the Flarum Api controllers within \Flarum\Api\Controller.
|
* or extend one of the Flarum Api controllers within \Flarum\Api\Controller.
|
||||||
*
|
*
|
||||||
* The handler should accept:
|
* The handler should accept:
|
||||||
@@ -81,9 +79,9 @@ class Routes implements ExtenderInterface
|
|||||||
*
|
*
|
||||||
* @param string $path: The path of the route
|
* @param string $path: The path of the route
|
||||||
* @param string $name: The name of the route, must be unique.
|
* @param string $name: The name of the route, must be unique.
|
||||||
* @param callable|class-string<RequestHandlerInterface> $handler: ::class attribute of the controller class, or a closure.
|
* @param callable|class-string<AbstractController> $handler: ::class attribute of the controller class, or a closure.
|
||||||
*
|
*
|
||||||
* If the handler is a controller class, it should implement \Psr\Http\Server\RequestHandlerInterface,
|
* If the handler is a controller class, it should extend \Flarum\Http\Controller,
|
||||||
* or extend one of the Flarum Api controllers within \Flarum\Api\Controller.
|
* or extend one of the Flarum Api controllers within \Flarum\Api\Controller.
|
||||||
*
|
*
|
||||||
* The handler should accept:
|
* The handler should accept:
|
||||||
@@ -105,9 +103,9 @@ class Routes implements ExtenderInterface
|
|||||||
*
|
*
|
||||||
* @param string $path: The path of the route
|
* @param string $path: The path of the route
|
||||||
* @param string $name: The name of the route, must be unique.
|
* @param string $name: The name of the route, must be unique.
|
||||||
* @param callable|class-string<RequestHandlerInterface> $handler: ::class attribute of the controller class, or a closure.
|
* @param callable|class-string<AbstractController> $handler: ::class attribute of the controller class, or a closure.
|
||||||
*
|
*
|
||||||
* If the handler is a controller class, it should implement \Psr\Http\Server\RequestHandlerInterface,
|
* If the handler is a controller class, it should extend \Flarum\Http\Controller,
|
||||||
* or extend one of the Flarum Api controllers within \Flarum\Api\Controller.
|
* or extend one of the Flarum Api controllers within \Flarum\Api\Controller.
|
||||||
*
|
*
|
||||||
* The handler should accept:
|
* The handler should accept:
|
||||||
@@ -129,9 +127,9 @@ class Routes implements ExtenderInterface
|
|||||||
*
|
*
|
||||||
* @param string $path: The path of the route
|
* @param string $path: The path of the route
|
||||||
* @param string $name: The name of the route, must be unique.
|
* @param string $name: The name of the route, must be unique.
|
||||||
* @param callable|class-string<RequestHandlerInterface> $handler: ::class attribute of the controller class, or a closure.
|
* @param callable|class-string<AbstractController> $handler: ::class attribute of the controller class, or a closure.
|
||||||
*
|
*
|
||||||
* If the handler is a controller class, it should implement \Psr\Http\Server\RequestHandlerInterface,
|
* If the handler is a controller class, it should extend \Flarum\Http\Controller,
|
||||||
* or extend one of the Flarum Api controllers within \Flarum\Api\Controller.
|
* or extend one of the Flarum Api controllers within \Flarum\Api\Controller.
|
||||||
*
|
*
|
||||||
* The handler should accept:
|
* The handler should accept:
|
||||||
@@ -176,29 +174,6 @@ class Routes implements ExtenderInterface
|
|||||||
|
|
||||||
public function extend(Container $container, Extension $extension = null): void
|
public function extend(Container $container, Extension $extension = null): void
|
||||||
{
|
{
|
||||||
if (empty($this->routes) && empty($this->removedRoutes)) {
|
$this->registerRoutes($container);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$container->resolving(
|
|
||||||
"flarum.{$this->appName}.routes",
|
|
||||||
function (RouteCollection $collection, Container $container) {
|
|
||||||
/** @var RouteHandlerFactory $factory */
|
|
||||||
$factory = $container->make(RouteHandlerFactory::class);
|
|
||||||
|
|
||||||
foreach ($this->removedRoutes as $routeName) {
|
|
||||||
$collection->removeRoute($routeName);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($this->routes as $route) {
|
|
||||||
$collection->addRoute(
|
|
||||||
$route['method'],
|
|
||||||
$route['path'],
|
|
||||||
$route['name'],
|
|
||||||
$factory->toController($route['handler'])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -12,7 +12,7 @@ namespace Flarum\Extend;
|
|||||||
use Flarum\Extension\Extension;
|
use Flarum\Extension\Extension;
|
||||||
use Flarum\Foundation\ContainerUtil;
|
use Flarum\Foundation\ContainerUtil;
|
||||||
use Illuminate\Contracts\Container\Container;
|
use Illuminate\Contracts\Container\Container;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class ThrottleApi implements ExtenderInterface
|
class ThrottleApi implements ExtenderInterface
|
||||||
{
|
{
|
||||||
@@ -23,10 +23,10 @@ class ThrottleApi implements ExtenderInterface
|
|||||||
* Add a new throttler (or override one with the same name).
|
* Add a new throttler (or override one with the same name).
|
||||||
*
|
*
|
||||||
* @param string $name: The name of the throttler.
|
* @param string $name: The name of the throttler.
|
||||||
* @param (callable(ServerRequestInterface $request): bool)|class-string $callback
|
* @param (callable(Request $request): bool)|class-string $callback
|
||||||
*
|
*
|
||||||
* The callable can be a closure or invokable class, and should accept:
|
* The callable can be a closure or invokable class, and should accept:
|
||||||
* - $request: The current `\Psr\Http\Message\ServerRequestInterface` request object.
|
* - $request: The current `\Illuminate\Http\Request` request object.
|
||||||
* `\Flarum\Http\RequestUtil::getActor($request)` can be used to get the current user.
|
* `\Flarum\Http\RequestUtil::getActor($request)` can be used to get the current user.
|
||||||
* `$request->getAttribute('routeName')` can be used to get the current route.
|
* `$request->getAttribute('routeName')` can be used to get the current route.
|
||||||
* Please note that every throttler runs by default on every route.
|
* Please note that every throttler runs by default on every route.
|
||||||
|
Reference in New Issue
Block a user