diff --git a/app/Http/Controllers/InstallController.php b/app/Http/Controllers/InstallController.php index 022b4ed..a51eea5 100644 --- a/app/Http/Controllers/InstallController.php +++ b/app/Http/Controllers/InstallController.php @@ -11,21 +11,16 @@ use Illuminate\Support\Facades\DB; class InstallController extends Controller { - public function start(Request $request) + public function administrator(Request $request) { - if (!$this->isDatabaseWorking()) + // Validate we're at the required stage + $stage = 3; + if (intval($request->session()->get('install_stage')) < $stage) { - return $this->databaseConnection($request); + return redirect(route('install.check')); } - else if (!$this->isAdministratorAccountCreated()) - { - return $this->administratorAccount($request); - } - } - protected function administratorAccount(Request $request) - { - if (strtolower($request->method()) == 'post') + if ($request->method() == 'POST') { $user = new User(); $user->name = $request->get('name'); @@ -35,28 +30,76 @@ class InstallController extends Controller $user->is_activated = true; $user->save(); - $request->session()->flash('', ''); - - return redirect(route('home')); + return redirect(url('login')); } - return view('install/administrator'); + return view('install.administrator'); } - protected function databaseConnection(Request $request) + public function check(Request $request) { - if (strtolower($request->method()) == 'post') + // This is the first installation step therefore it doesn't need to verify the stage + + if ($request->getMethod() == 'POST') + { + $request->session()->set('install_stage', 2); + return redirect(route('install.database')); + } + + $canContinue = true; + $requiredModules = [ + 'pdo_mysql' => 'installer.php_modules.mysql', + 'gd' => 'installer.php_modules.gd' + ]; + $availableModules = []; + + foreach ($requiredModules as $key => $langString) + { + $availableModules[$key] = extension_loaded($key); + if (!$availableModules[$key]) + { + $canContinue = false; + } + } + + $uploadLimit = MiscHelper::convertToBytes(ini_get('upload_max_filesize')); + $postMaxSize = MiscHelper::convertToBytes(ini_get('post_max_size')); + + $recommendedMinimum = 4 * 1024 * 1024; + + return view('install.check', [ + 'available_modules' => $availableModules, + 'can_continue' => $canContinue, + 'post_max_size' => ($postMaxSize / 1024 / 1024), + 'post_max_size_warning' => $postMaxSize < $recommendedMinimum, + 'recommended_minimum_upload' => ($recommendedMinimum / 1024 / 1024), + 'upload_limit' => ($uploadLimit / 1024 / 1024), + 'upload_limit_warning' => $uploadLimit < $recommendedMinimum, + 'required_modules' => $requiredModules + ]); + } + + public function database(Request $request) + { + // Validate we're at the required stage + $stage = 2; + if (intval($request->session()->get('install_stage')) < $stage) + { + return redirect(route('install.check')); + } + + if ($request->method() == 'POST') { $baseDirectory = dirname(dirname(dirname(__DIR__))); $data = [ - 'APP_KEY=' . config('app.key'), + sprintf('APP_KEY=%s', config('app.key')), 'DB_CONNECTION=mysql', - 'DB_HOST=' . $request->get('mysql-server'), - 'DB_PORT=' . intval($request->get('mysql-port')), - 'DB_DATABASE=' . $request->get('mysql-database'), - 'DB_USERNAME=' . $request->get('mysql-username'), - 'DB_PASSWORD=' . $request->get('mysql-password') + sprintf('DB_HOST=%s', $request->get('mysql-server')), + sprintf('DB_PORT=%s', intval($request->get('mysql-port'))), + sprintf('DB_DATABASE=%s', $request->get('mysql-database')), + sprintf('DB_USERNAME=%s', $request->get('mysql-username')), + sprintf('DB_PASSWORD=%s', $request->get('mysql-password')) ]; file_put_contents(sprintf('%s/.env', $baseDirectory), join(PHP_EOL, $data) . PHP_EOL); @@ -91,40 +134,19 @@ class InstallController extends Controller $result->save(); } - return redirect('/install'); + $request->session()->set('install_stage', 3); + return redirect(route('install.administrator')); } catch (\Exception $ex) { $request->session()->flash('database_error', $ex->getMessage()); - return redirect('/install') + return redirect(route('install.database')) ->withInput($request->input()); } } - return view('install/database', [ + return view('install.database', [ 'database_error' => $request->session()->get('database_error') ]); } - - private function isAdministratorAccountCreated() - { - return (count(User::administrators()) > 0); - } - - private function isDatabaseWorking() - { - try - { - if (!Configuration::installCompleted()) - { - throw new \Exception(sprintf('install_completed configuration record is not present!')); - } - - return true; - } - catch (\Exception $ex) - { - return false; - } - } } \ No newline at end of file diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 5449361..7e7fed3 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -2,7 +2,9 @@ namespace App\Http; +use App\Http\Middleware\AppInstallation; use App\Http\Middleware\CheckMaxPostSizeExceeded; +use App\Http\Middleware\GlobalConfiguration; use Illuminate\Foundation\Http\Kernel as HttpKernel; class Kernel extends HttpKernel @@ -16,6 +18,8 @@ class Kernel extends HttpKernel */ protected $middleware = [ \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class, + AppInstallation::class, + GlobalConfiguration::class ]; /** diff --git a/app/Http/Middleware/AppInstallation.php b/app/Http/Middleware/AppInstallation.php new file mode 100644 index 0000000..071f312 --- /dev/null +++ b/app/Http/Middleware/AppInstallation.php @@ -0,0 +1,78 @@ +app = $app; + $this->baseDirectory = dirname(dirname(dirname(__DIR__))); + $this->environmentFilePath = sprintf('%s/.env', $this->baseDirectory); + } + + public function handle(Request $request, Closure $next) + { + // We always need an encryption key if not already present + $this->generateAppKey(); + + if ($this->app->runningInConsole()) + { + // Allow the console to run successfully even if we're not installed + return $next($request); + } + + if ($request->is('install/*')) + { + // Already in the installer + return $next($request); + } + + try + { + if (Configuration::installCompleted()) + { + return $next($request); + } + } + catch (\Exception $ex) + { + // Empty catch block to allow falling through to the redirect below + } + + return redirect(route('install.check')); + } + + private function generateAppKey() + { + // Generate an application key and store to the .env file + if (!file_exists($this->environmentFilePath)) + { + $key = MiscHelper::randomString(32); + file_put_contents($this->environmentFilePath, sprintf('APP_KEY=%s', $key) . PHP_EOL); + app('config')->set(['app' => ['key' => $key]]); + } + } +} \ No newline at end of file diff --git a/app/Http/Middleware/GlobalConfiguration.php b/app/Http/Middleware/GlobalConfiguration.php new file mode 100644 index 0000000..c09545f --- /dev/null +++ b/app/Http/Middleware/GlobalConfiguration.php @@ -0,0 +1,106 @@ +app = $app; + } + + public function handle(Request $request, Closure $next) + { + // If running the installer, chances are our database isn't running yet + if ($request->is('install/*')) + { + return $next($request); + } + + // When running migrations, CLI tasks or the installer, don't need to add things to the view + if (php_sapi_name() != 'cli') + { + $this->addThemeInfoToView(); + $this->addAlbumsToView(); + } + + // Set the default mail configuration as per user's requirements + $this->updateMailConfig(); + + return $next($request); + } + + private function addAlbumsToView() + { + $albums = Album::all()->sortBy('name'); + View::share('albums', $albums); + } + + private function addThemeInfoToView() + { + $themeInfo = Theme::info(); + + // Add each theme info element to the view - prefixing with theme_ + // e.g. $themeInfo['name'] becomes $theme_name in the view + foreach ($themeInfo as $key => $value) + { + View::share('theme_' . $key, $value); + } + + // Also add a theme_url key + View::share('theme_url', sprintf('themes/%s', Theme::current())); + } + + private function updateMailConfig() + { + /** @var Mailer $mailer */ + $mailer = $this->app->mailer; + $swiftMailer = $mailer->getSwiftMailer(); + + /** @var \Swift_SmtpTransport $transport */ + $transport = $swiftMailer->getTransport(); + $transport->setHost(UserConfig::get('smtp_server')); + $transport->setPort(intval(UserConfig::get('smtp_port'))); + + $username = UserConfig::get('smtp_username'); + if (!is_null($username)) + { + $transport->setUsername($username); + } + + $password = UserConfig::get('smtp_password'); + if (!is_null($password)) + { + $transport->setPassword(decrypt($password)); + } + + if (UserConfig::get('smtp_encryption')) + { + $transport->setEncryption('tls'); + } + + $mailer->alwaysFrom(UserConfig::get('sender_address'), UserConfig::get('sender_name')); + } +} \ No newline at end of file diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 42cc89a..0a70cb2 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -25,31 +25,18 @@ class AppServiceProvider extends ServiceProvider */ public function boot() { - if ($this->checkIfInstalled()) + $this->app->singleton('image', function ($app) { - $this->app->singleton('image', function ($app) - { - return new ImageHelper(); - }); - $this->app->singleton('theme', function ($app) - { - return new ThemeHelper(); - }); - $this->app->singleton('user_config', function ($app) - { - return new ConfigHelper(); - }); - - // When running migrations or CLI tasks, don't need to add things to the view - if (php_sapi_name() != 'cli') - { - $this->addThemeInfoToView(); - $this->addAlbumsToView(); - } - - // Set the default mail configuration as per user's requirements - $this->updateMailConfig(); - } + return new ImageHelper(); + }); + $this->app->singleton('theme', function ($app) + { + return new ThemeHelper(); + }); + $this->app->singleton('user_config', function ($app) + { + return new ConfigHelper(); + }); } /** @@ -61,94 +48,4 @@ class AppServiceProvider extends ServiceProvider { // } - - private function checkIfInstalled() - { - if ($this->app->runningInConsole()) - { - return true; - } - - if ($_SERVER['REQUEST_URI'] == '/install') - { - $baseDirectory = dirname(dirname(__DIR__)); - - // Generate an application key and store to the .env file - if (!file_exists($baseDirectory . '/.env')) - { - $key = MiscHelper::randomString(32); - file_put_contents($baseDirectory . '/.env', sprintf('APP_KEY=%s', $key) . PHP_EOL); - app('config')->set(['app' => ['key' => $key]]); - } - - return false; - } - - try - { - if (!Configuration::installCompleted()) - { - throw new \Exception(sprintf('install_completed configuration record is not present!')); - } - - return true; - } - catch (\Exception $ex) - { - header(sprintf('Location: %s', url('/install'))); - die(); - } - } - - private function addAlbumsToView() - { - $albums = Album::all()->sortBy('name'); - View::share('albums', $albums); - } - - private function addThemeInfoToView() - { - $themeInfo = Theme::info(); - - // Add each theme info element to the view - prefixing with theme_ - // e.g. $themeInfo['name'] becomes $theme_name in the view - foreach ($themeInfo as $key => $value) - { - View::share('theme_' . $key, $value); - } - - // Also add a theme_url key - View::share('theme_url', sprintf('themes/%s', Theme::current())); - } - - private function updateMailConfig() - { - /** @var Mailer $mailer */ - $mailer = $this->app->mailer; - $swiftMailer = $mailer->getSwiftMailer(); - - /** @var \Swift_SmtpTransport $transport */ - $transport = $swiftMailer->getTransport(); - $transport->setHost(UserConfig::get('smtp_server')); - $transport->setPort(intval(UserConfig::get('smtp_port'))); - - $username = UserConfig::get('smtp_username'); - if (!is_null($username)) - { - $transport->setUsername($username); - } - - $password = UserConfig::get('smtp_password'); - if (!is_null($password)) - { - $transport->setPassword(decrypt($password)); - } - - if (UserConfig::get('smtp_encryption')) - { - $transport->setEncryption('tls'); - } - - $mailer->alwaysFrom(UserConfig::get('sender_address'), UserConfig::get('sender_name')); - } } diff --git a/resources/lang/en/installer.php b/resources/lang/en/installer.php index 7412473..0928c87 100644 --- a/resources/lang/en/installer.php +++ b/resources/lang/en/installer.php @@ -1,6 +1,6 @@ 'Blue Twilight Installer', + /*'app_name' => 'Blue Twilight Installer', 'license_file_label' => 'Upload your license file:', 'license_required_text' => 'Blue Twilight requires a license file to run. The license file is called "blue-twilight.lic" ' . 'and can be downloaded from the %link_start%My Orders%link_end% page on the %link2_start%Apps by Andy - Web Store%link2_end%.', @@ -8,5 +8,20 @@ return [ 'license_required_text3' => 'Once you have your license file, please upload it using the field below.', 'licensed_to' => 'Licensed to: ', 'save_button' => 'Save', - 'upload_button' => 'Upload' + 'upload_button' => 'Upload'*/ + 'php_config' => [ + 'heading' => 'PHP configuration:', + 'post_max_size' => 'Maximum POST request size:', + 'post_max_size_upload_limit_warning' => 'Your post_max_size setting should be slightly bigger than your upload_max_filesize setting to allow for the HTTP header.', + 'post_max_size_warning' => 'We recommend a minimum of :size :units. This value is controlled by the post_max_size php.ini setting.', + 'upload_limit' => 'Maximum file size allowed to upload:', + 'upload_limit_warning' => 'We recommend a minimum of :size :units. This value is controlled by the upload_max_filesize php.ini setting.' + ], + 'php_modules' => [ + 'gd' => 'GD Graphics Processing Library', + 'heading' => 'Required PHP modules:', + 'mysql' => 'MySQL Client Library' + ], + 'requirements_intro' => 'Your application/PHP environment have been checked and the results are below. Please correct any failed items before continuing.', + 'requirements_title' => 'System Requirements' ]; \ No newline at end of file diff --git a/resources/views/install/check.blade.php b/resources/views/install/check.blade.php new file mode 100644 index 0000000..ba9256c --- /dev/null +++ b/resources/views/install/check.blade.php @@ -0,0 +1,72 @@ +@extends('install.layout') + +@section('content') +

@lang('installer.requirements_title')

+

@lang('installer.requirements_intro')

+ +
+
+ + + + + + + @foreach ($required_modules as $key => $value) + + + + + @endforeach + + + + + + + + + + + + +
@lang('installer.php_modules.heading')
@lang($value)
@lang('installer.php_config.heading')
+ @lang('installer.php_config.upload_limit') + @if ($upload_limit_warning) +
@lang('installer.php_config.upload_limit_warning', ['size' => $recommended_minimum_upload, 'units' => trans('global.units.megabytes')]) + @endif +
+ {{ $upload_limit }} @lang('global.units.megabytes') + @if ($upload_limit_warning) + + @else + + @endif +
+ @lang('installer.php_config.post_max_size') + @if ($post_max_size_warning) +
@lang('installer.php_config.post_max_size_warning', ['size' => $recommended_minimum_upload, 'units' => trans('global.units.megabytes')]) + @endif + @if ($post_max_size <= $upload_limit ) +
@lang('installer.php_config.post_max_size_upload_limit_warning') + @endif +
+ {{ $post_max_size }} @lang('global.units.megabytes') + @if ($post_max_size_warning) + + @else + + @endif +
+ + @if ($can_continue) +
+
+ {{ csrf_field() }} + +
+
+ @endif +
+
+@endsection \ No newline at end of file diff --git a/resources/views/install/database.blade.php b/resources/views/install/database.blade.php index 3979d41..96b6324 100644 --- a/resources/views/install/database.blade.php +++ b/resources/views/install/database.blade.php @@ -11,7 +11,7 @@ @endif -
+ {{ csrf_field() }}
diff --git a/resources/views/install/layout.blade.php b/resources/views/install/layout.blade.php index 2f166ff..c2216f2 100644 --- a/resources/views/install/layout.blade.php +++ b/resources/views/install/layout.blade.php @@ -7,10 +7,12 @@ Blue Twilight - Installation + +