|
|
<?php |
|
|
namespace app\install\controller; |
|
|
use think\Controller; |
|
|
use think\Db; |
|
|
use think\Lang; |
|
|
use think\Request; |
|
|
|
|
|
class Index extends Controller |
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function __construct(Request $request = null) |
|
|
{ |
|
|
|
|
|
if (!defined('BIND_MODULE') || BIND_MODULE != 'install') { |
|
|
header('HTTP/1.1 403 Forbidden'); |
|
|
exit(); |
|
|
} |
|
|
parent::__construct($request); |
|
|
} |
|
|
|
|
|
public function index($step = 0) |
|
|
{ |
|
|
$langs = glob('./application/lang/*.php'); |
|
|
foreach ($langs as $k => &$v) { |
|
|
$v = str_replace(['./application/lang/','.php'],['',''],$v); |
|
|
} |
|
|
$this->assign('langs', $langs); |
|
|
|
|
|
if(in_array(session('lang'),$langs)){ |
|
|
$lang = Lang::range(session('lang')); |
|
|
Lang::load('./application/lang/'.$lang.'.php',$lang); |
|
|
} |
|
|
|
|
|
switch ($step) { |
|
|
case 2: |
|
|
session('install_error', false); |
|
|
return self::step2(); |
|
|
break; |
|
|
case 3: |
|
|
if (session('install_error')) { |
|
|
return $this->error(lang('install/environment_failed')); |
|
|
} |
|
|
return self::step3(); |
|
|
break; |
|
|
case 4: |
|
|
if (session('install_error')) { |
|
|
return $this->error(lang('install/environment_failed')); |
|
|
} |
|
|
return self::step4(); |
|
|
break; |
|
|
case 5: |
|
|
if (session('install_error')) { |
|
|
return $this->error(lang('install/init_err')); |
|
|
} |
|
|
return self::step5(); |
|
|
break; |
|
|
default: |
|
|
$param = input(); |
|
|
|
|
|
if(!in_array($param['lang'],$langs)) { |
|
|
$param['lang'] = 'zh-cn'; |
|
|
} |
|
|
$lang = Lang::range($param['lang']); |
|
|
Lang::load('./application/lang/'.$lang.'.php',$lang); |
|
|
session('lang',$param['lang']); |
|
|
$this->assign('lang',$param['lang']); |
|
|
|
|
|
session('install_error', false); |
|
|
return $this->fetch('install@/index/index'); |
|
|
break; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private function step2() |
|
|
{ |
|
|
$data = []; |
|
|
$data['env'] = self::checkNnv(); |
|
|
$data['dir'] = self::checkDir(); |
|
|
$data['func'] = self::checkFunc(); |
|
|
$this->assign('data', $data); |
|
|
return $this->fetch('install@index/step2'); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private function step3() |
|
|
{ |
|
|
$install_dir = $_SERVER["SCRIPT_NAME"]; |
|
|
$install_dir = mac_substring($install_dir, strripos($install_dir, "/")+1); |
|
|
$this->assign('install_dir',$install_dir); |
|
|
return $this->fetch('install@index/step3'); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private function step4() |
|
|
{ |
|
|
if ($this->request->isPost()) { |
|
|
if (!is_writable(APP_PATH.'database.php')) { |
|
|
return $this->error('[app/database.php]'.lang('install/write_read_err')); |
|
|
} |
|
|
$data = input('post.'); |
|
|
$data['type'] = 'mysql'; |
|
|
$rule = [ |
|
|
'hostname|'.lang('install/server_address') => 'require', |
|
|
'hostport|'.lang('install/database_port') => 'require|number', |
|
|
'database|'.lang('install/database_name') => 'require', |
|
|
'username|'.lang('install/database_username') => 'require', |
|
|
'prefix|'.lang('install/database_pre') => 'require|regex:^[a-z0-9]{1,20}[_]{1}', |
|
|
'cover|'.lang('install/overwrite_database') => 'require|in:0,1', |
|
|
]; |
|
|
$validate = $this->validate($data, $rule); |
|
|
if (true !== $validate) { |
|
|
return $this->error($validate); |
|
|
} |
|
|
$cover = $data['cover']; |
|
|
unset($data['cover']); |
|
|
$config = include APP_PATH.'database.php'; |
|
|
foreach ($data as $k => $v) { |
|
|
if (array_key_exists($k, $config) === false) { |
|
|
return $this->error(lang('param').''.$k.''.lang('install/not_found')); |
|
|
} |
|
|
} |
|
|
|
|
|
$database = $data['database']; |
|
|
unset($data['database']); |
|
|
|
|
|
$db_connect = Db::connect($data); |
|
|
|
|
|
try{ |
|
|
$db_connect->execute('select version()'); |
|
|
}catch(\Exception $e){ |
|
|
$this->error(lang('install/database_connect_err')); |
|
|
} |
|
|
|
|
|
|
|
|
$data['database'] = $database; |
|
|
self::mkDatabase($data); |
|
|
|
|
|
|
|
|
|
|
|
if (!$cover) { |
|
|
$check = $db_connect->execute('SELECT * FROM information_schema.schemata WHERE schema_name="'.$database.'"'); |
|
|
if ($check) { |
|
|
$this->success(lang('install/database_name_haved'),''); |
|
|
} |
|
|
} |
|
|
|
|
|
if (!$db_connect->execute("CREATE DATABASE IF NOT EXISTS `{$database}` DEFAULT CHARACTER SET utf8")) { |
|
|
return $this->error($db_connect->getError()); |
|
|
} |
|
|
|
|
|
|
|
|
return $this->success(lang('install/database_connect_ok'), ''); |
|
|
} else { |
|
|
return $this->error(lang('install/access_denied')); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private function step5() |
|
|
{ |
|
|
$account = input('post.account'); |
|
|
$password = input('post.password'); |
|
|
$install_dir = input('post.install_dir'); |
|
|
$initdata = input('post.initdata'); |
|
|
|
|
|
$config = include APP_PATH.'database.php'; |
|
|
if (empty($config['hostname']) || empty($config['database']) || empty($config['username'])) { |
|
|
return $this->error(lang('install/please_test_connect')); |
|
|
} |
|
|
if (empty($account) || empty($password)) { |
|
|
return $this->error(lang('install/please_input_admin_name_pass')); |
|
|
} |
|
|
|
|
|
$rule = [ |
|
|
'account|'.lang('install/admin_name') => 'require|alphaNum', |
|
|
'password|'.lang('install/admin_pass') => 'require|length:6,20', |
|
|
]; |
|
|
$validate = $this->validate(['account' => $account, 'password' => $password], $rule); |
|
|
if (true !== $validate) { |
|
|
return $this->error($validate); |
|
|
} |
|
|
if(empty($install_dir)) { |
|
|
$install_dir='/'; |
|
|
} |
|
|
$config_new = config('maccms'); |
|
|
$cofnig_new['app']['cache_flag'] = substr(md5(time()),0,10); |
|
|
$cofnig_new['app']['lang'] = session('lang'); |
|
|
|
|
|
$config_new['api']['vod']['status'] = 0; |
|
|
$config_new['api']['art']['status'] = 0; |
|
|
|
|
|
$config_new['interface']['status'] = 0; |
|
|
$config_new['interface']['pass'] = mac_get_rndstr(16); |
|
|
$config_new['site']['install_dir'] = $install_dir; |
|
|
|
|
|
|
|
|
$res = mac_arr2file(APP_PATH . 'extra/maccms.php', $config_new); |
|
|
if ($res === false) { |
|
|
return $this->error(lang('write_err_config')); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
$sql_file = APP_PATH.'install/sql/install.sql'; |
|
|
if (file_exists($sql_file)) { |
|
|
$sql = file_get_contents($sql_file); |
|
|
$sql_list = mac_parse_sql($sql, 0, ['mac_' => $config['prefix']]); |
|
|
if ($sql_list) { |
|
|
$sql_list = array_filter($sql_list); |
|
|
foreach ($sql_list as $v) { |
|
|
try { |
|
|
Db::execute($v); |
|
|
} catch(\Exception $e) { |
|
|
return $this->error(lang('install/sql_err'). $e); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
if($initdata=='1'){ |
|
|
$sql_file = APP_PATH.'install/sql/initdata.sql'; |
|
|
if (file_exists($sql_file)) { |
|
|
$sql = file_get_contents($sql_file); |
|
|
$sql_list = mac_parse_sql($sql, 0, ['mac_' => $config['prefix']]); |
|
|
if ($sql_list) { |
|
|
$sql_list = array_filter($sql_list); |
|
|
foreach ($sql_list as $v) { |
|
|
try { |
|
|
Db::execute($v); |
|
|
} catch(\Exception $e) { |
|
|
return $this->error(lang('install/init_data_err'). $e); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
$data = [ |
|
|
'admin_name' => $account, |
|
|
'admin_pwd' => $password, |
|
|
'admin_status' =>1, |
|
|
]; |
|
|
$res = model('Admin')->saveData($data); |
|
|
if (!$res['code']>1) { |
|
|
return $this->error(lang('install/admin_name_err').':'.$res['msg']); |
|
|
} |
|
|
file_put_contents(APP_PATH.'data/install/install.lock', date('Y-m-d H:i:s')); |
|
|
|
|
|
|
|
|
$root_dir = request()->baseFile(); |
|
|
$root_dir = preg_replace(['/install.php$/'], [''], $root_dir); |
|
|
return $this->success(lang('install/is_ok'), $root_dir.'admin.php'); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private function checkNnv() |
|
|
{ |
|
|
$items = [ |
|
|
'os' => [lang('install/os'), lang('install/not_limited'), 'Windows/Unix', PHP_OS, 'ok'], |
|
|
'php' => [lang('install/php'), '5.5', '5.5及以上', PHP_VERSION, 'ok'], |
|
|
]; |
|
|
if ($items['php'][3] < $items['php'][1]) { |
|
|
$items['php'][4] = 'no'; |
|
|
session('install_error', true); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return $items; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private function checkDir() |
|
|
{ |
|
|
$items = [ |
|
|
['file', './application/database.php', lang('install/read_and_write'), lang('install/read_and_write'), 'ok'], |
|
|
['file', './application/route.php', lang('install/read_and_write'), lang('install/read_and_write'), 'ok'], |
|
|
['dir', './application/extra', lang('install/read_and_write'), lang('install/read_and_write'), 'ok'], |
|
|
['dir', './application/data/backup', lang('install/read_and_write'), lang('install/read_and_write'), 'ok'], |
|
|
['dir', './application/data/update', lang('install/read_and_write'), lang('install/read_and_write'), 'ok'], |
|
|
['dir', './runtime', lang('install/read_and_write'), lang('install/read_and_write'), 'ok'], |
|
|
['dir', './upload', lang('install/read_and_write'), lang('install/read_and_write'), 'ok'], |
|
|
]; |
|
|
foreach ($items as &$v) { |
|
|
if ($v[0] == 'dir') { |
|
|
if(!is_writable($v[1])) { |
|
|
if(is_dir($v[1])) { |
|
|
$v[3] = lang('install/not_writable'); |
|
|
$v[4] = 'no'; |
|
|
} else { |
|
|
$v[3] = lang('install/not_found'); |
|
|
$v[4] = 'no'; |
|
|
} |
|
|
session('install_error', true); |
|
|
} |
|
|
} else { |
|
|
if(!is_writable($v[1])) { |
|
|
$v[3] = lang('install/not_writable'); |
|
|
$v[4] = 'no'; |
|
|
session('install_error', true); |
|
|
} |
|
|
} |
|
|
} |
|
|
return $items; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private function checkFunc() |
|
|
{ |
|
|
$items = [ |
|
|
['pdo', lang('install/support'), 'yes',lang('install/class')], |
|
|
['pdo_mysql', lang('install/support'), 'yes', lang('install/model')], |
|
|
['zip', lang('install/support'), 'yes', lang('install/model')], |
|
|
['fileinfo', lang('install/support'), 'yes', lang('install/model')], |
|
|
['curl', lang('install/support'), 'yes', lang('install/model')], |
|
|
['xml', lang('install/support'), 'yes', lang('install/function')], |
|
|
['file_get_contents', lang('install/support'), 'yes', lang('install/function')], |
|
|
['mb_strlen', lang('install/support'), 'yes', lang('install/function')], |
|
|
]; |
|
|
|
|
|
if(version_compare(PHP_VERSION,'5.6.0','ge') && version_compare(PHP_VERSION,'5.7.0','lt')){ |
|
|
$items[] = ['always_populate_raw_post_data',lang('install/support'),'yes',lang('install/config')]; |
|
|
} |
|
|
|
|
|
foreach ($items as &$v) { |
|
|
if(('类'==$v[3] && !class_exists($v[0])) || (lang('install/model')==$v[3] && !extension_loaded($v[0])) || (lang('install/function')==$v[3] && !function_exists($v[0])) || (lang('install/config')==$v[3] && ini_get('always_populate_raw_post_data')!=-1)) { |
|
|
$v[1] = lang('install/not_support'); |
|
|
$v[2] = 'no'; |
|
|
session('install_error', true); |
|
|
} |
|
|
} |
|
|
|
|
|
return $items; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private function mkDatabase(array $data) |
|
|
{ |
|
|
$code = <<<INFO |
|
|
<?php |
|
|
// +---------------------------------------------------------------------- |
|
|
// | ThinkPHP [ WE CAN DO IT JUST THINK ] |
|
|
// +---------------------------------------------------------------------- |
|
|
// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved. |
|
|
// +---------------------------------------------------------------------- |
|
|
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) |
|
|
// +---------------------------------------------------------------------- |
|
|
// | Author: liu21st <liu21st@gmail.com> |
|
|
// +---------------------------------------------------------------------- |
|
|
return [ |
|
|
// 数据库类型 |
|
|
'type' => 'mysql', |
|
|
// 服务器地址 |
|
|
'hostname' => '{$data['hostname']}', |
|
|
// 数据库名 |
|
|
'database' => '{$data['database']}', |
|
|
// 用户名 |
|
|
'username' => '{$data['username']}', |
|
|
// 密码 |
|
|
'password' => '{$data['password']}', |
|
|
// 端口 |
|
|
'hostport' => '{$data['hostport']}', |
|
|
// 连接dsn |
|
|
'dsn' => '', |
|
|
// 数据库连接参数 |
|
|
'params' => [], |
|
|
// 数据库编码默认采用utf8 |
|
|
'charset' => 'utf8', |
|
|
// 数据库表前缀 |
|
|
'prefix' => '{$data['prefix']}', |
|
|
// 数据库调试模式 |
|
|
'debug' => false, |
|
|
// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) |
|
|
'deploy' => 0, |
|
|
// 数据库读写是否分离 主从式有效 |
|
|
'rw_separate' => false, |
|
|
// 读写分离后 主服务器数量 |
|
|
'master_num' => 1, |
|
|
// 指定从服务器序号 |
|
|
'slave_no' => '', |
|
|
// 是否严格检查字段是否存在 |
|
|
'fields_strict' => false, |
|
|
// 数据集返回类型 |
|
|
'resultset_type' => 'array', |
|
|
// 自动写入时间戳字段 |
|
|
'auto_timestamp' => false, |
|
|
// 时间字段取出后的默认时间格式 |
|
|
'datetime_format' => 'Y-m-d H:i:s', |
|
|
// 是否需要进行SQL性能分析 |
|
|
'sql_explain' => false, |
|
|
// Builder类 |
|
|
'builder' => '', |
|
|
// Query类 |
|
|
'query' => '\\think\\db\\Query', |
|
|
]; |
|
|
INFO; |
|
|
file_put_contents(APP_PATH.'database.php', $code); |
|
|
|
|
|
$config = include APP_PATH.'database.php'; |
|
|
if (empty($config['database']) || $config['database'] != $data['database']) { |
|
|
return $this->error('[application/database.php]'.lang('write_err_database')); |
|
|
exit; |
|
|
} |
|
|
} |
|
|
} |