Add config.php at root; include configuration overhaul and then fixes to the installer #156

This commit is contained in:
Nabeel Shahzad 2018-01-29 13:16:39 -06:00
parent b1759d9276
commit f660af5c3b
17 changed files with 337 additions and 194 deletions

View File

@ -0,0 +1,46 @@
<?php
namespace App\Bootstrap;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Config\Repository as RepositoryContract;
/**
* Class LoadConfiguration
* @package App\Bootstrap
*
* I'm overriding this to take advantage of the configuration caching
* and not needing to read the files from disk every time.
*
* Hopefully it won't affect anything within core framework but this
* should be ok. Will just have to be cognizant of any changes to the
* LoadConfiguration parent class, or if the Kernel changes the boot
* order -NS
*/
class LoadConfiguration extends \Illuminate\Foundation\Bootstrap\LoadConfiguration
{
/**
* Load the configuration items from all of the files.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @param \Illuminate\Contracts\Config\Repository $repository
* @return void
* @throws \Exception
*/
protected function loadConfigurationFiles(Application $app, RepositoryContract $repository)
{
parent::loadConfigurationFiles($app, $repository);
/**
* Read in the base config, only if it exists
*/
if (file_exists($app->basePath().'/config.php')) {
$local_conf = include $app->basePath().'/config.php';
foreach ($local_conf as $namespace => $override_config) {
$config = $repository->get($namespace, []);
$update_config = array_replace_recursive($config, $override_config);
$repository->set($namespace, $update_config);
}
}
}
}

View File

