2019-12-06 09:17:40 +08:00
|
|
|
|
<?php
|
2020-02-26 09:06:35 +08:00
|
|
|
|
namespace catcher\command\install;
|
2019-12-06 09:17:40 +08:00
|
|
|
|
|
2019-12-09 16:22:00 +08:00
|
|
|
|
use catcher\CatchAdmin;
|
2019-12-06 09:17:40 +08:00
|
|
|
|
use think\console\Command;
|
|
|
|
|
use think\console\Input;
|
|
|
|
|
use think\console\input\Option;
|
|
|
|
|
use think\console\Output;
|
|
|
|
|
use think\facade\Console;
|
|
|
|
|
|
2020-02-26 09:06:35 +08:00
|
|
|
|
class InstallProjectCommand extends Command
|
2019-12-06 09:17:40 +08:00
|
|
|
|
{
|
|
|
|
|
|
2019-12-14 14:58:08 +08:00
|
|
|
|
protected $databaseLink = [];
|
2019-12-06 09:17:40 +08:00
|
|
|
|
|
|
|
|
|
protected function configure()
|
|
|
|
|
{
|
2019-12-14 15:03:39 +08:00
|
|
|
|
$this->setName('catch:install')
|
2020-01-21 17:00:17 +08:00
|
|
|
|
->addOption('reinstall', '-r',Option::VALUE_NONE, 'reinstall back')
|
2019-12-06 09:17:40 +08:00
|
|
|
|
->setDescription('install project');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @time 2019年11月29日
|
|
|
|
|
* @param Input $input
|
|
|
|
|
* @param Output $output
|
|
|
|
|
* @return int|void|null
|
|
|
|
|
*/
|
|
|
|
|
protected function execute(Input $input, Output $output)
|
|
|
|
|
{
|
2020-01-21 17:00:17 +08:00
|
|
|
|
if ($input->getOption('reinstall')) {
|
|
|
|
|
$this->reInstall();
|
|
|
|
|
$this->project();
|
|
|
|
|
} else {
|
2019-12-06 09:17:40 +08:00
|
|
|
|
|
2020-01-21 17:00:17 +08:00
|
|
|
|
$this->detectionEnvironment();
|
2019-12-06 09:17:40 +08:00
|
|
|
|
|
2020-01-21 17:00:17 +08:00
|
|
|
|
$this->firstStep();
|
2019-12-06 09:17:40 +08:00
|
|
|
|
|
2020-01-21 17:00:17 +08:00
|
|
|
|
$this->secondStep();
|
2019-12-06 09:17:40 +08:00
|
|
|
|
|
2020-01-21 17:00:17 +08:00
|
|
|
|
$this->thirdStep();
|
2019-12-06 09:17:40 +08:00
|
|
|
|
|
2020-01-21 17:00:17 +08:00
|
|
|
|
$this->finished();
|
|
|
|
|
|
|
|
|
|
$this->project();
|
|
|
|
|
}
|
2019-12-06 09:17:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 环境检测
|
|
|
|
|
*
|
|
|
|
|
* @time 2019年11月29日
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
protected function detectionEnvironment(): void
|
|
|
|
|
{
|
|
|
|
|
$this->output->info('environment begin to check...');
|
|
|
|
|
|
|
|
|
|
if (version_compare(PHP_VERSION, '7.1.0', '<')) {
|
|
|
|
|
$this->output->error('php version should >= 7.1.0');
|
|
|
|
|
exit();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->output->info('php version ' . PHP_VERSION);
|
|
|
|
|
|
|
|
|
|
if (!extension_loaded('mbstring')) {
|
|
|
|
|
$this->output->error('mbstring extension not install');exit();
|
|
|
|
|
}
|
|
|
|
|
$this->output->info('mbstring extension is installed');
|
|
|
|
|
|
|
|
|
|
if (!extension_loaded('json')) {
|
|
|
|
|
$this->output->error('json extension not install');
|
|
|
|
|
exit();
|
|
|
|
|
}
|
|
|
|
|
$this->output->info('json extension is installed');
|
|
|
|
|
|
|
|
|
|
if (!extension_loaded('openssl')) {
|
|
|
|
|
$this->output->error('openssl extension not install');
|
|
|
|
|
exit();
|
|
|
|
|
}
|
|
|
|
|
$this->output->info('openssl extension is installed');
|
|
|
|
|
|
|
|
|
|
if (!extension_loaded('pdo')) {
|
|
|
|
|
$this->output->error('pdo extension not install');
|
|
|
|
|
exit();
|
|
|
|
|
}
|
|
|
|
|
$this->output->info('pdo extension is installed');
|
|
|
|
|
|
|
|
|
|
if (!extension_loaded('xml')) {
|
|
|
|
|
$this->output->error('xml extension not install');
|
|
|
|
|
exit();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->output->info('xml extension is installed');
|
|
|
|
|
|
|
|
|
|
$this->output->info('🎉 environment checking finished');
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-21 17:00:17 +08:00
|
|
|
|
|
2019-12-06 09:17:40 +08:00
|
|
|
|
/**
|
|
|
|
|
* 安装第一步
|
|
|
|
|
*
|
|
|
|
|
* @time 2019年11月29日
|
2019-12-09 16:22:00 +08:00
|
|
|
|
* @return mixed
|
2019-12-06 09:17:40 +08:00
|
|
|
|
*/
|
2019-12-09 16:22:00 +08:00
|
|
|
|
protected function firstStep()
|
2019-12-06 09:17:40 +08:00
|
|
|
|
{
|
|
|
|
|
if (file_exists($this->app->getRootPath() . '.env')) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$answer = strtolower($this->output->ask($this->input, '🤔️ Did You Need to Set Database information? (Y/N): '));
|
|
|
|
|
|
|
|
|
|
if ($answer === 'y' || $answer === 'yes') {
|
|
|
|
|
$charset = $this->output->ask($this->input, '👉 please input database charset, default (utf8mb4):') ? : 'utf8mb4';
|
|
|
|
|
$database = '';
|
|
|
|
|
while (!$database) {
|
|
|
|
|
$database = $this->output->ask($this->input, '👉 please input database name: ');
|
|
|
|
|
if ($database) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$host = $this->output->ask($this->input, '👉 please input database host, default (127.0.0.1):') ? : '127.0.0.1';
|
|
|
|
|
$port = $this->output->ask($this->input, '👉 please input database host port, default (3306):') ? : '3306';
|
|
|
|
|
$prefix = $this->output->ask($this->input, '👉 please input table prefix, default (null):') ? : '';
|
|
|
|
|
$username = $this->output->ask($this->input, '👉 please input database username default (root): ') ? : 'root';
|
|
|
|
|
$password = '';
|
2020-02-21 08:09:33 +08:00
|
|
|
|
$tryTimes = 0;
|
2019-12-06 09:17:40 +08:00
|
|
|
|
while (!$password) {
|
|
|
|
|
$password = $this->output->ask($this->input, '👉 please input database password: ');
|
|
|
|
|
if ($password) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-02-21 08:09:33 +08:00
|
|
|
|
// 尝试三次以上未填写,视为密码空
|
|
|
|
|
$tryTimes++;
|
|
|
|
|
if (!$password && $tryTimes > 2) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
2019-12-06 09:17:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-12-14 14:58:08 +08:00
|
|
|
|
$this->databaseLink = [$host, $database, $username, $password, $port, $charset, $prefix];
|
|
|
|
|
|
2019-12-06 09:17:40 +08:00
|
|
|
|
$this->generateEnvFile($host, $database, $username, $password, $port, $charset, $prefix);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 安装第二部
|
|
|
|
|
*
|
|
|
|
|
* @time 2019年11月29日
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
protected function secondStep(): void
|
|
|
|
|
{
|
2019-12-14 15:03:39 +08:00
|
|
|
|
if (file_exists(root_path() . '.env')) {
|
|
|
|
|
$connections = \config('database.connections');
|
|
|
|
|
|
|
|
|
|
[
|
|
|
|
|
$connections['mysql']['hostname'],
|
|
|
|
|
$connections['mysql']['database'],
|
|
|
|
|
$connections['mysql']['username'],
|
|
|
|
|
$connections['mysql']['password'],
|
|
|
|
|
$connections['mysql']['hostport'],
|
|
|
|
|
$connections['mysql']['charset'],
|
|
|
|
|
$connections['mysql']['prefix'],
|
|
|
|
|
] = $this->databaseLink;
|
|
|
|
|
|
|
|
|
|
\config([
|
|
|
|
|
'connections' => $connections,
|
|
|
|
|
], 'database');
|
|
|
|
|
|
2020-01-21 17:00:17 +08:00
|
|
|
|
$this->migrateAndSeeds();
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-12-14 15:57:32 +08:00
|
|
|
|
|
2020-01-21 17:00:17 +08:00
|
|
|
|
/**
|
|
|
|
|
* 生成表结构
|
|
|
|
|
*
|
|
|
|
|
* @time 2020年01月20日
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
protected function migrateAndSeeds(): void
|
|
|
|
|
{
|
|
|
|
|
foreach (CatchAdmin::getModulesDirectory() as $directory) {
|
|
|
|
|
$moduleInfo = CatchAdmin::getModuleInfo($directory);
|
|
|
|
|
if (is_dir(CatchAdmin::moduleMigrationsDirectory($moduleInfo['alias']))) {
|
|
|
|
|
$output = Console::call('catch-migrate:run', [$moduleInfo['alias']]);
|
|
|
|
|
$this->output->info(sprintf('module [%s] migrations %s', $moduleInfo['alias'], $output->fetch()));
|
|
|
|
|
|
|
|
|
|
$seedOut = Console::call('catch-seed:run', [$moduleInfo['alias']]);
|
|
|
|
|
$this->output->info(sprintf('module [%s] seeds %s', $moduleInfo['alias'], $seedOut->fetch()));
|
2019-12-06 09:17:40 +08:00
|
|
|
|
}
|
2020-01-21 17:00:17 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected function migrateRollback()
|
|
|
|
|
{
|
|
|
|
|
foreach (CatchAdmin::getModulesDirectory() as $directory) {
|
|
|
|
|
$moduleInfo = CatchAdmin::getModuleInfo($directory);
|
|
|
|
|
if (is_dir(CatchAdmin::moduleMigrationsDirectory($moduleInfo['alias']))) {
|
|
|
|
|
$rollbackOut = Console::call('catch-migrate:rollback', [$moduleInfo['alias'], '-f']);
|
|
|
|
|
// $this->output->info(sprintf('module [%s] [%s] rollback %s', $moduleInfo['alias'], basename($migration), $rollbackOut->fetch()));
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-12-06 09:17:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 安装第四步
|
|
|
|
|
*
|
|
|
|
|
* @time 2019年11月29日
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
protected function thirdStep(): void
|
|
|
|
|
{
|
|
|
|
|
Console::call('catch:cache');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* finally
|
|
|
|
|
*
|
|
|
|
|
* @time 2019年11月30日
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
protected function finished(): void
|
|
|
|
|
{
|
|
|
|
|
// todo something
|
2020-01-06 20:20:24 +08:00
|
|
|
|
// create jwt
|
|
|
|
|
Console::call('jwt:create');
|
2019-12-06 09:17:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* generate env file
|
|
|
|
|
*
|
|
|
|
|
* @time 2019年11月29日
|
|
|
|
|
* @param $host
|
|
|
|
|
* @param $database
|
|
|
|
|
* @param $username
|
|
|
|
|
* @param $password
|
|
|
|
|
* @param $port
|
|
|
|
|
* @param $charset
|
|
|
|
|
* @param $prefix
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
protected function generateEnvFile($host, $database, $username, $password, $port, $charset, $prefix): void
|
|
|
|
|
{
|
2019-12-14 14:58:08 +08:00
|
|
|
|
try {
|
2019-12-06 09:17:40 +08:00
|
|
|
|
$env = \parse_ini_file(root_path() . '.example.env', true);
|
|
|
|
|
|
|
|
|
|
$env['DATABASE']['HOSTNAME'] = $host;
|
|
|
|
|
$env['DATABASE']['DATABASE'] = $database;
|
|
|
|
|
$env['DATABASE']['USERNAME'] = $username;
|
|
|
|
|
$env['DATABASE']['PASSWORD'] = $password;
|
|
|
|
|
$env['DATABASE']['HOSTPORT'] = $port;
|
|
|
|
|
$env['DATABASE']['CHARSET'] = $charset;
|
|
|
|
|
if ($prefix) {
|
|
|
|
|
$env['DATABASE']['PREFIX'] = $prefix;
|
|
|
|
|
}
|
|
|
|
|
$dotEnv = '';
|
|
|
|
|
foreach ($env as $key => $e) {
|
|
|
|
|
if (is_string($e)) {
|
|
|
|
|
$dotEnv .= sprintf('%s = %s', $key, $e === '1' ? 'true' : ($e === '' ? 'false' : $e)) . PHP_EOL;
|
|
|
|
|
$dotEnv .= PHP_EOL;
|
|
|
|
|
} else {
|
|
|
|
|
$dotEnv .= sprintf('[%s]', $key) . PHP_EOL;
|
|
|
|
|
foreach ($e as $k => $v) {
|
|
|
|
|
$dotEnv .= sprintf('%s = %s', $k, $v === '1' ? 'true' : ($v === '' ? 'false' : $v)) . PHP_EOL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$dotEnv .= PHP_EOL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ($this->getEnvFile()) {
|
|
|
|
|
$this->output->info('env file has been generated');
|
|
|
|
|
}
|
|
|
|
|
if ((new \mysqli($host, $username, $password, null, $port))->query(sprintf('CREATE DATABASE IF NOT EXISTS %s DEFAULT CHARSET %s COLLATE %s_general_ci;',
|
|
|
|
|
$database, $charset, $charset))) {
|
|
|
|
|
$this->output->info(sprintf('🎉 create database %s successfully', $database));
|
|
|
|
|
} else {
|
2019-12-09 16:22:00 +08:00
|
|
|
|
$this->output->warning(sprintf('create database %s failed,you need create database first by yourself', $database));
|
2019-12-06 09:17:40 +08:00
|
|
|
|
}
|
2019-12-14 14:58:08 +08:00
|
|
|
|
} catch (\Exception $e) {
|
2020-04-06 18:29:14 +08:00
|
|
|
|
unlink(root_path() . '.env');
|
2019-12-14 14:58:08 +08:00
|
|
|
|
$this->output->error($e->getMessage());
|
|
|
|
|
exit(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
file_put_contents(root_path() . '.env', $dotEnv);
|
2019-12-06 09:17:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @time 2019年11月29日
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
protected function getEnvFile(): string
|
|
|
|
|
{
|
|
|
|
|
return file_exists(root_path() . '.env') ? root_path() . '.env' : '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected function project()
|
|
|
|
|
{
|
|
|
|
|
$year = date('Y');
|
|
|
|
|
|
|
|
|
|
$this->output->info('🎉 project is installed, welcome!');
|
|
|
|
|
|
|
|
|
|
$this->output->info(sprintf('
|
|
|
|
|
/-------------------- welcome to use -------------------------\
|
|
|
|
|
| __ __ ___ __ _ |
|
|
|
|
|
| _________ _/ /______/ /_ / | ____/ /___ ___ (_)___ |
|
|
|
|
|
| / ___/ __ `/ __/ ___/ __ \ / /| |/ __ / __ `__ \/ / __ \ |
|
|
|
|
|
| / /__/ /_/ / /_/ /__/ / / / / ___ / /_/ / / / / / / / / / / |
|
|
|
|
|
| \___/\__,_/\__/\___/_/ /_/ /_/ |_\__,_/_/ /_/ /_/_/_/ /_/ |
|
|
|
|
|
| |
|
2019-12-18 18:54:01 +08:00
|
|
|
|
\ __ __ __ __ _ __ _ __ enjoy it ! _ __ __ __ __ __ __ ___ _ @ 2017 ~ %s
|
|
|
|
|
账号: admin@gmail.com
|
|
|
|
|
密码: admin
|
2019-12-06 09:17:40 +08:00
|
|
|
|
', $year));
|
|
|
|
|
|
|
|
|
|
}
|
2020-01-21 17:00:17 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected function reInstall(): void
|
|
|
|
|
{
|
|
|
|
|
$ask = strtolower($this->output->ask($this->input,'reset project? (Y/N)'));
|
|
|
|
|
|
|
|
|
|
if ($ask === 'y' || $ask === 'yes' ) {
|
|
|
|
|
$this->migrateRollback();
|
|
|
|
|
|
|
|
|
|
$this->migrateAndSeeds();
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-12-06 09:17:40 +08:00
|
|
|
|
}
|