2016-11-18 16:46:58 +08:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
|
2017-01-02 13:27:53 +08:00
|
|
|
use Log;
|
2017-08-05 15:10:08 +08:00
|
|
|
use File;
|
2016-11-18 16:46:58 +08:00
|
|
|
use Utils;
|
|
|
|
use Schema;
|
|
|
|
use Option;
|
2016-11-21 21:50:24 +08:00
|
|
|
use Storage;
|
2016-11-18 16:46:58 +08:00
|
|
|
use Artisan;
|
|
|
|
use App\Models\User;
|
|
|
|
use Illuminate\Http\Request;
|
|
|
|
use Illuminate\Validation\Validator;
|
2016-11-21 21:50:24 +08:00
|
|
|
use App\Exceptions\PrettyPageException;
|
2016-11-18 16:46:58 +08:00
|
|
|
|
|
|
|
class SetupController extends Controller
|
|
|
|
{
|
|
|
|
public function welcome()
|
|
|
|
{
|
2018-02-22 21:26:23 +08:00
|
|
|
$type = get_db_type();
|
2016-11-18 16:46:58 +08:00
|
|
|
|
2018-02-22 21:26:23 +08:00
|
|
|
if ($type === 'SQLite') {
|
2018-03-11 12:36:23 +08:00
|
|
|
// @codeCoverageIgnoreStart
|
2018-02-22 21:26:23 +08:00
|
|
|
$server = get_db_config()['database'];
|
2018-03-11 12:36:23 +08:00
|
|
|
// @codeCoverageIgnoreEnd
|
2018-02-22 21:26:23 +08:00
|
|
|
} else {
|
|
|
|
$config = get_db_config();
|
|
|
|
$server = "{$config['username']}@{$config['host']}";
|
|
|
|
}
|
|
|
|
|
|
|
|
return view('setup.wizard.welcome')->with(compact('type', 'server'));
|
2016-11-18 16:46:58 +08:00
|
|
|
}
|
|
|
|
|
2017-01-02 13:27:53 +08:00
|
|
|
public function info()
|
|
|
|
{
|
2018-02-22 22:29:25 +08:00
|
|
|
$existingTables = static::checkTablesExist([], true);
|
|
|
|
|
|
|
|
// Not installed completely
|
|
|
|
if (count($existingTables) > 0) {
|
|
|
|
Log::info('Remaining tables detected, exit setup wizard now', [$existingTables]);
|
|
|
|
|
|
|
|
$existingTables = array_map(function ($item) {
|
|
|
|
return get_db_config()['prefix'].$item;
|
|
|
|
}, $existingTables);
|
|
|
|
|
|
|
|
throw new PrettyPageException(trans('setup.database.table-already-exists', ['tables' => json_encode($existingTables)]), 1);
|
|
|
|
}
|
|
|
|
|
2018-03-11 12:36:23 +08:00
|
|
|
// @codeCoverageIgnoreStart
|
2018-02-22 23:07:23 +08:00
|
|
|
if (! function_exists('escapeshellarg')) {
|
|
|
|
throw new PrettyPageException(trans('setup.disabled-functions.escapeshellarg'), 1);
|
|
|
|
}
|
2018-03-11 12:36:23 +08:00
|
|
|
// @codeCoverageIgnoreEnd
|
2018-02-22 23:07:23 +08:00
|
|
|
|
2017-01-02 13:27:53 +08:00
|
|
|
return view('setup.wizard.info');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function finish(Request $request)
|
|
|
|
{
|
|
|
|
$this->validate($request, [
|
|
|
|
'email' => 'required|email',
|
2018-06-18 21:50:32 +08:00
|
|
|
'password' => 'required|min:8|max:32|confirmed',
|
2017-01-02 13:27:53 +08:00
|
|
|
'site_name' => 'required'
|
|
|
|
]);
|
|
|
|
|
2017-11-20 19:56:24 +08:00
|
|
|
if ($request->has('generate_random')) {
|
2018-02-16 17:31:04 +08:00
|
|
|
// Generate new APP_KEY & SALT randomly
|
2017-01-08 11:28:55 +08:00
|
|
|
if (is_writable(app()->environmentFile())) {
|
|
|
|
Artisan::call('key:random');
|
|
|
|
Artisan::call('salt:random');
|
|
|
|
|
|
|
|
Log::info("[SetupWizard] Random application key & salt set successfully.", [
|
|
|
|
'key' => config('app.key'),
|
|
|
|
'salt' => config('secure.salt')
|
|
|
|
]);
|
|
|
|
} else {
|
2017-11-20 19:56:24 +08:00
|
|
|
// @codeCoverageIgnoreStart
|
2017-01-08 11:28:55 +08:00
|
|
|
Log::warning("[SetupWizard] Failed to set application key. No write permission.");
|
2017-11-20 19:56:24 +08:00
|
|
|
// @codeCoverageIgnoreEnd
|
2017-01-08 11:28:55 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-22 22:29:25 +08:00
|
|
|
// Create tables
|
2017-01-02 13:27:53 +08:00
|
|
|
Artisan::call('migrate', ['--force' => true]);
|
|
|
|
Log::info("[SetupWizard] Tables migrated.");
|
|
|
|
|
|
|
|
Option::set('site_name', $request->input('site_name'));
|
2017-11-07 21:40:53 +08:00
|
|
|
|
|
|
|
$siteUrl = url('/');
|
|
|
|
|
|
|
|
if (ends_with($siteUrl, '/index.php')) {
|
2017-11-20 19:56:24 +08:00
|
|
|
$siteUrl = substr($siteUrl, 0, -10); // @codeCoverageIgnore
|
2017-11-07 21:40:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Option::set('site_url', $siteUrl);
|
2017-01-02 13:27:53 +08:00
|
|
|
|
2018-02-16 17:31:04 +08:00
|
|
|
// Register super admin
|
2017-01-02 13:27:53 +08:00
|
|
|
$user = User::register(
|
|
|
|
$request->input('email'),
|
|
|
|
$request->input('password'), function ($user)
|
|
|
|
{
|
|
|
|
$user->ip = Utils::getClientIp();
|
|
|
|
$user->score = option('user_initial_score');
|
|
|
|
$user->register_at = Utils::getTimeFormatted();
|
|
|
|
$user->last_sign_at = Utils::getTimeFormatted(time() - 86400);
|
|
|
|
$user->permission = User::SUPER_ADMIN;
|
|
|
|
});
|
|
|
|
Log::info("[SetupWizard] Super Admin registered.", ['user' => $user]);
|
|
|
|
|
|
|
|
$this->createDirectories();
|
|
|
|
Log::info("[SetupWizard] Installation completed.");
|
|
|
|
|
|
|
|
return view('setup.wizard.finish')->with([
|
|
|
|
'email' => $request->input('email'),
|
|
|
|
'password' => $request->input('password')
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
2016-11-18 16:46:58 +08:00
|
|
|
public function update()
|
|
|
|
{
|
2017-01-02 16:23:31 +08:00
|
|
|
if (Utils::versionCompare(config('app.version'), option('version', ''), '<=')) {
|
2018-02-16 17:31:04 +08:00
|
|
|
// No updates available
|
2016-11-18 16:46:58 +08:00
|
|
|
return view('setup.locked');
|
|
|
|
}
|
|
|
|
|
|
|
|
return view('setup.updates.welcome');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function doUpdate()
|
|
|
|
{
|
|
|
|
$resource = opendir(database_path('update_scripts'));
|
2016-12-18 17:32:46 +08:00
|
|
|
$updateScriptExist = false;
|
2016-11-18 16:46:58 +08:00
|
|
|
|
|
|
|
$tips = [];
|
|
|
|
|
|
|
|
while($filename = @readdir($resource)) {
|
|
|
|
if ($filename != "." && $filename != "..") {
|
|
|
|
preg_match('/update-(.*)-to-(.*).php/', $filename, $matches);
|
|
|
|
|
2018-02-16 17:31:04 +08:00
|
|
|
// Skip if the file is not valid or expired
|
|
|
|
if (! isset($matches[2]) ||
|
2017-01-02 16:23:31 +08:00
|
|
|
Utils::versionCompare($matches[2], config('app.version'), '<')) {
|
2016-11-18 16:46:58 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$result = require database_path('update_scripts')."/$filename";
|
|
|
|
|
|
|
|
if (is_array($result)) {
|
2018-02-16 17:31:04 +08:00
|
|
|
// Push the tip into array
|
2016-11-18 16:46:58 +08:00
|
|
|
foreach ($result as $tip) {
|
|
|
|
$tips[] = $tip;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-18 17:32:46 +08:00
|
|
|
$updateScriptExist = true;
|
2016-11-18 16:46:58 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
closedir($resource);
|
|
|
|
|
|
|
|
foreach (config('options') as $key => $value) {
|
2018-02-16 17:31:04 +08:00
|
|
|
if (! Option::has($key)) {
|
2016-11-18 16:46:58 +08:00
|
|
|
Option::set($key, $value);
|
2018-02-16 17:31:04 +08:00
|
|
|
}
|
2016-11-18 16:46:58 +08:00
|
|
|
}
|
|
|
|
|
2018-02-16 17:31:04 +08:00
|
|
|
if (! $updateScriptExist) {
|
|
|
|
// If there is no update script given
|
2016-11-18 16:46:58 +08:00
|
|
|
Option::set('version', config('app.version'));
|
|
|
|
}
|
|
|
|
|
2018-02-16 17:31:04 +08:00
|
|
|
// Clear all compiled view files
|
2017-08-05 15:10:08 +08:00
|
|
|
try {
|
|
|
|
Artisan::call('view:clear');
|
|
|
|
} catch (\Exception $e) {
|
2017-11-20 19:56:24 +08:00
|
|
|
Log::error('Error occured when processing view:clear', [$e]);
|
|
|
|
|
|
|
|
$files = collect(File::files(storage_path('framework/views')));
|
|
|
|
$files->reject(function ($path) {
|
|
|
|
return ends_with($path, '.gitignore');
|
|
|
|
})->each(function ($path) {
|
|
|
|
File::delete($path);
|
|
|
|
});
|
2017-08-05 15:10:08 +08:00
|
|
|
}
|
2017-01-13 22:34:06 +08:00
|
|
|
|
2016-11-18 16:46:58 +08:00
|
|
|
return view('setup.updates.success', ['tips' => $tips]);
|
|
|
|
}
|
|
|
|
|
2016-12-18 17:32:46 +08:00
|
|
|
/**
|
|
|
|
* Check if the given tables exist in current database.
|
|
|
|
*
|
2016-12-31 16:43:23 +08:00
|
|
|
* @param array $tables
|
2018-02-22 22:29:25 +08:00
|
|
|
* @param bool $returnExisting
|
|
|
|
* @return bool|array
|
2016-12-18 17:32:46 +08:00
|
|
|
*/
|
2018-02-22 22:29:25 +08:00
|
|
|
public static function checkTablesExist($tables = [], $returnExistingTables = false) {
|
|
|
|
$existingTables = [];
|
2018-02-16 17:31:04 +08:00
|
|
|
$tables = $tables ?: ['users', 'closets', 'players', 'textures', 'options'];
|
|
|
|
|
2016-12-31 16:43:23 +08:00
|
|
|
foreach ($tables as $tableName) {
|
2018-02-16 17:31:04 +08:00
|
|
|
// Table prefix will be added automatically
|
2016-12-31 16:43:23 +08:00
|
|
|
if (Schema::hasTable($tableName)) {
|
2018-02-22 22:29:25 +08:00
|
|
|
$existingTables[] = $tableName;
|
2016-11-18 16:46:58 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-22 22:29:25 +08:00
|
|
|
if (count($existingTables) == count($tables)) {
|
2016-12-31 16:43:23 +08:00
|
|
|
return true;
|
|
|
|
} else {
|
2018-02-22 22:29:25 +08:00
|
|
|
return $returnExistingTables ? $existingTables : false;
|
2016-12-31 16:43:23 +08:00
|
|
|
}
|
2016-11-18 16:46:58 +08:00
|
|
|
}
|
|
|
|
|
2017-01-02 14:49:28 +08:00
|
|
|
public static function checkDirectories()
|
2016-12-18 17:32:46 +08:00
|
|
|
{
|
2017-01-02 14:49:28 +08:00
|
|
|
$directories = ['storage/textures', 'plugins'];
|
|
|
|
|
|
|
|
try {
|
|
|
|
foreach ($directories as $dir) {
|
2018-02-16 17:31:04 +08:00
|
|
|
if (! Storage::disk('root')->has($dir)) {
|
|
|
|
// Try to mkdir
|
|
|
|
if (! Storage::disk('root')->makeDirectory($dir)) {
|
2017-01-02 14:49:28 +08:00
|
|
|
return false;
|
2018-02-16 17:31:04 +08:00
|
|
|
}
|
2017-01-02 14:49:28 +08:00
|
|
|
}
|
|
|
|
}
|
2016-12-18 17:32:46 +08:00
|
|
|
|
2017-01-02 14:49:28 +08:00
|
|
|
return true;
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
return false;
|
|
|
|
}
|
2016-12-18 17:32:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
protected function createDirectories()
|
|
|
|
{
|
2017-01-02 14:49:28 +08:00
|
|
|
return self::checkDirectories();
|
2016-12-18 17:32:46 +08:00
|
|
|
}
|
|
|
|
|
2016-11-18 16:46:58 +08:00
|
|
|
/**
|
|
|
|
* {@inheritdoc}
|
|
|
|
*/
|
|
|
|
protected function formatValidationErrors(Validator $validator)
|
|
|
|
{
|
|
|
|
return $validator->errors()->all();
|
|
|
|
}
|
|
|
|
}
|