@ -15,10 +15,6 @@ class InstalledCheck
*
* If the default key is set and we're not in any of the installer routes
* show the message that we need to be installed
*
* @param Request $request
* @param Closure $next
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View|mixed
*/
public function handle(Request $request, Closure $next)
{

View File

@ -2,12 +2,10 @@
namespace App\Providers;
use Log;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\ServiceProvider;
use App\Repositories\SettingRepository;
use Illuminate\Database\Eloquent\Relations\Relation;
use App\Models\Flight;
use App\Models\Pirep;
class AppServiceProvider extends ServiceProvider
{
@ -18,29 +16,18 @@ class AppServiceProvider extends ServiceProvider
{
Schema::defaultStringLength(191);
Relation::morphMap([
'flights' => Flight::class,
'pireps' => Pirep::class,
]);
$this->app->bind('setting', SettingRepository::class);
//\VaCentral\VaCentral::setVaCentralUrl(config('phpvms.vacentral_api_url'));
if(!empty(config('phpvms.vacentral_api_key'))) {
\VaCentral\VaCentral::setApiKey(config('phpvms.vacentral_api_key'));
}
# if there's a local.conf.php in the root, then merge that in
if(file_exists(base_path('config.php'))) {
/*if(file_exists(base_path('config.php'))) {
$local_conf = include base_path('config.php');
foreach($local_conf as $namespace => $override_config) {
$config = $this->app['config']->get($namespace, []);
$this->app['config']->set(
$namespace,
array_merge($config, $override_config)
);
$update_config = array_merge_recursive($config, $override_config);
$this->app['config']->set($namespace, $update_config);
}
}
}*/
}
/**

View File

@ -3,6 +3,7 @@
namespace App\Providers;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use App\Listeners\NotificationEventListener;
class EventServiceProvider extends ServiceProvider
@ -19,7 +20,7 @@ class EventServiceProvider extends ServiceProvider
];
protected $subscribe = [
'App\Listeners\NotificationEventListener',
NotificationEventListener::class,
];
/**

View File

@ -0,0 +1,38 @@
<?php
namespace App\Services;
use DB;
use PDO;
use Irazasyed\LaravelGAMP\Facades\GAMP;
use App\Models\Enums\AnalyticsDimensions;
class AnalyticsService
{
/**
* Send out some stats about the install
*/
public function sendInstall()
{
if(config('app.analytics') === false) {
return;
}
# some analytics
$gamp = GAMP::setClientId(uniqid('', true));
$gamp->setDocumentPath('/install');
$gamp->setCustomDimension(PHP_VERSION, AnalyticsDimensions::PHP_VERSION);
# figure out database version
$pdo = DB::connection()->getPdo();
$gamp->setCustomDimension(
strtolower($pdo->getAttribute(PDO::ATTR_SERVER_VERSION)),
AnalyticsDimensions::DATABASE_VERSION
);
$gamp->sendPageview();
}
}

View File

@ -1,6 +1,6 @@
<?php
use Illuminate\Foundation\Application as LaravelApplication;
use App\Bootstrap\LoadConfiguration;
if (!defined('DS')) {
define('DS', DIRECTORY_SEPARATOR);
@ -10,7 +10,7 @@ if (!defined('DS')) {
* Customized container to allow some of the base Laravel
* configurations to be overridden
*/
class Application extends LaravelApplication
class Application extends Illuminate\Foundation\Application
{
private $publicDirPath,
$publicUrlPath = '/';
@ -24,6 +24,21 @@ class Application extends LaravelApplication
$this->useStoragePath($this->basePath . '/storage');
}
/**
* Override this method so we can inject our own LoadConfiguration
* class, which looks for any configurations that have been overridden
* in the root's config.php file
* @param array $bootstrappers
*/
public function bootstrapWith(array $bootstrappers)
{
#$find = '\Illuminate\Foundation\Bootstrap\LoadConfiguration';
$replace = LoadConfiguration::class;
$bootstrappers[1] = $replace;
parent::bootstrapWith($bootstrappers); // TODO: Change the autogenerated stub
}
/**
*
*/

View File

@ -1,28 +1,42 @@
<?php
return [
/**
* DO NOT EDIT THIS OR ANY OF THE CONFIG FILES DIRECTLY
*
* Set your override options in the config.php file that's in the root of
* your install. Otherwise, any changes here will get overridden in an update!
*/
'name' => env('PHPVMS_VA_NAME', 'phpvms'),
'env' => env('APP_ENV', 'dev'),
'debug' => env('APP_DEBUG', true),
'url' => env('APP_URL', 'http://localhost'),
'version' => '7.0',
return [
'name' => 'phpVMS',
'env' => 'dev',
'debug' => true,
'url' => 'http://localhost',
'version' => '7.0.0',
'locale' => 'en',
'fallback_locale' => 'en',
'log' => 'daily',
'log_level' => 'debug',
'log_max_files' => 7,
# This sends install and vaCentral specific information to help with
# optimizations and figuring out where slowdowns might be happening
'analytics' => true,
#
# Anything below here won't need changing and could break things
#
# DON'T CHANGE THIS OR ELSE YOUR TIMES WILL BE MESSED UP!
'timezone' => 'UTC',
'locale' => env('APP_LOCALE', 'en'),
'fallback_locale' => 'en',
# Is the default key cipher. Needs to be changed, otherwise phpVMS will think
# that it isn't installed. Doubles as a security feature, so keys are scrambled
'key' => env('APP_KEY', 'base64:zdgcDqu9PM8uGWCtMxd74ZqdGJIrnw812oRMmwDF6KY='),
'cipher' => 'AES-256-CBC',
'log' => env('APP_LOG', 'daily'),
'log_level' => env('APP_LOG_LEVEL', 'debug'),
'log_max_files' => env('APP_LOG_MAX_FILES', 7),
'providers' => [
/*

View File

@ -2,24 +2,24 @@
return [
'fetch' => PDO::FETCH_ASSOC,
'default' => env('DB_CONNECTION', 'mysql'),
'default' => 'mysql',
'connections' => [
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', ''),
'username' => env('DB_USERNAME', ''),
'password' => env('DB_PASSWORD', ''),
'host' => '127.0.0.1',
'port' => 3306,
'database' => '',
'username' => '',
'password' => '',
//'unix_socket' => env('DB_SOCKET', ''),
'prefix' => env('DB_PREFIX', ''),
'prefix' => '',
'timezone' => '+00:00',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'strict' => false,
'engine' => null,
'options' => [
PDO::ATTR_EMULATE_PREPARES => env('DB_EMULATE_PREPARES', false),
PDO::ATTR_EMULATE_PREPARES => false,
#PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
],
],
@ -48,10 +48,10 @@ return [
'redis' => [
'cluster' => false,
'default' => [
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DATABASE', 1),
'host' => 'localhost',
'password' => null,
'port' => 6379,
'database' => 1,
],
]
];

View File

@ -4,7 +4,7 @@ return [
'tracking_id' => 'UA-100567975-1',
'protocol_version' => 1,
'is_ssl' => false,
'is_disabled' => env('APP_ANALYTICS_DISABLED', false),
'is_disabled' => false,
'anonymize_ip' => false,
'async_requests' => false,
];

View File

@ -2,25 +2,23 @@
namespace Modules\Installer\Http\Controllers;
use DB;
use Log;
use PDO;
use Irazasyed\LaravelGAMP\Facades\GAMP;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Validator;
use App\Models\User;
use App\Models\Enums\AnalyticsDimensions;
use App\Repositories\AirlineRepository;
use App\Facades\Utils;
use App\Services\AnalyticsService;
use App\Services\UserService;
use App\Http\Controllers\Controller;
use Modules\Installer\Services\DatabaseService;
use Modules\Installer\Services\EnvironmentService;
use Modules\Installer\Services\ConfigService;
use Modules\Installer\Services\RequirementsService;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
@ -28,6 +26,7 @@ use Symfony\Component\HttpFoundation\File\Exception\FileException;
class InstallerController extends Controller
{
protected $airlineRepo,
$analyticsSvc,
$dbService,
$envService,
$reqService,
@ -35,12 +34,14 @@ class InstallerController extends Controller
public function __construct(
AirlineRepository $airlineRepo,
AnalyticsService $analyticsSvc,
DatabaseService $dbService,
EnvironmentService $envService,
ConfigService $envService,
RequirementsService $reqService,
UserService $userService
) {
$this->airlineRepo = $airlineRepo;
$this->analyticsSvc = $analyticsSvc;
$this->dbService = $dbService;
$this->envService = $envService;
$this->reqService = $reqService;
@ -61,12 +62,12 @@ class InstallerController extends Controller
protected function testDb(Request $request)
{
$this->dbService->checkDbConnection(
$request->input('db_conn'),
$request->input('db_host'),
$request->input('db_port'),
$request->input('db_name'),
$request->input('db_user'),
$request->input('db_pass')
$request->post('db_conn'),
$request->post('db_host'),
$request->post('db_port'),
$request->post('db_name'),
$request->post('db_user'),
$request->post('db_pass')
);
}
@ -152,7 +153,7 @@ class InstallerController extends Controller
*/
public function envsetup(Request $request)
{
Log::info('ENV setup', $request->toArray());
Log::info('ENV setup', $request->post());
// Before writing out the env file, test the DB credentials
try {
@ -163,16 +164,25 @@ class InstallerController extends Controller
}
// Now write out the env file
$attrs = [
'SITE_NAME' => $request->post('site_name'),
'SITE_URL' => $request->post('site_url'),
'DB_CONN' => $request->post('db_conn'),
'DB_HOST' => $request->post('db_host'),
'DB_PORT' => $request->post('db_port'),
'DB_NAME' => $request->post('db_name'),
'DB_USER' => $request->post('db_user'),
'DB_PASS' => $request->post('db_pass'),
'DB_PREFIX' => $request->post('db_prefix'),
];
/**
* Create the config files and then redirect so that the
* framework can pickup all those configs, etc, before we
* setup the database and stuff
*/
try {
$this->envService->createEnvFile(
$request->input('db_conn'),
$request->input('db_host'),
$request->input('db_port'),
$request->input('db_name'),
$request->input('db_user'),
$request->input('db_pass')
);
$this->envService->createConfigFiles($attrs);
} catch(FileException $e) {
flash()->error($e->getMessage());
return redirect(route('installer.step2'))->withInput();
@ -271,27 +281,7 @@ class InstallerController extends Controller
# Set the intial admin e-mail address
setting('general.admin_email', $user->email);
# some analytics
$gamp = GAMP::setClientId(uniqid('', true));
$gamp->setDocumentPath('/install');
$gamp->setCustomDimension(PHP_VERSION, AnalyticsDimensions::PHP_VERSION);
# figure out database version
$pdo = DB::connection()->getPdo();
$gamp->setCustomDimension(
strtolower($pdo->getAttribute(PDO::ATTR_SERVER_VERSION)),
AnalyticsDimensions::DATABASE_VERSION
);
$gamp->sendPageview();
# If analytics are disabled
if((int) $request->post('analytics') === 0) {
$this->envService->updateKeysInEnv([
'APP_ANALYTICS_DISABLED' => 'true',
]);
}
$this->analyticsSvc->sendInstall();
return view('installer::steps/step3a-completed', []);
}

View File

@ -4,6 +4,33 @@
<div style="align-content: center;">
{!! Form::open(['route' => 'installer.envsetup', 'method' => 'POST']) !!}
<table class="table" width="25%">
<tr>
<td colspan="2"><h4>Site Config</h4></td>
</tr>
<tr>
<td>Site Name</td>
<td style="text-align:center;">
<div class="form-group">
{!! Form::input('text', 'site_name', 'phpvms', ['class' => 'form-control']) !!}
</div>
</td>
</tr>
<tr>
<td>Site URL</td>
<td style="text-align:center;">
<div class="form-group">
{!! Form::input('text', 'site_url', Request::root(), ['class' => 'form-control']) !!}
</div>
</td>
</tr>
<tr>
<td colspan="2"><h4>Database Config</h4></td>
</tr>
<tr>
<td><p>Select Database Type</p></td>
<td style="text-align:center;">
@ -70,6 +97,16 @@
</tbody>
<tr>
<td>Database Prefix</td>
<td style="text-align:center;">
<div class="form-group">
{!! Form::input('text', 'db_prefix', '', ['class' => 'form-control']) !!}
<p>Set this if you're sharing the database with another application.</p>
</div>
</td>
</tr>
</table>
<div id="dbtest"></div>
<p style="text-align: right">
@ -106,7 +143,6 @@ $(document).ready(function() {
db_pass: $("input[name=db_pass]").val(),
};
console.log(opts);
$.post("{!! route('installer.dbtest') !!}", opts, function(data) {
$("#dbtest").html(data);
})

View File

@ -71,26 +71,27 @@
</td>
</tr>
{{--
<tr>
<td colspan="2"><h4>Options</h4></td>
</tr>
<tr>
<td colspan="2"><h4>Options</h4></td>
</tr>
<tr>
<td><p>Analytics</p></td>
<td>
<div class="form-group">
{!! Form::hidden('analytics', 0) !!}
{!! Form::checkbox('analytics', 1, true, ['class' => 'form-control']) !!}
<br />
<p>
Allows collection of analytics. They won't identify you, and helps us to track
the PHP and database versions that are used, and help to figure out problems
and slowdowns when vaCentral integration is enabled.
</p>
</div>
</td>
</tr>
<tr>
<td><p>Analytics</p></td>
<td>
<div class="form-group">
{!! Form::hidden('analytics', 0) !!}
{!! Form::checkbox('analytics', 1, true, ['class' => 'form-control']) !!}
<br />
<p>
Allows collection of analytics. They won't identify you, and helps us to track
the PHP and database versions that are used, and help to figure out problems
and slowdowns when vaCentral integration is enabled.
</p>
</div>
</td>
</tr>
--}}
</table>
<div id="dbtest"></div>
<p style="text-align: right">

View File

@ -5,8 +5,9 @@
<div style="align-content: center;">
{!! Form::open(['route' => 'installer.complete', 'method' => 'GET']) !!}
<h4>Install Completed!</h4>
<h4>Installer Completed!</h4>
<p>Edit the <span class="code">config.php</span> to fill in some additional settings. </p>
<p>Click the button to proceed to the login screen!</p>
<p style="text-align: right">

View File

@ -9,41 +9,41 @@ use Illuminate\Encryption\Encrypter;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
/**
* Class EnvironmentService
* Class ConfigService
* @package Modules\Installer\Services
*/
class EnvironmentService
class ConfigService
{
/**
* Create the .env file
* @param $driver
* @param $host
* @param $port
* @param $name
* @param $user
* @param $pass
* @param $attrs
* @return boolean
* @throws \Symfony\Component\HttpFoundation\File\Exception\FileException
*/
public function createEnvFile($driver, $host, $port, $name, $user, $pass): bool
public function createConfigFiles($attrs): bool
{
$opts = [
'APP_ENV' => 'dev',
'APP_KEY' => $this->createAppKey(),
'DB_CONN' => $driver,
'DB_HOST' => $host,
'DB_PORT' => $port,
'DB_NAME' => $name,
'DB_USER' => $user,
'DB_PASS' => $pass,
'SITE_NAME' => '',
'SITE_URL' => 'http://phpvms.test',
'DB_CONN' => '',
'DB_HOST' => '',
'DB_PORT' => '',
'DB_NAME' => '',
'DB_USER' => '',
'DB_PASS' => '',
'DB_PREFIX' => '',
'DB_EMULATE_PREPARES' => false,
];
$opts = array_merge($opts, $attrs);
$opts = $this->determinePdoOptions($opts);
$opts = $this->getCacheDriver($opts);
$opts = $this->getQueueDriver($opts);
$this->writeEnvFile($opts);
$this->writeConfigFiles($opts);
return true;
}
@ -163,8 +163,10 @@ class EnvironmentService
* @param $opts
* @throws \Symfony\Component\HttpFoundation\File\Exception\FileException
*/
protected function writeEnvFile($opts)
protected function writeConfigFiles($opts)
{
Stub::setBasePath(resource_path('/stubs/installer'));
$env_file = \App::environmentFilePath();
if(file_exists($env_file) && !is_writable($env_file)) {
@ -172,27 +174,28 @@ class EnvironmentService
throw new FileException('Can\'t write to the env.php file! Check the permissions');
}
/**
* First write out the env file
*/
try {
$stub = new Stub('/env.stub', $opts);
$stub->render();
$stub->saveTo(\App::environmentPath(), \App::environmentFile());
} catch(\Exception $e) {
throw new FileException('Couldn\'t write the env.php. (' . $e . ')');
throw new FileException('Couldn\'t write env.php. (' . $e . ')');
}
/*$fp = fopen($env_file, 'wb');
if($fp === false) {
throw new FileException('Couldn\'t write the env.php. (' . error_get_last() .')');
/**
* Next write out the config file. If there's an error here,
* then throw an exception but delete the env file first
*/
try {
$stub = new Stub('/config.stub', $opts);
$stub->render();
$stub->saveTo(\App::environmentPath(), 'config.php');
} catch (\Exception $e) {
unlink(\App::environmentPath().'/'. \App::environmentFile());
throw new FileException('Couldn\'t write config.php. (' . $e . ')');
}
# render it within Blade and log the contents
$env_contents = view('installer::stubs/env', $opts);
Log::info($env_contents);
$env_contents = "<?php exit(); ?>\n\n"
.$env_contents;
fwrite($fp, $env_contents);
fclose($fp);*/
}
}

View File

@ -0,0 +1,60 @@
<?php
/**
* This file overrides any of the config files in the /config directory.
* The root key is the name of the file, and then the structure within.
* The config is merged, so only include what you want to override
*/
return [
# overrides app.php
'app' => [
'name' => '$SITE_NAME$',
'url' => '$SITE_URL$',
# Don't forget to change these when live
'env' => 'dev',
'debug' => true,
],
# overrides phpvms.php
'phpvms' => [
'skin' => 'default',
'vacentral_api_key' => '',
],
# overrides cache.php
'cache' => [
'default' => '$CACHE_DRIVER$',
'prefix' => 'phpvms_',
],
# overrides database.php
'database' => [
'default' => '$DB_CONN$',
'connections' => [
'mysql' => [
'host' => '$DB_HOST$',
'port' => $DB_PORT$,
'database' => '$DB_NAME$',
'username' => '$DB_USER$',
'password' => '$DB_PASS$',
'prefix' => '$DB_PREFIX$',
],
],
],
# overrides mail.php
'mail' => [
'driver' => 'smtp',
'host' => '',
'port' => 587,
'from' => [
'name' => '',
'address' => '',
],
'username' => '',
'password' => '',
],
];

View File

@ -0,0 +1,3 @@
<?php exit(); ?>
APP_KEY=base64:$APP_KEY$

View File

@ -1,48 +0,0 @@
<?php exit(); ?>
#
# Before you go live, remember to change the APP_ENV to production
# and APP_DEBUG to false. Adjust logging to taste
#
APP_ENV=$APP_ENV$
APP_URL=http://localhost
APP_SKIN=default
APP_KEY=base64:$APP_KEY$
APP_DEBUG=true
APP_LOCALE=en
APP_ANALYTICS_DISABLED=false
PHPVMS_INSTALLED=true
PHPVMS_VA_NAME="phpvms"
VACENTRAL_API_KEY=
CHECKWX_API_KEY=
APP_LOG=daily
APP_LOG_LEVEL=debug
APP_LOG_MAX_FILES=3
DB_CONNECTION=$DB_CONN$
DB_HOST=$DB_HOST$
DB_PORT=$DB_PORT$
DB_DATABASE=$DB_NAME$
DB_USERNAME=$DB_USER$
DB_PASSWORD=$DB_PASS$
DB_EMULATE_PREPARES=$DB_EMULATE_PREPARES$
DB_PREFIX=
MAIL_DRIVER=smtp
MAIL_FROM_ADDRESS=no-reply@phpvms.net
MAIL_FROM_NAME="phpVMS Admin"
MAIL_HOST=
MAIL_PORT=
MAIL_ENCRYPTION=
MAIL_USERNAME=
MAIL_PASSWORD=
CACHE_ENABLED=false
CACHE_DRIVER=$CACHE_DRIVER$
CACHE_PREFIX=phpvms
SESSION_DRIVER=file
QUEUE_DRIVER=$QUEUE_DRIVER$