· 5 years ago · Aug 25, 2020, 01:16 PM
1<?php
2/*
3* 2007-2014 PrestaShop
4*
5* NOTICE OF LICENSE
6*
7* This source file is subject to the Open Software License (OSL 3.0)
8* that is bundled with this package in the file LICENSE.txt.
9* It is also available through the world-wide-web at this URL:
10* http://opensource.org/licenses/osl-3.0.php
11* If you did not receive a copy of the license and are unable to
12* obtain it through the world-wide-web, please send an email
13* to license@prestashop.com so we can send you a copy immediately.
14*
15* DISCLAIMER
16*
17* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
18* versions in the future. If you wish to customize PrestaShop for your
19* needs please refer to http://www.prestashop.com for more information.
20*
21* @author PrestaShop SA <contact@prestashop.com>
22* @copyright 2007-2014 PrestaShop SA
23* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
24* International Registered Trademark & Property of PrestaShop SA
25*/
26
27class InstallModelInstall extends InstallAbstractModel
28{
29 const SETTINGS_FILE = 'config/settings.inc.php';
30
31 /**
32 * @var FileLogger
33 */
34 public $logger;
35
36 public function __construct()
37 {
38 parent::__construct();
39
40 $this->logger = new FileLogger();
41 if (is_writable(_PS_ROOT_DIR_.'/log/'))
42 $this->logger->setFilename(_PS_ROOT_DIR_.'/log/'.@date('Ymd').'_installation.log');
43 }
44
45 public function setError($errors)
46 {
47 if (!is_array($errors))
48 $errors = array($errors);
49
50 parent::setError($errors);
51
52 foreach ($errors as $error)
53 $this->logger->logError($error);
54 }
55
56 /**
57 * Generate settings file
58 */
59 public function generateSettingsFile($database_server, $database_login, $database_password, $database_name, $database_prefix, $database_engine)
60 {
61 // Check permissions for settings file
62 if (file_exists(_PS_ROOT_DIR_.'/'.self::SETTINGS_FILE) && !is_writable(_PS_ROOT_DIR_.'/'.self::SETTINGS_FILE))
63 {
64 $this->setError($this->language->l('%s file is not writable (check permissions)', self::SETTINGS_FILE));
65 return false;
66 }
67 elseif (!file_exists(_PS_ROOT_DIR_.'/'.self::SETTINGS_FILE) && !is_writable(_PS_ROOT_DIR_.'/'.dirname(self::SETTINGS_FILE)))
68 {
69 $this->setError($this->language->l('%s folder is not writable (check permissions)', dirname(self::SETTINGS_FILE)));
70 return false;
71 }
72
73 // Generate settings content and write file
74 $settings_constants = array(
75 '_DB_SERVER_' => $database_server,
76 '_DB_NAME_' => $database_name,
77 '_DB_USER_' => $database_login,
78 '_DB_PASSWD_' => $database_password,
79 '_DB_PREFIX_' => $database_prefix,
80 '_MYSQL_ENGINE_' => $database_engine,
81 '_PS_CACHING_SYSTEM_' => 'CacheMemcache',
82 '_PS_CACHE_ENABLED_' => '0',
83 '_MEDIA_SERVER_1_' => '',
84 '_MEDIA_SERVER_2_' => '',
85 '_MEDIA_SERVER_3_' => '',
86 '_COOKIE_KEY_' => Tools::passwdGen(56),
87 '_COOKIE_IV_' => Tools::passwdGen(8),
88 '_PS_CREATION_DATE_' => date('Y-m-d'),
89 '_PS_VERSION_' => _PS_INSTALL_VERSION_,
90 );
91
92 // If mcrypt is activated, add Rijndael 128 configuration
93 if (function_exists('mcrypt_encrypt'))
94 {
95 $settings_constants['_RIJNDAEL_KEY_'] = Tools::passwdGen(mcrypt_get_key_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB));
96 $settings_constants['_RIJNDAEL_IV_'] = base64_encode(mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB), MCRYPT_RAND));
97 }
98
99 $settings_content = "<?php\n";
100
101 foreach ($settings_constants as $constant => $value)
102 {
103 if ($constant == '_PS_VERSION_')
104 $settings_content .= 'if (!defined(\''.$constant.'\'))'."\n\t";
105
106 $settings_content .= "define('$constant', '".str_replace('\'', '\\\'', $value)."');\n";
107 }
108
109 if (!file_put_contents(_PS_ROOT_DIR_.'/'.self::SETTINGS_FILE, $settings_content))
110 {
111 $this->setError($this->language->l('Cannot write settings file'));
112 return false;
113 }
114 return true;
115 }
116
117 /**
118 * PROCESS : installDatabase
119 * Generate settings file and create database structure
120 */
121 public function installDatabase($clear_database = false)
122 {
123 // Clear database (only tables with same prefix)
124 require_once _PS_ROOT_DIR_.'/'.self::SETTINGS_FILE;
125 if ($clear_database)
126 $this->clearDatabase();
127
128 // Install database structure
129 $sql_loader = new InstallSqlLoader();
130 $sql_loader->setMetaData(array(
131 'PREFIX_' => _DB_PREFIX_,
132 'ENGINE_TYPE' => _MYSQL_ENGINE_,
133 ));
134
135 try
136 {
137 $sql_loader->parse_file(_PS_INSTALL_DATA_PATH_.'db_structure.sql');
138 }
139 catch (PrestashopInstallerException $e)
140 {
141 $this->setError($this->language->l('Database structure file not found'));
142 return false;
143 }
144
145 if ($errors = $sql_loader->getErrors())
146 {
147 foreach ($errors as $error)
148 $this->setError($this->language->l('SQL error on query <i>%s</i>', $error['error']));
149 return false;
150 }
151
152 return true;
153 }
154
155 /**
156 * Clear database (only tables with same prefix)
157 *
158 * @param bool $truncate If true truncate the table, if false drop the table
159 */
160 public function clearDatabase($truncate = false)
161 {
162 foreach (Db::getInstance()->executeS('SHOW TABLES') as $row)
163 {
164 $table = current($row);
165 if (!_DB_PREFIX_ || preg_match('#^'._DB_PREFIX_.'#i', $table))
166 Db::getInstance()->execute((($truncate) ? 'TRUNCATE' : 'DROP TABLE').' `'.$table.'`');
167 }
168 }
169
170 /**
171 * PROCESS : installDefaultData
172 * Create default shop and languages
173 */
174 public function installDefaultData($shop_name, $clear_database = false)
175 {
176 if ($clear_database)
177 $this->clearDatabase(true);
178
179 // Install first shop
180 if (!$this->createShop($shop_name))
181 return false;
182
183 // Install languages
184 try
185 {
186 $languages = $this->installLanguages(array($this->language->getLanguageIso()));
187 }
188 catch (PrestashopInstallerException $e)
189 {
190 $this->setError($e->getMessage());
191 return false;
192 }
193
194 $flip_languages = array_flip($languages);
195 $id_lang = (!empty($flip_languages[$this->language->getLanguageIso()])) ? $flip_languages[$this->language->getLanguageIso()] : 1;
196 Configuration::updateGlobalValue('PS_LANG_DEFAULT', $id_lang);
197 Configuration::updateGlobalValue('PS_VERSION_DB', _PS_INSTALL_VERSION_);
198 Configuration::updateGlobalValue('PS_INSTALL_VERSION', _PS_INSTALL_VERSION_);
199 return true;
200 }
201
202 /**
203 * PROCESS : populateDatabase
204 * Populate database with default data
205 */
206 public function populateDatabase($entity = null)
207 {
208 $languages = array();
209 foreach (Language::getLanguages(true) as $lang)
210 $languages[$lang['id_lang']] = $lang['iso_code'];
211
212 // Install XML data (data/xml/ folder)
213 $xml_loader = new InstallXmlLoader();
214 $xml_loader->setLanguages($languages);
215
216 if (isset($this->xml_loader_ids) && $this->xml_loader_ids)
217 $xml_loader->setIds($this->xml_loader_ids);
218
219 if ($entity)
220 $xml_loader->populateEntity($entity);
221 else
222 $xml_loader->populateFromXmlFiles();
223 if ($errors = $xml_loader->getErrors())
224 {
225 $this->setError($errors);
226 return false;
227 }
228
229 // IDS from xmlLoader are stored in order to use them for fixtures
230 $this->xml_loader_ids = $xml_loader->getIds();
231 unset($xml_loader);
232
233 // Install custom SQL data (db_data.sql file)
234 if (file_exists(_PS_INSTALL_DATA_PATH_.'db_data.sql'))
235 {
236 $sql_loader = new InstallSqlLoader();
237 $sql_loader->setMetaData(array(
238 'PREFIX_' => _DB_PREFIX_,
239 'ENGINE_TYPE' => _MYSQL_ENGINE_,
240 ));
241
242 $sql_loader->parse_file(_PS_INSTALL_DATA_PATH_.'db_data.sql', false);
243 if ($errors = $sql_loader->getErrors())
244 {
245 $this->setError($errors);
246 return false;
247 }
248 }
249
250 // Copy language default images (we do this action after database in populated because we need image types information)
251 foreach ($languages as $iso)
252 $this->copyLanguageImages($iso);
253
254 return true;
255 }
256
257 public function createShop($shop_name)
258 {
259 // Create default group shop
260 $shop_group = new ShopGroup();
261 $shop_group->name = 'Default';
262 $shop_group->active = true;
263 if (!$shop_group->add())
264 {
265 $this->setError($this->language->l('Cannot create group shop').' / '.Db::getInstance()->getMsgError());
266 return false;
267 }
268
269 // Create default shop
270 $shop = new Shop();
271 $shop->active = true;
272 $shop->id_shop_group = $shop_group->id;
273 $shop->id_category = 2;
274 $shop->id_theme = 1;
275 $shop->name = $shop_name;
276 if (!$shop->add())
277 {
278 $this->setError($this->language->l('Cannot create shop').' / '.Db::getInstance()->getMsgError());
279 return false;
280 }
281 Context::getContext()->shop = $shop;
282
283 // Create default shop URL
284 $shop_url = new ShopUrl();
285 $shop_url->domain = Tools::getHttpHost();
286 $shop_url->domain_ssl = Tools::getHttpHost();
287 $shop_url->physical_uri = __PS_BASE_URI__;
288 $shop_url->id_shop = $shop->id;
289 $shop_url->main = true;
290 $shop_url->active = true;
291 if (!$shop_url->add())
292 {
293 $this->setError($this->language->l('Cannot create shop URL').' / '.Db::getInstance()->getMsgError());
294 return false;
295 }
296
297 return true;
298 }
299
300 /**
301 * Install languages
302 *
303 * @return array Association between ID and iso array(id_lang => iso, ...)
304 */
305 public function installLanguages($languages_list = null)
306 {
307 if ($languages_list == null || !is_array($languages_list) || !count($languages_list))
308 $languages_list = $this->language->getIsoList();
309
310 $languages = array();
311 foreach ($languages_list as $iso)
312 {
313 if (!file_exists(_PS_INSTALL_LANGS_PATH_.$iso.'/language.xml'))
314 throw new PrestashopInstallerException($this->language->l('File "language.xml" not found for language iso "%s"', $iso));
315
316 if (!$xml = @simplexml_load_file(_PS_INSTALL_LANGS_PATH_.$iso.'/language.xml'))
317 throw new PrestashopInstallerException($this->language->l('File "language.xml" not valid for language iso "%s"', $iso));
318
319 $params_lang = array('name' => (string)$xml->name, 'iso_code' => substr((string)$xml->language_code, 0, 2));
320
321 //if (!InstallSession::getInstance()->safe_mode || !Language::downloadAndInstallLanguagePack($iso, _PS_INSTALL_VERSION_, $params_lang))
322 Language::checkAndAddLanguage($iso, false, true, $params_lang);
323
324 if (!$id_lang = Language::getIdByIso($iso))
325 throw new PrestashopInstallerException($this->language->l('Cannot install language "%s"', ($xml->name) ? $xml->name : $iso));
326 $languages[$id_lang] = $iso;
327
328 // Copy language flag
329 if (is_writable(_PS_IMG_DIR_.'l/'))
330 if (!copy(_PS_INSTALL_LANGS_PATH_.$iso.'/flag.jpg', _PS_IMG_DIR_.'l/'.$id_lang.'.jpg'))
331 throw new PrestashopInstallerException($this->language->l('Cannot copy flag language "%s"', _PS_INSTALL_LANGS_PATH_.$iso.'/flag.jpg => '._PS_IMG_DIR_.'l/'.$id_lang.'.jpg'));
332 }
333
334 return $languages;
335 }
336
337 public function copyLanguageImages($iso)
338 {
339 $img_path = _PS_INSTALL_LANGS_PATH_.$iso.'/img/';
340 if (!is_dir($img_path))
341 return;
342
343 $list = array(
344 'products' => _PS_PROD_IMG_DIR_,
345 'categories' => _PS_CAT_IMG_DIR_,
346 'manufacturers' => _PS_MANU_IMG_DIR_,
347 'suppliers' => _PS_SUPP_IMG_DIR_,
348 'scenes' => _PS_SCENE_IMG_DIR_,
349 'stores' => _PS_STORE_IMG_DIR_,
350 null => _PS_IMG_DIR_.'l/', // Little trick to copy images in img/l/ path with all types
351 );
352
353 foreach ($list as $cat => $dst_path)
354 {
355 if (!is_writable($dst_path))
356 continue;
357
358 copy($img_path.$iso.'.jpg', $dst_path.$iso.'.jpg');
359
360 $types = ImageType::getImagesTypes($cat);
361 foreach ($types as $type)
362 {
363 if (file_exists($img_path.$iso.'-default-'.$type['name'].'.jpg'))
364 copy($img_path.$iso.'-default-'.$type['name'].'.jpg', $dst_path.$iso.'-default-'.$type['name'].'.jpg');
365 else
366 ImageManager::resize($img_path.$iso.'.jpg', $dst_path.$iso.'-default-'.$type['name'].'.jpg', $type['width'], $type['height']);
367 }
368 }
369 }
370
371 /**
372 * PROCESS : configureShop
373 * Set default shop configuration
374 */
375 public function configureShop(array $data = array())
376 {
377 //clear image cache in tmp folder
378 if (file_exists(_PS_TMP_IMG_DIR_))
379 foreach (scandir(_PS_TMP_IMG_DIR_) as $file)
380 if ($file[0] != '.' && $file != 'index.php')
381 Tools::deleteFile(_PS_TMP_IMG_DIR_.$file);
382
383 $default_data = array(
384 'shop_name' => 'My Shop',
385 'shop_activity' => '',
386 'shop_country' => 'us',
387 'shop_timezone' => 'US/Eastern',
388 'use_smtp' => false,
389 'smtp_encryption' => 'off',
390 'smtp_port' => 25,
391 'rewrite_engine' => false,
392 );
393
394 foreach ($default_data as $k => $v)
395 if (!isset($data[$k]))
396 $data[$k] = $v;
397
398 Context::getContext()->shop = new Shop(1);
399 Configuration::loadConfiguration();
400
401 // use the old image system if the safe_mod is enabled otherwise the installer will fail with the fixtures installation
402 if (InstallSession::getInstance()->safe_mode)
403 Configuration::updateGlobalValue('PS_LEGACY_IMAGES', 1);
404
405 $id_country = Country::getByIso($data['shop_country']);
406
407 // Set default configuration
408 Configuration::updateGlobalValue('PS_SHOP_DOMAIN', Tools::getHttpHost());
409 Configuration::updateGlobalValue('PS_SHOP_DOMAIN_SSL', Tools::getHttpHost());
410 Configuration::updateGlobalValue('PS_INSTALL_VERSION', _PS_INSTALL_VERSION_);
411 Configuration::updateGlobalValue('PS_LOCALE_LANGUAGE', $this->language->getLanguageIso());
412 Configuration::updateGlobalValue('PS_SHOP_NAME', $data['shop_name']);
413 Configuration::updateGlobalValue('PS_SHOP_ACTIVITY', $data['shop_activity']);
414 Configuration::updateGlobalValue('PS_COUNTRY_DEFAULT', $id_country);
415 Configuration::updateGlobalValue('PS_LOCALE_COUNTRY', $data['shop_country']);
416 Configuration::updateGlobalValue('PS_TIMEZONE', $data['shop_timezone']);
417 Configuration::updateGlobalValue('PS_CONFIGURATION_AGREMENT', (int)$data['configuration_agrement']);
418
419 // Set mails configuration
420 Configuration::updateGlobalValue('PS_MAIL_METHOD', ($data['use_smtp']) ? 2 : 1);
421 Configuration::updateGlobalValue('PS_MAIL_SMTP_ENCRYPTION', $data['smtp_encryption']);
422 Configuration::updateGlobalValue('PS_MAIL_SMTP_PORT', $data['smtp_port']);
423
424 // Set default rewriting settings
425 Configuration::updateGlobalValue('PS_REWRITING_SETTINGS', $data['rewrite_engine']);
426
427 // Activate rijndael 128 encrypt algorihtm if mcrypt is activated
428 Configuration::updateGlobalValue('PS_CIPHER_ALGORITHM', function_exists('mcrypt_encrypt') ? 1 : 0);
429
430 // Set logo configuration
431 if (file_exists(_PS_IMG_DIR_.'logo.jpg'))
432 {
433 list($width, $height) = getimagesize(_PS_IMG_DIR_.'logo.jpg');
434 Configuration::updateGlobalValue('SHOP_LOGO_WIDTH', round($width));
435 Configuration::updateGlobalValue('SHOP_LOGO_HEIGHT', round($height));
436 }
437
438 // Disable cache for debug mode
439 if (_PS_MODE_DEV_)
440 Configuration::updateGlobalValue('PS_SMARTY_CACHE', 1);
441
442 // Active only the country selected by the merchant
443 Db::getInstance()->execute('UPDATE '._DB_PREFIX_.'country SET active = 0 WHERE id_country != '.(int)$id_country);
444
445 // Set localization configuration
446 $version = str_replace('.', '', _PS_VERSION_);
447 $version = substr($version, 0, 2);
448
449 $localization_file_content = @Tools::file_get_contents('http://api.prestashop.com/localization/'.$version.'/'.$data['shop_country'].'.xml');
450 if (!@simplexml_load_string($localization_file_content))
451 $localization_file_content = false;
452 if (!$localization_file_content)
453 {
454 $localization_file = _PS_ROOT_DIR_.'/localization/default.xml';
455 if (file_exists(_PS_ROOT_DIR_.'/localization/'.$data['shop_country'].'.xml'))
456 $localization_file = _PS_ROOT_DIR_.'/localization/'.$data['shop_country'].'.xml';
457
458 $localization_file_content = file_get_contents($localization_file);
459 }
460
461 $locale = new LocalizationPackCore();
462 $locale->loadLocalisationPack($localization_file_content, '', true);
463
464 // Create default employee
465 if (isset($data['admin_firstname']) && isset($data['admin_lastname']) && isset($data['admin_password']) && isset($data['admin_email']))
466 {
467 $employee = new Employee();
468 $employee->firstname = Tools::ucfirst($data['admin_firstname']);
469 $employee->lastname = Tools::ucfirst($data['admin_lastname']);
470 $employee->email = $data['admin_email'];
471 $employee->passwd = md5(_COOKIE_KEY_.$data['admin_password']);
472 $employee->last_passwd_gen = date('Y-m-d h:i:s', strtotime('-360 minutes'));
473 $employee->bo_theme = 'default';
474 $employee->default_tab = 1;
475 $employee->active = true;
476 $employee->optin = (bool)$data['send_informations'];
477 $employee->id_profile = 1;
478 $employee->id_lang = Configuration::get('PS_LANG_DEFAULT');
479 $employee->bo_menu = 1;
480 if (!$employee->add())
481 {
482 $this->setError($this->language->l('Cannot create admin account'));
483 return false;
484 }
485 }
486 else
487 {
488 $this->setError($this->language->l('Cannot create admin account'));
489 return false;
490 }
491
492 // Update default contact
493 if (isset($data['admin_email']))
494 {
495 Configuration::updateGlobalValue('PS_SHOP_EMAIL', $data['admin_email']);
496
497 $contacts = new PrestaShopCollection('Contact');
498 foreach ($contacts as $contact)
499 {
500 $contact->email = $data['admin_email'];
501 $contact->update();
502 }
503 }
504
505 if (!@Tools::generateHtaccess(null, $data['rewrite_engine']))
506 Configuration::updateGlobalValue('PS_REWRITING_SETTINGS', 0);
507
508 return true;
509 }
510
511 public function getModulesList()
512 {
513 $modules = array();
514 if (false)
515 {
516 foreach (scandir(_PS_MODULE_DIR_) as $module)
517 if ($module[0] != '.' && is_dir(_PS_MODULE_DIR_.$module) && file_exists(_PS_MODULE_DIR_.$module.'/'.$module.'.php'))
518 $modules[] = $module;
519 }
520 else
521 {
522 $modules = array(
523 'socialsharing',
524 'blockbanner',
525 'bankwire',
526 'blockbestsellers',
527 'blockcart',
528 'blocksocial',
529 'blockcategories',
530 'blockcurrencies',
531 'blockfacebook',
532 'blocklanguages',
533 'blocklayered',
534 'blockcms',
535 'blockcmsinfo',
536 'blockcontact',
537 'blockcontactinfos',
538 'blockmanufacturer',
539 'blockmyaccount',
540 'blockmyaccountfooter',
541 'blocknewproducts',
542 'blocknewsletter',
543 'blockpaymentlogo',
544 'blocksearch',
545 'blockspecials',
546 'blockstore',
547 'blocksupplier',
548 'blocktags',
549 'blocktopmenu',
550 'blockuserinfo',
551 'blockviewed',
552 'cheque',
553 'dashactivity',
554 'dashtrends',
555 'dashgoals',
556 'dashproducts',
557 'graphnvd3',
558 'gridhtml',
559 'homeslider',
560 'homefeatured',
561 'productpaymentlogos',
562 'pagesnotfound',
563 'sekeywords',
564 'statsbestcategories',
565 'statsbestcustomers',
566 'statsbestproducts',
567 'statsbestsuppliers',
568 'statsbestvouchers',
569 'statscarrier',
570 'statscatalog',
571 'statscheckup',
572 'statsdata',
573 'statsequipment',
574 'statsforecast',
575 'statslive',
576 'statsnewsletter',
577 'statsorigin',
578 'statspersonalinfos',
579 'statsproduct',
580 'statsregistrations',
581 'statssales',
582 'statssearch',
583 'statsstock',
584 'statsvisits',
585 'themeconfigurator',
586 );
587 }
588 return $modules;
589 }
590
591 public function getAddonsModulesList($params = array())
592 {
593 $addons_modules = array();
594 $content = Tools::addonsRequest('install-modules', $params);
595 $xml = @simplexml_load_string($content, null, LIBXML_NOCDATA);
596
597 if ($xml !== false and isset($xml->module))
598 foreach ($xml->module as $modaddons)
599 $addons_modules[] = array('id_module' => $modaddons->id, 'name' => $modaddons->name);
600
601 return $addons_modules;
602 }
603
604 /**
605 * PROCESS : installModules
606 * Download module from addons and Install all modules in ~/modules/ directory
607 */
608 public function installModulesAddons($module = null)
609 {
610 $addons_modules = $module ? array($module) : $this->getAddonsModulesList();
611 $modules = array();
612 if (!InstallSession::getInstance()->safe_mode)
613 {
614 foreach($addons_modules as $addons_module)
615 if (file_put_contents(_PS_MODULE_DIR_.$addons_module['name'].'.zip', Tools::addonsRequest('module', array('id_module' => $addons_module['id_module']))))
616 if (Tools::ZipExtract(_PS_MODULE_DIR_.$addons_module['name'].'.zip', _PS_MODULE_DIR_))
617 {
618 $modules[] = (string)$addons_module['name'];//if the module has been unziped we add the name in the modules list to install
619 unlink(_PS_MODULE_DIR_.$addons_module['name'].'.zip');
620 }
621 }
622
623 return count($modules) ? $this->installModules($modules) : true;
624 }
625
626 /**
627 * PROCESS : installModules
628 * Download module from addons and Install all modules in ~/modules/ directory
629 */
630 public function installModules($module = null)
631 {
632 if ($module && !is_array($module))
633 $module = array($module);
634
635 $modules = $module ? $module : $this->getModulesList();
636
637 Module::updateTranslationsAfterInstall(false);
638
639 $errors = array();
640 foreach ($modules as $module_name)
641 {
642 if (!file_exists(_PS_MODULE_DIR_.$module_name.'/'.$module_name.'.php'))
643 continue;
644
645 $module = Module::getInstanceByName($module_name);
646 if (!$module->install())
647 $errors[] = $this->language->l('Cannot install module "%s"', $module_name);
648 }
649
650 if ($errors)
651 {
652 $this->setError($errors);
653 return false;
654 }
655
656 Module::updateTranslationsAfterInstall(true);
657 Language::updateModulesTranslations($modules);
658
659 return true;
660 }
661
662 /**
663 * PROCESS : installFixtures
664 * Install fixtures (E.g. demo products)
665 */
666 public function installFixtures($entity = null, array $data = array())
667 {
668 $fixtures_path = _PS_INSTALL_FIXTURES_PATH_.'fashion/';
669 $fixtures_name = 'fashion';
670 $zip_file = _PS_ROOT_DIR_.'/download/fixtures.zip';
671 $temp_dir = _PS_ROOT_DIR_.'/download/fixtures/';
672
673 // try to download fixtures if no low memory mode
674 if ($entity === null)
675 {
676 if (Tools::copy('http://api.prestashop.com/fixtures/'.$data['shop_country'].'/'.$data['shop_activity'].'/fixtures.zip', $zip_file))
677 {
678 Tools::deleteDirectory($temp_dir, true);
679 if (Tools::ZipTest($zip_file))
680 if (Tools::ZipExtract($zip_file, $temp_dir))
681 {
682 $files = scandir($temp_dir);
683 if (count($files))
684 foreach ($files as $file)
685 if (!preg_match('/^\./', $file) && is_dir($temp_dir.$file.'/'))
686 {
687 $fixtures_path = $temp_dir.$file.'/';
688 $fixtures_name = $file;
689 break;
690 }
691 }
692 }
693 }
694
695 // Load class (use fixture class if one exists, or use InstallXmlLoader)
696 if (file_exists($fixtures_path.'/install.php'))
697 {
698 require_once $fixtures_path.'/install.php';
699 $class = 'InstallFixtures'.Tools::toCamelCase($fixtures_name);
700 if (!class_exists($class, false))
701 {
702 $this->setError($this->language->l('Fixtures class "%s" not found', $class));
703 return false;
704 }
705
706 $xml_loader = new $class();
707 if (!$xml_loader instanceof InstallXmlLoader)
708 {
709 $this->setError($this->language->l('"%s" must be an instance of "InstallXmlLoader"', $class));
710 return false;
711 }
712 }
713 else
714 $xml_loader = new InstallXmlLoader();
715
716 // Install XML data (data/xml/ folder)
717 $xml_loader->setFixturesPath($fixtures_path);
718 if (isset($this->xml_loader_ids) && $this->xml_loader_ids)
719 $xml_loader->setIds($this->xml_loader_ids);
720
721 $languages = array();
722 foreach (Language::getLanguages(false) as $lang)
723 $languages[$lang['id_lang']] = $lang['iso_code'];
724 $xml_loader->setLanguages($languages);
725
726 if ($entity)
727 $xml_loader->populateEntity($entity);
728 else
729 {
730 $xml_loader->populateFromXmlFiles();
731 Tools::deleteDirectory($temp_dir, true);
732 @unlink($zip_file);
733 }
734
735 if ($errors = $xml_loader->getErrors())
736 {
737 $this->setError($errors);
738 return false;
739 }
740
741 // IDS from xmlLoader are stored in order to use them for fixtures
742 $this->xml_loader_ids = $xml_loader->getIds();
743 unset($xml_loader);
744
745 // Index products in search tables
746 Search::indexation(true);
747
748 return true;
749 }
750
751 /**
752 * PROCESS : installTheme
753 * Install theme
754 */
755 public function installTheme()
756 {
757 // @todo do a real install of the theme
758 $sql_loader = new InstallSqlLoader();
759 $sql_loader->setMetaData(array(
760 'PREFIX_' => _DB_PREFIX_,
761 'ENGINE_TYPE' => _MYSQL_ENGINE_,
762 ));
763
764 $sql_loader->parse_file(_PS_INSTALL_DATA_PATH_.'theme.sql', false);
765 if ($errors = $sql_loader->getErrors())
766 {
767 $this->setError($errors);
768 return false;
769 }
770 }
771}
772