Display prerequisites for the setup (#3566)

* Display prerequisites for the setup
    - Block the doSetup() if SystemHealth is not true
    - Convert extensions when checking into array notation
    - Added new translations for the screen
    - New 'issues' page
    - Hide submit button when health is not good

* Fix more translations
This commit is contained in:
Benjamin Beganović 2020-03-30 14:30:32 +02:00 committed by GitHub
parent a6f3ca000d
commit 3bc84f86d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 136 additions and 55 deletions

View File

@ -1,6 +1,6 @@
<?php <?php
/** /**
* Invoice Ninja (https://invoiceninja.com) * Invoice Ninja (https://invoiceninja.com).
* *
* @link https://github.com/invoiceninja/invoiceninja source repository * @link https://github.com/invoiceninja/invoiceninja source repository
* *
@ -21,25 +21,30 @@ use Illuminate\Http\Response;
use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\Artisan;
/** /**
* Class SetupController * Class SetupController.
*/ */
class SetupController extends Controller class SetupController extends Controller
{ {
/**
* Main setup view.
*
* @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory
*/
public function index() public function index()
{ {
$data = SystemHealth::check(); $check = SystemHealth::check();
if ($data['system_health'] !== false) { return view('setup.index', ['check' => $check]);
return view('setup.index', $data);
}
if ($system_health !== true) {
return redirect('/');
}
} }
public function doSetup(StoreSetupRequest $request) public function doSetup(StoreSetupRequest $request)
{ {
$check = SystemHealth::check();
if ($check['system_status'] === false) {
return; /* This should never be reached. */
}
$_ENV['APP_KEY'] = config('app.key'); $_ENV['APP_KEY'] = config('app.key');
$_ENV['APP_URL'] = $request->input('url'); $_ENV['APP_URL'] = $request->input('url');
$_ENV['APP_DEBUG'] = $request->input('debug') ? 'true' : 'false'; $_ENV['APP_DEBUG'] = $request->input('debug') ? 'true' : 'false';
@ -82,9 +87,9 @@ class SetupController extends Controller
$fp = fopen($filePath, 'w'); $fp = fopen($filePath, 'w');
fwrite($fp, $config); fwrite($fp, $config);
fclose($fp); fclose($fp);
/* We need this in some environments that do not have STDIN defined */ /* We need this in some environments that do not have STDIN defined */
define('STDIN',fopen("php://stdin","r")); define('STDIN', fopen('php://stdin', 'r'));
/* Make sure no stale connections are cached */ /* Make sure no stale connections are cached */
\DB::purge('db-ninja-01'); \DB::purge('db-ninja-01');
@ -98,7 +103,7 @@ class SetupController extends Controller
if (Account::count() == 0) { if (Account::count() == 0) {
$account = CreateAccount::dispatchNow($request->all()); $account = CreateAccount::dispatchNow($request->all());
} }
return redirect('/'); return redirect('/');
} }
@ -109,7 +114,6 @@ class SetupController extends Controller
*/ */
public function checkDB(CheckDatabaseRequest $request): Response public function checkDB(CheckDatabaseRequest $request): Response
{ {
$status = SystemHealth::dbCheck($request); $status = SystemHealth::dbCheck($request);
info($status); info($status);
@ -128,17 +132,15 @@ class SetupController extends Controller
*/ */
public function checkMail(CheckMailRequest $request) public function checkMail(CheckMailRequest $request)
{ {
try { try {
$response_array = SystemHealth::testMailServer($request); $response_array = SystemHealth::testMailServer($request);
if(count($response_array) == 0) if (count($response_array) == 0) {
return response([], 200); return response([], 200);
else } else {
return response()->json($response_array, 200); return response()->json($response_array, 200);
}
` } catch (\Exception $e) {
} catch (\Exception $e) {
return response()->json(['message' => $e->getMessage()], 400); return response()->json(['message' => $e->getMessage()], 400);
} }
} }

View File

@ -1,6 +1,6 @@
<?php <?php
/** /**
* Invoice Ninja (https://invoiceninja.com) * Invoice Ninja (https://invoiceninja.com).
* *
* @link https://github.com/invoiceninja/invoiceninja source repository * @link https://github.com/invoiceninja/invoiceninja source repository
* *
@ -15,6 +15,7 @@ use App\Http\Requests\Setup\CheckDatabaseRequest;
use App\Http\Requests\Setup\CheckMailRequest; use App\Http\Requests\Setup\CheckMailRequest;
use App\Libraries\MultiDB; use App\Libraries\MultiDB;
use App\Mail\TestMailServer; use App\Mail\TestMailServer;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Mail;
@ -31,14 +32,13 @@ class SystemHealth
'gmp', 'gmp',
'openssl', 'openssl',
'mbstring', 'mbstring',
'xml' 'xml',
]; ];
private static $php_version = 7.3; private static $php_version = 7.3;
/** /**
* Check loaded extensions / PHP version / DB Connections * Check loaded extensions / PHP version / DB Connections.
* *
* @return array Result set of checks * @return array Result set of checks
*/ */
@ -46,20 +46,23 @@ class SystemHealth
{ {
$system_health = true; $system_health = true;
if (in_array(false, self::extensions())) { if (in_array(false, Arr::dot(self::extensions()))) {
$system_health = false; $system_health = false;
} elseif (phpversion() < self::$php_version) { } elseif (phpversion() < self::$php_version) {
$system_health = false; $system_health = false;
} }
return [ return [
'system_health' => (bool)$system_health, 'system_health' => (bool) $system_health,
'extensions' => self::extensions(), 'extensions' => self::extensions(),
'php_version' => phpversion(), 'php_version' => [
'min_php_version' => self::$php_version, 'minimum_php_version' => self::$php_version,
'current_php_version' => phpversion(),
'is_okay' => version_compare(phpversion(), self::$php_version, '>='),
],
'env_writable' => self::checkEnvWritable(),
//'dbs' => self::dbCheck(), //'dbs' => self::dbCheck(),
//'mail' => self::testMailServer(), //'mail' => self::testMailServer(),
'env_writable' => self::checkEnvWritable(),
]; ];
} }
@ -91,10 +94,10 @@ class SystemHealth
if (! config('ninja.db.multi_db_enabled')) { if (! config('ninja.db.multi_db_enabled')) {
try { try {
$pdo = DB::connection()->getPdo(); $pdo = DB::connection()->getPdo();
$result[] = [ DB::connection()->getDatabaseName() => true ]; $result[] = [DB::connection()->getDatabaseName() => true];
$result['success'] = true; $result['success'] = true;
} catch (\Exception $e) { } catch (\Exception $e) {
$result[] = [ config('database.connections.' . config('database.default') . '.database') => false ]; $result[] = [config('database.connections.'.config('database.default').'.database') => false];
$result['success'] = false; $result['success'] = false;
} }
} else { } else {
@ -103,10 +106,10 @@ class SystemHealth
try { try {
$pdo = DB::connection()->getPdo(); $pdo = DB::connection()->getPdo();
$result[] = [ DB::connection()->getDatabaseName() => true ]; $result[] = [DB::connection()->getDatabaseName() => true];
$result['success'] = true; $result['success'] = true;
} catch (\Exception $e) { } catch (\Exception $e) {
$result[] = [ config('database.connections.' . config('database.default') . '.database') => false ]; $result[] = [config('database.connections.'.config('database.default').'.database') => false];
$result['success'] = false; $result['success'] = false;
} }
} }
@ -138,15 +141,17 @@ class SystemHealth
->send(new TestMailServer('Email Server Works!', config('mail.from.address'))); ->send(new TestMailServer('Email Server Works!', config('mail.from.address')));
} catch (\Exception $e) { } catch (\Exception $e) {
\Log::error($e->getMessage()); \Log::error($e->getMessage());
return $e->getMessage(); return $e->getMessage();
} }
if (count(Mail::failures()) > 0) { if (count(Mail::failures()) > 0) {
\Log::error(print_r(Mail::failures(),1)); \Log::error(print_r(Mail::failures(), 1));
return Mail::failures(); return Mail::failures();
} }
return response()->json(['message'=>'Success'],200); return response()->json(['message'=>'Success'], 200);
} }
private static function checkEnvWritable() private static function checkEnvWritable()

View File

@ -3183,4 +3183,12 @@ return [
'waiting_for_approval' => 'Waiting for approval', 'waiting_for_approval' => 'Waiting for approval',
'quote_still_not_approved' => 'This quote is still not approved', 'quote_still_not_approved' => 'This quote is still not approved',
'list_of_credits' => 'Credits', 'list_of_credits' => 'Credits',
'required_extensions' => 'Required extensions',
'php_version' => 'PHP version',
'writable_env_file' => 'Writable .env file',
'env_not_writable' => '.env file is not writable by the current user.',
'minumum_php_version' => 'Minimum PHP version',
'satisfy_requirements' => 'Make sure all requirements are satisfied.',
'oops_issues' => 'Oops, something doesn\'t look right!',
]; ];

View File

@ -0,0 +1,61 @@
<div class="bg-white shadow overflow-hidden rounded-lg mt-8">
<div class="px-4 py-5 border-b border-gray-200 sm:px-6">
<h3 class="text-lg leading-6 font-medium text-gray-900">
{{ ctrans('texts.oops_issues') }}
</h3>
<p class="mt-1 max-w-2xl text-sm leading-5 text-gray-500">
{{ ctrans('texts.satisfy_requirements') }}
</p>
</div>
<div>
<dl>
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6 sm:flex sm:items-center">
<dt class="text-sm leading-5 font-medium text-gray-500">
{{ ctrans('texts.required_extensions') }}
</dt>
<dd class="text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
@foreach($check['extensions'] as $extension)
<span class="alert py-1 {{ $extension[key($extension)] == true ? 'alert-success' : 'alert-failure' }} block w-full">
{{ key($extension) }}
</span>
@endforeach
</dd>
</div>
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6 sm:flex sm:items-center">
<dt class="text-sm leading-5 font-medium text-gray-500">
{{ ctrans('texts.php_version') }}
</dt>
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
@if($check['php_version']['is_okay'])
<span class="alert alert-success block">
{{ strtoupper(ctrans('texts.ok')) }}!
</span>
@else
<span class="alert block">
{{ ctrans('texts.minumum_php_version') }}: {{ $check['php_version']['minimum_php_version'] }}
</span>
<span class="alert alert-failure block">
{{ ctrans('texts.current') }}: {{ $check['php_version']['current_php_version'] }}
</span>
@endif
</dd>
</div>
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6 sm:flex sm:items-center">
<dt class="text-sm leading-5 font-medium text-gray-500">
{{ ctrans('texts.writable_env_file') }}
</dt>
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
@if($check['env_writable'])
<span class="alert alert-success block">
{{ strtoupper(ctrans('texts.ok')) }}!
</span>
@else
<span class="alert alert-failure block">
{{ ctrans('texts.env_not_writable') }}
</span>
@endif
</dd>
</div>
</dl>
</div>
</div>

View File

@ -29,29 +29,34 @@
</div> </div>
@endif @endif
@include('setup._application') @if($check['system_health'] === false)
@include('setup._database') @include('setup._issues')
@include('setup._mail') @else
@include('setup._account')
<div class="flex justify-center mt-4"> @include('setup._application')
<div class="flex flex-col"> @include('setup._database')
<div class="mt-4"> @include('setup._mail')
<input type="checkbox" class="form-checkbox" name="terms_of_service" required> @include('setup._account')
<span>I agree to
<a class="button-link" href="https://www.invoiceninja.com/self-hosting-terms-service/">{{ ctrans('texts.terms_of_service') }}</a> <div class="flex justify-center mt-4">
</span> <div class="flex flex-col">
<div class="mt-4">
<input type="checkbox" class="form-checkbox" name="terms_of_service" required>
<span>I agree to
<a class="button-link" href="https://www.invoiceninja.com/self-hosting-terms-service/">{{ ctrans('texts.terms_of_service') }}</a>
</span>
</div>
<div class="mt-2">
<input type="checkbox" class="form-checkbox" name="privacy_policy" required>
<span>I agree to
<a class="button-link" href="https://www.invoiceninja.com/self-hosting-privacy-data-control/">{{ ctrans('texts.privacy_policy') }}</a>
</span>
</div>
<button type="submit" class="button button-primary w-1/2 my-4">{{ ctrans('texts.submit') }}</button>
</div> </div>
<div class="mt-2">
<input type="checkbox" class="form-checkbox" name="privacy_policy" required>
<span>I agree to
<a class="button-link" href="https://www.invoiceninja.com/self-hosting-privacy-data-control/">{{ ctrans('texts.privacy_policy') }}</a>
</span>
</div>
<button type="submit" class="button button-primary w-1/2 my-4">{{ ctrans('texts.submit') }}</button>
</div> </div>
</div> @endif
</div> </div>
</div> </div>
</form> </form>