Add a setup step to fill database info

This commit is contained in:
Pig Fang 2018-07-21 16:55:36 +08:00
parent 07e5d8b3ec
commit 0233e44ccd
10 changed files with 208 additions and 26 deletions

View File

@ -2,6 +2,7 @@
namespace App\Http\Controllers;
use DB;
use Log;
use File;
use Utils;
@ -17,20 +18,69 @@ use App\Exceptions\PrettyPageException;
class SetupController extends Controller
{
public function welcome()
public function database(Request $request)
{
$type = get_db_type();
config([
'database.connections.temp.driver' => $request->input('type'),
'database.connections.temp.host' => $request->input('host'),
'database.connections.temp.port' => $request->input('port'),
'database.connections.temp.username' => $request->input('username'),
'database.connections.temp.password' => $request->input('password'),
'database.connections.temp.database' => $request->input('db') == '' ? null : $request->input('db'),
'database.connections.temp.prefix' => $request->input('prefix') == '' ? null : $request->input('prefix'),
]);
if ($type === 'SQLite') {
// @codeCoverageIgnoreStart
$server = get_db_config()['database'];
// @codeCoverageIgnoreEnd
} else {
$config = get_db_config();
$server = "{$config['username']}@{$config['host']}";
try {
DB::connection('temp')->getPdo();
} catch (\Exception $e) {
$msg = iconv('gbk', 'utf-8', $e->getMessage());
$type = humanize_db_type($request->input('type'));
throw new PrettyPageException(
trans('setup.database.connection-error', compact('msg', 'type')),
$e->getCode()
);
}
return view('setup.wizard.welcome')->with(compact('type', 'server'));
$content = File::get('.env');
$content = str_replace(
'DB_CONNECTION = '.env('DB_CONNECTION'),
'DB_CONNECTION = '.$request->input('type'),
$content
);
$content = str_replace(
'DB_HOST = '.env('DB_HOST'),
'DB_HOST = '.$request->input('host'),
$content
);
$content = str_replace(
'DB_PORT = '.env('DB_PORT'),
'DB_PORT = '.$request->input('port'),
$content
);
$content = str_replace(
'DB_DATABASE = '.env('DB_DATABASE'),
'DB_DATABASE = '.$request->input('db'),
$content
);
$content = str_replace(
'DB_USERNAME = '.env('DB_USERNAME'),
'DB_USERNAME = '.$request->input('username'),
$content
);
$content = str_replace(
'DB_PASSWORD = '.env('DB_PASSWORD'),
'DB_PASSWORD = '.$request->input('password'),
$content
);
$content = str_replace(
'DB_PREFIX = '.env('DB_PREFIX'),
'DB_PREFIX = '.$request->input('prefix'),
$content
);
File::put('.env', $content);
return redirect('setup/info');
}
public function info()

View File

@ -65,7 +65,7 @@ class BootServiceProvider extends ServiceProvider
}
$msg = iconv('gbk', 'utf-8', $e->getMessage());
$type = get_db_type();
$type = humanize_db_type();
throw new PrettyPageException(
trans('setup.database.connection-error', compact('msg', 'type')),

View File

@ -448,9 +448,9 @@ if (! function_exists('die_with_utf8_encoding')) {
}
}
if (! function_exists('get_db_type')) {
if (! function_exists('humanize_db_type')) {
function get_db_type($type = null)
function humanize_db_type($type = null)
{
$map = [
'mysql' => 'MySQL',

View File

@ -1,6 +1,5 @@
database:
connection-error: "Unable to connect to the target :type database, please check your configuration. The server replied with: :msg"
connection-success: Connect to the target :type database [:server] successfully, just click NEXT to start installation.
table-already-exists: There are some tables already exist in target database, which names conflict with ones we are going to create. To avoid data loss, please manually delete these tables :tables, or set a different table prefix.
file:
@ -43,6 +42,20 @@ wizard:
button: Next
text: Welcome to Blessing Skin Server v:version!
database:
title: Database
text: The database is used for storing data of Blessing Skin.
type: Database Type
host: Database Host
port: Database Port
username: Database Username
password: Database Password
db: Database Name
db-notice: You should provide the path to SQLite file and there is no need to fill other blanks if you use SQLite.
prefix: Prefix of Database Table (Optional)
prefix-notice: You don't need to use this option unless you want to install multiple Blessing Skin Server into one database.
info:
title: Information needed
button: Run install

View File

@ -1,6 +1,5 @@
database:
connection-error: 无法连接至 :type 服务器,请检查你的配置。服务器返回的信息:「:msg」
connection-success: 成功连接至 :type 服务器 [:server] ,点击下一步以开始安装。
table-already-exists: 检测到目标数据库中已存在如下数据表 :tables它们与本程序即将创建的数据表名称冲突为了避免原有数据被覆盖请手动删除它们或者为本程序选择一个不同的数据表前缀。
file:
@ -43,6 +42,20 @@ wizard:
button: 下一步
text: 欢迎使用 Blessing Skin Server v:version
database:
title: 填写数据库信息
text: 您提供的数据库将用于存储 Blessing Skin 的数据
type: 数据库类型
host: 数据库服务器地址
port: 端口
username: 数据库用户名
password: 数据库密码
db: 数据库名称
db-notice: 如果您使用 SQLite那么您应该填写 SQLite 数据库文件的路径,并且无需填写其它信息
prefix: 数据表前缀(可选)
prefix-notice: 通常您不需要填写此项,除非您有向同一数据库安装多个 Blessing Skin 的需要
info:
title: 填写信息
button: 开始安装

View File

@ -0,0 +1,89 @@
@extends('setup.master')
@section('content')
<h1>@lang('setup.wizard.database.title')
@include('setup.wizard.language')
</h1>
<p>@lang('setup.wizard.database.text')</p>
<form id="setup" method="post" action="{{ url('setup/database') }}" novalidate="novalidate">
<table class="form-table">
<tr class="form-field form-required">
<th scope="row"><label for="type">@lang('setup.wizard.database.type')</label></th>
<td>
<input name="type" type="radio" value="mysql" id="type-mysql" checked />
<label for="type-mysql">MySQL / MariaDB</label>
<input name="type" type="radio" value="pgsql" id="type-pgsql" />
<label for="type-pgsql">PostgreSQL</label>
<input name="type" type="radio" value="sqlite" id="type-sqlite" />
<label for="type-sqlite">SQLite</label>
</td>
</tr>
<tr class="form-field form-required">
<th scope="row"><label for="host">@lang('setup.wizard.database.host')</label></th>
<td>
<input name="host" type="text" id="host" size="25" value="127.0.0.1" />
</td>
</tr>
<tr class="form-field form-required">
<th scope="row"><label for="port">@lang('setup.wizard.database.port')</label></th>
<td>
<input name="port" type="text" id="port" size="25" value="3306" />
</td>
</tr>
<tr class="form-field form-required">
<th scope="row"><label for="username">@lang('setup.wizard.database.username')</label></th>
<td>
<input name="username" type="text" id="username" size="25" value="" />
</td>
</tr>
<tr class="form-field form-required">
<th scope="row"><label for="password">@lang('setup.wizard.database.password')</label></th>
<td>
<input type="password" name="password" id="password" class="regular-text" autocomplete="off" />
</td>
</tr>
<tr class="form-field form-required">
<th scope="row"><label for="db">@lang('setup.wizard.database.db')</label></th>
<td>
<input name="db" type="text" id="db" size="25" value="" />
<p>@lang('setup.wizard.database.db-notice')</p>
</td>
</tr>
<tr>
<th scope="row"><label for="prefix">@lang('setup.wizard.database.prefix')</label></th>
<td>
<input name="prefix" type="text" id="prefix" size="25" value="" />
<p>@lang('setup.wizard.database.prefix-notice')</p>
</td>
</tr>
</table>
@if (count($errors) > 0)
<div class="alert alert-warning" role="alert">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<p class="step">
<input type="submit" name="submit" id="submit" class="button button-large" value="@lang('setup.wizard.welcome.button')" />
</p>
</form>
@endsection
@section('script')
<script>
var port = document.getElementById('port')
document.getElementById('type-mysql').onchange = function () {
port.value = 3306
}
document.getElementById('type-pgsql').onchange = function () {
port.value = 5432
}
</script>
@endsection

View File

@ -6,9 +6,8 @@
</h1>
<p>@lang('setup.wizard.welcome.text', ['version' => config('app.version')])</p>
<p>@lang('setup.database.connection-success', ['server' => $server, 'type' => $type])</p>
<p class="step">
<a href="{{ url('setup/info') }}" class="button button-large">@lang('setup.wizard.welcome.button')</a>
<a href="{{ url('setup/database') }}" class="button button-large">@lang('setup.wizard.welcome.button')</a>
</p>
@endsection

View File

@ -17,7 +17,9 @@
Route::group(['prefix' => 'setup'], function ()
{
Route::group(['middleware' => 'setup'], function () {
Route::get ('/', 'SetupController@welcome');
Route::view('/', 'setup.wizard.welcome');
Route::view('/database', 'setup.wizard.database');
Route::post('/database', 'SetupController@database');
Route::get ('/info', 'SetupController@info');
Route::post('/finish', 'SetupController@finish');
});

0
storage/database.db Normal file
View File

View File

@ -37,16 +37,32 @@ class SetupControllerTest extends TestCase
public function testWelcome()
{
$type = get_db_type();
$this->get('/setup')->assertViewIs('setup.wizard.welcome');
}
if ($type === 'SQLite') {
$server = get_db_config()['database'];
} else {
$config = get_db_config();
$server = "{$config['username']}@{$config['host']}";
}
public function testDatabase()
{
$fake = [
'type' => 'mysql',
'host' => '127.0.0.1',
'port' => '3306',
'db' => env('DB_DATABASE'),
'username' => env('DB_USERNAME'),
'password' => env('DB_PASSWORD'),
'prefix' => '',
];
File::shouldReceive('get')->with('.env')->andReturn('');
File::shouldReceive('put')->with('.env', '');
$this->post('/setup/database', $fake)->assertRedirect('/setup/info');
}
$this->get('/setup')->assertSee($type)->assertSee($server);
public function testReportDatabaseConnectionError()
{
$this->post('/setup/database', ['type' => 'sqlite', 'host' => '', 'db' => 'test'])
->assertSee(trans('setup.database.connection-error', [
'type' => 'SQLite',
'msg' => 'Database (test) does not exist.'
]));
}
public function testInfo()