diff --git a/app/Helpers/MiscHelper.php b/app/Helpers/MiscHelper.php index 4f2b49c..25553ed 100644 --- a/app/Helpers/MiscHelper.php +++ b/app/Helpers/MiscHelper.php @@ -111,9 +111,9 @@ class MiscHelper return sprintf('%s/.env', dirname(dirname(__DIR__))); } - public static function getEnvironmentSetting($settingName) + public static function getEnvironmentSetting($settingName, $envFile = null) { - $envFile = MiscHelper::getEnvironmentFilePath(); + $envFile = $envFile ?? MiscHelper::getEnvironmentFilePath(); if (!file_exists($envFile)) { diff --git a/app/Http/Controllers/InstallController.php b/app/Http/Controllers/InstallController.php index 46a5e24..c3cae63 100644 --- a/app/Http/Controllers/InstallController.php +++ b/app/Http/Controllers/InstallController.php @@ -19,10 +19,10 @@ class InstallController extends Controller public function administrator(StoreUserRequest $request) { // Validate we're at the required stage - $stage = 3; + $stage = 2; if (intval($request->session()->get('install_stage')) < $stage) { - return redirect(route('install.check')); + return redirect(route('install.database')); } // If we already have an admin account, this step can be skipped @@ -52,70 +52,9 @@ class InstallController extends Controller ]); } - public function check(Request $request) - { - // This is the first installation step therefore it doesn't need to verify the stage - - if ($request->getMethod() == 'POST') - { - $request->session()->put('install_stage', 2); - return redirect(route('install.database')); - } - - $canContinue = true; - $runtimeMinimum = '7.0.0'; // this minimum is imposed by Laravel 5.5 - $runtimeVersion = phpversion(); - $phpIsValid = version_compare($runtimeVersion, $runtimeMinimum) >= 0; - - if (!$phpIsValid) - { - $canContinue = false; - } - - $requiredModules = [ - 'curl' => 'installer.php_modules.curl', - '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, - 'php_is_valid' => $phpIsValid, - 'php_version_current' => $runtimeVersion, - 'php_version_required' => $runtimeMinimum, - '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')); - } + // This is the first installation step therefore it doesn't need to verify the stage if ($request->method() == 'POST') { @@ -162,7 +101,7 @@ class InstallController extends Controller // Default settings $this->setConfigurationForNewSystems(); - $request->session()->put('install_stage', 3); + $request->session()->put('install_stage', 2); return redirect(route('install.administrator')); } catch (\Exception $ex) diff --git a/app/Http/Middleware/AppInstallation.php b/app/Http/Middleware/AppInstallation.php index fb88b19..b711d99 100644 --- a/app/Http/Middleware/AppInstallation.php +++ b/app/Http/Middleware/AppInstallation.php @@ -14,9 +14,6 @@ use Illuminate\Support\Facades\Log; class AppInstallation { - private $baseDirectory; - private $environmentFilePath; - /** * The application instance. * @@ -33,8 +30,6 @@ class AppInstallation public function __construct(Application $app) { $this->app = $app; - $this->baseDirectory = dirname(dirname(dirname(__DIR__))); - $this->environmentFilePath = sprintf('%s/.env', $this->baseDirectory); } public function handle(Request $request, Closure $next) @@ -51,6 +46,14 @@ class AppInstallation // See if the successful flag has been written to the .env file $isAppInstalled = MiscHelper::getEnvironmentSetting('APP_INSTALLED'); + // See if the vendors are out-of-date + if ($this->isVendorUpdateRequired()) + { + return $isAppInstalled + ? redirect('/update') + : redirect('/install'); + } + if ($request->is('install/*')) { // Already in the installer @@ -72,20 +75,31 @@ class AppInstallation return $next($request); } - return redirect(route('install.check')); + return redirect(route('install.database')); } private function generateAppKey() { // Generate an application key and store to the .env file - if (!file_exists($this->environmentFilePath)) + if (!file_exists(MiscHelper::getEnvironmentFilePath())) { $key = MiscHelper::randomString(32); - file_put_contents($this->environmentFilePath, sprintf('APP_KEY=%s', $key) . PHP_EOL); + file_put_contents(MiscHelper::getEnvironmentFilePath(), sprintf('APP_KEY=%s', $key) . PHP_EOL); app('config')->set(['app' => ['key' => $key]]); } } + private function isVendorUpdateRequired() + { + $vendorsVersionFilename = $this->app->basePath('vendor/version.txt'); + if (!file_exists($vendorsVersionFilename)) + { + return true; + } + + return trim(file_get_contents($vendorsVersionFilename)) != trim(config('app.version')); + } + private function updateDatabaseIfRequired() { $versionNumber = UserConfig::getOrCreateModel('app_version'); diff --git a/composer.lock b/composer.lock index 41a6105..7fc42a4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "9a11d044f41aef4c08fcddf00fd6f7ed", + "content-hash": "9dfa65a2590e8d0d5305a4be35a8b140", "packages": [ { "name": "aws/aws-sdk-php", - "version": "3.134.8", + "version": "3.135.4", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "8a9b598a0ede2165be5988899dcebead6fcc4d41" + "reference": "fb6f4a12d9ad1b8fc1481aef61ed1f8a9fe2164b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/8a9b598a0ede2165be5988899dcebead6fcc4d41", - "reference": "8a9b598a0ede2165be5988899dcebead6fcc4d41", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/fb6f4a12d9ad1b8fc1481aef61ed1f8a9fe2164b", + "reference": "fb6f4a12d9ad1b8fc1481aef61ed1f8a9fe2164b", "shasum": "" }, "require": { @@ -88,7 +88,7 @@ "s3", "sdk" ], - "time": "2020-04-17T18:11:57+00:00" + "time": "2020-04-24T18:14:04+00:00" }, { "name": "doctrine/cache", @@ -174,16 +174,16 @@ }, { "name": "doctrine/dbal", - "version": "v2.10.1", + "version": "2.10.2", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "c2b8e6e82732a64ecde1cddf9e1e06cb8556e3d8" + "reference": "aab745e7b6b2de3b47019da81e7225e14dcfdac8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/c2b8e6e82732a64ecde1cddf9e1e06cb8556e3d8", - "reference": "c2b8e6e82732a64ecde1cddf9e1e06cb8556e3d8", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/aab745e7b6b2de3b47019da81e7225e14dcfdac8", + "reference": "aab745e7b6b2de3b47019da81e7225e14dcfdac8", "shasum": "" }, "require": { @@ -195,9 +195,11 @@ "require-dev": { "doctrine/coding-standard": "^6.0", "jetbrains/phpstorm-stubs": "^2019.1", - "phpstan/phpstan": "^0.11.3", + "nikic/php-parser": "^4.4", + "phpstan/phpstan": "^0.12", "phpunit/phpunit": "^8.4.1", - "symfony/console": "^2.0.5|^3.0|^4.0|^5.0" + "symfony/console": "^2.0.5|^3.0|^4.0|^5.0", + "vimeo/psalm": "^3.11" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." @@ -262,7 +264,21 @@ "sqlserver", "sqlsrv" ], - "time": "2020-01-04T12:56:21+00:00" + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdbal", + "type": "tidelift" + } + ], + "time": "2020-04-20T17:19:26+00:00" }, { "name": "doctrine/event-manager", @@ -838,16 +854,16 @@ }, { "name": "laravel/framework", - "version": "v6.18.8", + "version": "v6.18.10", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "852c91c46adfbc2f5a0f6985cba3d7b7a769b773" + "reference": "9177744ccdd8d5db970fdff2383fe89c2e94aabe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/852c91c46adfbc2f5a0f6985cba3d7b7a769b773", - "reference": "852c91c46adfbc2f5a0f6985cba3d7b7a769b773", + "url": "https://api.github.com/repos/laravel/framework/zipball/9177744ccdd8d5db970fdff2383fe89c2e94aabe", + "reference": "9177744ccdd8d5db970fdff2383fe89c2e94aabe", "shasum": "" }, "require": { @@ -980,7 +996,7 @@ "framework", "laravel" ], - "time": "2020-04-15T20:56:03+00:00" + "time": "2020-04-21T18:53:10+00:00" }, { "name": "laravel/socialite", @@ -1048,16 +1064,16 @@ }, { "name": "league/commonmark", - "version": "1.3.4", + "version": "1.4.2", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "dd3261eb9a322e009fa5d96d19b9ae19708ce04b" + "reference": "9e780d972185e4f737a03bade0fd34a9e67bbf31" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/dd3261eb9a322e009fa5d96d19b9ae19708ce04b", - "reference": "dd3261eb9a322e009fa5d96d19b9ae19708ce04b", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/9e780d972185e4f737a03bade0fd34a9e67bbf31", + "reference": "9e780d972185e4f737a03bade0fd34a9e67bbf31", "shasum": "" }, "require": { @@ -1075,7 +1091,7 @@ "github/gfm": "0.29.0", "michelf/php-markdown": "~1.4", "mikehaertl/php-shellcommand": "^1.4", - "phpstan/phpstan-shim": "^0.11.5", + "phpstan/phpstan": "^0.12", "phpunit/phpunit": "^7.5", "scrutinizer/ocular": "^1.5", "symfony/finder": "^4.2" @@ -1118,7 +1134,33 @@ "md", "parser" ], - "time": "2020-04-13T20:52:18+00:00" + "funding": [ + { + "url": "https://enjoy.gitstore.app/repositories/thephpleague/commonmark", + "type": "custom" + }, + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + }, + { + "url": "https://www.patreon.com/colinodell", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/commonmark", + "type": "tidelift" + } + ], + "time": "2020-04-24T13:39:56+00:00" }, { "name": "league/flysystem", @@ -1202,6 +1244,12 @@ "sftp", "storage" ], + "funding": [ + { + "url": "https://offset.earth/frankdejonge", + "type": "other" + } + ], "time": "2020-04-16T13:21:26+00:00" }, { @@ -1474,6 +1522,16 @@ "datetime", "time" ], + "funding": [ + { + "url": "https://opencollective.com/Carbon", + "type": "open_collective" + }, + { + "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon", + "type": "tidelift" + } + ], "time": "2020-03-31T13:43:19+00:00" }, { @@ -1584,16 +1642,16 @@ }, { "name": "php-amqplib/php-amqplib", - "version": "v2.11.0", + "version": "v2.11.1", "source": { "type": "git", "url": "https://github.com/php-amqplib/php-amqplib.git", - "reference": "9ee212baced63442ca1ab029acde38e1144a00b8" + "reference": "cfbfaf6262cd8d017f29862164f75e265d832434" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-amqplib/php-amqplib/zipball/9ee212baced63442ca1ab029acde38e1144a00b8", - "reference": "9ee212baced63442ca1ab029acde38e1144a00b8", + "url": "https://api.github.com/repos/php-amqplib/php-amqplib/zipball/cfbfaf6262cd8d017f29862164f75e265d832434", + "reference": "cfbfaf6262cd8d017f29862164f75e265d832434", "shasum": "" }, "require": { @@ -1602,6 +1660,9 @@ "php": ">=5.6.3", "phpseclib/phpseclib": "^2.0.0" }, + "conflict": { + "php": "7.4.0 - 7.4.1" + }, "replace": { "videlalvaro/php-amqplib": "self.version" }, @@ -1654,7 +1715,7 @@ "queue", "rabbitmq" ], - "time": "2019-11-19T15:15:19+00:00" + "time": "2020-02-24T17:37:52+00:00" }, { "name": "php-opencloud/openstack", @@ -1864,6 +1925,20 @@ "x.509", "x509" ], + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], "time": "2020-04-04T23:17:33+00:00" }, { @@ -2323,6 +2398,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-03-30T11:41:10+00:00" }, { @@ -2376,6 +2465,20 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-03-27T16:56:45+00:00" }, { @@ -2432,6 +2535,20 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-03-27T16:54:36+00:00" }, { @@ -2488,6 +2605,20 @@ ], "description": "Symfony ErrorHandler Component", "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-03-30T14:07:33+00:00" }, { @@ -2558,6 +2689,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-03-27T16:54:36+00:00" }, { @@ -2665,6 +2810,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-03-27T16:54:36+00:00" }, { @@ -2720,6 +2879,20 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-03-30T14:07:33+00:00" }, { @@ -2810,6 +2983,20 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-03-30T14:59:15+00:00" }, { @@ -2872,6 +3059,20 @@ "mime", "mime-type" ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-03-27T16:56:45+00:00" }, { @@ -2930,6 +3131,20 @@ "polyfill", "portable" ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-02-27T09:26:54+00:00" }, { @@ -2989,6 +3204,20 @@ "portable", "shim" ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-03-09T19:04:49+00:00" }, { @@ -3051,6 +3280,20 @@ "portable", "shim" ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-03-09T19:04:49+00:00" }, { @@ -3110,6 +3353,20 @@ "portable", "shim" ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-03-09T19:04:49+00:00" }, { @@ -3165,6 +3422,20 @@ "portable", "shim" ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-02-27T09:26:54+00:00" }, { @@ -3223,6 +3494,20 @@ "portable", "shim" ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-02-27T09:26:54+00:00" }, { @@ -3272,6 +3557,20 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-03-27T16:54:36+00:00" }, { @@ -3348,6 +3647,20 @@ "uri", "url" ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-03-30T11:41:10+00:00" }, { @@ -3482,6 +3795,20 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-03-27T16:54:36+00:00" }, { @@ -3615,6 +3942,20 @@ "debug", "dump" ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-03-27T16:54:36+00:00" }, { @@ -3727,6 +4068,12 @@ "env", "environment" ], + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", + "type": "tidelift" + } + ], "time": "2020-04-12T15:18:03+00:00" } ], @@ -3839,6 +4186,12 @@ "flare", "reporting" ], + "funding": [ + { + "url": "https://www.patreon.com/spatie", + "type": "patreon" + } + ], "time": "2020-03-02T15:52:04+00:00" }, { @@ -4332,24 +4685,21 @@ }, { "name": "phpdocumentor/reflection-common", - "version": "2.0.0", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a" + "reference": "6568f4687e5b41b054365f9ae03fcb1ed5f2069b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/63a995caa1ca9e5590304cd845c15ad6d482a62a", - "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/6568f4687e5b41b054365f9ae03fcb1ed5f2069b", + "reference": "6568f4687e5b41b054365f9ae03fcb1ed5f2069b", "shasum": "" }, "require": { "php": ">=7.1" }, - "require-dev": { - "phpunit/phpunit": "~6" - }, "type": "library", "extra": { "branch-alias": { @@ -4380,7 +4730,7 @@ "reflection", "static analysis" ], - "time": "2018-08-07T13:53:10+00:00" + "time": "2020-04-27T09:25:28+00:00" }, { "name": "phpdocumentor/reflection-docblock", @@ -4798,16 +5148,16 @@ }, { "name": "phpunit/phpunit", - "version": "8.5.3", + "version": "8.5.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "67750516bc02f300e2742fed2f50177f8f37bedf" + "reference": "8474e22d7d642f665084ba5ec780626cbd1efd23" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/67750516bc02f300e2742fed2f50177f8f37bedf", - "reference": "67750516bc02f300e2742fed2f50177f8f37bedf", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/8474e22d7d642f665084ba5ec780626cbd1efd23", + "reference": "8474e22d7d642f665084ba5ec780626cbd1efd23", "shasum": "" }, "require": { @@ -4877,7 +5227,17 @@ "testing", "xunit" ], - "time": "2020-03-31T08:52:04+00:00" + "funding": [ + { + "url": "https://phpunit.de/donate.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-04-23T04:39:42+00:00" }, { "name": "scrivo/highlight.php", @@ -4946,6 +5306,12 @@ "highlight.php", "syntax" ], + "funding": [ + { + "url": "https://github.com/allejo", + "type": "github" + } + ], "time": "2020-03-02T05:59:21+00:00" }, { @@ -5662,5 +6028,6 @@ "ext-curl": "*", "ext-json": "*" }, - "platform-dev": [] + "platform-dev": [], + "plugin-api-version": "1.1.0" } diff --git a/config/app.php b/config/app.php index 763a831..1f0f69e 100644 --- a/config/app.php +++ b/config/app.php @@ -2,7 +2,7 @@ return [ // Version number of Blue Twilight - 'version' => '2.2.0-beta.1', + 'version' => '2.2.0-beta.2', /* |-------------------------------------------------------------------------- diff --git a/config/services.php b/config/services.php index 726cfc4..5ff7f8c 100644 --- a/config/services.php +++ b/config/services.php @@ -28,11 +28,11 @@ return [ ], 'gitea' => [ - 'api_url' => 'https://apps.andysh.uk/api/v1', + 'api_url' => env('GITEA_API_URL', 'https://apps.andysh.uk/api/v1'), 'cache_time_seconds' => 3600, - 'releases_url' => 'https://apps.andysh.uk/%s/%s/releases', - 'repo_name' => 'blue-twilight', - 'repo_owner' => 'aheathershaw' + 'releases_url' => env('GITEA_RELEASES_URL', 'https://apps.andysh.uk/%s/%s/releases'), + 'repo_name' => env('GITEA_REPO_NAME', 'blue-twilight'), + 'repo_owner' => env('GITEA_REPO_OWNER', 'aheathershaw') ], 'rackspace' => [ diff --git a/database/migrations/2020_04_18_212642_add_s3_signed_urls_column_to_storages_table.php b/database/migrations/2020_04_18_212642_add_s3_signed_urls_column_to_storages_table.php index af6aff9..52ddb17 100644 --- a/database/migrations/2020_04_18_212642_add_s3_signed_urls_column_to_storages_table.php +++ b/database/migrations/2020_04_18_212642_add_s3_signed_urls_column_to_storages_table.php @@ -14,7 +14,7 @@ class AddS3SignedUrlsColumnToStoragesTable extends Migration public function up() { Schema::table('storages', function (Blueprint $table) { - $table->boolean('s3_signed_urls'); + $table->boolean('s3_signed_urls')->default(false); }); } diff --git a/installer/AppRequirements.php b/installer/AppRequirements.php new file mode 100644 index 0000000..79b31d0 --- /dev/null +++ b/installer/AppRequirements.php @@ -0,0 +1,71 @@ +=') ? self::STATUS_OK : self::STATUS_NOT_MET; + } + + private static function getPhpIniValueAsBytes($settingName) + { + return MiscHelper::convertToBytes(ini_get($settingName)); + } + + private static function isModuleLoaded($name) + { + return extension_loaded($name); + } +} \ No newline at end of file diff --git a/installer/Installer.php b/installer/Installer.php index 11cd304..f94a6f0 100644 --- a/installer/Installer.php +++ b/installer/Installer.php @@ -26,6 +26,12 @@ class Installer */ private $installerDir; + /** + * True if we're upgrading Blue Twilight, false if it's a new install + * @var bool + */ + private $isUpgrade; + /** * Path to / - the app's root * @var string @@ -44,6 +50,11 @@ class Installer */ private $vendorDir; + /** + * @var string + */ + private $versionNumber; + /** * Path to /installer/views * @var string @@ -55,20 +66,20 @@ class Installer $this->installerDir = __DIR__; $this->rootDir = dirname($this->installerDir); - $this->configDir = sprintf('%s/config', dirname(dirname($this->installerDir))); + $this->configDir = sprintf('%s/config', $this->rootDir); $this->tempDir = sprintf('%s/temp', $this->installerDir); $this->vendorDir = sprintf('%s/vendor', $this->rootDir); $this->viewsDir = sprintf('%s/views', $this->installerDir); - chdir($this->rootDir); - putenv('HOME=' . $this->rootDir); + $appConfig = require_once sprintf('%s/app.php', $this->configDir); + $this->versionNumber = $appConfig['version']; } public function handleRequest() { if (!isset($_GET['act'])) { - $this->view('index', ['appName' => 'Blue Twilight Bootstrapper']); + $this->checkInstallation(); } else { @@ -92,12 +103,88 @@ class Installer } } + /** + * @param bool $isUpgrade + */ + public function setIsUpgrade(bool $isUpgrade): void + { + $this->isUpgrade = $isUpgrade; + } + + protected function checkInstallation() + { + $requirements = [ + 'core:php72OrLater', + 'php:hasCurlLibrary', + 'php:hasMySqlClientLibrary', + 'php:hasGdLibrary', + 'config:maxUploadSize', + 'config:maxPostRequestSize' + ]; + $requirementsGrouped = []; + $canInstall = true; + + foreach ($requirements as $requirement) + { + $requirementSplit = explode(':', $requirement); + $groupName = $requirementSplit[0]; + $functionName = $requirementSplit[1]; + + $status = null; + $result = call_user_func_array([AppRequirements::class, $functionName], [&$status]); + + if ($result == AppRequirements::STATUS_NOT_MET) + { + $canInstall = false; + } + + if (!array_key_exists($groupName, $requirementsGrouped)) + { + $requirementsGrouped[$groupName] = []; + } + + if (!array_key_exists($functionName, $requirementsGrouped[$groupName])) + { + $requirementsGrouped[$groupName][$functionName] = [ + 'result' => $result, + 'status' => $status + ]; + } + } + + $requirementGroupNames = [ + 'config' => 'PHP configuration', + 'core' => 'Core requirements', + 'php' => 'Required PHP modules' + ]; + + $requirementNames = [ + 'hasCurlLibrary' => 'cURL Web Requests Library', + 'hasGdLibrary' => 'GD Graphics Procesisng Library', + 'hasMySqlClientLibrary' => 'MySQL PDO Data Access Library', + 'maxPostRequestSize' => 'Maximum POST request size (recommended: 4 MB)', + 'maxUploadSize' => 'Maximum file size allowed to upload (recommended: 4 MB)', + 'php72OrLater' => 'Requires PHP 7.2.0 minimum', + ]; + + $this->view('index', [ + 'appName' => 'Blue Twilight Installer', + 'canInstall' => $canInstall, + 'isUpgrade' => $this->isUpgrade, + 'requirementGroupNames' => $requirementGroupNames, + 'requirementNames' => $requirementNames, + 'statusNotMet' => AppRequirements::STATUS_NOT_MET, + 'statusOK' => AppRequirements::STATUS_OK, + 'statusWarning' => AppRequirements::STATUS_WARNING, + 'systemRequirements' => $requirementsGrouped + ]); + } + protected function download() { - $appConfig = require_once sprintf('%s/app.php', $this->configDir); $servicesConfig = require_once sprintf('%s/services.php', $this->configDir); - $versionNumber = sprintf('v%s', $appConfig['version']); + $versionNumber = sprintf('v%s', $this->versionNumber); $gitea = new GiteaService($servicesConfig['gitea'], $versionNumber); $releaseInfo = $gitea->getSpecificRelease($versionNumber); @@ -162,6 +249,8 @@ class Installer if (file_exists($vendorsTestFile)) { + $this->writeVersionFile(); + $this->json([ 'result' => true, 'testFile' => $vendorsTestFile @@ -176,10 +265,12 @@ class Installer protected function finalise() { $result = [ + 'cacheFilesRemoved' => 0, 'envFileCreated' => false ]; - $result['envFileCreated'] = $this->createEnvFileIfNotExist(); + $result['cacheFilesRemoved'] = $this->clearCacheIfExists(); + $result['envFileCreated'] = !$this->isUpgrade && $this->createEnvFileIfNotExist(); require sprintf('%s/bootstrap/autoload.php', $this->rootDir); @@ -222,6 +313,23 @@ class Installer @fclose($tempFilename); } + private function clearCacheIfExists() + { + $filesDeleted = 0; + $cacheDir = sprintf('%s/bootstrap/cache', $this->rootDir); + + $di = new \DirectoryIterator($cacheDir); + foreach ($di as $fileInfo) + { + if (@unlink($fileInfo->getRealPath())) + { + $filesDeleted++; + } + } + + return $filesDeleted; + } + private function createEnvFileIfNotExist() { $envFile = $this->getEnvFileName(); @@ -255,6 +363,11 @@ class Installer return sprintf('%s/vendors.tar.gz', $this->tempDir); } + private function getVendorsVersionFileName() + { + return sprintf('%s/version.txt', $this->vendorDir); + } + private function json($data) { echo json_encode($data); @@ -273,4 +386,9 @@ class Installer require_once $viewFile; } + + private function writeVersionFile() + { + file_put_contents($this->getVendorsVersionFileName(), $this->versionNumber . PHP_EOL); + } } \ No newline at end of file diff --git a/installer/helpers.php b/installer/helpers.php index 65a9328..68c2d2b 100644 --- a/installer/helpers.php +++ b/installer/helpers.php @@ -1,13 +1,27 @@ = strlen($stringToFind) && substr(strtolower($stringToCheck), strlen($stringToCheck) - strlen($stringToFind), strlen($stringToFind)) == strtolower($stringToFind); } +/** + * A crude implementation of a .env reader to allow the installer to have overriden values from .env.install. + * @param $key + * @param null $default + */ +function env($key, $default = null) +{ + $envFilePath = sprintf('%s/.env.install', dirname(__DIR__)); + if (!file_exists($envFilePath)) + { + return $default; + } + + return \App\Helpers\MiscHelper::getEnvironmentSetting($key, $envFilePath) ?? $default; +} + function starts_with($stringToCheck, $stringToFind) { return strlen($stringToCheck) >= strlen($stringToFind) && diff --git a/installer/views/index.php b/installer/views/index.php index 58b3dce..ded62f5 100644 --- a/installer/views/index.php +++ b/installer/views/index.php @@ -4,6 +4,7 @@ + <?php echo $appName; ?> + +
+

Welcome to Blue Twilight - the self-hosted PHP photo gallery.

+

Your application/PHP environment have been checked and the results are below. Please correct any failed items before continuing.

+
-
-
-

+
+
+ Blue Twilight will automatically download the required third-party libraries when you + click Continue.
-
-

Welcome to Blue Twilight - the self-hosted PHP photo gallery.

-
-

We need to download and install a few more files before you get started.

-

Click the "Let's Go" button below to begin.

-

+ $items): ?> +
+
+

-
-
    -
  • -
    - - - -
    - -
  • -
+
+ + + $result): ?> + + + + + + +
+ + + + + + +
+ + + +

+ +
+ Blue Twilight cannot be installed until the issues identified above are rectified. +
+ +
+
+
    +
  • +
    + + + +
    + +
  • +
diff --git a/public/install/index.php b/public/install/index.php index a3fbeb2..9df9553 100644 --- a/public/install/index.php +++ b/public/install/index.php @@ -5,16 +5,6 @@ $installerDir = sprintf('%s/installer', dirname(dirname(__DIR__))); require_once sprintf('%s/vendor/autoload.php', $installerDir); require_once sprintf('%s/helpers.php', $installerDir); -if (!function_exists('env')) -{ - // Define a dummy env() function that always returns the default value so we can load the config/app.php file - // to get the current version number - function env($key, $default = null) - { - return $default; - } -} - try { $installer = new \AppInstaller\Installer(); diff --git a/public/update/images/completed.svg b/public/update/images/completed.svg new file mode 100644 index 0000000..517ce74 --- /dev/null +++ b/public/update/images/completed.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/update/images/loading.svg b/public/update/images/loading.svg new file mode 100644 index 0000000..c0f8953 --- /dev/null +++ b/public/update/images/loading.svg @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/public/update/images/waiting.svg b/public/update/images/waiting.svg new file mode 100644 index 0000000..f93f32a --- /dev/null +++ b/public/update/images/waiting.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/update/index.php b/public/update/index.php new file mode 100644 index 0000000..f9b7ce8 --- /dev/null +++ b/public/update/index.php @@ -0,0 +1,17 @@ +setIsUpgrade(true); + $installer->handleRequest(); +} +catch (\Exception $ex) +{ + echo sprintf('ERROR: %s', $ex); +} \ No newline at end of file diff --git a/resources/views/install/navbar.blade.php b/resources/views/install/navbar.blade.php index cb21d84..216162b 100644 --- a/resources/views/install/navbar.blade.php +++ b/resources/views/install/navbar.blade.php @@ -1,5 +1,5 @@