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.
This commit is contained in:
Franz Liedke 2017-07-02 13:30:02 +02:00
parent 051bb5acb8
commit e46b3d54d1
No known key found for this signature in database
GPG Key ID: 9A0231A879B055F4
4 changed files with 143 additions and 123 deletions

View File

@ -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') : []]
));
}

View File

@ -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');

View File

@ -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();

View File

@ -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';
}
}