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

/baser/controllers/installations_controller.php

https://github.com/hashing/basercms
PHP | 1057 lines | 633 code | 129 blank | 295 comment | 125 complexity | 347c4a6dc2da74f7bea45d1c0ef3b7ee MD5 | raw file
Possible License(s): MIT
  1. <?php
  2. /* SVN FILE: $Id$ */
  3. /**
  4. * インストーラーコントローラー
  5. *
  6. * PHP versions 5
  7. *
  8. * baserCMS : Based Website Development Project <http://basercms.net>
  9. * Copyright 2008 - 2012, baserCMS Users Community <http://sites.google.com/site/baserusers/>
  10. *
  11. * @copyright Copyright 2008 - 2012, baserCMS Users Community
  12. * @link http://basercms.net baserCMS Project
  13. * @package cake
  14. * @subpackage cake.app.controllers
  15. * @since baserCMS v 0.1.0
  16. * @version $Revision$
  17. * @modifiedby $LastChangedBy$
  18. * @lastmodified $Date$
  19. * @license http://basercms.net/license/index.html
  20. */
  21. /**
  22. * Include files
  23. */
  24. /**
  25. * インストール条件
  26. *
  27. * @global string PHP_MINIMUM_VERSION
  28. * @global integer PHP_MINIMUM_MEMORY_LIMIT in MB
  29. */
  30. define("PHP_MINIMUM_VERSION","4.3.0");
  31. define("PHP_MINIMUM_MEMORY_LIMIT", 16);
  32. /**
  33. * インストーラーコントローラー
  34. */
  35. class InstallationsController extends AppController {
  36. /**
  37. * クラス名
  38. *
  39. * @var string
  40. * @access public
  41. */
  42. var $name = 'Installations';
  43. /**
  44. * コンポーネント
  45. *
  46. * @var array
  47. * @access public
  48. */
  49. var $components = array('Session', 'BcEmail', 'BcManager');
  50. /**
  51. * レイアウトパス
  52. *
  53. * @var string
  54. * @access public
  55. */
  56. var $layoutPath = 'admin';
  57. /**
  58. * サブフォルダ
  59. *
  60. * @var string
  61. * @access public
  62. */
  63. var $subDir = 'admin';
  64. /**
  65. * ヘルパー
  66. *
  67. * @var array
  68. * @access public
  69. */
  70. var $helpers = array(BC_HTML_HELPER, BC_FORM_HELPER, 'Javascript', BC_TIME_HELPER);
  71. /**
  72. * モデル
  73. *
  74. * @var array
  75. * @access public
  76. */
  77. var $uses = null;
  78. /**
  79. * データベースエラーハンドラ
  80. *
  81. * @param int $errno
  82. * @param string $errstr
  83. * @param string $errfile
  84. * @param int $errline
  85. * @param string $errcontext
  86. * @return void
  87. * @access public
  88. */
  89. function dbErrorHandler( $errno, $errstr, $errfile=null, $errline=null, $errcontext=null ) {
  90. if ($errno==2) {
  91. $this->Session->setFlash("データベースへの接続でエラーが発生しました。データベース設定を見直してください。<br />".$errstr);
  92. restore_error_handler();
  93. }
  94. }
  95. /**
  96. * beforeFilter
  97. *
  98. * @return void
  99. * @access public
  100. */
  101. function beforeFilter() {
  102. parent::beforeFilter();
  103. /* インストール状態判別 */
  104. if(file_exists(CONFIGS.'database.php')) {
  105. $db = ConnectionManager::getInstance();
  106. if($db->config->baser['driver'] != '') {
  107. $installed = 'complete';
  108. }else {
  109. $installed = 'half';
  110. }
  111. }else {
  112. $installed = 'yet';
  113. }
  114. switch ($this->action) {
  115. case 'alert':
  116. break;
  117. case 'reset':
  118. if(Configure::read('debug') != -1) {
  119. $this->notFound();
  120. }
  121. break;
  122. default:
  123. if($installed == 'complete') {
  124. if($this->action != 'step5') {
  125. $this->notFound();
  126. }
  127. }else {
  128. if(Configure::read('debug') == 0) {
  129. $this->redirect(array('action'=>'alert'));
  130. }
  131. }
  132. break;
  133. }
  134. if (strpos($this->webroot, 'webroot') === false) {
  135. $this->webroot = DS;
  136. }
  137. $this->theme = null;
  138. $this->Security->validatePost = false;
  139. }
  140. /**
  141. * Step 1: ウェルカムページ
  142. *
  143. * @return void
  144. * @access public
  145. */
  146. function index() {
  147. $this->pageTitle = 'baserCMSのインストール';
  148. // 一時ファイルを削除する(再インストール用)
  149. if(is_writable(TMP)) {
  150. $folder = new Folder(TMP);
  151. $files = $folder->read(true, true, true);
  152. if(isset($files[0])) {
  153. foreach($files[0] as $file) {
  154. $folder->delete($file);
  155. }
  156. }
  157. if(isset($files[1])) {
  158. foreach($files[1] as $file) {
  159. if(basename($file) != 'empty') {
  160. $folder->delete($file);
  161. }
  162. }
  163. }
  164. }
  165. }
  166. /**
  167. * Step 2: 必須条件チェック
  168. *
  169. * @return void
  170. * @access public
  171. */
  172. function step2() {
  173. if($this->data && $this->data['clicked']=='next'){
  174. $this->redirect('step3');
  175. }
  176. // PHPバージョンチェック
  177. $phpVersionOk= version_compare ( preg_replace('/[a-z-]/','', phpversion()),PHP_MINIMUM_VERSION,'>=');
  178. // PHP memory limit チェック
  179. $phpCurrentMemoryLimit = intval(ini_get('memory_limit'));
  180. $phpMemoryOk = ((($phpCurrentMemoryLimit >= PHP_MINIMUM_MEMORY_LIMIT) || $phpCurrentMemoryLimit == -1) === TRUE);
  181. // セーフモード
  182. $safeModeOff = !ini_get('safe_mode');
  183. // configs 書き込み権限
  184. $configDirWritable = is_writable(CONFIGS);
  185. // core.phpの書き込み権限
  186. $coreFileWritable = is_writable(CONFIGS.'core.php');
  187. // DEMO用のページディレクトリの書き込み権限
  188. $themeDirWritable = is_writable(WWW_ROOT.'themed');
  189. // 一時フォルダの書き込み権限
  190. $tmpDirWritable = is_writable(TMP);
  191. // SQLiteディレクトリ書き込み権限
  192. $dbDirWritable = is_writable(APP.'db');
  193. /* ダミーのデータベース設定ファイルを保存 */
  194. $this->_writeDatabaseConfig();
  195. /* viewに変数をセット */
  196. $this->set('phpVersionOk', $phpVersionOk);
  197. $this->set('phpActualVersion', preg_replace('/[a-z-]/','', phpversion()));
  198. $this->set('phpMinimumVersion', PHP_MINIMUM_VERSION);
  199. $this->set('phpMinimumMemoryLimit', PHP_MINIMUM_MEMORY_LIMIT);
  200. $this->set('phpCurrentMemoryLimit', $phpCurrentMemoryLimit);
  201. $this->set('phpMemoryOk', $phpMemoryOk);
  202. $this->set('configDirWritable', $configDirWritable);
  203. $this->set('coreFileWritable',$coreFileWritable);
  204. $this->set('safeModeOff', $safeModeOff);
  205. $this->set('dbDirWritable',$dbDirWritable);
  206. $this->set('tmpDirWritable',$tmpDirWritable);
  207. $this->set('themeDirWritable',$themeDirWritable);
  208. $this->set('blRequirementsMet', ($tmpDirWritable && $configDirWritable && $coreFileWritable && $phpVersionOk && $themeDirWritable));
  209. $this->pageTitle = 'baserCMSのインストール [ステップ2]';
  210. }
  211. /**
  212. * Step 3: データベースの接続設定
  213. *
  214. * @return void
  215. * @access public
  216. */
  217. function step3() {
  218. if(!$this->data) {
  219. $this->data = $this->_getDefaultValuesStep3();
  220. } else {
  221. $this->_writeDbSettingToSession($this->data['Installation']);
  222. /* 戻るボタンクリック時 */
  223. if ($this->data['buttonclicked']=='back') {
  224. $this->redirect('step2');
  225. /* 接続テスト */
  226. } elseif ($this->data['buttonclicked']=='checkdb') {
  227. $this->set('blDBSettingsOK',$this->_testConnectDb($this->_readDbSettingFromSession()));
  228. /* 「次のステップへ」クリック時 */
  229. } elseif ($this->data['buttonclicked']=='createdb') {
  230. ini_set("max_execution_time",180);
  231. $nonDemoData = false;
  232. if(isset($this->data['Installation']['non_demo_data'])) {
  233. $nonDemoData = $this->data['Installation']['non_demo_data'];
  234. }
  235. $this->deleteAllTables();
  236. if($this->_constructionDb($nonDemoData)) {
  237. $this->Session->setFlash("データベースの構築に成功しました。");
  238. $this->redirect('step4');
  239. }else {
  240. $db =& ConnectionManager::getDataSource('baser');
  241. $this->Session->setFlash("データベースの構築中にエラーが発生しました。<br />".$db->error);
  242. }
  243. }
  244. }
  245. $this->pageTitle = 'baserCMSのインストール [ステップ3]';
  246. $this->set('dbsource', $this->_getDbSource());
  247. }
  248. /**
  249. * Step 4: データベース生成/管理者ユーザー作成
  250. *
  251. * @return void
  252. * @access public
  253. */
  254. function step4() {
  255. if(!$this->data) {
  256. $this->data = $this->_getDefaultValuesStep4();
  257. } else {
  258. // ユーザー情報をセッションに保存
  259. $this->Session->write('Installation.admin_email', $this->data['Installation']['admin_email']);
  260. $this->Session->write('Installation.admin_username', $this->data['Installation']['admin_username']);
  261. $this->Session->write('Installation.admin_password', $this->data['Installation']['admin_password']);
  262. if($this->data['clicked'] == 'back') {
  263. $this->redirect('step3');
  264. } elseif($this->data['clicked'] == 'finish') {
  265. // DB接続
  266. $db =& $this->_connectDb($this->_readDbSettingFromSession());
  267. // サイト基本設定登録
  268. App::import('Model','SiteConfig');
  269. $siteConfig['SiteConfig']['email'] = $this->data['Installation']['admin_email'];
  270. $SiteConfigClass = new SiteConfig();
  271. $SiteConfigClass->saveKeyValue($siteConfig);
  272. // 管理ユーザー登録
  273. $salt = $this->_createKey(40);
  274. Configure::write('Security.salt',$salt);
  275. $this->Session->write('Installation.salt',$salt);
  276. App::import('Model','User');
  277. $user = array();
  278. $user['User']['name'] = $this->data['Installation']['admin_username'];
  279. $user['User']['real_name_1'] = $this->data['Installation']['admin_username'];
  280. $user['User']['email'] = $this->data['Installation']['admin_email'];
  281. $user['User']['user_group_id'] = 1;
  282. $user['User']['password_1'] = $this->data['Installation']['admin_password'];
  283. $user['User']['password_2'] = $this->data['Installation']['admin_confirmpassword'];
  284. $user['User']['password'] = $user['User']['password_1'];
  285. $User = new User();
  286. $User->create($user);
  287. if ($User->validates()) {
  288. $user['User']['password'] = Security::hash($this->data['Installation']['admin_password'],null,true);
  289. $User->save($user,false);
  290. $this->_sendCompleteMail($user['User']['email'], $user['User']['name'], $this->data['Installation']['admin_password']);
  291. $this->redirect('step5');
  292. } else {
  293. $message = '管理ユーザーを作成できませんでした。<br />'.$db->error;
  294. $this->Session->setFlash($message);
  295. }
  296. }
  297. }
  298. $this->pageTitle = 'baserCMSのインストール [ステップ4]';
  299. }
  300. /**
  301. * インストール完了メールを送信する
  302. *
  303. * @param string $email
  304. * @param string $name
  305. * @param string $password
  306. * @return void
  307. * @access protected
  308. */
  309. function _sendCompleteMail($email, $name, $password) {
  310. $body = array('name'=>$name, 'password'=>$password, 'siteUrl' => siteUrl());
  311. $this->sendMail($email, 'baserCMSインストール完了', $body, array('template'=>'installed', 'from'=>$email));
  312. }
  313. /**
  314. * Step 5: 設定ファイルの生成
  315. * データベース設定ファイル[database.php]
  316. * インストールファイル[install.php]
  317. *
  318. * @return void
  319. * @access public
  320. */
  321. function step5() {
  322. $this->pageTitle = 'baserCMSのインストール完了!';
  323. if(!BC_INSTALLED) {
  324. $installationData = $this->Session->read('Installation');
  325. $installationData['lastStep'] = true;
  326. checkTmpFolders();
  327. Configure::write('Cache.disable', false);
  328. Cache::config('default', array('engine' => 'File'));
  329. // インストールファイルでセッションの保存方法を切り替える為、インストール情報をキャッシュに保存
  330. Cache::write('Installation', $installationData, 'default');
  331. // データベース設定を書き込む
  332. $this->_writeDatabaseConfig($this->_readDbSettingFromSession());
  333. // インストールファイルを生成する
  334. $this->_createInstallFile();
  335. $this->redirect('step5');
  336. } elseif(BC_INSTALLED) {
  337. $installationData = Cache::read('Installation', 'default');
  338. if(empty($installationData['lastStep'])) {
  339. return;
  340. }
  341. }
  342. // ブログの投稿日を更新
  343. $this->_updateEntryDate();
  344. // プラグインのステータスを更新
  345. $this->_updatePluginStatus();
  346. // ログイン
  347. $this->_login();
  348. // テーマを配置する
  349. $this->BcManager->deployTheme();
  350. $this->BcManager->deployTheme('skelton');
  351. // pagesファイルを生成する
  352. $this->_createPages();
  353. ClassRegistry::removeObject('View');
  354. $this->Session->delete('InstallLastStep');
  355. }
  356. /**
  357. * インストールファイルを生成する
  358. *
  359. * @return boolean
  360. * @access protected
  361. */
  362. function _createInstallFile() {
  363. $corefilename=CONFIGS.'install.php';
  364. $siteUrl = siteUrl();
  365. $installCoreData = array("<?php",
  366. "Configure::write('Security.salt', '".$this->Session->read('Installation.salt')."');",
  367. "Configure::write('Cache.disable', false);",
  368. "Configure::write('Session.save', 'cake');",
  369. "Configure::write('BcEnv.siteUrl', '{$siteUrl}');",
  370. "Configure::write('BcEnv.sslUrl', '');",
  371. "Configure::write('BcApp.adminSsl', false);",
  372. "Configure::write('BcApp.mobile', true);",
  373. "Configure::write('BcApp.smartphone', true);",
  374. "Cache::config('default', array('engine' => 'File'));",
  375. "Configure::write('debug', 0);",
  376. "?>");
  377. if(file_put_contents($corefilename, implode("\n", $installCoreData))) {
  378. return chmod($corefilename,0666);
  379. }else {
  380. return false;
  381. }
  382. }
  383. /**
  384. * プラグインのステータスを更新する
  385. *
  386. * @return boolean
  387. * @access protected
  388. */
  389. function _updatePluginStatus() {
  390. $this->_connectDb($this->_readDbSettingFromSession());
  391. $version = $this->getBaserVersion();
  392. App::import('Model', 'Plugin');
  393. $Plugin = new Plugin();
  394. $datas = $Plugin->find('all');
  395. if($datas){
  396. $result = true;
  397. foreach($datas as $data) {
  398. $data['Plugin']['version'] = $version;
  399. $data['Plugin']['status'] = true;
  400. if(!$Plugin->save($data)) {
  401. $result = false;
  402. }
  403. }
  404. return $result;
  405. } else {
  406. return false;
  407. }
  408. }
  409. /**
  410. * 登録日を更新する
  411. *
  412. * @return boolean
  413. * @access protected
  414. */
  415. function _updateEntryDate() {
  416. $db =& $this->_connectDb($this->_readDbSettingFromSession());
  417. $db =& $this->_connectDb($this->_readDbSettingFromSession(),'plugin');
  418. App::import('Model', 'Blog.BlogPost');
  419. $BlogPost = new BlogPost();
  420. $blogPosts = $BlogPost->find('all');
  421. if($blogPosts) {
  422. $ret = true;
  423. foreach($blogPosts as $blogPost) {
  424. $blogPost['BlogPost']['posts_date'] = date('Y-m-d H:i:s');
  425. if(!$BlogPost->save($blogPost)) {
  426. $ret = false;
  427. }
  428. }
  429. return $ret;
  430. } else {
  431. return false;
  432. }
  433. }
  434. /**
  435. * 管理画面にログインする
  436. *
  437. * @return void
  438. * @access protected
  439. */
  440. function _login() {
  441. $extra = array();
  442. // ログインするとセッションが初期化されてしまうので一旦取得しておく
  443. $installationSetting = Cache::read('Installation', 'default');
  444. Cache::delete('Installation', 'default');
  445. Configure::write('Security.salt', $installationSetting['salt']);
  446. $extra['data']['User']['name'] = $installationSetting['admin_username'];
  447. $extra['data']['User']['password'] = $installationSetting['admin_password'];
  448. $this->requestAction(array('admin' => true, 'controller' => 'users', 'action' => 'login_exec'), $extra);
  449. $this->Session->write('Installation', $installationSetting);
  450. }
  451. /**
  452. * テーマ用のページファイルを生成する
  453. *
  454. * @access protected
  455. */
  456. function _createPages() {
  457. App::import('Model','Page');
  458. $Page = new Page(null, null, 'baser');
  459. $pages = $Page->find('all', array('recursive' => -1));
  460. if($pages) {
  461. foreach($pages as $page) {
  462. $Page->data = $page;
  463. $Page->afterSave(true);
  464. }
  465. }
  466. }
  467. /**
  468. * データベースに接続する
  469. *
  470. * @param array $config
  471. * @return DboSource $db
  472. * @access public
  473. */
  474. function &_connectDb($config, $name='baser') {
  475. if($name == 'plugin') {
  476. $config['prefix'].=Configure::read('BcEnv.pluginDbPrefix');
  477. }
  478. $result = ConnectionManager::create($name ,array(
  479. 'driver' => $config['driver'],
  480. 'persistent' => false,
  481. 'host' => $config['host'],
  482. 'port' => $config['port'],
  483. 'login' => $config['login'],
  484. 'password' => $config['password'],
  485. 'database' => $config['database'],
  486. 'schema' => $config['schema'],
  487. 'prefix' => $config['prefix'],
  488. 'encoding' => $config['encoding']));
  489. if($result) {
  490. return $result;
  491. } else {
  492. return ConnectionManager::getDataSource($name);
  493. }
  494. }
  495. /**
  496. * データベースを構築する
  497. *
  498. * @param type $nonDemoData
  499. * @return boolean
  500. * @access protected
  501. */
  502. function _constructionDb($nonDemoData = false) {
  503. $dbConfig = $this->_readDbSettingFromSession();
  504. if(!$this->BcManager->constructionTable(BASER_CONFIGS.'sql', 'baser', $dbConfig, $nonDemoData)) {
  505. return false;
  506. }
  507. $dbConfig['prefix'].=Configure::read('BcEnv.pluginDbPrefix');
  508. if(!$this->BcManager->constructionTable(BASER_PLUGINS.'blog'.DS.'config'.DS.'sql', 'plugin', $dbConfig, $nonDemoData)) {
  509. return false;
  510. }
  511. if(!$this->BcManager->constructionTable(BASER_PLUGINS.'feed'.DS.'config'.DS.'sql', 'plugin', $dbConfig, $nonDemoData)) {
  512. return false;
  513. }
  514. if(!$this->BcManager->constructionTable(BASER_PLUGINS.'mail'.DS.'config'.DS.'sql', 'plugin', $dbConfig, $nonDemoData)) {
  515. return false;
  516. }
  517. return true;
  518. }
  519. /**
  520. * ステップ3用のフォーム初期値を取得する
  521. *
  522. * @return array
  523. * @access protected
  524. */
  525. function _getDefaultValuesStep3() {
  526. $data = array();
  527. if( $this->Session->read('Installation.dbType') ){
  528. $_data = $this->_readDbSettingFromSession();
  529. $data['Installation']['dbType'] = $_data['driver'];
  530. $data['Installation']['dbHost'] = $_data['host'];
  531. $data['Installation']['dbPort'] = $_data['port'];
  532. $data['Installation']['dbPrefix'] = $_data['prefix'];
  533. $_data['database'] = basename($_data['database']);
  534. $_data['database'] = str_replace(array('.csv', '.db'), '', $_data['database']);
  535. $_data['database'] = basename($_data['database']);
  536. $data['Installation']['dbName'] = $_data['database'];
  537. $data['Installation']['dbUsername'] = $_data['login'];
  538. $data['Installation']['dbPassword'] = $_data['password'];
  539. } else {
  540. $data['Installation']['dbType'] = 'mysql';
  541. $data['Installation']['dbHost'] = 'localhost';
  542. $data['Installation']['dbPort'] = '3306';
  543. $data['Installation']['dbPrefix'] = 'bc_';
  544. $data['Installation']['dbName'] = 'basercms';
  545. }
  546. return $data;
  547. }
  548. /**
  549. * ステップ4用のフォーム初期値を取得する
  550. *
  551. * @return array
  552. * @access protected
  553. */
  554. function _getDefaultValuesStep4() {
  555. $data = array();
  556. if ( $this->Session->read('Installation.admin_username') ) {
  557. $data['Installation']['admin_username'] = $this->Session->read('Installation.admin_username');
  558. } else {
  559. $data['Installation']['admin_username'] = 'admin';
  560. }
  561. if ( $this->Session->read('Installation.admin_password') ) {
  562. $data['Installation']['admin_password'] = $this->Session->read('Installation.admin_password');
  563. $data['Installation']['admin_confirmpassword'] = $data['Installation']['admin_password'];
  564. } else {
  565. $data['Installation']['admin_password'] = '';
  566. }
  567. if ( $this->Session->read('Installation.admin_email') ) {
  568. $data['Installation']['admin_email'] = $this->Session->read('Installation.admin_email');
  569. } else {
  570. $data['Installation']['admin_email'] = '';
  571. }
  572. return $data;
  573. }
  574. /**
  575. * DB設定をセッションから取得
  576. *
  577. * @return array
  578. * @access protected
  579. */
  580. function _readDbSettingFromSession() {
  581. $data = array();
  582. $data['driver'] = $this->Session->read('Installation.dbType');
  583. $data['host'] = $this->Session->read('Installation.dbHost');
  584. $data['port'] = $this->Session->read('Installation.dbPort');
  585. $data['login'] = $this->Session->read('Installation.dbUsername');
  586. $data['password'] = $this->Session->read('Installation.dbPassword');
  587. $data['prefix'] = $this->Session->read('Installation.dbPrefix');
  588. $data['database'] = $this->_getRealDbName($data['driver'], $this->Session->read('Installation.dbName'));
  589. $data['schema'] = $this->Session->read('Installation.dbSchema');
  590. $data['encoding'] = $this->Session->read('Installation.dbEncoding');
  591. $data['persistent'] = false;
  592. return $data;
  593. }
  594. /**
  595. * 実際の設定用のDB名を取得する
  596. *
  597. * @param string $type
  598. * @param string $name
  599. * @return string
  600. * @access protected
  601. */
  602. function _getRealDbName($type, $name) {
  603. /* dbName */
  604. if(!empty($type) && !empty($name)) {
  605. $type = preg_replace('/^bc_/', '', $type);
  606. if($type == 'sqlite3') {
  607. return APP.'db'.DS.'sqlite'.DS.$name.'.db';
  608. }elseif($type == 'csv') {
  609. return APP.'db'.DS.'csv'.DS.$name;
  610. }
  611. }
  612. return $name;
  613. }
  614. /**
  615. * DB設定をセッションに保存
  616. *
  617. * @param array $data
  618. * @return void
  619. * @access protected
  620. */
  621. function _writeDbSettingToSession($data) {
  622. /* dbEncoding */
  623. $data['dbEncoding'] = 'utf8';
  624. /* dbSchema */
  625. if($data['dbType'] == 'postgres') {
  626. $data['dbSchema'] = 'public'; // TODO とりあえずpublic固定
  627. }else {
  628. $data['dbSchema'] = '';
  629. }
  630. if($data['dbType'] == 'csv') {
  631. $data['dbEncoding'] = 'sjis';
  632. }
  633. $data['dbType'] = 'bc_'.$data['dbType'];
  634. $this->Session->write('Installation.dbType', $data['dbType']);
  635. $this->Session->write('Installation.dbHost', $data['dbHost']);
  636. $this->Session->write('Installation.dbPort', $data['dbPort']);
  637. $this->Session->write('Installation.dbUsername', $data['dbUsername']);
  638. $this->Session->write('Installation.dbPassword', $data['dbPassword']);
  639. $this->Session->write('Installation.dbPrefix', $data['dbPrefix']);
  640. $this->Session->write('Installation.dbName', $data['dbName']);
  641. $this->Session->write('Installation.dbSchema',$data['dbSchema']);
  642. $this->Session->write('Installation.dbEncoding',$data['dbEncoding']);
  643. }
  644. /**
  645. * データベース接続テスト
  646. *
  647. * @param array $config
  648. * @return boolean
  649. * @access protected
  650. */
  651. function _testConnectDb($config){
  652. set_error_handler(array($this, "dbErrorHandler"));
  653. /* データベース接続生成 */
  654. $db =& $this->_connectDb($config);
  655. if ($db->connected) {
  656. /* 一時的にテーブルを作成できるかテスト */
  657. $randomtablename='deleteme'.rand(100,100000);
  658. $result = $db->execute("CREATE TABLE $randomtablename (a varchar(10))");
  659. if ($result) {
  660. $db->execute("drop TABLE $randomtablename");
  661. $this->Session->setFlash('データベースへの接続に成功しました。');
  662. return true;
  663. } else {
  664. $this->Session->setFlash("データベースへの接続でエラーが発生しました。<br />".$db->error);
  665. }
  666. } else {
  667. if (!$this->Session->read('Message.flash.message')) {
  668. if($db->connection){
  669. $this->Session->setFlash("データベースへの接続でエラーが発生しました。データベース設定を見直してください。<br />サーバー上に指定されたデータベースが存在しない可能性が高いです。");
  670. } else {
  671. $this->Session->setFlash("データベースへの接続でエラーが発生しました。データベース設定を見直してください。");
  672. }
  673. }
  674. }
  675. return false;
  676. }
  677. /**
  678. * データベース設定ファイル[database.php]を保存する
  679. *
  680. * @param array $options
  681. * @return boolean
  682. * @access private
  683. */
  684. function _writeDatabaseConfig($options = array()) {
  685. if(!is_writable(CONFIGS)) {
  686. return false;
  687. }
  688. extract($options);
  689. if(!isset($driver)) {
  690. $driver = '';
  691. }
  692. if(!isset($host)) {
  693. $host = 'localhost';
  694. }
  695. if(!isset($port)) {
  696. $port = '';
  697. }
  698. if(!isset($login)) {
  699. $login = 'dummy';
  700. }
  701. if(!isset($password)) {
  702. $password = 'dummy';
  703. }
  704. if(!isset($database)) {
  705. $database = 'dummy';
  706. }
  707. if(!isset($prefix)) {
  708. $prefix = '';
  709. }
  710. if(!isset($schema)) {
  711. $schema = '';
  712. }
  713. if(!isset($encoding)) {
  714. $encoding = 'utf8';
  715. }
  716. App::import('File');
  717. $dbfilename=CONFIGS.'database.php';
  718. $dbfilehandler = & new File($dbfilename);
  719. if ($dbfilehandler!==false) {
  720. if ($dbfilehandler->exists()) {
  721. $dbfilehandler->delete();
  722. }
  723. if($driver == 'mysql' || $driver == 'sqlite3' || $driver == 'postgres') {
  724. $driver = 'bc_'.$driver;
  725. }
  726. $dbfilehandler->create();
  727. $dbfilehandler->open('w',true);
  728. $dbfilehandler->write("<?php\n");
  729. $dbfilehandler->write("//\n");
  730. $dbfilehandler->write("// Database Configuration File created by baserCMS Installation\n");
  731. $dbfilehandler->write("//\n");
  732. $dbfilehandler->write("class DATABASE_CONFIG {\n");
  733. $dbfilehandler->write('var $baser = array('."\n");
  734. $dbfilehandler->write("\t'driver' => '".$driver."',\n");
  735. $dbfilehandler->write("\t'persistent' => false,\n");
  736. $dbfilehandler->write("\t'host' => '".$host."',\n");
  737. $dbfilehandler->write("\t'port' => '".$port."',\n");
  738. $dbfilehandler->write("\t'login' => '".$login."',\n");
  739. $dbfilehandler->write("\t'password' => '".$password."',\n");
  740. $dbfilehandler->write("\t'database' => '".$database."',\n");
  741. $dbfilehandler->write("\t'schema' => '".$schema."',\n");
  742. $dbfilehandler->write("\t'prefix' => '".$prefix."',\n");
  743. $dbfilehandler->write("\t'encoding' => '".$encoding."'\n");
  744. $dbfilehandler->write(");\n");
  745. $dbfilehandler->write('var $plugin = array('."\n");
  746. $dbfilehandler->write("\t'driver' => '".$driver."',\n");
  747. $dbfilehandler->write("\t'persistent' => false,\n");
  748. $dbfilehandler->write("\t'host' => '".$host."',\n");
  749. $dbfilehandler->write("\t'port' => '".$port."',\n");
  750. $dbfilehandler->write("\t'login' => '".$login."',\n");
  751. $dbfilehandler->write("\t'password' => '".$password."',\n");
  752. $dbfilehandler->write("\t'database' => '".$database."',\n");
  753. $dbfilehandler->write("\t'schema' => '".$schema."',\n");
  754. $dbfilehandler->write("\t'prefix' => '".$prefix.Configure::read('BcEnv.pluginDbPrefix')."',\n");
  755. $dbfilehandler->write("\t'encoding' => '".$encoding."'\n");
  756. $dbfilehandler->write(");\n");
  757. $dbfilehandler->write("}\n");
  758. $dbfilehandler->write("?>\n");
  759. $dbfilehandler->close();
  760. return true;
  761. } else {
  762. return false;
  763. }
  764. }
  765. /**
  766. * 利用可能なデータソースを取得する
  767. *
  768. * @return array
  769. * @access protected
  770. */
  771. function _getDbSource() {
  772. /* DBソース取得 */
  773. $dbsource = array();
  774. $folder = new Folder();
  775. /* MySQL利用可否 */
  776. if(function_exists('mysql_connect')) {
  777. $dbsource['mysql'] = 'MySQL';
  778. }
  779. /* PostgreSQL利用可否 */
  780. if(function_exists('pg_connect')) {
  781. $dbsource['postgres'] = 'PostgreSQL';
  782. }
  783. /* SQLite利用可否チェック */
  784. if(class_exists('PDO') && version_compare ( preg_replace('/[a-z-]/','', phpversion()),'5','>=')) {
  785. $pdoDrivers = PDO::getAvailableDrivers();
  786. if(in_array('sqlite',$pdoDrivers)) {
  787. $dbFolderPath = APP.'db'.DS.'sqlite';
  788. if($folder->create($dbFolderPath, 0777) && is_writable($dbFolderPath)){
  789. $dbsource['sqlite3'] = 'SQLite3';
  790. }
  791. }else {
  792. // TODO SQLite2 実装
  793. // AlTER TABLE できないので、実装には、テーブル構造の解析が必要になる。
  794. // 一度一時テーブルを作成し、データを移動させた上で、DROP。
  795. // 新しい状態のテーブルを作成し、一時テーブルよりデータを移行。
  796. // その後、一時テーブルを削除する必要がある。
  797. // 【参考】http://seclan.dll.jp/dtdiary/2007/dt20070228.htm
  798. // プラグインコンテンツのアカウント変更時、メールフォームのフィールド変更時の処理を実装する必要あり
  799. //$dbsource['sqlite'] = 'SQLite';
  800. }
  801. }
  802. /* CSV利用可否 */
  803. $dbFolderPath = APP.'db'.DS.'csv';
  804. if($folder->create($dbFolderPath, 0777) && is_writable($dbFolderPath)){
  805. $dbsource['csv'] = 'CSV';
  806. }
  807. return $dbsource;
  808. }
  809. /**
  810. * セキュリティ用のキーを生成する
  811. *
  812. * @param int $length
  813. * @return string キー
  814. * @access protected
  815. */
  816. function _createKey($length) {
  817. $keyset = "abcdefghijklmABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  818. $randkey = "";
  819. for ($i=0; $i<$length; $i++)
  820. $randkey .= substr($keyset, rand(0,strlen($keyset)-1), 1);
  821. return $randkey;
  822. }
  823. /**
  824. * インストール不能警告メッセージを表示
  825. *
  826. * @return void
  827. * @access public
  828. */
  829. function alert() {
  830. $this->pageTitle = 'baserCMSのインストールを開始できません';
  831. }
  832. /**
  833. * baserCMSを初期化する
  834. * debug フラグが -1 の場合のみ実行可能
  835. *
  836. * @return void
  837. * @access public
  838. */
  839. function reset() {
  840. $this->pageTitle = 'baserCMSの初期化';
  841. $this->layoutPath = 'admin';
  842. $this->layout = 'default';
  843. $this->subDir = 'admin';
  844. if(!empty($this->data['Installation']['reset'])) {
  845. $messages = array();
  846. $file = new File(CONFIGS.'core.php');
  847. $data = $file->read();
  848. $pattern = '/Configure\:\:write[\s]*\([\s]*\'App\.baseUrl\'[\s]*,[\s]*\'\'[\s]*\);\n/is';
  849. if(preg_match($pattern, $data)) {
  850. $data = preg_replace($pattern, "Configure::write('App.baseUrl', env('SCRIPT_NAME'));\n", $data);
  851. if(!$file->write($data)){
  852. $messages[] = 'スマートURLの設定を正常に初期化できませんでした。';
  853. }
  854. $file->close();
  855. }
  856. if(!$this->writeSmartUrl(false)){
  857. $messages[] = 'スマートURLの設定を正常に初期化できませんでした。';
  858. }
  859. $this->deleteAllTables();
  860. if(file_exists(CONFIGS.'database.php')) {
  861. // データベースのデータを削除
  862. unlink(CONFIGS.'database.php');
  863. }
  864. if(file_exists(CONFIGS.'install.php')) {
  865. unlink(CONFIGS.'install.php');
  866. }
  867. $themeFolder = new Folder(WWW_ROOT.'themed');
  868. $themeFiles = $themeFolder->read(true,true,true);
  869. foreach($themeFiles[0] as $theme){
  870. $pagesFolder = new Folder($theme.DS.'pages');
  871. $pathes = $pagesFolder->read(true,true,true);
  872. foreach($pathes[0] as $path){
  873. if(basename($path) != 'admin') {
  874. $folder = new Folder();
  875. $folder->delete($path);
  876. $folder = null;
  877. }
  878. }
  879. foreach($pathes[1] as $path){
  880. if(basename($path) != 'empty') {
  881. unlink($path);
  882. }
  883. }
  884. $pagesFolder = null;
  885. }
  886. $themeFolder = null;
  887. if($messages) {
  888. $messages[] = '手動でサーバー上より上記ファイルを削除して初期化を完了させてください。';
  889. }
  890. $messages = am(array('baserCMSを初期化しました。',''),$messages);
  891. $message = implode('<br />', $messages);
  892. ClassRegistry::flush();
  893. clearAllCache();
  894. $this->Session->setFlash($message);
  895. // アクション名で指定した場合、環境によっては正常にリダイレクトできないのでスマートURLオフのフルパスで記述
  896. $this->redirect('reset');
  897. $this->redirect('/index.php/installations/reset');
  898. } elseif(!BC_INSTALLED) {
  899. $complete = true;
  900. }else {
  901. $complete = false;
  902. }
  903. $this->set('complete', $complete);
  904. }
  905. /**
  906. * 全てのテーブルを削除する
  907. *
  908. * @return void
  909. * @access public
  910. */
  911. function deleteAllTables() {
  912. $baserConfig = $this->_readDbSettingFromSession();
  913. if(!$baserConfig) {
  914. $baserConfig = getDbConfig('baser');
  915. $pluginConfig = getDbConfig('plugin');
  916. } else {
  917. $pluginConfig = $baserConfig;
  918. $pluginConfig['prefix'] .= Configure::read('BcEnv.pluginDbPrefix');
  919. }
  920. if($baserConfig) {
  921. $this->BcManager->deleteTables('baser', $baserConfig);
  922. }
  923. if($pluginConfig) {
  924. $this->BcManager->deleteTables('plugin', $pluginConfig);
  925. }
  926. }
  927. }
  928. ?>