SiteController.php 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. <?php
  2. namespace install\controllers;
  3. use common\components\ModuleManager;
  4. use common\modules\user\models\User;
  5. use yii\web\Controller;
  6. use Yii;
  7. use install\models\DatabaseForm;
  8. use install\models\SiteForm;
  9. use install\models\AdminForm;
  10. class SiteController extends Controller
  11. {
  12. protected function renderJson($status = true, $message = '')
  13. {
  14. Yii::$app->response->format = 'json';
  15. return [
  16. 'status' => $status,
  17. 'message' => $message
  18. ];
  19. }
  20. public $migrationPath = '@database/migrations';
  21. public $migrationTable = '{{%migration}}';
  22. public $envPath = '@root/.env';
  23. public function init()
  24. {
  25. parent::init();
  26. $this->migrationPath = Yii::getAlias($this->migrationPath);
  27. }
  28. /**
  29. * Lists all Menu models.
  30. *
  31. * @return mixed
  32. */
  33. public function actionIndex()
  34. {
  35. return $this->render('index');
  36. }
  37. public function actionLanguage()
  38. {
  39. return $this->render('index');
  40. }
  41. public function actionLicenseAgreement()
  42. {
  43. if (\Yii::$app->getRequest()->isPost) {
  44. if (\Yii::$app->getRequest()->post("license") == "on") {
  45. return $this->renderJson(true);
  46. } else {
  47. return $this->renderJson(false, "同意安装协议才能继续安装!");
  48. }
  49. }
  50. return $this->render('license');
  51. }
  52. public function actionCheckEnv()
  53. {
  54. $checkResult = include Yii::getAlias('@install/requirements.php');
  55. // Render template
  56. return $this->render('checkenv', [
  57. "data" => $checkResult
  58. ]);
  59. }
  60. public function actionCheckDirFile()
  61. {
  62. $items = [
  63. ['dir', '可写', 'success', '@root/cache'],
  64. ['dir', '可写', 'success', '@backend/runtime'],
  65. ['dir', '可写', 'success', '@frontend/runtime'],
  66. ['dir', '可写', 'success', '@api/runtime'],
  67. ['dir', '可写', 'success', '@root/web/storage'],
  68. ['dir', '可写', 'success', '@root/web/assets'],
  69. ['dir', '可写', 'success', '@root/web/admin/assets'],
  70. ['dir', '可写', 'success', '@root/web/api/assets'],
  71. ];
  72. $result = true;
  73. foreach ($items as &$val) {
  74. $val[3] = Yii::getAlias($val[3]);
  75. if('dir' == $val[0]){
  76. if(!is_writable($val[3])) {
  77. if(is_dir($val[3])) {
  78. $val[1] = '可读';
  79. $val[2] = 'error';
  80. } else {
  81. $val[1] = '不存在';
  82. $val[2] = 'error';
  83. }
  84. $result = false;
  85. }
  86. } else {
  87. if(file_exists($val[3])) {
  88. if(!is_writable($val[3])) {
  89. $val[1] = '不可写';
  90. $val[2] = 'error';
  91. $result = false;
  92. }
  93. } else {
  94. if(!is_writable(dirname($val[3]))) {
  95. $val[1] = '不存在';
  96. $val[2] = 'error';
  97. $result = false;
  98. }
  99. }
  100. }
  101. }
  102. if (Yii::$app->request->isPost) {
  103. if ($result == true) {
  104. return $this->renderJson(true);
  105. }else {
  106. return $this->renderJson(false, '请确保目录和文件拥有指定权限');
  107. }
  108. }
  109. return $this->render('checkdirfile', [
  110. "items" => $items
  111. ]);
  112. }
  113. public function actionSelectDb()
  114. {
  115. return $this->render('index');
  116. }
  117. public function actionSetDb()
  118. {
  119. $model = new DatabaseForm();
  120. $model->loadDefaultValues();
  121. if ($model->load(Yii::$app->request->post())) {
  122. if ($model->validate() && $model->save()) {
  123. return $this->renderJson(true);
  124. } else {
  125. return $this->renderJson(false, current($model->getFirstErrors()));
  126. }
  127. }
  128. return $this->render('setdb', [
  129. "model" => $model
  130. ]);
  131. }
  132. public function actionSetSite()
  133. {
  134. $model = new SiteForm();
  135. $model->loadDefaultValues();
  136. if ($model->load(Yii::$app->request->post())) {
  137. if ($model->validate() && $model->save()) {
  138. return $this->renderJson(true);
  139. } else {
  140. return $this->renderJson(false, current($model->getFirstErrors()));
  141. }
  142. }
  143. return $this->render('setsite', [
  144. "model" => $model
  145. ]);
  146. }
  147. public function actionSetAdmin()
  148. {
  149. $model = new AdminForm();
  150. $model->loadDefaultValues();
  151. if ($model->load(Yii::$app->request->post())) {
  152. if (!$model->validate() || !$model->save()) {
  153. return $this->renderJson(false, current($model->getFirstErrors()));
  154. }
  155. $error = $this->installDb();
  156. if ($error != null) {
  157. return $this->renderJson(false, $error);
  158. }
  159. //安装核心模块
  160. $this->installConfig();
  161. // 创建用户
  162. $error = $this->createAdminUser();
  163. if ($error != null) {
  164. return $this->renderJson(false, $error);
  165. }
  166. return $this->renderJson(true);
  167. }
  168. return $this->render('setadmin', [
  169. "model" => $model
  170. ]);
  171. }
  172. public function actionSelectModule()
  173. {
  174. $moduleManager = new ModuleManager();
  175. $modules = $moduleManager->findAll();
  176. if (Yii::$app->request->isPost) {
  177. $installModules = Yii::$app->request->post('modules', []);
  178. foreach ($installModules as $installModule) {
  179. $installModuleInfo = $moduleManager->findOne($installModule);
  180. $moduleManager->install($installModuleInfo);
  181. }
  182. // 安装核心模块
  183. $cores = $moduleManager->findCore();
  184. foreach ($cores as $core) {
  185. $moduleManager->install($core);
  186. }
  187. //清缓存
  188. \Yii::$app->getCache()->flush();
  189. //安装完成
  190. Yii::$app->setInstalled();
  191. return $this->renderJson(true);
  192. }
  193. return $this->render('selectmodule', [
  194. "modules" => $modules
  195. ]);
  196. }
  197. /**
  198. * 安装数据库
  199. */
  200. public function installDb()
  201. {
  202. $handle = opendir($this->migrationPath);
  203. while (($file = readdir($handle)) !== false) {
  204. if ($file === '.' || $file === '..') {
  205. continue;
  206. }
  207. $path = $this->migrationPath . DIRECTORY_SEPARATOR . $file;
  208. if (preg_match('/^(m(\d{6}_\d{6})_.*?)\.php$/', $file, $matches) && !isset($applied[$matches[2]]) && is_file($path)) {
  209. $migrations[] = $matches[1];
  210. }
  211. }
  212. closedir($handle);
  213. sort($migrations);
  214. $error = "";
  215. ob_start();
  216. if (Yii::$app->db->schema->getTableSchema($this->migrationTable, true) === null) {
  217. $this->createMigrationHistoryTable();
  218. }
  219. foreach ($migrations as $migration) {
  220. $migrationClass = $this->createMigration($migration);
  221. try {
  222. if ($migrationClass->up() === false) {
  223. $error = "数据库迁移失败";
  224. }
  225. $this->addMigrationHistory($migration);
  226. } catch (\Exception $e) {
  227. $error = "数据表已经存在,或者其他错误!";
  228. }
  229. }
  230. ob_end_clean();
  231. if (! empty($error)) {
  232. return $error;
  233. }
  234. return null;
  235. }
  236. //写入配置文件
  237. public function installConfig()
  238. {
  239. \Yii::$app->setKeys($this->envPath);
  240. $data = \Yii::$app->getCache()->get(SiteForm::CACHE_KEY);
  241. foreach ($data as $name => $value) {
  242. Yii::$app->setEnv($name, $value);
  243. }
  244. return true;
  245. }
  246. public function createAdminUser()
  247. {
  248. $data = \Yii::$app->getCache()->get(AdminForm::CACHE_KEY);
  249. $user = new User();
  250. $user->setScenario("create");
  251. $user->email = $data["email"];
  252. $user->username = $data["username"];
  253. $user->password = $data["password"];
  254. if($user->create() == false) {
  255. return current($user->getFirstErrors());
  256. }
  257. return null;
  258. }
  259. protected function createMigrationHistoryTable()
  260. {
  261. Yii::$app->db->createCommand()->createTable($this->migrationTable, [
  262. 'version' => 'varchar(180) NOT NULL PRIMARY KEY',
  263. 'apply_time' => 'integer',
  264. ])->execute();
  265. Yii::$app->db->createCommand()->insert($this->migrationTable, [
  266. 'version' => 'm000000_000000_base',
  267. 'apply_time' => time(),
  268. ])->execute();
  269. }
  270. protected function createMigration($class)
  271. {
  272. $file = $this->migrationPath . DIRECTORY_SEPARATOR . $class . '.php';
  273. require_once($file);
  274. return new $class();
  275. }
  276. protected function addMigrationHistory($version)
  277. {
  278. $command = Yii::$app->db->createCommand();
  279. $command->insert($this->migrationTable, [
  280. 'version' => $version,
  281. 'apply_time' => time(),
  282. ])->execute();
  283. }
  284. }