PageRenderTime 59ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/src/applications/install/controller/IndexController.php

https://github.com/cuijinquan/nextwind
PHP | 827 lines | 663 code | 53 blank | 111 comment | 58 complexity | 4550a1e84fba96c1ee31bbe4ab256f36 MD5 | raw file
  1. <?php
  2. define('WIND_SETUP', 'install');
  3. /**
  4. * 安装流程
  5. *
  6. * @author jinlong.panjl <jinlong.panjl@aliyun-inc.com>
  7. * @copyright ©2003-2103 phpwind.com
  8. * @license http://www.phpwind.com
  9. * @version $$Id$$
  10. * @package application
  11. */
  12. class IndexController extends WindController {
  13. /**
  14. *
  15. * 定义需要导入默认数据sql文件
  16. *
  17. * @var array
  18. */
  19. private $wind_data = array(
  20. 'wind_structure.sql',
  21. 'pw_windid_area.sql',
  22. 'pw_windid_school.sql',
  23. 'pw_windid_config.sql',
  24. 'pw_user_groups.sql',
  25. 'pw_common_config.sql',
  26. 'pw_design.sql',
  27. 'pw_acloud.sql',
  28. 'wind_data.sql',
  29. 'demo_data.sql');
  30. /* (non-PHPdoc)
  31. * @see WindSimpleController::beforeAction()
  32. */
  33. public function beforeAction($handlerAdapter) {
  34. if ('finish' != $handlerAdapter->getAction()) Wekit::createapp('install');
  35. //ajax递交编码转换
  36. if ($this->getRequest()->getIsAjaxRequest()) {
  37. $toCharset = $this->getResponse()->getCharset();
  38. if (strtoupper(substr($toCharset, 0, 2)) != 'UT') {
  39. $_tmp = array();
  40. foreach ($_POST as $key => $value) {
  41. $key = WindConvert::convert($key, $toCharset, 'UTF-8');
  42. $_tmp[$key] = WindConvert::convert($value, $toCharset, 'UTF-8');
  43. }
  44. $_POST = $_tmp;
  45. }
  46. }
  47. $_consts = include (Wind::getRealPath('CONF:publish.php', true));
  48. foreach ($_consts as $const => $value) {
  49. if (defined($const)) continue;
  50. if ($const === 'PUBLIC_URL' && !$value) {
  51. $value = Wind::getApp()->getRequest()->getBaseUrl(true);
  52. }
  53. define($const, $value);
  54. }
  55. $url = array();
  56. $url['base'] = PUBLIC_URL;
  57. $url['res'] = WindUrlHelper::checkUrl(PUBLIC_RES, PUBLIC_URL);
  58. $url['css'] = WindUrlHelper::checkUrl(PUBLIC_RES . '/css/', PUBLIC_URL);
  59. $url['images'] = WindUrlHelper::checkUrl(PUBLIC_RES . '/images/', PUBLIC_URL);
  60. $url['js'] = WindUrlHelper::checkUrl(PUBLIC_RES . '/js/dev/', PUBLIC_URL);
  61. $url['attach'] = WindUrlHelper::checkUrl(PUBLIC_ATTACH, PUBLIC_URL);
  62. Wekit::setGlobal($url, 'url');
  63. $this->setOutput(NEXT_VERSION, 'wind_version');
  64. WindFile::isFile($this->_getInstallLockFile()) && $this->showError('INSTALL:have_install_lock');
  65. }
  66. /**
  67. * 协议
  68. * @see WindAction::run()
  69. */
  70. public function run() {
  71. $wind_license = WindFile::read(Wind::getRealPath('ROOT:LICENSE', false));
  72. $this->setOutput($wind_license, 'wind_license');
  73. }
  74. /**
  75. * 检测环境
  76. */
  77. public function checkAction() {
  78. $lowestEnvironment = $this->_getLowestEnvironment();
  79. $currentEnvironment = $this->_getCurrentEnvironment();
  80. $recommendEnvironment = $this->_getRecommendEnvironment();
  81. $writeAble = $this->_checkFileRight();
  82. $check_pass = true;
  83. foreach ($currentEnvironment as $key => $value) {
  84. if (false !== strpos($key, '_ischeck') && false === $value) $check_pass = false;
  85. }
  86. foreach ($writeAble as $value) {
  87. if (false === $value) $check_pass = false;
  88. }
  89. $this->setOutput($writeAble, 'writeAble');
  90. $this->setOutput($lowestEnvironment, 'lowestEnvironment');
  91. $this->setOutput($currentEnvironment, 'currentEnvironment');
  92. $this->setOutput($recommendEnvironment, 'recommendEnvironment');
  93. }
  94. /**
  95. * 数据库信息配置
  96. */
  97. public function infoAction() {
  98. WindFile::del($this->_getTableLogFile());
  99. WindFile::del($this->_getTableSqlFile());
  100. $database_writable = $this->_checkWriteAble($this->_getDatabaseFile());
  101. $founder_writable = $this->_checkWriteAble($this->_getFounderFile());
  102. $this->setOutput($database_writable, 'database_writable');
  103. $this->setOutput($founder_writable, 'founder_writable');
  104. }
  105. /**
  106. * 创建数据库
  107. */
  108. public function databaseAction() {
  109. $keys = array(
  110. 'dbhost',
  111. 'dbuser',
  112. 'dbname',
  113. 'dbprefix',
  114. 'manager',
  115. 'manager_pwd',
  116. 'manager_ckpwd',
  117. 'manager_email',
  118. 'dbpw',
  119. 'engine');
  120. $input = $this->getInput($keys, 'post');
  121. $force = $this->getInput('force');
  122. $input = array_combine($keys, $input);
  123. foreach ($input as $k => $v) {
  124. if (!in_array($k, array('dbpw', 'engine')) && empty($v)) $this->showError("INSTALL:input_empty_$k");
  125. }
  126. if ($input['manager_pwd'] !== $input['manager_ckpwd']) {
  127. $this->showError('INSTALL:manager_pwd.eque.ckpwd');
  128. }
  129. if (!preg_match('/^[\x7f-\xff\dA-Za-z\.\_]+$/', $input['manager'])) {
  130. $this->showError('INSTALL:founder.name.error');
  131. }
  132. $usernameLen = Pw::strlen($input['manager']);
  133. $passwordLen = Pw::strlen($input['manager_pwd']);
  134. if ($usernameLen < 1 || $usernameLen > 15 || $passwordLen < 1 || $passwordLen > 25) {
  135. $this->showError('INSTALL:founder.init.fail');
  136. }
  137. if (false === WindValidator::isEmail($input['manager_email'])) {
  138. $this->showError('INSTALL:founder.init.email.error');
  139. }
  140. list($input['dbhost'], $input['dbport']) = explode(':', $input['dbhost']);
  141. $input['dbport'] = !empty($input['dbport']) ? intval($input['dbport']) : 3306;
  142. if (!empty($input['engine'])) {
  143. $input['engine'] = strtoupper($input['engine']);
  144. !in_array($input['engine'], array('MyISAM', 'InnoDB')) && $input['engine'] = 'MyISAM';
  145. } else {
  146. $input['engine'] = 'MyISAM';
  147. }
  148. $charset = Wind::getApp()->getResponse()->getCharset();
  149. $charset = str_replace('-', '', strtolower($charset));
  150. if (!in_array($charset, array('gbk', 'utf8', 'big5'))) $charset = 'utf8';
  151. // 检测是否安装过了
  152. Wind::import("WIND:db.WindConnection");
  153. $dsn = 'mysql:host=' . $input['dbhost'] . ';port=' . $input['dbport'];
  154. try {
  155. $pdo = new WindConnection($dsn, $input['dbuser'], $input['dbpw']);
  156. $result = $pdo->query("SHOW DATABASES")->fetchAll();
  157. foreach ($result as $v) {
  158. if ($v['Database'] == $input['dbname']) {
  159. $dbnameExist = true;
  160. break;
  161. }
  162. }
  163. if ($dbnameExist) {
  164. $result = $pdo->query("SHOW TABLES FROM `{$input['dbname']}`")->rowCount();
  165. empty($result) && $dbnameExist = false;
  166. }
  167. } catch (PDOException $e) {
  168. $error = $e->getMessage();
  169. $this->showError($error, false);
  170. }
  171. if ($dbnameExist && !$force) $this->showError('INSTALL:have_install', true, 'index/database', true);
  172. if (!$dbnameExist) {
  173. try {
  174. $pdo = new WindConnection($dsn, $input['dbuser'], $input['dbpw']);
  175. $pdo->query("CREATE DATABASE IF NOT EXISTS `{$input['dbname']}` DEFAULT CHARACTER SET $charset");
  176. } catch (PDOException $e) {
  177. $error = $e->getMessage();
  178. $this->showError($error, false);
  179. }
  180. }
  181. $pdo->close();
  182. if (!$this->_checkWriteAble($this->_getDatabaseFile())) {
  183. $this->showError('INSTALL:error_777_database');
  184. }
  185. if (!$this->_checkWriteAble($this->_getFounderFile())) {
  186. $this->showError('INSTALL:error_777_founder');
  187. }
  188. $database = array(
  189. 'dsn' => 'mysql:host=' . $input['dbhost'] . ';dbname=' . $input['dbname'] . ';port=' . $input['dbport'],
  190. 'user' => $input['dbuser'],
  191. 'pwd' => $input['dbpw'],
  192. 'charset' => $charset,
  193. 'tableprefix' => $input['dbprefix'],
  194. 'engine' => $input['engine'],
  195. 'founder' => array(
  196. 'manager' => $input['manager'],
  197. 'manager_pwd' => $input['manager_pwd'],
  198. 'manager_email' => $input['manager_email']));
  199. WindFile::savePhpData($this->_getTempFile(), $database);
  200. $arrSQL = array();
  201. foreach ($this->wind_data as $file) {
  202. $file = Wind::getRealPath("APPS:install.lang.$file", true);
  203. if (!WindFile::isFile($file)) continue;
  204. $content = WindFile::read($file);
  205. if (!empty($content)) $arrSQL = array_merge_recursive($arrSQL,
  206. $this->_sqlParser($content, $charset, $input['dbprefix'], $input['engine']));
  207. }
  208. WindFile::savePhpData($this->_getTableSqlFile(), $arrSQL['SQL']);
  209. WindFile::write($this->_getTableLogFile(), implode('<wind>', $arrSQL['LOG']['CREATE']));
  210. $this->showMessage('success', false, 'index/table');
  211. }
  212. /**
  213. * 创建数据表
  214. */
  215. public function tableAction() {
  216. @set_time_limit(300);
  217. $db = $this->_checkDatabase();
  218. try {
  219. $pdo = new WindConnection($db['dsn'], $db['user'], $db['pwd']);
  220. $pdo->setConfig($db);
  221. } catch (PDOException $e) {
  222. $this->showError($e->getMessage(), false);
  223. }
  224. $tableSql = include $this->_getTableSqlFile();
  225. try {
  226. foreach ($tableSql['DROP'] as $sql) {
  227. $pdo->query($sql);
  228. }
  229. foreach ($tableSql['CREATE'] as $sql) {
  230. $pdo->query($sql);
  231. }
  232. } catch (PDOException $e) {
  233. $this->showError($e->getMessage(), false);
  234. }
  235. $pdo->close();
  236. $log = WindFile::read($this->_getTableLogFile());
  237. $this->setOutput($log, 'log');
  238. }
  239. /**
  240. * 导入默认数据
  241. */
  242. public function dataAction() {
  243. @set_time_limit(300);
  244. $db = $this->_checkDatabase();
  245. try {
  246. $pdo = new WindConnection($db['dsn'], $db['user'], $db['pwd']);
  247. $pdo->setConfig($db);
  248. } catch (PDOException $e) {
  249. $this->showError($e->getMessage(), false);
  250. }
  251. $tableSql = include $this->_getTableSqlFile();
  252. try {
  253. foreach ($tableSql['UPDATE'] as $sql) {
  254. $pdo->query($sql);
  255. }
  256. } catch (PDOException $e) {
  257. $this->showError($e->getMessage(), false);
  258. }
  259. $pdo->close();
  260. //数据库配置
  261. $database = array(
  262. 'dsn' => $db['dsn'],
  263. 'user' => $db['user'],
  264. 'pwd' => $db['pwd'],
  265. 'charset' => $db['charset'],
  266. 'tableprefix' => $db['tableprefix'],
  267. 'engine' => $db['engine']);
  268. WindFile::savePhpData($this->_getDatabaseFile(), $database);
  269. //写入windid配置信息
  270. $this->_writeWindid();
  271. $this->forwardRedirect(WindUrlHelper::createUrl('index/finish'));
  272. }
  273. /**
  274. * 安装完成
  275. */
  276. public function finishAction() {
  277. //Wekit::createapp('phpwind');
  278. Wekit::C()->reload('windid');
  279. WindidApi::api('user');
  280. $db = $this->_checkDatabase();
  281. //更新HOOK配置数据
  282. Wekit::load('hook.srv.PwHookRefresh')->refresh();
  283. //初始化站点config
  284. $site_hash = WindUtility::generateRandStr(8);
  285. $cookie_pre = WindUtility::generateRandStr(3);
  286. Wekit::load('config.PwConfig')->setConfig('site', 'hash', $site_hash);
  287. Wekit::load('config.PwConfig')->setConfig('site', 'cookie.pre', $cookie_pre);
  288. Wekit::load('config.PwConfig')->setConfig('site', 'info.mail', $db['founder']['manager_email']);
  289. Wekit::load('config.PwConfig')->setConfig('site', 'info.url', PUBLIC_URL);
  290. Wekit::load('nav.srv.PwNavService')->updateConfig();
  291. Wind::import('WINDID:service.config.srv.WindidConfigSet');
  292. $windidConfig = new WindidConfigSet('site');
  293. $windidConfig->set('hash', $site_hash)
  294. ->set('cookie.pre', $cookie_pre)
  295. ->flush();
  296. //风格默认数据
  297. Wekit::load('APPCENTER:service.srv.PwStyleInit')->init();
  298. //计划任务默认数据
  299. Wekit::load('cron.srv.PwCronService')->updateSysCron();
  300. //更新数据缓存
  301. /* @var $usergroup PwUserGroupsService */
  302. $usergroup = Wekit::load('SRV:usergroup.srv.PwUserGroupsService');
  303. $usergroup->updateLevelCache();
  304. $usergroup->updateGroupCache(range(1, 16));
  305. $usergroup->updateGroupRightCache();
  306. /* @var $emotion PwEmotionService */
  307. $emotion = Wekit::load('SRV:emotion.srv.PwEmotionService');
  308. $emotion->updateCache();
  309. //创始人配置
  310. $uid = $this->_writeFounder($db['founder']['manager'], $db['founder']['manager_pwd'], $db['founder']['manager_email']);
  311. //门户演示数据
  312. Wekit::load('SRV:design.srv.PwDesignDefaultService')->likeModule();
  313. Wekit::load('SRV:design.srv.PwDesignDefaultService')->tagModule();
  314. Wekit::load('SRV:design.srv.PwDesignDefaultService')->reviseDefaultData();
  315. //演示数据导入
  316. Wind::import('SRV:forum.srv.PwPost');
  317. Wind::import('SRV:forum.srv.post.PwTopicPost');
  318. $pwPost = new PwPost(new PwTopicPost(2, new PwUserBo($uid)));
  319. $threads = $this->_getDemoThreads();
  320. foreach ($threads as $thread) {
  321. $postDm = $pwPost->getDm();
  322. $postDm->setTitle($thread['title'])->setContent($thread['content']);
  323. $result = $pwPost->execute($postDm);
  324. }
  325. //全局缓存更新
  326. Wekit::load('SRV:cache.srv.PwCacheUpdateService')->updateConfig();
  327. Wekit::load('SRV:cache.srv.PwCacheUpdateService')->updateMedal();
  328. //清理安装过程的文件
  329. WindFile::write($this->_getInstallLockFile(), 'LOCKED');
  330. WindFile::del($this->_getTempFile());
  331. WindFile::del($this->_getTableLogFile());
  332. WindFile::del($this->_getTableSqlFile());
  333. }
  334. /* (non-PHPdoc)
  335. * @see WindSimpleController::setDefaultTemplateName()
  336. */
  337. protected function setDefaultTemplateName($handlerAdapter) {
  338. $template = $handlerAdapter->getController() . '_' . $handlerAdapter->getAction();
  339. $this->setTemplate(strtolower($template));
  340. }
  341. /**
  342. * 显示信息
  343. *
  344. * @param string $message 消息信息
  345. * @param string $referer 跳转地址
  346. * @param boolean $referer 是否刷新页面
  347. * @param string $action 处理句柄
  348. * @see WindSimpleController::showMessage()
  349. */
  350. protected function showMessage($message = '', $lang = true, $referer = '', $refresh = false) {
  351. $this->addMessage('success', 'state');
  352. $this->addMessage($this->forward->getVars('data'), 'data');
  353. $this->showError($message, $lang, $referer, $refresh);
  354. }
  355. /**
  356. * 显示错误
  357. *
  358. * @param array $error array('',array())
  359. */
  360. protected function showError($error = '', $lang = true, $referer = '', $refresh = false) {
  361. $referer && $referer = WindUrlHelper::createUrl($referer);
  362. $this->addMessage($referer, 'referer');
  363. $this->addMessage($refresh, 'refresh');
  364. if ($lang) {
  365. $lang = Wind::getComponent('i18n');
  366. $error = $lang->getMessage($error);
  367. }
  368. parent::showMessage($error);
  369. }
  370. /**
  371. * WIND SQL 格式解析
  372. *
  373. * @param string $strSQL SQL语句字串
  374. * @param string $charset 字符集
  375. * @return array(SQL, log)
  376. */
  377. private function _sqlParser($strSQL, $charset, $dbprefix, $engine) {
  378. if (empty($strSQL)) return array();
  379. $query = '';
  380. $logData = $tableSQL = $dataSQL = $fieldSQL = array();
  381. $strSQL = str_replace(array("\r", "\n\n", ";\n"), array('', "\n", ";<wind>\n"), trim($strSQL, " \n\t") . "\n");
  382. $arrSQL = explode("\n", $strSQL);
  383. foreach ($arrSQL as $value) {
  384. $value = trim($value, " \t");
  385. if (!$value || substr($value, 0, 2) === '--') continue;
  386. $query .= $value;
  387. if (substr($query, -7) != ';<wind>') continue;
  388. $query = preg_replace('/([ `]+)pw_/', "\${1}$dbprefix", $query, 1);
  389. $sql_key = strtoupper(substr($query, 0, strpos($query, ' ')));
  390. if ($sql_key == 'CREATE') {
  391. $tablename = trim(strrchr(trim(substr($query, 0, strpos($query, '('))), ' '), '` ');
  392. $query = str_replace(array('ENGINE=MyISAM', 'DEFAULT CHARSET=utf8', ';<wind>'),
  393. array("ENGINE=$engine", "DEFAULT CHARSET=$charset", ';'), $query);
  394. $dataSQL['CREATE'][] = $query;
  395. $logData['CREATE'][] = $tablename;
  396. } elseif ($sql_key == 'DROP') {
  397. $tablename = trim(strrchr(trim(substr($query, 0, strrpos($query, ';'))), ' '), '` ');
  398. $query = str_replace(';<wind>', '', $query);
  399. $dataSQL['DROP'][] = $query;
  400. //$logData['DROP'][] = $tablename;
  401. } elseif ($sql_key == 'ALTER') {
  402. $query = str_replace(';<wind>', '', $query);
  403. $dataSQL['ALTER'][] = $query;
  404. //$logData['ALTER'][] = $query;
  405. } elseif (in_array($sql_key, array('INSERT', 'REPLACE', 'UPDATE'))) {
  406. $query = str_replace(';<wind>', '', $query);
  407. $sql_key == 'INSERT' && $query = 'REPLACE' . substr($query, 6);
  408. $dataSQL['UPDATE'][] = $query;
  409. //$logData['UPDATE'][] = $query;
  410. }
  411. $query = '';
  412. }
  413. return array('SQL' => $dataSQL, 'LOG' => $logData);
  414. }
  415. /**
  416. * 获得当前的环境信息
  417. *
  418. * @return array
  419. */
  420. private function _getCurrentEnvironment() {
  421. $lowestEnvironment = $this->_getLowestEnvironment();
  422. $rootPath = Wind::getRealDir('ROOT:');
  423. $space = floor(@disk_free_space($rootPath) / (1024 * 1024));
  424. $space = !empty($space) ? $space . 'M': 'unknow';
  425. $currentUpload = ini_get('file_uploads') ? ini_get('upload_max_filesize') : 'unknow';
  426. $upload_ischeck = intval($currentUpload) >= intval($lowestEnvironment['upload']) ? true : false;
  427. $space_ischeck = intval($space) >= intval($lowestEnvironment['space']) ? true : false;
  428. $version_ischeck = version_compare(phpversion(), $lowestEnvironment['version']) < 0 ? false : true;
  429. $pdo_mysql_ischeck = extension_loaded('pdo_mysql');
  430. if (function_exists('mysql_get_client_info')) {
  431. $mysql = mysql_get_client_info();
  432. $mysql_ischeck = true;//version_compare($mysql, $lowestEnvironment['mysql']) < 0 ? false : true;
  433. } elseif (function_exists('mysqli_get_client_info')) {
  434. $mysql = mysqli_get_client_info();
  435. $mysql_ischeck = true;//version_compare($mysql, $lowestEnvironment['mysql']) < 0 ? false : true;
  436. } elseif ($pdo_mysql_ischeck) {
  437. $mysql_ischeck = true;
  438. $mysql = 'unknow';
  439. } else {
  440. $mysql_ischeck = false;
  441. $mysql = 'unknow';
  442. }
  443. if (function_exists('gd_info')) {
  444. $gdinfo = gd_info();
  445. $gd = $gdinfo['GD Version'];
  446. $gd_ischeck = version_compare($lowestEnvironment['gd'], $gd) < 0 ? false : true;
  447. } else {
  448. $gd_ischeck = false;
  449. $gd = 'unknow';
  450. }
  451. return array(
  452. 'os_ischeck' => true,
  453. 'version_ischeck' => $version_ischeck,
  454. 'mysql_ischeck' => $mysql_ischeck,
  455. 'pdo_mysql_ischeck' => $pdo_mysql_ischeck,
  456. 'upload_ischeck' => $upload_ischeck,
  457. 'space_ischeck' => $space_ischeck,
  458. 'gd_ischeck' => $gd_ischeck,
  459. 'gd' => $gd,
  460. 'os' => PHP_OS,
  461. 'version' => phpversion(),
  462. 'mysql' => $mysql,
  463. 'pdo_mysql' => $pdo_mysql_ischeck,
  464. 'upload' => $currentUpload,
  465. 'space' => $space);
  466. }
  467. /**
  468. * 获取推荐的环境配置信息
  469. *
  470. * @return array
  471. */
  472. private function _getRecommendEnvironment() {
  473. return array(
  474. 'os' => '类UNIX',
  475. 'version' => '>5.3.x',
  476. 'mysql' => '>5.x.x',
  477. 'pdo_mysql' => '必须',
  478. 'upload' => '>2M',
  479. 'space' => '>50M',
  480. 'gd' => '>2.0.28');
  481. }
  482. /**
  483. * 获取环境的最低配置要求
  484. *
  485. * @return array
  486. */
  487. private function _getLowestEnvironment() {
  488. return array(
  489. 'os' => '不限制',
  490. 'version' => '5.1.2',
  491. 'mysql' => '4.2',
  492. 'pdo_mysql' => '必须',
  493. 'upload' => '不限制',
  494. 'space' => '50M',
  495. 'gd' => '2.0');
  496. }
  497. /**
  498. * 检查目录权限
  499. *
  500. * @return array
  501. */
  502. private function _checkFileRight() {
  503. $rootdir = Wind::getRootPath('ROOT');
  504. $files_writeble[] = CONF_PATH;
  505. $files_writeble[] = DATA_PATH; //数据缓存目录
  506. $files_writeble[] = DATA_PATH . 'cache/';
  507. $files_writeble[] = DATA_PATH . 'compile/';
  508. $files_writeble[] = DATA_PATH . 'log/';
  509. $files_writeble[] = DATA_PATH . 'tmp/';
  510. $files_writeble[] = DATA_PATH . 'design/';
  511. $files_writeble[] = EXT_PATH; //扩展应用目录
  512. $files_writeble[] = ATTACH_PATH ; //本地附近目录
  513. $files_writeble[] = HTML_PATH; //本地静态文件可写目录
  514. $files_writeble[] = THEMES_PATH; //风格目录
  515. $files_writeble[] = THEMES_PATH . 'extres/';
  516. $files_writeble[] = THEMES_PATH . 'forum/';
  517. $files_writeble[] = THEMES_PATH . 'portal/';
  518. $files_writeble[] = THEMES_PATH . 'site/';
  519. $files_writeble[] = THEMES_PATH . 'space/';
  520. $files_writeble[] = PUBLIC_PATH . 'windid/attachment/';
  521. $files_writeble[] = $this->_getDatabaseFile();
  522. $files_writeble[] = $this->_getFounderFile();
  523. //$files_writeble[] = $this->_getWindidFile();
  524. $files_writeble = array_unique($files_writeble);
  525. sort($files_writeble);
  526. $writable = array();
  527. foreach ($files_writeble as $file) {
  528. $key = str_replace($rootdir, '', $file);
  529. $isWritable = $this->_checkWriteAble($file) ? true : false;
  530. if ($isWritable) {
  531. $flag = false;
  532. foreach ($writable as $k=>$v) {
  533. if (0 === strpos($key, $k)) $flag = true;
  534. }
  535. $flag || $writable[$key] = $isWritable;
  536. } else {
  537. $writable[$key] = $isWritable;
  538. }
  539. }
  540. return $writable;
  541. }
  542. /**
  543. * 检查目录可写
  544. *
  545. * @param string $pathfile
  546. * @return boolean
  547. */
  548. private function _checkWriteAble($pathfile) {
  549. if (!$pathfile) return false;
  550. $isDir = in_array(substr($pathfile, -1), array('/', '\\')) ? true : false;
  551. if ($isDir) {
  552. if (is_dir($pathfile)) {
  553. mt_srand((double) microtime() * 1000000);
  554. $pathfile = $pathfile . 'pw_' . uniqid(mt_rand()) . '.tmp';
  555. } elseif (@mkdir($pathfile)) {
  556. return self::_checkWriteAble($pathfile);
  557. } else {
  558. return false;
  559. }
  560. }
  561. @chmod($pathfile, 0777);
  562. $fp = @fopen($pathfile, 'ab');
  563. if ($fp === false) return false;
  564. fclose($fp);
  565. $isDir && @unlink($pathfile);
  566. return true;
  567. }
  568. /**
  569. * 创建创始人
  570. *
  571. * @param string $manager
  572. * @param string $manager_pwd
  573. * @param string $manager_email
  574. * @return PwError
  575. */
  576. private function _writeFounder($manager, $manager_pwd, $manager_email) {
  577. Wekit::C()->reload('windid');
  578. Wind::import('SRV:user.dm.PwUserInfoDm');
  579. $data = array($manager => md5($manager_pwd));
  580. WindFile::savePhpData($this->_getFounderFile(), $data);
  581. //TODO 创始人添加:用户的配置信息先更新。添加完之后再更新回 开始
  582. $config = new PwConfigSet('register');
  583. $config->set('security.username.max', 15)
  584. ->set('security.ban.username', '')
  585. ->set('security.username.min', 1)
  586. ->set('security.password.max', 25)
  587. ->set('security.password.min', 1)
  588. ->flush();
  589. Wind::import('WINDID:service.config.srv.WindidConfigSet');
  590. $windidConfig = new WindidConfigSet('reg');
  591. $windidConfig->set('security.ban.username', '')
  592. ->set('security.password.max', 25)
  593. ->set('security.password.min', 1)
  594. ->set('security.username.max', 15)
  595. ->set('security.username.min', 1)
  596. ->flush();
  597. Wekit::C()->reload('register');
  598. WindidApi::C()->reload('reg');
  599. //TODO结束
  600. $userDm = new PwUserInfoDm();
  601. $userDm->setUsername($manager)->setPassword($manager_pwd)->setEmail($manager_email)->setGroupid(3)->setRegdate(
  602. Pw::getTime())->setLastvisit(Pw::getTime())->setRegip(Wind::getApp()->getRequest()->getClientIp())->setGroups(array('3'=>'0'));
  603. //特殊操作 gao.wanggao
  604. if (true !== ($result = $userDm->beforeAdd())) {
  605. $this->showError($result->getError());
  606. }
  607. if (($uid = Wekit::load('WSRV:user.WindidUser')->addUser($userDm->dm)) < 1) {
  608. $this->showError('WINDID:code.' . $uid);
  609. }
  610. $userDm->setUid($uid);
  611. Wind::import('SRV:user.PwUser');
  612. $daoMap = array();
  613. $daoMap[PwUser::FETCH_MAIN] = 'user.dao.PwUserDao';
  614. $daoMap[PwUser::FETCH_DATA] = 'user.dao.PwUserDataDao';
  615. $daoMap[PwUser::FETCH_INFO] = 'user.dao.PwUserInfoDao';
  616. Wekit::loadDaoFromMap(PwUser::FETCH_ALL, $daoMap, 'PwUser')->addUser($userDm->getSetData());
  617. //特殊操作
  618. //$uid = Wekit::load('user.PwUser')->addUser($userDm);
  619. //TODO 创始人添加完成:恢复默认数据:开始
  620. $config = new PwConfigSet('register');
  621. $config->set('security.username.max', 15)
  622. ->set('security.ban.username', '创始人,管理员,版主,斑竹,admin')
  623. ->set('security.username.min', 3)
  624. ->set('security.password.max', 15)
  625. ->set('security.password.min', 6)
  626. ->flush();
  627. $windidConfig = new WindidConfigSet('reg');
  628. $windidConfig->set('security.ban.username', '创始人,管理员,版主,斑竹,admin')
  629. ->set('security.password.max', 15)
  630. ->set('security.password.min', 6)
  631. ->set('security.username.max', 15)
  632. ->set('security.username.min', 3)
  633. ->flush();
  634. //TODO 结束
  635. if ($uid instanceof PwError) {
  636. $this->showError($uid->getError());
  637. }
  638. //特殊操作 gao.wanggao
  639. $this->_defaultAvatar($uid);
  640. $this->_defaultAvatar(0);
  641. //特殊操作
  642. //Wekit::load('user.srv.PwUserService')->restoreDefualtAvatar($uid);//用户的默认头像需要设置
  643. //Wekit::load('user.srv.PwUserService')->restoreDefualtAvatar(0);//游客的默认头像需要设置
  644. //站点统计信息
  645. Wind::import('SRV:site.dm.PwBbsinfoDm');
  646. $dm = new PwBbsinfoDm();
  647. $dm->setNewmember($manager)->addTotalmember(1);
  648. Wekit::load('site.PwBbsinfo')->updateInfo($dm);
  649. return $uid;
  650. }
  651. private function _defaultAvatar($uid, $type = 'face') {
  652. Wind::import('LIB:upload.PwUpload');
  653. $_avatar = array('.jpg' => '_big.jpg', '_middle.jpg' => '_middle.jpg', '_small.jpg' => '_small.jpg');
  654. $defaultBanDir = Wind::getRealDir('ROOT:') . 'res/images/face/';
  655. $fileDir = 'avatar/' . Pw::getUserDir($uid) . '/';
  656. $attachPath = Wind::getRealDir('ROOT:') . 'windid/attachment/';
  657. foreach ($_avatar as $des => $org) {
  658. $toPath = $attachPath . $fileDir . $uid . $des;
  659. $fromPath = $defaultBanDir . $type . $org;
  660. PwUpload::createFolder(dirname($toPath));
  661. PwUpload::copyFile($fromPath, $toPath);
  662. }
  663. return true;
  664. }
  665. private function _writeWindid() {
  666. $baseUrl = Wekit::url()->base;
  667. $key = md5(WindUtility::generateRandStr(10));
  668. $charset = Wekit::V('charset');
  669. $charset = str_replace('-', '', strtolower($charset));
  670. if (!in_array($charset, array('gbk', 'utf8', 'big5'))) $charset = 'utf8';
  671. $config = new PwConfigSet('windid');
  672. $config->set('windid', 'local')
  673. ->set('serverUrl', $baseUrl . '/windid')
  674. ->set('clientId', 1)
  675. ->set('clientKey', $key)
  676. ->set('connect', 'db')->flush();
  677. Wekit::C()->reload('windid');
  678. Wind::import('WINDID:service.app.dm.WindidAppDm');
  679. $dm = new WindidAppDm();
  680. $dm->setApiFile('windid.php')
  681. ->setIsNotify('1')
  682. ->setIsSyn('1')
  683. ->setAppName('phpwind9.0')
  684. ->setSecretkey($key)
  685. ->setAppUrl($baseUrl)
  686. ->setCharset($charset)
  687. ->setAppIp('');
  688. $result = WindidApi::api('app')->addApp($dm);
  689. if ($result instanceof WindidError) $this->showError('INSTALL:windid.init.fail');
  690. WindidApi::api('avatar')->setStorages('local');
  691. Wekit::load('config.PwConfig')->setConfig('site', 'avatarUrl', $baseUrl . '/windid/attachment');
  692. Wind::import('WINDID:service.config.srv.WindidConfigSet');
  693. $windidConfig = new WindidConfigSet('site');
  694. $windidConfig->set('avatarUrl', $baseUrl . '/windid/attachment')->flush();
  695. return true;
  696. }
  697. /**
  698. * 检查目录
  699. *
  700. * @return array
  701. */
  702. private function _checkDatabase() {
  703. if (!WindFile::isFile($this->_getDatabaseFile()) || !WindFile::isFile($this->_getTableSqlFile())) {
  704. $this->showError('INSTALL:database_config_noexists');
  705. }
  706. if (!$this->_checkWriteAble($this->_getDatabaseFile())) {
  707. $this->showError('INSTALL:error_777_database');
  708. }
  709. if (!$this->_checkWriteAble($this->_getFounderFile())) {
  710. $this->showError('INSTALL:error_777_founder');
  711. }
  712. /*if (!$this->_checkWriteAble($this->_getWindidFile())) {
  713. $this->showError('INSTALL:error_777_windid');
  714. }*/
  715. $database = include $this->_getTempFile();
  716. if (!$database['founder']) {
  717. $this->showError('INSTALL:database_config_error');
  718. }
  719. return $database;
  720. }
  721. private function _getDemoThreads() {
  722. $data = include Wind::getRealPath("APPS:install.lang.demo_threads");
  723. return $data;
  724. }
  725. /*private function _getWindidFile() {
  726. return Wind::getRealPath('ROOT:conf.windidconfig.php', true);
  727. }*/
  728. private function _getFounderFile() {
  729. return Wind::getRealPath('ROOT:conf.founder.php', true);
  730. }
  731. private function _getInstallLockFile() {
  732. return Wind::getRealPath('DATA:install.lock', true);
  733. }
  734. private function _getTableSqlFile() {
  735. return Wind::getRealPath('DATA:tmp.install.sql', true);
  736. }
  737. private function _getTableLogFile() {
  738. return Wind::getRealPath('DATA:tmp.install.log', true);
  739. }
  740. private function _getTempFile() {
  741. return Wind::getRealPath('DATA:tmp.database.php', true);
  742. }
  743. private function _getDatabaseFile() {
  744. return Wind::getRealPath('ROOT:conf.database.php', true);
  745. }
  746. }