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); } // See if the successful flag has been written to the .env file $isAppInstalled = MiscHelper::getEnvironmentSetting('APP_INSTALLED'); if ($request->is('install/*')) { // Already in the installer // For security reasons, don't allow the installer to be used if it has been previously completed if (boolval($isAppInstalled)) { return redirect(route('home')); } return $next($request); } if ($isAppInstalled) { // See if an update is necessary $this->updateDatabaseIfRequired(); // App is configured, continue on return $next($request); } 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]]); } } private function updateDatabaseIfRequired() { $versionNumber = UserConfig::getOrCreateModel('app_version'); $appVersionNumber = config('app.version'); if (is_null($appVersionNumber) || $versionNumber->value != $appVersionNumber) { Log::info('Upgrading database', ['new_version' => $appVersionNumber]); Artisan::call('config:cache'); Artisan::call('cache:clear'); Artisan::call('view:clear'); Artisan::call('migrate', ['--force' => true]); Artisan::call('db:seed', ['--force' => true]); // Run any data migrations relevant to the new version $dataMigrationsFolder = join(DIRECTORY_SEPARATOR, [dirname(dirname(dirname(__DIR__))), 'database', 'data_migrations']); $di = new \RecursiveDirectoryIterator($dataMigrationsFolder, \RecursiveDirectoryIterator::SKIP_DOTS); $updateClasses = []; // First load all data migration classes and examine the version number to decide if we need it or not /** @var \SplFileInfo $fileInfo */ foreach ($di as $fileInfo) { if (!$di->isFile() || $di->getExtension() != 'php') { continue; } $className = substr($fileInfo->getFilename(), 0, strlen($fileInfo->getFilename()) - 4); /** @var DataMigration $upgradeClass */ $upgradeClass = new $className; if (version_compare($versionNumber->value, $upgradeClass->getVersion()) < 0) { $updateClasses[] = $upgradeClass; } } // Now run the migrations foreach ($updateClasses as $upgradeClass) { $upgradeClass->run($versionNumber); } // Save the new version number $versionNumber->value = $appVersionNumber; $versionNumber->save(); } } }