diff --git a/error/503.html b/error/503.html new file mode 100644 index 000000000..46243a1c5 --- /dev/null +++ b/error/503.html @@ -0,0 +1,13 @@ + + + + + + + + +

503 Service Unavailable

+

This forum is down for maintenance.

+ + + diff --git a/src/Admin/Server.php b/src/Admin/Server.php index d417d2f70..13469292c 100644 --- a/src/Admin/Server.php +++ b/src/Admin/Server.php @@ -15,7 +15,6 @@ use Flarum\Foundation\Application; use Flarum\Http\AbstractServer; use Zend\Stratigility\MiddlewarePipe; use Flarum\Http\Middleware\HandleErrors; -use Franzl\Middleware\Whoops\Middleware as WhoopsMiddleware; class Server extends AbstractServer { @@ -27,18 +26,21 @@ class Server extends AbstractServer $pipe = new MiddlewarePipe; if ($app->isInstalled()) { - $app->register('Flarum\Admin\AdminServiceProvider'); - $adminPath = parse_url($app->url('admin'), PHP_URL_PATH); - $routes = $app->make('flarum.admin.routes'); + $errorDir = __DIR__ . '/../../error'; - $pipe->pipe($adminPath, $app->make('Flarum\Http\Middleware\AuthenticateWithCookie')); - $pipe->pipe($adminPath, $app->make('Flarum\Http\Middleware\ParseJsonBody')); - $pipe->pipe($adminPath, $app->make('Flarum\Admin\Middleware\RequireAdministrateAbility')); - $pipe->pipe($adminPath, $app->make('Flarum\Http\Middleware\DispatchRoute', compact('routes'))); - - $pipe->pipe(new HandleErrors(__DIR__.'/../../error', $app->inDebugMode())); + if ($app->isUpToDate()) { + $pipe->pipe($adminPath, $app->make('Flarum\Http\Middleware\AuthenticateWithCookie')); + $pipe->pipe($adminPath, $app->make('Flarum\Http\Middleware\ParseJsonBody')); + $pipe->pipe($adminPath, $app->make('Flarum\Admin\Middleware\RequireAdministrateAbility')); + $pipe->pipe($adminPath, $app->make('Flarum\Http\Middleware\DispatchRoute', ['routes' => $app->make('flarum.admin.routes')])); + $pipe->pipe($adminPath, new HandleErrors($errorDir, $app->inDebugMode())); + } else { + $app->register('Flarum\Update\UpdateServiceProvider'); + $pipe->pipe($adminPath, $app->make('Flarum\Http\Middleware\DispatchRoute', ['routes' => $app->make('flarum.update.routes')])); + $pipe->pipe($adminPath, new HandleErrors($errorDir, true)); + } } return $pipe; diff --git a/src/Api/Server.php b/src/Api/Server.php index 91b18dcfb..48f57dc0f 100644 --- a/src/Api/Server.php +++ b/src/Api/Server.php @@ -13,6 +13,7 @@ namespace Flarum\Api; use Flarum\Foundation\Application; use Flarum\Http\AbstractServer; +use Tobscure\JsonApi\Document; use Zend\Stratigility\MiddlewarePipe; class Server extends AbstractServer @@ -24,19 +25,27 @@ class Server extends AbstractServer { $pipe = new MiddlewarePipe; - if ($app->isInstalled()) { - $app->register('Flarum\Api\ApiServiceProvider'); - - $routes = $app->make('flarum.api.routes'); - $apiPath = parse_url($app->url('api'), PHP_URL_PATH); + $apiPath = parse_url($app->url('api'), PHP_URL_PATH); + if ($app->isInstalled() && $app->isUpToDate()) { $pipe->pipe($apiPath, $app->make('Flarum\Http\Middleware\AuthenticateWithCookie')); $pipe->pipe($apiPath, $app->make('Flarum\Api\Middleware\AuthenticateWithHeader')); $pipe->pipe($apiPath, $app->make('Flarum\Http\Middleware\ParseJsonBody')); $pipe->pipe($apiPath, $app->make('Flarum\Api\Middleware\FakeHttpMethods')); - $pipe->pipe($apiPath, $app->make('Flarum\Http\Middleware\DispatchRoute', compact('routes'))); - + $pipe->pipe($apiPath, $app->make('Flarum\Http\Middleware\DispatchRoute', ['routes' => $app->make('flarum.api.routes')])); $pipe->pipe($apiPath, $app->make('Flarum\Api\Middleware\HandleErrors')); + } else { + $pipe->pipe($apiPath, function () { + $document = new Document; + $document->setErrors([ + [ + 'code' => 503, + 'title' => 'Service Unavailable' + ] + ]); + + return new JsonApiResponse($document, 503); + }); } return $pipe; diff --git a/src/Console/Server.php b/src/Console/Server.php index 91a193e1b..f63d2d7e6 100644 --- a/src/Console/Server.php +++ b/src/Console/Server.php @@ -32,12 +32,9 @@ class Server extends AbstractServer $console = new Application('Flarum', $app::VERSION); - if (! $app->isInstalled()) { - $app->register('Flarum\Install\InstallServiceProvider'); - - $console->add($app->make('Flarum\Install\Console\InstallCommand')); - } + $app->register('Flarum\Install\InstallServiceProvider'); + $console->add($app->make('Flarum\Install\Console\InstallCommand')); $console->add($app->make('Flarum\Console\Command\UpgradeCommand')); $console->add($app->make('Flarum\Console\Command\GenerateExtensionCommand')); $console->add($app->make('Flarum\Console\Command\GenerateMigrationCommand')); diff --git a/src/Forum/Server.php b/src/Forum/Server.php index 0adde2019..03d0b3029 100644 --- a/src/Forum/Server.php +++ b/src/Forum/Server.php @@ -13,6 +13,7 @@ namespace Flarum\Forum; use Flarum\Foundation\Application; use Flarum\Http\AbstractServer; +use Zend\Diactoros\Response\HtmlResponse; use Zend\Stratigility\MiddlewarePipe; use Flarum\Http\Middleware\HandleErrors; @@ -25,26 +26,25 @@ class Server extends AbstractServer { $pipe = new MiddlewarePipe; - $installed = $app->isInstalled(); $basePath = parse_url($app->url(), PHP_URL_PATH); + $errorDir = __DIR__.'/../../error'; - if ($installed) { - $app->register('Flarum\Forum\ForumServiceProvider'); - - $routes = $app->make('flarum.forum.routes'); - - $pipe->pipe($basePath, $app->make('Flarum\Http\Middleware\AuthenticateWithCookie')); - $pipe->pipe($basePath, $app->make('Flarum\Http\Middleware\ParseJsonBody')); - } else { + if (! $app->isInstalled()) { $app->register('Flarum\Install\InstallServiceProvider'); - $routes = $app->make('flarum.install.routes'); + $pipe->pipe($basePath, $app->make('Flarum\Http\Middleware\DispatchRoute', ['routes' => $app->make('flarum.install.routes')])); + $pipe->pipe($basePath, new HandleErrors($errorDir, true)); + } elseif ($app->isUpToDate()) { + $pipe->pipe($basePath, $app->make('Flarum\Http\Middleware\AuthenticateWithCookie')); + $pipe->pipe($basePath, $app->make('Flarum\Http\Middleware\ParseJsonBody')); + $pipe->pipe($basePath, $app->make('Flarum\Http\Middleware\DispatchRoute', ['routes' => $app->make('flarum.forum.routes')])); + $pipe->pipe($basePath, new HandleErrors($errorDir, $app->inDebugMode())); + } else { + $pipe->pipe($basePath, function () use ($errorDir) { + return new HtmlResponse(file_get_contents($errorDir.'/503.html', 503)); + }); } - $pipe->pipe($basePath, $app->make('Flarum\Http\Middleware\DispatchRoute', compact('routes'))); - - $pipe->pipe(new HandleErrors(__DIR__.'/../../error', $app->inDebugMode() || ! $installed)); - return $pipe; } } diff --git a/src/Install/Controller/IndexController.php b/src/Install/Controller/IndexController.php index db14cb595..d793defa9 100644 --- a/src/Install/Controller/IndexController.php +++ b/src/Install/Controller/IndexController.php @@ -44,16 +44,15 @@ class IndexController extends AbstractHtmlController */ public function render(Request $request, array $routeParams = []) { - $view = $this->view->make('flarum.install::app'); + $view = $this->view->make('flarum.install::app')->with('title', 'Install Flarum'); $this->prerequisite->check(); $errors = $this->prerequisite->getErrors(); if (count($errors)) { - $view->content = $this->view->make('flarum.install::errors'); - $view->content->errors = $errors; + $view->with('content', $this->view->make('flarum.install::errors')->with('errors', $errors)); } else { - $view->content = $this->view->make('flarum.install::install'); + $view->with('content', $this->view->make('flarum.install::install')); } return $view; diff --git a/src/Install/Controller/InstallController.php b/src/Install/Controller/InstallController.php index e76566b4a..c14af5187 100644 --- a/src/Install/Controller/InstallController.php +++ b/src/Install/Controller/InstallController.php @@ -12,8 +12,7 @@ namespace Flarum\Install\Controller; use Flarum\Http\Controller\ControllerInterface; use Psr\Http\Message\ServerRequestInterface as Request; -use Zend\Diactoros\Response\EmptyResponse; -use Zend\Diactoros\Response\JsonResponse; +use Zend\Diactoros\Response\HtmlResponse; use Zend\Diactoros\Response; use Flarum\Install\Console\InstallCommand; use Flarum\Install\Console\DefaultsDataProvider; @@ -85,9 +84,7 @@ class InstallController implements ControllerInterface try { $this->command->run($input, $output); } catch (Exception $e) { - return new JsonResponse([ - 'error' => $e->getMessage() - ], 500); + return new HtmlResponse($e->getMessage(), 500); } $token = $this->bus->dispatch( diff --git a/src/Console/Command/UpgradeCommand.php b/src/Update/Console/MigrateCommand.php similarity index 78% rename from src/Console/Command/UpgradeCommand.php rename to src/Update/Console/MigrateCommand.php index 0482d52aa..af2bd9089 100644 --- a/src/Console/Command/UpgradeCommand.php +++ b/src/Update/Console/MigrateCommand.php @@ -8,15 +8,16 @@ * file that was distributed with this source code. */ -namespace Flarum\Console\Command; +namespace Flarum\Update\Console; +use Flarum\Console\Command\AbstractCommand; use Illuminate\Contracts\Container\Container; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Output\OutputInterface; -class UpgradeCommand extends AbstractCommand +class MigrateCommand extends AbstractCommand { /** * @var Container @@ -39,8 +40,8 @@ class UpgradeCommand extends AbstractCommand protected function configure() { $this - ->setName('upgrade') - ->setDescription("Run Flarum's upgrade script"); + ->setName('migrate') + ->setDescription("Run outstanding migrations."); } /** @@ -48,7 +49,7 @@ class UpgradeCommand extends AbstractCommand */ protected function fire() { - $this->info('Upgrading Flarum...'); + $this->info('Migrating Flarum...'); $this->upgrade(); @@ -66,7 +67,7 @@ class UpgradeCommand extends AbstractCommand $migrator->run(base_path('core/migrations')); foreach ($migrator->getNotes() as $note) { -// $this->info($note); + $this->info($note); } $extensions = $this->container->make('Flarum\Extension\ExtensionManager'); @@ -78,13 +79,15 @@ class UpgradeCommand extends AbstractCommand continue; } -// $this->info('Upgrading extension: '.$extension->name); + $this->info('Migrating extension: '.$name); $extensions->migrate($name); foreach ($migrator->getNotes() as $note) { -// $this->info($note); + $this->info($note); } } + + $this->container->make('Flarum\Settings\SettingsRepositoryInterface')->set('version', $this->container->version()); } } diff --git a/src/Update/Controller/IndexController.php b/src/Update/Controller/IndexController.php new file mode 100644 index 000000000..559e23f23 --- /dev/null +++ b/src/Update/Controller/IndexController.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Flarum\Update\Controller; + +use Flarum\Http\Controller\AbstractHtmlController; +use Psr\Http\Message\ServerRequestInterface as Request; +use Illuminate\Contracts\View\Factory; + +class IndexController extends AbstractHtmlController +{ + /** + * @var Factory + */ + protected $view; + + /** + * @param Factory $view + */ + public function __construct(Factory $view) + { + $this->view = $view; + } + + /** + * @param Request $request + * @param array $routeParams + * @return \Psr\Http\Message\ResponseInterface + */ + public function render(Request $request, array $routeParams = []) + { + $view = $this->view->make('flarum.update::app')->with('title', 'Update Flarum'); + + $view->with('content', $this->view->make('flarum.update::update')); + + return $view; + } +} diff --git a/src/Update/Controller/UpdateController.php b/src/Update/Controller/UpdateController.php new file mode 100644 index 000000000..5ace721a5 --- /dev/null +++ b/src/Update/Controller/UpdateController.php @@ -0,0 +1,68 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Flarum\Update\Controller; + +use Exception; +use Flarum\Foundation\Application; +use Flarum\Http\Controller\ControllerInterface; +use Flarum\Update\Console\MigrateCommand; +use Illuminate\Contracts\Bus\Dispatcher; +use Psr\Http\Message\ServerRequestInterface as Request; +use Symfony\Component\Console\Input\StringInput; +use Symfony\Component\Console\Output\StreamOutput; +use Zend\Diactoros\Response; +use Zend\Diactoros\Response\HtmlResponse; + +class UpdateController implements ControllerInterface +{ + protected $command; + + /** + * @var Application + */ + protected $app; + + /** + * @param MigrateCommand $command + * @param Application $app + */ + public function __construct(MigrateCommand $command, Application $app) + { + $this->command = $command; + $this->app = $app; + } + + /** + * @param Request $request + * @param array $routeParams + * @return \Psr\Http\Message\ResponseInterface + */ + public function handle(Request $request, array $routeParams = []) + { + $input = $request->getParsedBody(); + + if (array_get($input, 'databasePassword') !== $this->app->config('database.password')) { + return new HtmlResponse('Incorrect database password.', 500); + } + + $body = fopen('php://temp', 'wb+'); + $input = new StringInput(''); + $output = new StreamOutput($body); + + try { + $this->command->run($input, $output); + } catch (Exception $e) { + return new HtmlResponse($e->getMessage(), 500); + } + + return new Response($body, 200); + } +} diff --git a/src/Update/UpdateServiceProvider.php b/src/Update/UpdateServiceProvider.php new file mode 100644 index 000000000..8004f75e5 --- /dev/null +++ b/src/Update/UpdateServiceProvider.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Flarum\Update; + +use Flarum\Http\GenerateRouteHandlerTrait; +use Flarum\Http\RouteCollection; +use Flarum\Foundation\AbstractServiceProvider; +use Psr\Http\Message\ServerRequestInterface; + +class UpdateServiceProvider extends AbstractServiceProvider +{ + use GenerateRouteHandlerTrait; + + /** + * {@inheritdoc} + */ + public function register() + { + $this->app->singleton('flarum.update.routes', function () { + return $this->getRoutes(); + }); + + $this->loadViewsFrom(__DIR__.'/../../views/install', 'flarum.update'); + } + + /** + * @return RouteCollection + */ + protected function getRoutes() + { + $routes = new RouteCollection; + + $toController = $this->getHandlerGenerator($this->app); + + $routes->get( + '/', + 'index', + $toController('Flarum\Update\Controller\IndexController') + ); + + $routes->post( + '/', + 'update', + $toController('Flarum\Update\Controller\UpdateController') + ); + + return $routes; + } +} diff --git a/views/install/app.php b/views/install/app.php index e6facc153..c3403a4bb 100644 --- a/views/install/app.php +++ b/views/install/app.php @@ -3,7 +3,7 @@ - Install Flarum + <?php echo $title; ?>