SiteController.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. <?php
  2. /**
  3. * Author: lf
  4. * Blog: https://blog.feehi.com
  5. * Email: job@feehi.com
  6. * Created at: 2017-03-15 21:16
  7. */
  8. namespace install\controllers;
  9. use Yii;
  10. use common\components\Feehi;
  11. use install\database\Tables;
  12. use Exception;
  13. use yii\db\Connection;
  14. use yii\helpers\Url;
  15. use common\models\AdminUser;
  16. use common\models\Options;
  17. use yii\web\Response;
  18. use yii\web\ErrorAction;
  19. /**
  20. * Site controller
  21. */
  22. class SiteController extends \yii\web\Controller
  23. {
  24. public $enableCsrfValidation = false;
  25. public static $installLockFile = '@install/install.lock';
  26. public function init()
  27. {
  28. self::$installLockFile = Yii::getAlias(self::$installLockFile);
  29. Feehi::determineLanguage();
  30. parent::init();
  31. if (self::getIsInstalled()) {
  32. $response = Yii::$app->getResponse();
  33. $response->content = Yii::t('install', "Has been installed, if you want to reinstall please remove {lock_file} and try it again", ['lock_file'=>self::$installLockFile]);
  34. $response->send();
  35. exit(0);
  36. }
  37. }
  38. public static function getIsInstalled()
  39. {
  40. return file_exists(self::$installLockFile);
  41. }
  42. public function actions()
  43. {
  44. return [
  45. 'error' => [
  46. 'class' => ErrorAction::className(),
  47. ],
  48. ];
  49. }
  50. public function actionError()
  51. {
  52. return $this->render('error');
  53. }
  54. public function actionIndex()
  55. {
  56. return $this->redirect(['choose-language']);
  57. }
  58. public function actionChooseLanguage()
  59. {
  60. return $this->render('choose-language');
  61. }
  62. public function actionAccept()
  63. {
  64. return $this->render('accept');
  65. }
  66. public function actionCheckEnvironment()
  67. {
  68. if (!isset($_SESSION['_install_env_passed']) || $_SESSION['_install_env_passed'] != 1) {
  69. if (!in_array(Yii::$app->getRequest()->headers['referer'], [
  70. Url::to(['accept'], true),
  71. Url::to(['check-environment'], true)
  72. ])
  73. ) {
  74. return $this->redirect(['accept']);
  75. };
  76. }
  77. $data = array();
  78. $data['phpversion'] = @phpversion();
  79. $data['os'] = PHP_OS;
  80. $tmp = function_exists('gd_info') ? gd_info() : array();
  81. $max_execution_time = ini_get('max_execution_time');
  82. $allow_reference = (ini_get('allow_call_time_pass_reference') ? '<font color=green>[√]On</font>' : '<font color=red>[×]Off</font>');
  83. $allow_url_fopen = (ini_get('allow_url_fopen') ? '<font color=green>[√]On</font>' : '<font color=red>[×]Off</font>');
  84. $safe_mode = (ini_get('safe_mode') ? '<font color=red>[×]On</font>' : '<font color=green>[√]Off</font>');
  85. $err = 0;
  86. if (!version_compare($data['phpversion'], '5.4', '<')) {
  87. $data['phpversion'] = '<i class="fa fa-check correct"></i> ' . Yii::t('install', 'Yes') . ' ' . $data['phpversion'];
  88. } else {
  89. $data['phpversion'] = '<i class="fa fa-remove error"></i> ' . Yii::t('install', 'No') . ' ' . $data['phpversion'];
  90. $err++;
  91. }
  92. if (empty($tmp['GD Version'])) {
  93. $gd = '<font color=red>[×]Off</font>';
  94. if (!extension_loaded('imagick')){
  95. $err++;
  96. }
  97. } else {
  98. $gd = '<font color=green>[√]On</font> ' . $tmp['GD Version'];
  99. }
  100. if (class_exists('pdo')) {
  101. $data['pdo'] = '<i class="fa fa-check correct"></i> ' . Yii::t('install', 'Yes');
  102. } else {
  103. $data['pdo'] = '<i class="fa fa-remove error"></i> ' . Yii::t('install', 'No');
  104. $err++;
  105. }
  106. /*if (extension_loaded('pdo_mysql')) {
  107. $data['pdo_mysql'] = '<i class="fa fa-check correct"></i> ' . Yii::t('install', 'Yes');
  108. } else {
  109. $data['pdo_mysql'] = '<i class="fa fa-remove error"></i> ' . Yii::t('install', 'No');
  110. $err++;
  111. }*/
  112. if (extension_loaded('curl')) {
  113. $data['curl'] = '<i class="fa fa-check correct"></i> ' . Yii::t('install', 'Yes');
  114. } else {
  115. $data['curl'] = '<i class="fa fa-remove error"></i> ' . Yii::t('install', 'No');
  116. $err++;
  117. }
  118. if (extension_loaded('gd')) {
  119. $data['gd'] = '<i class="fa fa-check correct"></i> ' . Yii::t('install', 'Yes');
  120. } else {
  121. $data['gd'] = '<i class="fa fa-remove error"></i> ' . Yii::t('install', 'No');
  122. if (function_exists('imagettftext')) {
  123. $data['gd'] .= '<br><i class="fa fa-remove error"></i> FreeType Support ' . Yii::t('install', 'No');
  124. }
  125. $err++;
  126. }
  127. if (extension_loaded('json')) {
  128. $data['json'] = '<i class="fa fa-check correct"></i> ' . Yii::t('install', 'Yes');
  129. } else {
  130. $data['json'] = '<i class="fa fa-remove error"></i> ' . Yii::t('install', 'No');
  131. $err++;
  132. }
  133. if (extension_loaded('mbstring')) {
  134. $data['mbstring'] = '<i class="fa fa-check correct"></i> ' . Yii::t('install', 'Yes');
  135. } else {
  136. $data['mbstring'] = '<i class="fa fa-remove error"></i> ' . Yii::t('install', 'No');
  137. $err++;
  138. }
  139. if (ini_get('file_uploads')) {
  140. $data['upload_size'] = '<i class="fa fa-check correct"></i> ' . ini_get('upload_max_filesize');
  141. } else {
  142. $data['upload_size'] = '<i class="fa fa-remove error"></i> ' . Yii::t('install', 'Forbidden');
  143. }
  144. if (function_exists('session_start')) {
  145. $data['session'] = '<i class="fa fa-check correct"></i> ' . Yii::t('install', 'Yes');
  146. } else {
  147. $data['session'] = '<i class="fa fa-remove error"></i> ' . Yii::t('install', 'No');
  148. $err++;
  149. }
  150. $folders = array(
  151. '@frontend/runtime',
  152. '@frontend/web/assets',
  153. '@backend/runtime',
  154. '@frontend/web/admin/assets',
  155. );
  156. $newFolders = array();
  157. foreach ($folders as &$dir) {
  158. $dir = Yii::getAlias($dir);
  159. if (is_writable($dir)) {
  160. $newFolders[$dir]['w'] = true;
  161. } else {
  162. $newFolders[$dir]['w'] = false;
  163. $err++;
  164. }
  165. if (is_readable($dir)) {
  166. $newFolders[$dir]['r'] = true;
  167. } else {
  168. $newFolders[$dir]['r'] = false;
  169. $err++;
  170. }
  171. }
  172. $data['folders'] = $newFolders;
  173. $_SESSION['_install_env_passed'] = 0;
  174. if ($err == 0) {
  175. $_SESSION['_install_env_passed'] = 1;
  176. }
  177. $data['err'] = $err;
  178. return $this->render('check-environment', $data);
  179. }
  180. public function actionSetinfo()
  181. {
  182. set_time_limit(300);
  183. if (! isset($_SESSION['_install_env_passed']) || $_SESSION['_install_env_passed'] != 1) {
  184. $url = Url::to(['check-environment']);
  185. echo "<script>alert('" . Yii::t('install', 'Please check your environment to suite the cms') . Yii::t('install', ' If environment have been suit to the cms please check php session can set correctly') . "');location.href='{$url}';</script>";
  186. exit(0);
  187. }
  188. if (Yii::$app->getRequest()->getIsPost()) {
  189. $this->on(self::EVENT_AFTER_ACTION, function () {
  190. $request = Yii::$app->getRequest();
  191. Yii::$app->getResponse()->format = Response::FORMAT_JSON;
  192. try {
  193. $db = $this->_getDbConnection();
  194. Yii::$app->set("db", $db);
  195. $tables = new Tables(['db' => Yii::$app->db]);
  196. $tables->importDatabase();
  197. //更新配置信息
  198. $data = [
  199. 'username' => $request->post('manager', 'admin'),
  200. 'password_hash' => Yii::$app->security->generatePasswordHash($request->post('manager_pwd')),
  201. 'email' => $request->post('manager_email'),
  202. ];
  203. Yii::$app->getDb()->createCommand()->update(AdminUser::tableName(), $data, 'id = 1')->execute();
  204. $model = Options::findOne(['name' => 'website_title']);
  205. $model->value = $request->post('sitename', 'Feehi CMS');
  206. $model->save(false);
  207. $model = Options::findOne(['name' => 'website_url']);
  208. $model->value = $request->post('website_url', '');
  209. $model->save(false);
  210. $model = Options::findOne(['name' => 'website_url']);
  211. $model->value = $request->post('siteurl', '');
  212. $model->save(false);
  213. $model = Options::findOne(['name' => 'seo_keywords']);
  214. $model->value = $request->post('sitekeywords', '');
  215. $model->save(false);
  216. $model = Options::findOne(['name' => 'seo_description']);
  217. $model->value = $request->post('siteinfo', '');
  218. $model->save(false);
  219. }catch (Exception $e){
  220. echo str_repeat(" ", 1024 * 64 * 99);
  221. $msg = str_replace(array("\r\n", "\r", "\n"), "", $e->getMessage());
  222. $msg = str_replace('"', '', $msg);
  223. $msg = str_replace("'", '', $msg);
  224. echo "<script type=\"text/javascript\">alert(\"$msg\");history.back();</script>";
  225. ob_flush();
  226. flush();
  227. exit(0);
  228. }
  229. $_SESSION["_install_setinfo"] = 1;
  230. $configFile = yii::getAlias("@common/config/main-local.php");
  231. $array = require $configFile;
  232. $array['components']['db'] = [
  233. 'class' => yii\db\Connection::className(),
  234. 'dsn' => $db->dsn,
  235. 'username' => $db->username,
  236. 'password' => $db->password,
  237. 'charset' => 'utf8',
  238. 'tablePrefix' => $db->tablePrefix,
  239. ];
  240. $str = "<?php \n return " . var_export($array,true) . ";";
  241. $str = str_replace('\\\\', '\\', $str);
  242. if( !file_put_contents($configFile, $str) ){
  243. sleep(1);
  244. $message = Yii::t("install", "Installed success;but update write config file error.please update common/config/main-local.php components db section.");
  245. echo "<script>alert('{$message}');location.href='" . Url::to(['success']) . "';</script>";
  246. }else {
  247. sleep(1);
  248. echo "<script>location.href='" . Url::to(['success']) . "';</script>";
  249. }
  250. exit(0);
  251. });
  252. $html = $this->render('installing');
  253. echo $html;
  254. flush();
  255. if(ob_get_level() > 0){
  256. ob_flush();
  257. }
  258. } else {
  259. return $this->render('setinfo');
  260. }
  261. }
  262. public function actionCreateDatabase()
  263. {
  264. Yii::$app->getResponse()->format = Response::FORMAT_JSON;
  265. try {
  266. $this->_getDbConnection();
  267. return ['message' => ''];
  268. } catch (Exception $e) {
  269. throw new Exception($e->getMessage());
  270. }
  271. }
  272. private function _getDbConnection()
  273. {
  274. $request = Yii::$app->getRequest();
  275. $dbtype = $request->post('dbtype', 'mysql');
  276. $dbhost = $request->post('dbhost', 'dbhost');
  277. $dbuser = $request->post('dbuser', 'root');
  278. $dbpassword = $request->post('dbpw', '');
  279. $dbport = $request->post('dbport', '3306');
  280. $dbname = $request->post('dbname', '');
  281. $tablePrefix = $request->post("dbprefix", '');
  282. $dsn = '';
  283. switch ($dbtype) {
  284. case "pgsql":
  285. case "mysql":
  286. $dsn = $dbtype . ":host=" . $dbhost . ';port=' . $dbport;
  287. if( !empty($dbname) ) $dsn .= ";dbname=" . $dbname;
  288. break;
  289. case "sqlite":
  290. $path = Yii::getAlias($dbhost);
  291. $dsn = "sqlite:$path";
  292. break;
  293. }
  294. $db = new Connection([
  295. 'dsn' => $dsn,
  296. 'username' => $dbuser,
  297. 'password' => $dbpassword,
  298. 'charset' => 'utf8',
  299. 'tablePrefix' => $tablePrefix,
  300. ]);
  301. $this->checkAccountPermission($db, $dbtype, $dbname);
  302. return $db;
  303. }
  304. public function actionSuccess()
  305. {
  306. if (isset($_SESSION["_install_setinfo"]) && $_SESSION["_install_setinfo"] == 1) {
  307. if( !touch(Yii::getAlias(self::$installLockFile)) ){
  308. $message = Yii::t("install", "Touch install lock file {lock_file} failed,please touch file handled", ['lock_file'=>self::$installLockFile]);
  309. echo "<script>alert('{$message}')</script>";
  310. }
  311. session_destroy();
  312. return $this->render("success");
  313. } else {
  314. return $this->redirect(['setinfo']);
  315. }
  316. }
  317. public function actionLanguage()
  318. {
  319. $language = Yii::$app->getRequest()->get('lang');
  320. if (isset($language)) {
  321. Yii::$app->session['language'] = $language;
  322. }
  323. return $this->redirect(['accept']);
  324. }
  325. private function checkAccountPermission(Connection $db, $dbtype, $dbname)
  326. {
  327. if($dbtype != "sqlite") {
  328. try {
  329. if($dbtype === "pgsql"){
  330. }else {
  331. $db->createCommand("use $dbname")->execute();
  332. }
  333. }catch (\yii\db\Exception $e){
  334. if( $e->getCode() == 1049 ) {
  335. $request = Yii::$app->getRequest();
  336. $dbhost = $request->post('dbhost', 'dbhost');
  337. $dbport = $request->post('dbport', '3306');
  338. $dsn = $dbtype . ":host=" . $dbhost . ';port=' . $dbport;
  339. $db->dsn = $dsn;
  340. $db->pdo = null;
  341. $db->open();
  342. $result = $db->createCommand("CREATE DATABASE IF NOT EXISTS `{$dbname}` DEFAULT CHARACTER SET utf8")->execute();
  343. if ($result == 1) {
  344. $this->checkAccountPermission($db, $dbtype, $dbname);
  345. return;
  346. } else {
  347. throw new Exception(Yii::t('install', 'Create database error, please create yourself and retry'));
  348. }
  349. }else{
  350. throw new Exception($e->getMessage());
  351. }
  352. }
  353. $db->createCommand("create table test(id integer)")->execute();
  354. $db->createCommand("insert into test values(1)")->execute();
  355. $result = $db->createCommand("select * from test where id=1")->queryOne();
  356. if ($result === false) {
  357. throw new Exception(Yii::t('install', 'Access to database `{database}` error. Maybe permission denied', ['database' => $dbname]));
  358. }
  359. try {
  360. $db->createCommand("drop table test")->execute();
  361. } catch (Exception $exception) {
  362. Yii::error("after install feehicms delete test database table `test` error:" . $exception->getFile() . "(" . $exception->getLine() . ")" . $exception->getMessage());
  363. }
  364. }
  365. }
  366. }