PageRenderTime 49ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/install/install.controller.php

http://xe-core.googlecode.com/
PHP | 652 lines | 537 code | 38 blank | 77 comment | 31 complexity | 57faa2eba7727a27865ae562704bc2e7 MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause
  1. <?php
  2. /**
  3. * @class installController
  4. * @author NHN (developers@xpressengine.com)
  5. * @brief install module of the Controller class
  6. */
  7. class installController extends install
  8. {
  9. var $db_tmp_config_file = '';
  10. var $etc_tmp_config_file = '';
  11. /**
  12. * @brief Initialization
  13. */
  14. function init()
  15. {
  16. // Error occurs if already installed
  17. if(Context::isInstalled())
  18. {
  19. return new Object(-1, 'msg_already_installed');
  20. }
  21. $this->db_tmp_config_file = _XE_PATH_.'files/config/tmpDB.config.php';
  22. $this->etc_tmp_config_file = _XE_PATH_.'files/config/tmpEtc.config.php';
  23. }
  24. /**
  25. * @brief cubrid db setting wrapper, becase Server Side Validator...
  26. * Server Side Validatro can use only one proc, one ruleset
  27. */
  28. function procCubridDBSetting()
  29. {
  30. return $this->_procDBSetting();
  31. }
  32. /**
  33. * @brief firebird db setting wrapper, becase Server Side Validator...
  34. * Server Side Validatro can use only one proc, one ruleset
  35. */
  36. function procFirebirdDBSetting()
  37. {
  38. return $this->_procDBSetting();
  39. }
  40. /**
  41. * @brief mssql db setting wrapper, becase Server Side Validator...
  42. * Server Side Validatro can use only one proc, one ruleset
  43. */
  44. function procMssqlDBSetting()
  45. {
  46. return $this->_procDBSetting();
  47. }
  48. /**
  49. * @brief mysql db setting wrapper, becase Server Side Validator...
  50. * Server Side Validatro can use only one proc, one ruleset
  51. */
  52. function procMysqlDBSetting()
  53. {
  54. return $this->_procDBSetting();
  55. }
  56. /**
  57. * @brief postgresql db setting wrapper, becase Server Side Validator...
  58. * Server Side Validatro can use only one proc, one ruleset
  59. */
  60. function procPostgresqlDBSetting()
  61. {
  62. return $this->_procDBSetting();
  63. }
  64. /**
  65. * @brief sqlite db setting wrapper, becase Server Side Validator...
  66. * Server Side Validatro can use only one proc, one ruleset
  67. */
  68. function procSqliteDBSetting()
  69. {
  70. return $this->_procDBSetting();
  71. }
  72. /**
  73. * @brief division install step... DB Config temp file create
  74. */
  75. function _procDBSetting()
  76. {
  77. // Get DB-related variables
  78. $con_string = Context::gets('db_type','db_port','db_hostname','db_userid','db_password','db_database','db_table_prefix');
  79. $db_info->master_db = get_object_vars($con_string);
  80. $db_info->slave_db[] = get_object_vars($con_string);
  81. if(!$db_info->default_url) $db_info->default_url = Context::getRequestUri();
  82. $db_info->lang_type = Context::getLangType();
  83. $db_info->use_mobile_view = 'Y';
  84. // Set DB type and information
  85. Context::setDBInfo($db_info);
  86. // Create DB Instance
  87. $oDB = &DB::getInstance();
  88. // Check if available to connect to the DB
  89. $output = $oDB->getError();
  90. if(!$output->toBool()) return $output;
  91. if(!$oDB->isConnected()) return $oDB->getError();
  92. // When installing firebird DB, transaction will not be used
  93. if($db_info->db_type != "firebird") $oDB->begin();
  94. if($db_info->db_type != "firebird") $oDB->commit();
  95. // Create a db temp config file
  96. if(!$this->makeDBConfigFile()) return new Object(-1, 'msg_install_failed');
  97. if(!in_array(Context::getRequestMethod(),array('XMLRPC','JSON')))
  98. {
  99. $returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'act', 'dispInstallConfigForm');
  100. header('location:'.$returnUrl);
  101. return;
  102. }
  103. }
  104. /**
  105. * @brief division install step... rewrite, time_zone Config temp file create
  106. */
  107. function procConfigSetting()
  108. {
  109. // Get variables
  110. $config_info = Context::gets('use_rewrite','time_zone');
  111. if($config_info->use_rewrite!='Y') $config_info->use_rewrite = 'N';
  112. // Create a db temp config file
  113. if(!$this->makeEtcConfigFile($config_info)) return new Object(-1, 'msg_install_failed');
  114. if(!in_array(Context::getRequestMethod(),array('XMLRPC','JSON')))
  115. {
  116. $returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'act', 'dispInstallManagerForm');
  117. header('location:'.$returnUrl);
  118. return;
  119. }
  120. }
  121. /**
  122. * @brief Install with received information
  123. */
  124. function procInstall()
  125. {
  126. // Check if it is already installed
  127. if(Context::isInstalled()) return new Object(-1, 'msg_already_installed');
  128. // Assign a temporary administrator when installing
  129. $logged_info->is_admin = 'Y';
  130. Context::set('logged_info', $logged_info);
  131. // check install config
  132. if(Context::get('install_config'))
  133. {
  134. $db_info = $this->_makeDbInfoByInstallConfig();
  135. }
  136. // install by default XE UI
  137. else
  138. {
  139. include $this->db_tmp_config_file;
  140. include $this->etc_tmp_config_file;
  141. }
  142. // Set DB type and information
  143. Context::setDBInfo($db_info);
  144. // Create DB Instance
  145. $oDB = &DB::getInstance();
  146. // Check if available to connect to the DB
  147. if(!$oDB->isConnected()) return $oDB->getError();
  148. // When installing firebire DB, transaction will not be used
  149. if($db_info->db_type != "firebird") $oDB->begin();
  150. // Install all the modules
  151. $this->installDownloadedModule();
  152. if($db_info->db_type != "firebird") $oDB->commit();
  153. // Create a config file
  154. if(!$this->makeConfigFile()) return new Object(-1, 'msg_install_failed');
  155. // load script
  156. $scripts = FileHandler::readDir('./modules/install/script','/(\.php)$/');
  157. if(count($scripts)>0)
  158. {
  159. sort($scripts);
  160. foreach($scripts as $script)
  161. {
  162. $output = include(FileHandler::getRealPath('./modules/install/script/'.$script));
  163. }
  164. }
  165. // save selected lang info
  166. $oInstallAdminController = &getAdminController('install');
  167. $oInstallAdminController->saveLangSelected(array(Context::getLangType()));
  168. // Display a message that installation is completed
  169. $this->setMessage('msg_install_completed');
  170. unset($_SESSION['use_rewrite']);
  171. if(!in_array(Context::getRequestMethod(),array('XMLRPC','JSON')))
  172. {
  173. $returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('');
  174. header('location:'.$returnUrl);
  175. return;
  176. }
  177. }
  178. /**
  179. * @brief Make DB Information by Install Config
  180. */
  181. function _makeDbInfoByInstallConfig()
  182. {
  183. $db_info->master_db['db_type'] = Context::get('db_type');
  184. $db_info->master_db['db_port'] = Context::get('db_port');
  185. $db_info->master_db['db_hostname'] = Context::get('db_hostname');
  186. $db_info->master_db['db_userid'] = Context::get('db_userid');
  187. $db_info->master_db['db_password'] = Context::get('db_password');
  188. $db_info->master_db['db_database'] = Context::get('db_database');
  189. $db_info->master_db['db_table_prefix'] = Context::get('db_table_prefix');
  190. $db_info->slave_db = array($db_info->master_db);
  191. $db_info->default_url = Context::getRequestUri();
  192. $db_info->lang_type = Context::getLangType();
  193. $db_info->use_rewrite = Context::get('use_rewrite');
  194. $db_info->time_zone = Context::get('time_zone');
  195. return $db_info;
  196. }
  197. /**
  198. * @brief Set FTP Information
  199. */
  200. function procInstallFTP()
  201. {
  202. if(Context::isInstalled()) return new Object(-1, 'msg_already_installed');
  203. $ftp_info = Context::gets('ftp_host', 'ftp_user','ftp_password','ftp_port','ftp_root_path');
  204. $ftp_info->ftp_port = (int)$ftp_info->ftp_port;
  205. if(!$ftp_info->ftp_port) $ftp_info->ftp_port = 21;
  206. if(!$ftp_info->ftp_host) $ftp_info->ftp_host = '127.0.0.1';
  207. if(!$ftp_info->ftp_root_path) $ftp_info->ftp_root_path = '/';
  208. $buff = '<?php if(!defined("__XE__")) exit();'."\n";
  209. foreach($ftp_info as $key => $val)
  210. {
  211. $buff .= sprintf("\$ftp_info->%s = '%s';\n", $key, str_replace("'","\\'",$val));
  212. }
  213. $buff .= "?".">";
  214. // If safe_mode
  215. if(ini_get('safe_mode'))
  216. {
  217. if(!$ftp_info->ftp_user || !$ftp_info->ftp_password) return new Object(-1,'msg_safe_mode_ftp_needed');
  218. require_once(_XE_PATH_.'libs/ftp.class.php');
  219. $oFtp = new ftp();
  220. if(!$oFtp->ftp_connect($ftp_info->ftp_host, $ftp_info->ftp_port)) return new Object(-1, sprintf(Context::getLang('msg_ftp_not_connected'), $ftp_info->ftp_host));
  221. if(!$oFtp->ftp_login($ftp_info->ftp_user, $ftp_info->ftp_password))
  222. {
  223. $oFtp->ftp_quit();
  224. return new Object(-1,'msg_ftp_invalid_auth_info');
  225. }
  226. if(!is_dir(_XE_PATH_.'files') && !$oFtp->ftp_mkdir($ftp_info->ftp_root_path.'files'))
  227. {
  228. $oFtp->ftp_quit();
  229. return new Object(-1,'msg_ftp_mkdir_fail');
  230. }
  231. if(!$oFtp->ftp_site("CHMOD 777 ".$ftp_info->ftp_root_path.'files'))
  232. {
  233. $oFtp->ftp_quit();
  234. return new Object(-1,'msg_ftp_chmod_fail');
  235. }
  236. if(!is_dir(_XE_PATH_.'files/config') && !$oFtp->ftp_mkdir($ftp_info->ftp_root_path.'files/config'))
  237. {
  238. $oFtp->ftp_quit();
  239. return new Object(-1,'msg_ftp_mkdir_fail');
  240. }
  241. if(!$oFtp->ftp_site("CHMOD 777 ".$ftp_info->ftp_root_path.'files/config'))
  242. {
  243. $oFtp->ftp_quit();
  244. return new Object(-1,'msg_ftp_chmod_fail');
  245. }
  246. $oFtp->ftp_quit();
  247. }
  248. $config_file = Context::getFTPConfigFile();
  249. FileHandler::WriteFile($config_file, $buff);
  250. }
  251. function procInstallCheckFtp()
  252. {
  253. $ftp_info = Context::gets('ftp_user','ftp_password','ftp_port','sftp');
  254. $ftp_info->ftp_port = (int)$ftp_info->ftp_port;
  255. if(!$ftp_info->ftp_port) $ftp_info->ftp_port = 21;
  256. if(!$ftp_info->sftp) $ftp_info->sftp = 'N';
  257. if(!$ftp_info->ftp_user || !$ftp_info->ftp_password) return new Object(-1,'msg_safe_mode_ftp_needed');
  258. if($ftp_info->sftp == 'Y')
  259. {
  260. $connection = ssh2_connect('localhost', $ftp_info->ftp_port);
  261. if(!ssh2_auth_password($connection, $ftp_info->ftp_user, $ftp_info->ftp_password))
  262. {
  263. return new Object(-1,'msg_ftp_invalid_auth_info');
  264. }
  265. }
  266. else
  267. {
  268. require_once(_XE_PATH_.'libs/ftp.class.php');
  269. $oFtp = new ftp();
  270. if(!$oFtp->ftp_connect('localhost', $ftp_info->ftp_port)) return new Object(-1, sprintf(Context::getLang('msg_ftp_not_connected'), 'localhost'));
  271. if(!$oFtp->ftp_login($ftp_info->ftp_user, $ftp_info->ftp_password))
  272. {
  273. $oFtp->ftp_quit();
  274. return new Object(-1,'msg_ftp_invalid_auth_info');
  275. }
  276. $oFtp->ftp_quit();
  277. }
  278. $this->setMessage('msg_ftp_connect_success');
  279. }
  280. /**
  281. * @brief Result returned after checking the installation environment
  282. */
  283. function checkInstallEnv()
  284. {
  285. // Check each item
  286. $checklist = array();
  287. // 0. check your version of php (5.2.2 is not supported)
  288. if(phpversion()=='5.2.2') $checklist['php_version'] = false;
  289. else $checklist['php_version'] = true;
  290. // 1. Check permission
  291. if(is_writable('./')||is_writable('./files')) $checklist['permission'] = true;
  292. else $checklist['permission'] = false;
  293. // 2. Check if xml_parser_create exists
  294. if(function_exists('xml_parser_create')) $checklist['xml'] = true;
  295. else $checklist['xml'] = false;
  296. // 3. Check if ini_get (session.auto_start) == 1
  297. if(ini_get(session.auto_start)!=1) $checklist['session'] = true;
  298. else $checklist['session'] = false;
  299. // 4. Check if iconv exists
  300. if(function_exists('iconv')) $checklist['iconv'] = true;
  301. else $checklist['iconv'] = false;
  302. // 5. Check gd(imagecreatefromgif function)
  303. if(function_exists('imagecreatefromgif')) $checklist['gd'] = true;
  304. else $checklist['gd'] = false;
  305. // 6. Check DB
  306. if(DB::getEnableList()) $checklist['db'] = true;
  307. else $checklist['db'] = false;
  308. if(!$checklist['php_version'] || !$checklist['permission'] || !$checklist['xml'] || !$checklist['session'] || !$checklist['db']) $install_enable = false;
  309. else $install_enable = true;
  310. // Save the checked result to the Context
  311. Context::set('checklist', $checklist);
  312. Context::set('install_enable', $install_enable);
  313. Context::set('phpversion', phpversion());
  314. return $install_enable;
  315. }
  316. /**
  317. * @brief Create files and subdirectories
  318. * Local evironment setting before installation by using DB information
  319. */
  320. function makeDefaultDirectory()
  321. {
  322. $directory_list = array(
  323. './files/config',
  324. './files/cache/queries',
  325. './files/cache/js_filter_compiled',
  326. './files/cache/template_compiled',
  327. );
  328. foreach($directory_list as $dir)
  329. {
  330. FileHandler::makeDir($dir);
  331. }
  332. }
  333. /**
  334. * @brief Install all the modules
  335. *
  336. * Create a table by using schema xml file in the shcema directory of each module
  337. */
  338. function installDownloadedModule()
  339. {
  340. $oModuleModel = &getModel('module');
  341. // Create a table ny finding schemas/*.xml file in each module
  342. $module_list = FileHandler::readDir('./modules/', NULL, false, true);
  343. foreach($module_list as $module_path)
  344. {
  345. // Get module name
  346. $tmp_arr = explode('/',$module_path);
  347. $module = $tmp_arr[count($tmp_arr)-1];
  348. $xml_info = $oModuleModel->getModuleInfoXml($module);
  349. if(!$xml_info) continue;
  350. $modules[$xml_info->category][] = $module;
  351. }
  352. // Install "module" module in advance
  353. $this->installModule('module','./modules/module');
  354. $oModule = &getClass('module');
  355. if($oModule->checkUpdate()) $oModule->moduleUpdate();
  356. // Determine the order of module installation depending on category
  357. $install_step = array('system','content','member');
  358. // Install all the remaining modules
  359. foreach($install_step as $category)
  360. {
  361. if(count($modules[$category]))
  362. {
  363. foreach($modules[$category] as $module)
  364. {
  365. if($module == 'module') continue;
  366. $this->installModule($module, sprintf('./modules/%s', $module));
  367. $oModule = &getClass($module);
  368. if(is_object($oModule) && method_exists($oModule, 'checkUpdate'))
  369. {
  370. if($oModule->checkUpdate()) $oModule->moduleUpdate();
  371. }
  372. }
  373. unset($modules[$category]);
  374. }
  375. }
  376. // Install all the remaining modules
  377. if(count($modules))
  378. {
  379. foreach($modules as $category => $module_list)
  380. {
  381. if(count($module_list))
  382. {
  383. foreach($module_list as $module)
  384. {
  385. if($module == 'module') continue;
  386. $this->installModule($module, sprintf('./modules/%s', $module));
  387. $oModule = &getClass($module);
  388. if($oModule && method_exists($oModule, 'checkUpdate') && method_exists($oModule, 'moduleUpdate'))
  389. {
  390. if($oModule->checkUpdate()) $oModule->moduleUpdate();
  391. }
  392. }
  393. }
  394. }
  395. }
  396. return new Object();
  397. }
  398. /**
  399. * @brief Install an each module
  400. */
  401. function installModule($module, $module_path)
  402. {
  403. // create db instance
  404. $oDB = &DB::getInstance();
  405. // Create a table if the schema xml exists in the "schemas" directory of the module
  406. $schema_dir = sprintf('%s/schemas/', $module_path);
  407. $schema_files = FileHandler::readDir($schema_dir, NULL, false, true);
  408. $file_cnt = count($schema_files);
  409. for($i=0;$i<$file_cnt;$i++)
  410. {
  411. $file = trim($schema_files[$i]);
  412. if(!$file || substr($file,-4)!='.xml') continue;
  413. $output = $oDB->createTableByXmlFile($file);
  414. }
  415. // Create a table and module instance and then execute install() method
  416. unset($oModule);
  417. $oModule = &getClass($module);
  418. if(method_exists($oModule, 'moduleInstall')) $oModule->moduleInstall();
  419. return new Object();
  420. }
  421. function _getDbConnText($key, $val, $with_array = false){
  422. $buff = '';
  423. if($with_array)
  424. $buff .= "\$db_info->$key = array(";
  425. else
  426. $buff .= "\$db_info->$key = ";
  427. if(!$with_array) $val = array($val);
  428. foreach($val as $con_string)
  429. {
  430. $buff .= 'array(';
  431. foreach($con_string as $k => $v)
  432. {
  433. if(in_array($k, array('resource', 'is_connected'))) continue;
  434. if($k == 'db_table_prefix' && !empty($v))
  435. {
  436. if(substr($v,-1)!='_') $v .= '_';
  437. }
  438. $buff .= "'$k' => '$v',";
  439. }
  440. $buff = substr($buff, 0, -1);
  441. $buff .= '),';
  442. }
  443. $buff = substr($buff, 0, -1);
  444. if($with_array)
  445. $buff .= ');' . PHP_EOL;
  446. else
  447. $buff .= ';' . PHP_EOL;
  448. return $buff;
  449. }
  450. function _getDBConfigFileContents($db_info)
  451. {
  452. $buff = '<?php if(!defined("__XE__")) exit();'."\n";
  453. $db_info = get_object_vars($db_info);
  454. foreach($db_info as $key => $val)
  455. {
  456. if($key == 'master_db')
  457. {
  458. $tmpValue = $this->_getDbConnText($key, $val);
  459. }
  460. else if($key == 'slave_db')
  461. {
  462. $tmpValue = $this->_getDbConnText($key, $val, true);
  463. }
  464. else
  465. {
  466. if($key == 'default_url')
  467. {
  468. $tmpValue = sprintf("\$db_info->%s = '%s';" . PHP_EOL, $key, addslashes($val));
  469. }
  470. else
  471. {
  472. $tmpValue = sprintf("\$db_info->%s = '%s';" . PHP_EOL, $key, str_replace("'","\\'",$val));
  473. }
  474. }
  475. if(preg_match('/(<\?|<\?php|\?>|fputs|fopen|fwrite|fgets|fread|\/\*|\*\/|chr\()/xsm', preg_replace('/\s/', '', $tmpValue)))
  476. {
  477. throw new Exception('msg_invalid_request');
  478. }
  479. $buff .= $tmpValue;
  480. }
  481. $buff .= "?>";
  482. return $buff;
  483. }
  484. /**
  485. * @brief Create DB temp config file
  486. * Create the config file when all settings are completed
  487. */
  488. function makeDBConfigFile()
  489. {
  490. $db_tmp_config_file = $this->db_tmp_config_file;
  491. $db_info = Context::getDbInfo();
  492. if(!$db_info) return;
  493. $buff = $this->_getDBConfigFileContents($db_info);
  494. FileHandler::writeFile($db_tmp_config_file, $buff);
  495. if(@file_exists($db_tmp_config_file)) return true;
  496. return false;
  497. }
  498. /**
  499. * @brief Create etc config file
  500. * Create the config file when all settings are completed
  501. */
  502. function makeEtcConfigFile($config_info)
  503. {
  504. $etc_tmp_config_file = $this->etc_tmp_config_file;
  505. $buff = '<?php if(!defined("__XE__")) exit();'."\n";
  506. foreach($config_info as $key => $val)
  507. {
  508. $buff .= sprintf("\$db_info->%s = '%s';\n", $key, str_replace("'","\\'",$val));
  509. }
  510. $buff .= "?>";
  511. FileHandler::writeFile($etc_tmp_config_file, $buff);
  512. if(@file_exists($etc_tmp_config_file)) return true;
  513. return false;
  514. }
  515. /**
  516. * @brief Create config file
  517. * Create the config file when all settings are completed
  518. */
  519. function makeConfigFile()
  520. {
  521. try {
  522. $config_file = Context::getConfigFile();
  523. //if(file_exists($config_file)) return;
  524. $db_info = Context::getDbInfo();
  525. if(!$db_info) return;
  526. $buff = $this->_getDBConfigFileContents($db_info);
  527. FileHandler::writeFile($config_file, $buff);
  528. if(@file_exists($config_file))
  529. {
  530. FileHandler::removeFile($this->db_tmp_config_file);
  531. FileHandler::removeFile($this->etc_tmp_config_file);
  532. return true;
  533. }
  534. return false;
  535. } catch (Exception $e) {
  536. return false;
  537. }
  538. }
  539. function installByConfig($install_config_file)
  540. {
  541. include $install_config_file;
  542. if(!is_array($auto_config)) return false;
  543. $auto_config['module'] = 'install';
  544. $auto_config['act'] = 'procInstall';
  545. $fstr = "<%s><![CDATA[%s]]></%s>\r\n";
  546. $fheader = "POST %s HTTP/1.1\r\nHost: %s\r\nContent-Type: application/xml\r\nContent-Length: %s\r\n\r\n%s\r\n";
  547. $body = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n<methodCall>\r\n<params>\r\n";
  548. foreach($auto_config as $k => $v)
  549. {
  550. if(!in_array($k,array('host','port','path'))) $body .= sprintf($fstr,$k,$v,$k);
  551. }
  552. $body .= "</params>\r\n</methodCall>";
  553. $header = sprintf($fheader,$auto_config['path'],$auto_config['host'],strlen($body),$body);
  554. $fp = @fsockopen($auto_config['host'], $auto_config['port'], $errno, $errstr, 5);
  555. if($fp)
  556. {
  557. fputs($fp, $header);
  558. while(!feof($fp))
  559. {
  560. $line = trim(fgets($fp, 4096));
  561. if(preg_match("/^<error>/i",$line))
  562. {
  563. fclose($fp);
  564. return false;
  565. }
  566. }
  567. fclose($fp);
  568. }
  569. return true;
  570. }
  571. }
  572. /* End of file install.controller.php */
  573. /* Location: ./modules/install/install.controller.php */