From e46b3d54d1b7cef6f475b8a8f843eac3388360ae Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Sun, 2 Jul 2017 13:30:02 +0200 Subject: [PATCH] Extract Flarum\Foundation\Site class This class holds all information relevant to a local Flarum site, such as paths and local configuration. From this information, it is able to instantiate a Flarum\Foundation\Application instance, which represents a Flarum installation's runtime. This will also be useful for setting up e.g. multi-tenant environments. --- src/Console/Server.php | 35 +++-- src/Foundation/Application.php | 3 +- .../{AbstractServer.php => Site.php} | 147 ++++++++---------- src/Http/Server.php | 81 ++++++---- 4 files changed, 143 insertions(+), 123 deletions(-) rename src/Foundation/{AbstractServer.php => Site.php} (61%) diff --git a/src/Console/Server.php b/src/Console/Server.php index f7ad12cbb..36cdea59d 100644 --- a/src/Console/Server.php +++ b/src/Console/Server.php @@ -13,14 +13,30 @@ namespace Flarum\Console; use Flarum\Database\Console\GenerateMigrationCommand; use Flarum\Database\Console\MigrateCommand; -use Flarum\Foundation\AbstractServer; +use Flarum\Foundation\Application; use Flarum\Foundation\Console\CacheClearCommand; use Flarum\Foundation\Console\InfoCommand; +use Flarum\Foundation\Site; use Flarum\Install\Console\InstallCommand; -use Symfony\Component\Console\Application; +use Flarum\Install\InstallServiceProvider; +use Symfony\Component\Console\Application as ConsoleApplication; -class Server extends AbstractServer +class Server { + /** + * @param Site $site + * @return Server + */ + public static function fromSite(Site $site) + { + return new static($site->boot()); + } + + public function __construct(Application $app) + { + $this->app = $app; + } + public function listen() { $console = $this->getConsoleApplication(); @@ -29,14 +45,13 @@ class Server extends AbstractServer } /** - * @return Application + * @return ConsoleApplication */ protected function getConsoleApplication() { - $app = $this->getApp(); - $console = new Application('Flarum', $app->version()); + $console = new ConsoleApplication('Flarum', $this->app->version()); - $app->register('Flarum\Install\InstallServiceProvider'); + $this->app->register(InstallServiceProvider::class); $commands = [ InstallCommand::class, @@ -44,7 +59,7 @@ class Server extends AbstractServer GenerateMigrationCommand::class, ]; - if ($app->isInstalled()) { + if ($this->app->isInstalled()) { $commands = array_merge($commands, [ InfoCommand::class, CacheClearCommand::class @@ -52,9 +67,9 @@ class Server extends AbstractServer } foreach ($commands as $command) { - $console->add($app->make( + $console->add($this->app->make( $command, - ['config' => $app->isInstalled() ? $app->make('flarum.config') : []] + ['config' => $this->app->isInstalled() ? $this->app->make('flarum.config') : []] )); } diff --git a/src/Foundation/Application.php b/src/Foundation/Application.php index a432bdbb8..85533ffd9 100644 --- a/src/Foundation/Application.php +++ b/src/Foundation/Application.php @@ -11,6 +11,7 @@ namespace Flarum\Foundation; +use Flarum\Settings\SettingsRepositoryInterface; use Illuminate\Container\Container; use Illuminate\Contracts\Foundation\Application as ApplicationContract; use Illuminate\Events\EventServiceProvider; @@ -125,7 +126,7 @@ class Application extends Container implements ApplicationContract public function isUpToDate() { - $settings = $this->make('Flarum\Settings\SettingsRepositoryInterface'); + $settings = $this->make(SettingsRepositoryInterface::class); try { $version = $settings->get('version'); diff --git a/src/Foundation/AbstractServer.php b/src/Foundation/Site.php similarity index 61% rename from src/Foundation/AbstractServer.php rename to src/Foundation/Site.php index bcc7c534b..d59b6f056 100644 --- a/src/Foundation/AbstractServer.php +++ b/src/Foundation/Site.php @@ -11,12 +11,35 @@ namespace Flarum\Foundation; +use Flarum\Admin\AdminServiceProvider; +use Flarum\Api\ApiServiceProvider; +use Flarum\Database\DatabaseServiceProvider; +use Flarum\Database\MigrationServiceProvider; +use Flarum\Discussion\DiscussionServiceProvider; +use Flarum\Extension\ExtensionServiceProvider; +use Flarum\Formatter\FormatterServiceProvider; +use Flarum\Forum\ForumServiceProvider; +use Flarum\Group\GroupServiceProvider; +use Flarum\Locale\LocaleServiceProvider; +use Flarum\Notification\NotificationServiceProvider; +use Flarum\Post\PostServiceProvider; +use Flarum\Search\SearchServiceProvider; +use Flarum\Settings\SettingsRepositoryInterface; +use Flarum\Settings\SettingsServiceProvider; +use Flarum\User\UserServiceProvider; +use Illuminate\Bus\BusServiceProvider; use Illuminate\Config\Repository as ConfigRepository; +use Illuminate\Filesystem\FilesystemServiceProvider; +use Illuminate\Hashing\HashServiceProvider; +use Illuminate\Mail\MailServiceProvider; +use Illuminate\Validation\ValidationServiceProvider; +use Illuminate\View\ViewServiceProvider; use Monolog\Formatter\LineFormatter; use Monolog\Handler\StreamHandler; use Monolog\Logger; -abstract class AbstractServer +// TODO: This should be an interface maybe? +class Site { /** * @var Application @@ -43,27 +66,12 @@ abstract class AbstractServer */ protected $config; - /** - * @var callable[] - */ - protected $extendCallbacks = []; + protected $extenders = []; - /** - * @param null $basePath - * @param null $publicPath - */ - public function __construct($basePath = null, $publicPath = null) + public function __construct() { - if ($basePath === null) { - $basePath = getcwd(); - } - - if ($publicPath === null) { - $publicPath = $basePath; - } - - $this->basePath = $basePath; - $this->publicPath = $publicPath; + $this->basePath = getcwd(); + $this->publicPath = $this->basePath; if (file_exists($file = $this->basePath.'/config.php')) { $this->config = include $file; @@ -71,81 +79,61 @@ abstract class AbstractServer } /** - * @return string + * @return Application */ - public function getBasePath() + public function boot() { - return $this->basePath; - } - - /** - * @return string - */ - public function getPublicPath() - { - return $this->publicPath; - } - - /** - * @return string - */ - public function getStoragePath() - { - return $this->storagePath; + return $this->getApp(); } /** * @param $basePath + * @return static */ public function setBasePath($basePath) { $this->basePath = $basePath; + + return $this; } /** * @param $publicPath + * @return static */ public function setPublicPath($publicPath) { $this->publicPath = $publicPath; + + return $this; } /** * @param $storagePath + * @return static */ public function setStoragePath($storagePath) { $this->storagePath = $storagePath; - } - /** - * @return array - */ - public function getConfig() - { - return $this->config; + return $this; } /** * @param array $config + * @return static */ public function setConfig(array $config) { $this->config = $config; - } - /** - * @param callable $callback - */ - public function extend(callable $callback) - { - $this->extendCallbacks[] = $callback; + return $this; } /** * @return Application */ - public function getApp() + protected function getApp() { if ($this->app !== null) { return $this->app; @@ -167,19 +155,19 @@ abstract class AbstractServer $this->registerCache($app); - $app->register('Flarum\Database\DatabaseServiceProvider'); - $app->register('Flarum\Database\MigrationServiceProvider'); - $app->register('Flarum\Settings\SettingsServiceProvider'); - $app->register('Flarum\Locale\LocaleServiceProvider'); - $app->register('Illuminate\Bus\BusServiceProvider'); - $app->register('Illuminate\Filesystem\FilesystemServiceProvider'); - $app->register('Illuminate\Hashing\HashServiceProvider'); - $app->register('Illuminate\Mail\MailServiceProvider'); - $app->register('Illuminate\View\ViewServiceProvider'); - $app->register('Illuminate\Validation\ValidationServiceProvider'); + $app->register(DatabaseServiceProvider::class); + $app->register(MigrationServiceProvider::class); + $app->register(SettingsServiceProvider::class); + $app->register(LocaleServiceProvider::class); + $app->register(BusServiceProvider::class); + $app->register(FilesystemServiceProvider::class); + $app->register(HashServiceProvider::class); + $app->register(MailServiceProvider::class); + $app->register(ViewServiceProvider::class); + $app->register(ValidationServiceProvider::class); if ($app->isInstalled() && $app->isUpToDate()) { - $settings = $app->make('Flarum\Settings\SettingsRepositoryInterface'); + $settings = $app->make(SettingsRepositoryInterface::class); $config->set('mail.driver', $settings->get('mail_driver')); $config->set('mail.host', $settings->get('mail_host')); @@ -190,25 +178,26 @@ abstract class AbstractServer $config->set('mail.username', $settings->get('mail_username')); $config->set('mail.password', $settings->get('mail_password')); - $app->register('Flarum\BusServiceProvider'); + $app->register(\Flarum\BusServiceProvider::class); - $app->register('Flarum\Discussion\DiscussionServiceProvider'); - $app->register('Flarum\Formatter\FormatterServiceProvider'); - $app->register('Flarum\Group\GroupServiceProvider'); - $app->register('Flarum\Notification\NotificationServiceProvider'); - $app->register('Flarum\Post\PostServiceProvider'); - $app->register('Flarum\Search\SearchServiceProvider'); - $app->register('Flarum\User\UserServiceProvider'); + $app->register(DiscussionServiceProvider::class); + $app->register(FormatterServiceProvider::class); + $app->register(GroupServiceProvider::class); + $app->register(NotificationServiceProvider::class); + $app->register(PostServiceProvider::class); + $app->register(SearchServiceProvider::class); + $app->register(UserServiceProvider::class); - $app->register('Flarum\Api\ApiServiceProvider'); - $app->register('Flarum\Forum\ForumServiceProvider'); - $app->register('Flarum\Admin\AdminServiceProvider'); + $app->register(ApiServiceProvider::class); + $app->register(ForumServiceProvider::class); + $app->register(AdminServiceProvider::class); - foreach ($this->extendCallbacks as $callback) { - $app->call($callback); + foreach ($this->extenders as $extender) { + // TODO: Create extenders architecture + // $extender->apply($app); } - $app->register('Flarum\Extension\ExtensionServiceProvider'); + $app->register(ExtensionServiceProvider::class); } $app->boot(); diff --git a/src/Http/Server.php b/src/Http/Server.php index 86ce0af6a..590a73a24 100644 --- a/src/Http/Server.php +++ b/src/Http/Server.php @@ -11,8 +11,8 @@ namespace Flarum\Http; -use Flarum\Foundation\AbstractServer; use Flarum\Foundation\Application; +use Flarum\Foundation\Site; use Flarum\Http\Middleware\DispatchRoute; use Flarum\Http\Middleware\HandleErrors; use Flarum\Http\Middleware\StartSession; @@ -29,8 +29,22 @@ use Zend\Stratigility\MiddlewareInterface; use Zend\Stratigility\MiddlewarePipe; use Zend\Stratigility\NoopFinalHandler; -class Server extends AbstractServer +class Server { + /** + * @param Site $site + * @return Server + */ + public static function fromSite(Site $site) + { + return new static($site->boot()); + } + + public function __construct(Application $app) + { + $this->app = $app; + } + public function listen() { DiactorosServer::createServer( @@ -53,43 +67,44 @@ class Server extends AbstractServer */ public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $out) { - $app = $this->getApp(); + $this->collectGarbage(); - $this->collectGarbage($app); - - $middleware = $this->getMiddleware($app, $request->getUri()->getPath()); + $middleware = $this->getMiddleware($request->getUri()->getPath()); return $middleware($request, $response, $out); } /** - * @param Application $app * @param string $requestPath * @return MiddlewareInterface */ - protected function getMiddleware(Application $app, $requestPath) + protected function getMiddleware($requestPath) { $pipe = new MiddlewarePipe; $pipe->raiseThrowables(); - if (! $app->isInstalled()) { - return $this->getInstallerMiddleware($pipe, $app); - } elseif ($app->isDownForMaintenance()) { - return $this->getMaintenanceMiddleware($pipe); - } elseif (! $app->isUpToDate()) { - return $this->getUpdaterMiddleware($pipe, $app); + if (! $this->app->isInstalled()) { + return $this->getInstallerMiddleware($pipe); } - $forum = parse_url($app->url(''), PHP_URL_PATH) ?: '/'; - $admin = parse_url($app->url('admin'), PHP_URL_PATH); - $api = parse_url($app->url('api'), PHP_URL_PATH); + if ($this->app->isDownForMaintenance()) { + return $this->getMaintenanceMiddleware($pipe); + } + + if (! $this->app->isUpToDate()) { + return $this->getUpdaterMiddleware($pipe); + } + + $api = parse_url($this->app->url('api'), PHP_URL_PATH); + $admin = parse_url($this->app->url('admin'), PHP_URL_PATH); + $forum = parse_url($this->app->url(''), PHP_URL_PATH) ?: '/'; if ($this->pathStartsWith($requestPath, $api)) { - $pipe->pipe($api, $app->make('flarum.api.middleware')); + $pipe->pipe($api, $this->app->make('flarum.api.middleware')); } elseif ($this->pathStartsWith($requestPath, $admin)) { - $pipe->pipe($admin, $app->make('flarum.admin.middleware')); + $pipe->pipe($admin, $this->app->make('flarum.admin.middleware')); } else { - $pipe->pipe($forum, $app->make('flarum.forum.middleware')); + $pipe->pipe($forum, $this->app->make('flarum.forum.middleware')); } return $pipe; @@ -100,14 +115,14 @@ class Server extends AbstractServer return $path === $prefix || starts_with($path, "$prefix/"); } - protected function getInstallerMiddleware(MiddlewarePipe $pipe, Application $app) + protected function getInstallerMiddleware(MiddlewarePipe $pipe) { - $app->register(InstallServiceProvider::class); + $this->app->register(InstallServiceProvider::class); - $pipe->pipe(new HandleErrors($this->getErrorDir(), $app->make('log'), true)); + $pipe->pipe(new HandleErrors($this->getErrorDir(), $this->app->make('log'), true)); - $pipe->pipe($app->make(StartSession::class)); - $pipe->pipe($app->make(DispatchRoute::class, ['routes' => $app->make('flarum.install.routes')])); + $pipe->pipe($this->app->make(StartSession::class)); + $pipe->pipe($this->app->make(DispatchRoute::class, ['routes' => $this->app->make('flarum.install.routes')])); return $pipe; } @@ -123,11 +138,11 @@ class Server extends AbstractServer return $pipe; } - protected function getUpdaterMiddleware(MiddlewarePipe $pipe, Application $app) + protected function getUpdaterMiddleware(MiddlewarePipe $pipe) { - $app->register(UpdateServiceProvider::class); + $this->app->register(UpdateServiceProvider::class); - $pipe->pipe($app->make(DispatchRoute::class, ['routes' => $app->make('flarum.update.routes')])); + $pipe->pipe($this->app->make(DispatchRoute::class, ['routes' => $this->app->make('flarum.update.routes')])); // TODO: FOR API render JSON-API error document for HTTP 503 @@ -147,13 +162,13 @@ class Server extends AbstractServer } } - private function getErrorDir() - { - return __DIR__.'/../../error'; - } - private function hitsLottery() { return mt_rand(1, 100) <= 2; } + + private function getErrorDir() + { + return __DIR__.'/../../error'; + } }