Simplify PrerequisiteInterface

I went with a return type of Collection, because it is easier to call
methods such as isEmpty() directly on those objects.
This commit is contained in:
Franz Liedke 2018-11-13 22:23:52 +01:00
parent 3314a84b4e
commit 9a415670a3
11 changed files with 98 additions and 97 deletions

View File

@ -80,21 +80,16 @@ class InstallCommand extends AbstractCommand
{ {
$this->init(); $this->init();
$prerequisites = $this->installation->prerequisites(); $problems = $this->installation->prerequisites()->problems();
$prerequisites->check();
$errors = $prerequisites->getErrors();
if (empty($errors)) { if ($problems->isEmpty()) {
$this->info('Installing Flarum...'); $this->info('Installing Flarum...');
$this->install(); $this->install();
$this->info('DONE.'); $this->info('DONE.');
} else { } else {
$this->output->writeln( $this->showProblems($problems);
'<error>Please fix the following errors before we can continue with the installation.</error>'
);
$this->showErrors($errors);
} }
} }
@ -178,13 +173,17 @@ class InstallCommand extends AbstractCommand
->run(); ->run();
} }
protected function showErrors($errors) protected function showProblems($problems)
{ {
foreach ($errors as $error) { $this->output->writeln(
$this->info($error['message']); '<error>Please fix the following problems before we can continue with the installation.</error>'
);
if (isset($error['detail'])) { foreach ($problems as $problem) {
$this->output->writeln('<comment>'.$error['detail'].'</comment>'); $this->info($problem['message']);
if (isset($problem['detail'])) {
$this->output->writeln('<comment>'.$problem['detail'].'</comment>');
} }
} }
} }

View File

