PageRenderTime 27ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/app/code/Ecart/Install/Model/Wizard.php

https://code.google.com/p/ecartcommerce/
PHP | 461 lines | 325 code | 41 blank | 95 comment | 17 complexity | 21ee88786b9199fc24880cf8970f4cab MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.1
  1. <?php
  2. /**
  3. * Ecart
  4. *
  5. * This file is part of Ecart.
  6. *
  7. * Ecart is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation, either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * Ecart is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with Ecart. If not, see <http://www.gnu.org/licenses/>.
  19. *
  20. * @category Ecart
  21. * @package Ecart_Install
  22. * @copyright Copyright 2008-2009 E-Cart LLC
  23. * @license GNU Public License V3.0
  24. */
  25. /**
  26. *
  27. * @category Ecart
  28. * @package Ecart_Install
  29. * @subpackage Model
  30. * @author Ecart Core Team <core@ecartcommerce.com>
  31. */
  32. class Ecart_Install_Model_Wizard
  33. {
  34. const STEP_LICENSE = 'license';
  35. const STEP_REQUIREMENTS = 'requirements';
  36. const STEP_LOCALIZATION = 'localization';
  37. const STEP_CONFIGURATION = 'configuration';
  38. const STEP_USER = 'user';
  39. const STEP_MODULES = 'modules';
  40. const STEP_FINISH = 'finish';
  41. private static $_instance;
  42. /**
  43. *
  44. * @var const array
  45. */
  46. private $_steps = array(
  47. 'license' => 'License agreements',
  48. 'requirements' => 'Server requirements',
  49. 'localization' => 'Localization',
  50. 'configuration' => 'Store configuration',
  51. 'user' => 'Setup admin account',
  52. 'modules' => 'Modules',
  53. 'finish' => 'All done'
  54. );
  55. /**
  56. *
  57. * @var Zend_Session_Namespace
  58. */
  59. private $_session;
  60. private function __construct()
  61. {
  62. $this->_session = Zend_Registry::get('session');
  63. if (!isset($this->_session->step)) {
  64. $this->_session->step = self::STEP_REQUIREMENTS;
  65. }
  66. }
  67. /**
  68. * Return instance of self
  69. *
  70. * @static
  71. * @return Ecart_Install_Model_Wizard
  72. */
  73. public static function getInstance()
  74. {
  75. if (null === self::$_instance) {
  76. self::$_instance = new self();
  77. }
  78. return self::$_instance;
  79. }
  80. /**
  81. *
  82. * @return const array
  83. */
  84. public function getSteps()
  85. {
  86. return $this->_steps;
  87. }
  88. public function getCurrent()
  89. {
  90. return $this->_session->step;
  91. }
  92. public function setStep($step)
  93. {
  94. $this->_session->step = $step;
  95. }
  96. /**
  97. * Return requirements
  98. *
  99. * @return array
  100. */
  101. public function checkRequirements()
  102. {
  103. $requirements = array(
  104. 'Server Capabilities' => array(
  105. 'php_version' => array(
  106. 'title' => 'PHP Version',
  107. 'expected' => '>= 5.2',
  108. 'value' => phpversion(),
  109. 'success' => phpversion() >= 5.2 ? true : false
  110. )
  111. ),
  112. 'PHP Settings' => array(
  113. 'magic_quotes' => array(
  114. 'title' => 'Magic quotes',
  115. 'expected' => 'Off'
  116. ),
  117. 'file_uploads' => array(
  118. 'title' => 'File uploads',
  119. 'expected' => 'On'
  120. ),
  121. 'session.auto_start' => array(
  122. 'title' => 'Session autostart',
  123. 'expected' => 'Off'
  124. ),
  125. 'session.use_trans_sid' => array(
  126. 'title' => 'Session use trans SID',
  127. 'expected' => 'Off'
  128. )
  129. ),
  130. 'PHP Extensions' => array(
  131. 'pdo_mysql' => array(
  132. 'title' => 'pdo_mysql',
  133. 'expected' => 'Loaded'
  134. ),
  135. 'gd' => array(
  136. 'title' => 'gd',
  137. 'expected' => 'Loaded'
  138. ),
  139. 'curl' => array(
  140. 'title' => 'curl',
  141. 'expected' => 'Loaded'
  142. ),
  143. 'mcrypt' => array(
  144. 'title' => 'MCrypt',
  145. 'expected' => 'Loaded'
  146. )
  147. ),
  148. 'File Permissions' => array(
  149. '../var' => array(
  150. 'title' => '/var',
  151. 'expected' => 'Writable'
  152. ),
  153. '../app/etc' => array(
  154. 'title' => '/app/etc',
  155. 'expected' => 'Writable'
  156. ),
  157. '../media' => array(
  158. 'title' => '/media',
  159. 'expected' => 'Writable'
  160. )
  161. )
  162. );
  163. foreach ($requirements['PHP Settings'] as $key => &$values) {
  164. $values['value'] = intval(ini_get($key)) === 1 ? 'On' : 'Off';
  165. $values['success'] = $values['value'] === $values['expected'] ? true : false;
  166. }
  167. foreach ($requirements['PHP Extensions'] as $key => &$values) {
  168. $values['value'] = extension_loaded($key) ? 'Loaded' : 'Not Loaded';
  169. $values['success'] = $values['value'] === $values['expected'] ? true : false;
  170. }
  171. foreach ($requirements['File Permissions'] as $key => &$values) {
  172. $values['value'] = is_writable($key) ? 'Writable' : 'Not Writable';
  173. $values['success'] = $values['value'] === $values['expected'] ? true : false;
  174. }
  175. return $requirements;
  176. }
  177. /**
  178. * Checks, database connection
  179. *
  180. * @return Ecart_Install_Model_Wizard Provides fluent interface
  181. * @throws Ecart_Exception
  182. */
  183. public function checkConnection()
  184. {
  185. $conn = @mysql_connect(
  186. $this->_session->db_host,
  187. $this->_session->db_username,
  188. $this->_session->db_password
  189. );
  190. if (!$conn) {
  191. throw new Ecart_Exception(__(
  192. "Can't connect to database. Check server name, username or user password"
  193. ));
  194. }
  195. if (!mysql_select_db($this->_session->db_dbname, $conn)) {
  196. throw new Ecart_Exception(__(
  197. "Can't select this database, check database name"
  198. ));
  199. }
  200. return $this;
  201. }
  202. /**
  203. *
  204. * @param int $minlength [optional]
  205. * @param int $maxlength [optional]
  206. * @param bool $useupper [optional]
  207. * @param bool $usespecial [optional]
  208. * @param bool $usenumbers [optional]
  209. * @return string
  210. */
  211. private function _generateKey(
  212. $minlength = 32,
  213. $maxlength = 64,
  214. $useupper = true,
  215. $usespecial = true,
  216. $usenumbers = true)
  217. {
  218. $charset = "abcdefghijklmnopqrstuvwxyz";
  219. if ($useupper) { $charset .= "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; }
  220. if ($usenumbers) { $charset .= "0123456789"; }
  221. if ($usespecial) { $charset .= "~@#$%^*()_+-={}|]["; } // Note: using all special characters this reads: "~!@#$%^&*()_+`-={}|\\]?[\":;'><,./";
  222. if ($minlength > $maxlength) { $length = mt_rand($maxlength, $minlength); }
  223. else { $length = mt_rand($minlength, $maxlength);}
  224. $key = null;
  225. for ($i = 0; $i < $length; $i++) {
  226. $key .= $charset[(mt_rand(0, (strlen($charset) - 1)))];
  227. }
  228. return $key;
  229. }
  230. /**
  231. * Write store config options to session
  232. *
  233. * @return Ecart_Install_Model_Wizard Provides fluent interface
  234. */
  235. public function initStore()
  236. {
  237. $baseUrl = Zend_Controller_Front::getInstance()->getBaseUrl();
  238. $this->_session->store_path = str_replace('\\', '/', realpath('..'));
  239. if (null === $this->_session->store_baseUrl) {
  240. $this->_session->store_baseUrl = 'http://' . $_SERVER['HTTP_HOST']
  241. . str_replace('/install', '', $baseUrl);
  242. }
  243. if (null === $this->_session->store_secureUrl) {
  244. $this->_session->store_secureUrl = 'https://' . $_SERVER['HTTP_HOST']
  245. . str_replace('/install', '', $baseUrl);
  246. }
  247. if (null === $this->_session->store_adminUrl) {
  248. $this->_session->store_adminUrl = 'admin';
  249. }
  250. if (null === $this->_session->store_cryptKey) {
  251. $this->_session->store_cryptKey = md5($this->_generateKey());
  252. }
  253. return $this;
  254. }
  255. /**
  256. * Insert row to the core_site table
  257. *
  258. * @return Ecart_Install_Model_Wizard Provides fluent interface
  259. */
  260. private function _installStore()
  261. {
  262. Ecart::single('core/site')->insert(array(
  263. 'base' => $this->_session->store_baseUrl,
  264. 'secure' => $this->_session->store_secureUrl,
  265. 'name' => 'Main Store' //@todo get from form
  266. ));
  267. Ecart::single('core/config_value')->update(array(
  268. 'value' => trim($this->_session->store_adminUrl, '/ ')
  269. ), "path = 'core/backend/route'");
  270. Ecart::single('core/config_value')->update(array(
  271. 'value' => $this->_session->use_ssl
  272. ), "path = 'core/backend/ssl'");
  273. Ecart::single('core/config_value')->update(array(
  274. 'value' => $this->_session->use_ssl
  275. ), "path = 'core/frontend/ssl'");
  276. Ecart::single('core/config_value')->update(array(
  277. 'value' => $this->_session->user_firstname . ' '
  278. . $this->_session->user_lastname
  279. ), "path = 'core/store/owner'");
  280. Ecart::single('core/config_value')->update(array(
  281. 'value' => $this->_session->user_email
  282. ), "path = 'mail/mailboxes/email1'");
  283. Ecart::single('core/config_value')->update(array(
  284. 'value' => 'email1'
  285. ), "path = 'core/company/administratorEmail'");
  286. return $this;
  287. }
  288. /**
  289. * Inserts selected timezone, locales and currencies
  290. *
  291. * @return Ecart_Install_Model_Wizard Provides fluent interface
  292. */
  293. private function _installLocale()
  294. {
  295. /* setting default store values */
  296. Ecart::single('core/config_value')->update(array(
  297. 'value' => current($this->_session->locale['timezone'])
  298. ), "path = 'locale/main/timezone'");
  299. Ecart::single('core/config_value')->update(array(
  300. 'value' => current($this->_session->locale['locale'])
  301. ), "path = 'locale/main/locale'");
  302. Ecart::single('core/config_value')->update(array(
  303. 'value' => current($this->_session->locale['currency'])
  304. ), "path = 'locale/main/currency'");
  305. Ecart::single('core/config_value')->update(array(
  306. 'value' => current($this->_session->locale['currency'])
  307. ), "path = 'locale/main/baseCurrency'");
  308. /* setting languages and currencies available on frontend */
  309. foreach ($this->_session->locale['locale'] as $locale) {
  310. $code = current(explode('_', $locale));
  311. $language = Zend_Locale::getTranslation($code, 'language', $locale);
  312. if (!$language) {
  313. $language = Zend_Locale::getTranslation($code, 'language', 'en_US');
  314. }
  315. Ecart::single('locale/language')->insert(array(
  316. 'code' => $code,
  317. 'language' => ucfirst($language),
  318. 'locale' => $locale
  319. ));
  320. }
  321. reset($this->_session->locale['locale']);
  322. foreach ($this->_session->locale['currency'] as $currency) {
  323. $title = Zend_Locale::getTranslation(
  324. $currency, 'NameToCurrency', current($this->_session->locale['locale'])
  325. );
  326. if (!$title) {
  327. $title = Zend_Locale::getTranslation($currency, 'NameToCurrency', 'en_US');
  328. }
  329. Ecart::single('locale/currency')->insert(array(
  330. 'code' => $currency,
  331. 'currency_precision' => 2,
  332. 'display' => 2,
  333. 'format' => current($this->_session->locale['locale']),
  334. 'position' => 8,
  335. 'title' => $title ? ucfirst($title) : $currency,
  336. 'rate' => 1
  337. ));
  338. }
  339. return $this;
  340. }
  341. /**
  342. * Cleares admin_user table and insert a new record into it
  343. *
  344. * @return Ecart_Install_Model_Wizard Provides fluent interface
  345. */
  346. private function _addUser()
  347. {
  348. $date = date("Y-m-d H:i:s");
  349. Ecart::single('admin/user')->delete('id = 1');
  350. Ecart::single('admin/user')->insert(array(
  351. 'id' => 1,
  352. 'role_id' => 1,
  353. 'firstname' => $this->_session->user_firstname,
  354. 'lastname' => $this->_session->user_lastname,
  355. 'email' => $this->_session->user_email,
  356. 'username' => $this->_session->user_login,
  357. 'password' => md5($this->_session->user_password),
  358. 'created' => $date,
  359. 'modified' => $date,
  360. 'lastlogin' => $date,
  361. 'lognum' => 0,
  362. 'reload_acl_flag' => 0,
  363. 'is_active' => 1
  364. ));
  365. return $this;
  366. }
  367. /**
  368. * Run modules installation
  369. *
  370. * @return Ecart_Install_Model_Wizard Provides fluent interface
  371. */
  372. public function run()
  373. {
  374. @set_time_limit(300);
  375. $modelModule = Ecart::single('core/module');
  376. if (!count(Ecart::db()->fetchAll("SHOW TABLES LIKE '%core_module'"))) {
  377. $modelModule->getByCode('Ecart_Core')->install();
  378. $modelModule->getByCode('Ecart_Locale')->install();
  379. $this->_installStore()->_installLocale();
  380. }
  381. foreach ($this->_session->modules as $code) {
  382. if (!strstr($code, '_')) {
  383. continue;
  384. }
  385. $this->log("Module {$code}:");
  386. $moduleRow = $modelModule->getByCode($code);
  387. if ($moduleRow->isInstalled()) {
  388. $this->log("\tSkipped (already installed)");
  389. continue;
  390. }
  391. $this->log("\tBegin");
  392. $moduleRow->install();
  393. $this->log("\tEnd");
  394. }
  395. $this->_addUser();
  396. return $this;
  397. }
  398. public function applyTemplate()
  399. {
  400. Ecart::single('core/template')->importTemplateFromXmlFile(
  401. ECART_ROOT
  402. . '/app/code/Ecart/Install/etc/'
  403. . 'default.xml'
  404. );
  405. return $this;
  406. }
  407. public function log($message)
  408. {
  409. try {
  410. $logger = new Zend_Log(new Zend_Log_Writer_Stream(
  411. ECART_ROOT . '/var/logs/installation.log'
  412. ));
  413. $logger->log($message, Zend_Log::DEBUG);
  414. } catch (Exception $e) {
  415. error_log($e->getMessage());
  416. error_log($message);
  417. }
  418. }
  419. }