PageRenderTime 53ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/install/Plugin/Install/PublicController.php

https://gitlab.com/x33n/ImpressPages
PHP | 454 lines | 382 code | 54 blank | 18 comment | 41 complexity | 08b1fb3cb88bd3767791351be6be0892 MD5 | raw file
  1. <?php
  2. /**
  3. * @package ImpressPages
  4. *
  5. */
  6. namespace Plugin\Install;
  7. class PublicController extends \Ip\Controller
  8. {
  9. protected function init()
  10. {
  11. if (ipRequest()->getRequest('debug') !== NULL) {
  12. $_SESSION['install_debug'] = (int)ipRequest()->getRequest('debug');
  13. }
  14. if (!empty($_SESSION['install_debug'])) {
  15. error_reporting(E_ALL);
  16. ini_set('display_errors', 1);
  17. }
  18. if (empty($_SESSION['websiteId'])) {
  19. $_SESSION['websiteId'] = Helper::randString(32);
  20. }
  21. ipAddJs('Plugin/Install/assets/js/jquery.js');
  22. ipAddJs('Plugin/Install/assets/js/bootstrap.js');
  23. ipAddJs('Plugin/Install/assets/js/ModuleInstall.js');
  24. ipAddJs('Plugin/Install/assets/js/install.js');
  25. }
  26. public function testSessions()
  27. {
  28. if (!empty($_SESSION['websiteId'])) {
  29. return new \Ip\Response\Json(array('status' => 'success'));
  30. }
  31. $answer = array(
  32. 'html' => ipView('view/sessionsDontWork.php')->render()
  33. );
  34. return new \Ip\Response\Json($answer);
  35. }
  36. public function index()
  37. {
  38. $this->init();
  39. if (isset($_GET['step'])) {
  40. $step = (int)$_GET['step'];
  41. } else {
  42. $step = Helper::$firstStep;
  43. }
  44. if ($step < Helper::$firstStep) {
  45. $step = Helper::$firstStep;
  46. }
  47. // going to the last step
  48. if (!Helper::isInstallAvailable() || $step > Helper::$lastStep) {
  49. $step = Helper::$lastStep;
  50. }
  51. switch ($step) {
  52. case '1':
  53. $response = $this->configuration();
  54. break;
  55. case '2':
  56. $response = $this->systemCheck();
  57. break;
  58. case '3':
  59. $response = $this->database();
  60. break;
  61. case '4':
  62. $response = $this->finish();
  63. break;
  64. default:
  65. $response = new LayoutResponse();
  66. }
  67. return $response;
  68. }
  69. protected function configuration()
  70. {
  71. $timezoneSelectOptions = Helper::getTimezoneSelectOptions();
  72. if (!isset($_SESSION['config'])) {
  73. $_SESSION['config'] = array(
  74. 'websiteName' => '',
  75. 'websiteEmail' => '',
  76. 'timezone' => '',
  77. 'support' => 1
  78. );
  79. }
  80. $data = array(
  81. 'config' => $_SESSION['config'],
  82. 'timezoneSelectOptions' => $timezoneSelectOptions,
  83. );
  84. return Helper::renderLayout('view/configuration.php', $data);
  85. }
  86. protected function systemCheck()
  87. {
  88. $requirements = array();
  89. if (!Helper::isApache() && !Helper::isNginx()) {
  90. $requirements[] = array(
  91. 'name' => __('Apache or Nginx required', 'Install'),
  92. 'type' => 'warning'
  93. );
  94. }
  95. if (Helper::isNginx()) {
  96. $requirements[] = array(
  97. 'name' => __('Nginx configuration required', 'Install'),
  98. 'helpUrl' => 'http://www.impresspages.org/help/nginx',
  99. 'type' => 'warning'
  100. );
  101. }
  102. $requirements[] = array(
  103. 'name' => __('PHP version >= 5.3.3', 'Install'),
  104. 'helpUrl' => 'http://www.impresspages.org/help/php533',
  105. 'type' => Helper::checkPhpVersion()
  106. );
  107. $requirements[] = array(
  108. 'name' => __('PHP module "PDO"', 'Install'),
  109. 'helpUrl' => 'http://www.impresspages.org/help/pdo',
  110. 'type' => Helper::checkPDO()
  111. );
  112. $requirements[] = array(
  113. 'name' => __('GD Graphics Library', 'Install'),
  114. 'helpUrl' => 'http://www.impresspages.org/help/gd',
  115. 'type' => Helper::checkGD()
  116. );
  117. $requirements[] = array(
  118. 'name' => __('PHP sessions', 'Install'),
  119. 'helpUrl' => 'http://www.impresspages.org/help/sessions',
  120. 'type' => Helper::checkPhpSessions()
  121. );
  122. $requirements[] = array(
  123. 'name' => __('index.html removed', 'Install'),
  124. 'helpUrl' => 'http://www.impresspages.org/help/index-html',
  125. 'type' => Helper::checkFileIndexDotHtml()
  126. );
  127. $requirements[] = array(
  128. 'name' => __('Magic quotes off (optional)', 'Install'),
  129. 'helpUrl' => 'http://www.impresspages.org/help/magic-quotes',
  130. 'type' => Helper::checkMagicQuotes()
  131. );
  132. if (Helper::isApache()) {
  133. $requirements[] = array(
  134. 'name' => __('Apache module "mod_rewrite"', 'Install'),
  135. 'helpUrl' => 'http://www.impresspages.org/help/mod-rewrite',
  136. 'type' => Helper::checkModRewrite()
  137. );
  138. $requirements[] = array(
  139. 'name' => __('.htaccess file', 'Install'),
  140. 'helpUrl' => 'http://www.impresspages.org/help/htaccess',
  141. 'type' => Helper::checkFileDotHtaccess()
  142. );
  143. }
  144. $requirements[] = array(
  145. 'name' => __('PHP module "Curl"', 'Install'),
  146. 'helpUrl' => 'http://www.impresspages.org/help/curl',
  147. 'type' => Helper::checkCurl()
  148. );
  149. $requirements[] = array(
  150. 'name' => sprintf( __('PHP memory limit (%s)', 'Install'), ini_get('memory_limit')),
  151. 'helpUrl' => 'http://www.impresspages.org/help/php-memory',
  152. 'type' => Helper::checkMemoryLimit()
  153. );
  154. $requirements[] = array(
  155. 'name' => '/Ip/ ' . __('writable', 'Install') . ' ' . __('(including subfolders and files)', 'Install'),
  156. 'helpUrl' => 'http://www.impresspages.org/help/ip-dir-writable',
  157. 'type' => Helper::checkFolderIp()
  158. );
  159. $requirements[] = array(
  160. 'name' => '/Plugin/ ' . __('writable (including subfolders and files)', 'Install'),
  161. 'helpUrl' => 'http://www.impresspages.org/help/plugin-dir-writable',
  162. 'type' => Helper::checkFolderPlugin()
  163. );
  164. $requirements[] = array(
  165. 'name' => '/Theme/ ' . __('writable (including subfolders and files)', 'Install'),
  166. 'helpUrl' => 'http://www.impresspages.org/help/theme-dir-writable',
  167. 'type' => Helper::checkFolderTheme()
  168. );
  169. $requirements[] = array(
  170. 'name' => '/file/ ' . __('writable', 'Install') . ' ' . __('(including subfolders and files)', 'Install'),
  171. 'helpUrl' => 'http://www.impresspages.org/help/file-dir-writable',
  172. 'type' => Helper::checkFolderFile()
  173. );
  174. $requirements[] = array(
  175. 'name' => '/config.php ' . __('writable', 'Install'),
  176. 'helpUrl' => 'http://www.impresspages.org/help/config-writable',
  177. 'type' => Helper::checkFileConfigPhp()
  178. );
  179. $showNextStep = true;
  180. $autoForward = true;
  181. $notSuccess = array();
  182. foreach ($requirements as $req) {
  183. if ($req['type'] == 'success') { continue; } // skipping
  184. // Force to repeat system check
  185. if ($req['type'] == 'error') {
  186. $showNextStep = false;
  187. }
  188. // If something isn't perfect we collect and show to user
  189. $autoForward = false;
  190. $notSuccess[] = $req;
  191. }
  192. $data = array(
  193. 'requirements' => $requirements,
  194. 'showNextStep' => $showNextStep
  195. );
  196. // Send usage statistics
  197. $usageStatistics = Helper::setUsageStatistics('Install.systemCheck', $notSuccess);
  198. \Ip\Internal\System\Model::sendUsageStatistics($usageStatistics);
  199. if ($autoForward) {
  200. header('Location: ' . ipConfig()->baseUrl() . 'index.php?step=3') ;
  201. exit;
  202. }
  203. return Helper::renderLayout('view/system.php', $data);
  204. }
  205. protected function database()
  206. {
  207. if (!isset($_SESSION['db'])) {
  208. $_SESSION['db'] = array(
  209. 'hostname' => 'localhost',
  210. 'username' => '',
  211. 'password' => '',
  212. 'database' => '',
  213. 'charset' => 'utf8',
  214. 'tablePrefix' => 'ip_'
  215. );
  216. }
  217. $data = array(
  218. 'db' => $_SESSION['db'],
  219. );
  220. return Helper::renderLayout('view/database.php', $data);
  221. }
  222. protected function finish()
  223. {
  224. // cleaning session data (logins, passwords, etc.)
  225. if (isset($_SESSION['config'])) { $_SESSION['config'] = null; }
  226. if (isset($_SESSION['db'])) { $_SESSION['db'] = null; }
  227. if (isset($_SESSION['db_errors'])) { $_SESSION['db_errors'] = null; }
  228. $showInfo = false;
  229. // Showing extra info if user tries to get back when installation is finished
  230. if (isset($_GET['step']) && (int)$_GET['step'] < Helper::$lastStep) {
  231. $showInfo = true;
  232. }
  233. $data = array(
  234. 'showInfo' => $showInfo,
  235. );
  236. return Helper::renderLayout('view/finish.php', $data);
  237. }
  238. public function testConfiguration()
  239. {
  240. if (!Helper::isInstallAvailable()) {
  241. return sprintf(__('Please remove content from %s file.', 'Install', false), 'config.php');
  242. }
  243. // Validating input
  244. $errors = array();
  245. // Website name
  246. if (!Helper::validateWebsiteName(ipRequest()->getPost('configWebsiteName'))) {
  247. $errors[] = __('Please enter website name.', 'Install', false);
  248. }
  249. // Website email
  250. if (!Helper::validateWebsiteEmail(ipRequest()->getPost('configWebsiteEmail'))) {
  251. $errors[] = __('Please enter correct website email.', 'Install', false);
  252. }
  253. // Website timezone
  254. if (!Helper::validateTimezone(ipRequest()->getPost('configTimezone'))) {
  255. $errors[] = __('Please choose website time zone.', 'Install', false);
  256. }
  257. // Support
  258. // ipRequest()->getPost('configSupport')
  259. // Let's save config data to user session
  260. if (ipRequest()->getPost('configWebsiteName')) {
  261. $_SESSION['config']['websiteName'] = ipRequest()->getPost('configWebsiteName');
  262. }
  263. if (ipRequest()->getPost('configWebsiteEmail')) {
  264. $_SESSION['config']['websiteEmail'] = ipRequest()->getPost('configWebsiteEmail');
  265. }
  266. if (ipRequest()->getPost('configTimezone')) {
  267. $_SESSION['config']['timezone'] = ipRequest()->getPost('configTimezone');
  268. }
  269. if (ipRequest()->getPost('configSupport') !== null) {
  270. $_SESSION['config']['support'] = ipRequest()->getPost('configSupport');
  271. }
  272. // Send usage statistics
  273. $usageStatistics = Helper::setUsageStatistics('Install.configuration', $errors);
  274. \Ip\Internal\System\Model::sendUsageStatistics($usageStatistics);
  275. if (!empty($errors)) {
  276. return \Ip\Response\JsonRpc::error(__('Please correct errors.', 'Install', false))->addErrorData('errors', $errors);
  277. }
  278. return \Ip\Response\JsonRpc::result(array('redirect' => 'index.php?step=2'));
  279. }
  280. public function createDatabase()
  281. {
  282. if (!Helper::isInstallAvailable()) {
  283. return sprintf(__('Please remove content from %s file.', 'Install', false), 'config.php');
  284. }
  285. $db = ipRequest()->getPost('db');
  286. if (!isset($_SESSION['db_errors'])) {
  287. $_SESSION['db_errors'] = array();
  288. }
  289. foreach (array('hostname', 'username', 'database') as $key) {
  290. if (empty($db[$key])) {
  291. $_SESSION['db_errors'][] = 'Required fields';
  292. return \Ip\Response\JsonRpc::error(__('Please fill in required fields.', 'Install', false));
  293. }
  294. }
  295. if (empty($db['tablePrefix'])) {
  296. $db['tablePrefix'] = '';
  297. }
  298. if (strlen($db['tablePrefix']) > 7) {
  299. $_SESSION['db_errors'][] = 'Prefix too long';
  300. return \Ip\Response\JsonRpc::error(__("Prefix can't be longer than 7 symbols.", 'Install', false));
  301. }
  302. if ($db['tablePrefix'] != '' && !preg_match('/^([A-Za-z_][A-Za-z0-9_]*)$/', $db['tablePrefix'])) {
  303. $_SESSION['db_errors'][] = 'Prefix is bad';
  304. return \Ip\Response\JsonRpc::error(__("Prefix can't contain any special characters and should start with a letter.", 'Install', false));
  305. }
  306. $dbConfig = array(
  307. 'hostname' => $db['hostname'],
  308. 'username' => $db['username'],
  309. 'password' => $db['password'],
  310. 'tablePrefix' => $db['tablePrefix'],
  311. 'database' => '', // If database doesn't exist, we will create it.
  312. 'charset' => 'utf8',
  313. );
  314. ipConfig()->set('db', $dbConfig);
  315. try {
  316. ipDb()->getConnection();
  317. } catch (\Exception $e) {
  318. $_SESSION['db_errors'][] = 'Cannot connect';
  319. return \Ip\Response\JsonRpc::error(__("Can't connect to database.", 'Install'), false);
  320. }
  321. try {
  322. Model::createAndUseDatabase($db['database']);
  323. } catch (\Ip\Exception $e) {
  324. $_SESSION['db_errors'][] = 'DB cannot be created';
  325. return \Ip\Response\JsonRpc::error(__('Specified database does not exists and cannot be created.', 'Install', false));
  326. }
  327. if (Helper::testDBTables($db['tablePrefix']) && empty($db['replaceTables'])) {
  328. $_SESSION['db_errors'][] = 'Replace tables';
  329. return \Ip\Response\JsonRpc::error(__('Do you like to replace existing tables in the database?', 'Install', false), 'table_exists');
  330. }
  331. $errors = Model::createDatabaseStructure($db['database'], $db['tablePrefix']);
  332. if (!$errors) {
  333. $errors = Model::importData($dbConfig['tablePrefix']);
  334. }
  335. if ($errors) {
  336. $_SESSION['db_errors'][] = 'Failed install';
  337. return \Ip\Response\JsonRpc::error(__('There were errors while executing install queries. ' . serialize($errors), 'Install', false));
  338. }
  339. $dbConfig['database'] = $db['database'];
  340. $_SESSION['db'] = $dbConfig;
  341. $configToFile = array();
  342. $configToFile['sessionName'] = 'ses' . rand();
  343. $configToFile['db'] = $_SESSION['db'];
  344. $configToFile['timezone'] = $_SESSION['config']['timezone'];
  345. if (Helper::checkModRewrite() != 'success') {
  346. $configToFile['rewritesDisabled'] = true;
  347. }
  348. $admin = ipRequest()->getPost('admin');
  349. if ($admin) {
  350. $adminUsername = $admin['username'];
  351. $adminEmail = $admin['email'];
  352. $adminPassword = $admin['password'];
  353. }
  354. $cachedBaseUrl = substr(rtrim(ipConfig()->baseUrl(),"/"), 0, - strlen('install'));
  355. try {
  356. ipConfig()->set('db', $dbConfig);
  357. // if admin data is posted then user will be created
  358. if ($admin) {
  359. Model::insertAdmin($adminUsername, $adminEmail, $adminPassword);
  360. }
  361. ipSetOptionLang('Config.websiteTitle', $_SESSION['config']['websiteName'], 'en');
  362. ipSetOptionLang('Config.websiteEmail', $_SESSION['config']['websiteEmail'], 'en');
  363. Model::generateCronPassword();
  364. ipStorage()->set('Ip', 'cachedBaseUrl', $cachedBaseUrl);
  365. ipStorage()->set('Ip', 'websiteId', $_SESSION['websiteId']);
  366. ipStorage()->set('Ip', 'getImpressPagesSupport', $_SESSION['config']['support']);
  367. } catch (\Exception $e) {
  368. $_SESSION['db_errors'][] = $e->getTraceAsString();
  369. return \Ip\Response\JsonRpc::error($e->getTraceAsString());
  370. }
  371. try {
  372. Model::writeConfigFile($configToFile, ipFile('config.php'));
  373. } catch (\Exception $e) {
  374. $_SESSION['db_errors'][] = 'Cannot write config file';
  375. return \Ip\Response\JsonRpc::error(__('Can\'t write configuration "/config.php"', 'Install', false));
  376. }
  377. // Send usage statistics
  378. $usageStatistics = Helper::setUsageStatistics('Install.database', $_SESSION['db_errors']);
  379. \Ip\Internal\System\Model::sendUsageStatistics($usageStatistics);
  380. $redirect = $cachedBaseUrl . 'admin';
  381. return \Ip\Response\JsonRpc::result(array('redirect' => $redirect));
  382. }
  383. }