@ -46,14 +46,12 @@ class IndexController extends AbstractHtmlController
{ {
$view = $this->view->make('flarum.install::app')->with('title', 'Install Flarum'); $view = $this->view->make('flarum.install::app')->with('title', 'Install Flarum');
$prerequisites = $this->installation->prerequisites(); $problems = $this->installation->prerequisites()->problems();
$prerequisites->check();
$errors = $prerequisites->getErrors();
if (count($errors)) { if ($problems->isEmpty()) {
$view->with('content', $this->view->make('flarum.install::errors')->with('errors', $errors));
} else {
$view->with('content', $this->view->make('flarum.install::install')); $view->with('content', $this->view->make('flarum.install::install'));
} else {
$view->with('content', $this->view->make('flarum.install::problems')->with('problems', $problems));
} }
return $view; return $view;

View File

@ -1,24 +0,0 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Install\Prerequisite;
abstract class AbstractPrerequisite implements PrerequisiteInterface
{
protected $errors = [];
abstract public function check();
public function getErrors()
{
return $this->errors;
}
}

View File

@ -11,6 +11,8 @@
namespace Flarum\Install\Prerequisite; namespace Flarum\Install\Prerequisite;
use Illuminate\Support\Collection;
class Composite implements PrerequisiteInterface class Composite implements PrerequisiteInterface
{ {
/** /**
@ -25,21 +27,14 @@ class Composite implements PrerequisiteInterface
} }
} }
public function check() public function problems(): Collection
{ {
return array_reduce( return array_reduce(
$this->prerequisites, $this->prerequisites,
function ($previous, PrerequisiteInterface $prerequisite) { function (Collection $errors, PrerequisiteInterface $condition) {
return $prerequisite->check() && $previous; return $errors->concat($condition->problems());
}, },
true collect()
); );
} }
public function getErrors()
{
return collect($this->prerequisites)->map(function (PrerequisiteInterface $prerequisite) {
return $prerequisite->getErrors();
})->reduce('array_merge', []);
}
} }

View File

@ -11,7 +11,9 @@
namespace Flarum\Install\Prerequisite; namespace Flarum\Install\Prerequisite;
class PhpExtensions extends AbstractPrerequisite use Illuminate\Support\Collection;
class PhpExtensions implements PrerequisiteInterface
{ {
protected $extensions; protected $extensions;
@ -20,14 +22,15 @@ class PhpExtensions extends AbstractPrerequisite
$this->extensions = $extensions; $this->extensions = $extensions;
} }
public function check() public function problems(): Collection
{ {
foreach ($this->extensions as $extension) { return collect($this->extensions)
if (! extension_loaded($extension)) { ->reject(function ($extension) {
$this->errors[] = [ return extension_loaded($extension);
})->map(function ($extension) {
return [
'message' => "The PHP extension '$extension' is required.", 'message' => "The PHP extension '$extension' is required.",
]; ];
} });
}
} }
} }

View File

@ -11,7 +11,9 @@
namespace Flarum\Install\Prerequisite; namespace Flarum\Install\Prerequisite;
class PhpVersion extends AbstractPrerequisite use Illuminate\Support\Collection;
class PhpVersion implements PrerequisiteInterface
{ {
protected $minVersion; protected $minVersion;
@ -20,13 +22,15 @@ class PhpVersion extends AbstractPrerequisite
$this->minVersion = $minVersion; $this->minVersion = $minVersion;
} }
public function check() public function problems(): Collection
{ {
if (version_compare(PHP_VERSION, $this->minVersion, '<')) { if (version_compare(PHP_VERSION, $this->minVersion, '<')) {
$this->errors[] = [ return collect()->push([
'message' => "PHP $this->minVersion is required.", 'message' => "PHP $this->minVersion is required.",
'detail' => 'You are running version '.PHP_VERSION.'. Talk to your hosting provider about upgrading to the latest PHP version.', 'detail' => 'You are running version '.PHP_VERSION.'. Talk to your hosting provider about upgrading to the latest PHP version.',
]; ]);
} }
return collect();
} }
} }

View File

@ -11,9 +11,18 @@
namespace Flarum\Install\Prerequisite; namespace Flarum\Install\Prerequisite;
use Illuminate\Support\Collection;
interface PrerequisiteInterface interface PrerequisiteInterface
{ {
public function check(); /**
* Verify that this prerequisite is fulfilled.
public function getErrors(); *
* If everything is okay, this method should return an empty Collection
* instance. When problems are detected, it should return a Collection of
* arrays, each having at least a "message" and optionally a "detail" key.
*
* @return Collection
*/
public function problems(): Collection;
} }

View File

@ -11,7 +11,9 @@
namespace Flarum\Install\Prerequisite; namespace Flarum\Install\Prerequisite;
class WritablePaths extends AbstractPrerequisite use Illuminate\Support\Collection;
class WritablePaths implements PrerequisiteInterface
{ {
protected $paths; protected $paths;
@ -20,21 +22,36 @@ class WritablePaths extends AbstractPrerequisite
$this->paths = $paths; $this->paths = $paths;
} }
public function check() public function problems(): Collection
{ {
foreach ($this->paths as $path) { return $this->getMissingPaths()
if (! file_exists($path)) { ->concat($this->getNonWritablePaths());
$this->errors[] = [ }
private function getMissingPaths(): Collection
{
return collect($this->paths)
->reject(function ($path) {
return file_exists($path);
})->map(function ($path) {
return [
'message' => 'The '.$this->getAbsolutePath($path).' directory doesn\'t exist', 'message' => 'The '.$this->getAbsolutePath($path).' directory doesn\'t exist',
'detail' => 'This directory is necessary for the installation. Please create the folder.', 'detail' => 'This directory is necessary for the installation. Please create the folder.',
]; ];
} elseif (! is_writable($path)) { });
$this->errors[] = [ }
private function getNonWritablePaths(): Collection
{
return collect($this->paths)
->filter(function ($path) {
return file_exists($path) && ! is_writable($path);
})->map(function ($path) {
return [
'message' => 'The '.$this->getAbsolutePath($path).' directory is not writable.', 'message' => 'The '.$this->getAbsolutePath($path).' directory is not writable.',
'detail' => 'Please chmod this directory'.($path !== public_path() ? ' and its contents' : '').' to 0775.' 'detail' => 'Please chmod this directory'.($path !== public_path() ? ' and its contents' : '').' to 0775.'
]; ];
} });
}
} }
private function getAbsolutePath($path) private function getAbsolutePath($path)

View File

@ -129,30 +129,30 @@
animation-name: fadeIn; animation-name: fadeIn;
} }
.Errors { .Problems {
margin-top: 50px; margin-top: 50px;
} }
.Errors .Error:first-child { .Problems .Problem:first-child {
border-top-left-radius: 4px; border-top-left-radius: 4px;
border-top-right-radius: 4px; border-top-right-radius: 4px;
} }
.Errors .Error:last-child { .Problems .Problem:last-child {
border-bottom-left-radius: 4px; border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px; border-bottom-right-radius: 4px;
} }
.Error { .Problem {
background: #EDF2F7; background: #EDF2F7;
margin: 0 0 1px; margin: 0 0 1px;
padding: 20px 25px; padding: 20px 25px;
text-align: left; text-align: left;
} }
.Error-message { .Problem-message {
font-size: 16px; font-size: 16px;
color: #3C5675; color: #3C5675;
font-weight: normal; font-weight: normal;
margin: 0; margin: 0;
} }
.Error-detail { .Problem-detail {
font-size: 13px; font-size: 13px;
margin: 5px 0 0; margin: 5px 0 0;
} }

View File

@ -1,14 +0,0 @@
<h2>Hold Up!</h2>
<p>These errors must be resolved before you can continue the installation. If you're having trouble, get help on the <a href="https://flarum.org/docs/install.html" target="_blank">Flarum website</a>.</p>
<div class="Errors">
<?php foreach ($errors as $error): ?>
<div class="Error">
<h3 class="Error-message"><?php echo $error['message']; ?></h3>
<?php if (! empty($error['detail'])): ?>
<p class="Error-detail"><?php echo $error['detail']; ?></p>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div>

View File

@ -0,0 +1,14 @@
<h2>Hold Up!</h2>
<p>These problems must be resolved before you can continue the installation. If you're having trouble, get help on the <a href="https://flarum.org/docs/install.html" target="_blank">Flarum website</a>.</p>
<div class="Problems">
<?php foreach ($problems as $problem): ?>
<div class="Problem">
<h3 class="Problem-message"><?php echo $problem['message']; ?></h3>
<?php if (! empty($problem['detail'])): ?>
<p class="Problem-detail"><?php echo $problem['detail']; ?></p>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div>