* @copyright 2007-2013 PrestaShop SA * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) * International Registered Trademark & Property of PrestaShop SA */ if (!defined('_PS_VERSION_')) exit; class ThemeConfigurator extends Module { protected $max_image_size = 1048576; protected $default_language; protected $languages; public function __construct() { $this->name = 'themeconfigurator'; $this->tab = 'front_office_features'; $this->version = '0.1'; $this->bootstrap = true; $this->secure_key = Tools::encrypt($this->name); $this->default_language = Language::getLanguage(Configuration::get('PS_LANG_DEFAULT')); $this->languages = Language::getLanguages(); parent::__construct(); $this->displayName = $this->l('Theme configurator'); $this->description = $this->l('Configure elements of your theme'); $this->module_path = _PS_MODULE_DIR_.$this->name.'/'; $this->uploads_path = _PS_MODULE_DIR_.$this->name.'/images/'; $this->admin_tpl_path = _PS_MODULE_DIR_.$this->name.'/views/templates/admin/'; $this->hooks_tpl_path = _PS_MODULE_DIR_.$this->name.'/views/templates/hooks/'; } public function install() { $themes_colors = array('theme1', 'theme2', 'theme3', 'theme4', 'theme5', 'theme6', 'theme7', 'theme8', 'theme9'); $themes_fonts = array( 'Georgia, serif', '"Palatino Linotype", "Book Antiqua", Palatino, serif', '"Times New Roman", Times, serif', 'Arial, Helvetica, sans-serif', '"Arial Black", Gadget, sans-serif', 'Impact, Charcoal, sans-serif', '"Lucida Sans Unicode", "Lucida Grande", sans-serif', 'Tahoma, Geneva, sans-serif', '"Trebuchet MS", Helvetica, sans-serif', 'Verdana, Geneva, sans-serif', '"Courier New", Courier, monospace', '"Lucida Console", Monaco, monospace' ); if (!parent::install() || !$this->installDB() || !$this->installFixtures() || !$this->registerHook('displayHeader') || !$this->registerHook('displayTopColumn') || !$this->registerHook('displayLeftColumn') || !$this->registerHook('displayRightColumn') || !$this->registerHook('displayHome') || !$this->registerHook('displayFooter') || !$this->registerHook('displayBackOfficeHeader') || !Configuration::updateValue('PS_TC_THEMES', serialize($themes_colors)) || !Configuration::updateValue('PS_TC_FONTS', serialize($themes_fonts))) return false; return true; } private function installDB() { return ( Db::getInstance()->Execute('DROP TABLE IF EXISTS `'._DB_PREFIX_.'themeconfigurator`') && Db::getInstance()->Execute(' CREATE TABLE `'._DB_PREFIX_.'themeconfigurator` ( `id_item` int(10) unsigned NOT NULL AUTO_INCREMENT, `id_shop` int(10) unsigned NOT NULL, `id_lang` int(10) unsigned NOT NULL, `item_order` int(10) unsigned NOT NULL, `title` VARCHAR(100), `title_use` tinyint(1) unsigned NOT NULL DEFAULT \'0\', `hook` VARCHAR(100), `url` VARCHAR(100), `target` tinyint(1) unsigned NOT NULL DEFAULT \'0\', `image` VARCHAR(100), `image_w` VARCHAR(10), `image_h` VARCHAR(10), `html` TEXT, `active` tinyint(1) unsigned NOT NULL DEFAULT \'1\', PRIMARY KEY (`id_item`) ) ENGINE = '._MYSQL_ENGINE_.' DEFAULT CHARSET=UTF8;') ); return true; } public function installFixtures() { $result = true; for ($i = 1; $i < 6; $i++) { $result &= Db::getInstance()->Execute(' INSERT INTO `'._DB_PREFIX_.'themeconfigurator` ( `id_shop`, `id_lang`, `item_order`, `title`, `title_use`, `hook`, `url`, `target`, `image`, `image_w`, `image_h`, `html`, `active` ) VALUES ( \''.(int)$this->context->shop->id.'\', \''.(int)$this->context->language->id.'\', \''.(int)$i.'\', \'\', \'0\', \'home\', \'\', \'0\', \'banner-img'.$i.'.jpg\', \'\', \'\', \'\', 1) '); } for ($i = 6; $i < 8; $i++) { $result &= Db::getInstance()->Execute(' INSERT INTO `'._DB_PREFIX_.'themeconfigurator` ( `id_shop`, `id_lang`, `item_order`, `title`, `title_use`, `hook`, `url`, `target`, `image`, `image_w`, `image_h`, `html`, `active` ) VALUES ( \''.(int)$this->context->shop->id.'\', \''.(int)$this->context->language->id.'\', \''.(int)$i.'\', \'\', \'0\', \'top\', \'\', \'0\', \'banner-img'.$i.'.jpg\', \'\', \'\', \'\', 1) '); } return $result; } public function uninstall() { $images = Db::getInstance()->executeS('SELECT image FROM `'._DB_PREFIX_.'themeconfigurator`'); foreach ($images as $image) $this->deleteImage($image['image']); if (!Db::getInstance()->Execute('DROP TABLE IF EXISTS `'._DB_PREFIX_.'themeconfigurator`') || !parent::uninstall()) return false; return true; } public function hookDisplayBackOfficeHeader() { if (Tools::getValue('configure') != $this->name) return; $this->context->controller->addCSS($this->_path.'views/css/admin.css'); $this->context->controller->addJquery(); $this->context->controller->addJS($this->_path.'views/js/admin.js'); } public function hookdisplayHeader($params) { $this->context->controller->addCss($this->_path.'views/css/hooks.css', 'all'); if ((int)Tools::getValue('live_configurator', 0) == 1) { if (Tools::getValue('theme')) $this->context->controller->addCss($this->smarty->smarty->tpl_vars['css_dir']->value.Tools::getValue('theme').'.css', 'all'); } else { if (Configuration::get('PS_TC_THEME') != '') $this->context->controller->addCss($this->smarty->smarty->tpl_vars['css_dir']->value.Tools::getValue('theme').'.css', 'all'); } } public function hookdisplayTopColumn($params) { return $this->hookdisplayTop($params); } public function hookdisplayTop($params) { if ((int)Tools::getValue('live_configurator', 0) == 1) { if (Tools::isSubmit('submitLiveConfigurator')) { Configuration::updateValue('PS_TC_THEME', Tools::getValue('theme')); Configuration::updateValue('PS_TC_FONT', Tools::getValue('font')); } $this->context->controller->addCSS($this->_path.'css/live_configurator.css'); $this->context->controller->addJS($this->_path.'js/live_configurator.js'); $this->smarty->assign(array( 'themes' => unserialize(Configuration::get('PS_TC_THEMES')), 'fonts' => unserialize(Configuration::get('PS_TC_FONTS')), 'theme' => Tools::getValue('theme', ''), 'advertisement_image' => $this->_path.'/img/'.$this->context->language->iso_code.'/advertisement.png', 'advertisement_text' => $this->l('Over 500+ PrestaShop Premium Templates! Browse Now!') )); return $this->display(__FILE__, 'live_configurator.tpl'); } $this->context->smarty->assign(array( 'htmlitems'=> $this->getItemsFromHook('top'), 'hook' => 'top' )); return $this->display(__FILE__, 'hook.tpl'); } public function hookDisplayHome() { $this->context->smarty->assign(array( 'htmlitems'=> $this->getItemsFromHook('home'), 'hook' => 'home' )); return $this->display(__FILE__, 'hook.tpl'); } public function hookDisplayLeftColumn() { $this->context->smarty->assign(array( 'htmlitems'=> $this->getItemsFromHook('left'), 'hook' => 'left' )); return $this->display(__FILE__, 'hook.tpl'); } public function hookDisplayRightColumn() { $this->context->smarty->assign(array( 'htmlitems'=> $this->getItemsFromHook('right'), 'hook' => 'right' )); return $this->display(__FILE__, 'hook.tpl'); } public function hookDisplayFooter() { $this->context->smarty->assign(array( 'htmlitems'=> $this->getItemsFromHook('footer'), 'hook' => 'footer' )); return $this->display(__FILE__, 'hook.tpl'); } protected function getItemsFromHook($hook) { if (!$hook) return false; return Db::getInstance()->ExecuteS(' SELECT * FROM `'._DB_PREFIX_.'themeconfigurator` WHERE id_shop = '.(int)$this->context->shop->id.' AND id_lang = '.(int)$this->context->language->id.' AND hook = \''.pSQL($hook).'\' AND active = 1 ORDER BY item_order ASC' ); } protected function deleteImage($image) { $file_name = $this->uploads_path.$image; if (realpath(dirname($file_name)).DIRECTORY_SEPARATOR != $this->uploads_path) Tools::dieOrLog(sprintf('Could not find upload directory')); if ($image != '' && is_file($file_name)) unlink($file_name); } protected function removeItem() { $id_item = (int)Tools::getValue('item_id'); if ($image = Db::getInstance()->getValue('SELECT image FROM `'._DB_PREFIX_.'themeconfigurator` WHERE id_item = '.(int)$id_item)) $this->deleteImage($image); Db::getInstance()->delete(_DB_PREFIX_.'themeconfigurator', 'id_item = '.(int)$id_item); if (Db::getInstance()->Affected_Rows() == 1) { Db::getInstance()->execute(' UPDATE `'._DB_PREFIX_.'themeconfigurator` SET item_order = item_order-1 WHERE ( item_order > '.(int)Tools::getValue('item_order').' AND id_shop = '.(int)$this->context->shop->id.' AND hook = \''.pSQL(Tools::getValue('item_hook')).'\') '); $this->context->smarty->assign('confirmation', $this->l('Successful deletion.')); } else $this->context->smarty->assign('error', $this->l('Can\'t delete the slide.')); } protected function updateItem() { $id_item = (int)Tools::getValue('item_id'); $title = Tools::getValue('item_title'); $content = Tools::getValue('item_html'); if (!Validate::isCleanHtml($title, (int)Configuration::get('PS_ALLOW_HTML_IFRAME')) || !Validate::isCleanHtml($content,(int)Configuration::get('PS_ALLOW_HTML_IFRAME'))) { $this->context->smarty->assign('error', $this->l('Invalid content')); return false; } $new_image = ''; $image_w = (is_numeric(Tools::getValue('item_img_w'))) ? (int)Tools::getValue('item_img_w') : ''; $image_h = (is_numeric(Tools::getValue('item_img_h'))) ? (int)Tools::getValue('item_img_h') : ''; if(!empty($_FILES['item_img']['name'])) { if ($old_image = Db::getInstance()->getValue('SELECT image FROM `'._DB_PREFIX_.'themeconfigurator` WHERE id_item = '.(int)$id_item)) $this->_deleteImages($old_image); if (!$image = $this->uploadImage($_FILES['item_img'], $image_w, $image_h)) return false; $new_image = 'image = \''.pSQL($image).'\','; } else { $image_w = ''; $image_h = ''; } if (!Db::getInstance()->execute(' UPDATE `'._DB_PREFIX_.'themeconfigurator` SET title = \''.pSQL($title).'\', title_use = '.(int)Tools::getValue('item_title_use').', hook = \''.pSQL(Tools::getValue('item_hook')).'\', url = \''.pSQL(Tools::getValue('item_url')).'\', target = '.(int)Tools::getValue('item_target').', '.$new_image.' image_w = '.(int)$image_w.', image_h = '.(int)$image_h.', active = '.(int)Tools::getValue('item_active').', html = \''.pSQL($content).'\' WHERE id_item = '.(int)Tools::getValue('item_id') )) { if ($image = Db::getInstance()->getValue('SELECT image FROM `'._DB_PREFIX_.'themeconfigurator` WHERE id_item = '.(int)Tools::getValue('item_id'))) $this->deleteImage($image); $this->context->smarty->assign('error', $this->l('An error occured while saving data.')); return false; } $this->context->smarty->assign('confirmation', $this->l('Successfully updated.')); return true; } protected function uploadImage($image, $image_w = '', $image_h = '') { $res = false; if (is_array($image) && (ImageManager::validateUpload($image, $this->max_image_size) === false) && ($tmp_name = tempnam(_PS_TMP_IMG_DIR_, 'PS')) && move_uploaded_file($image['tmp_name'], $tmp_name)) { $type = Tools::strtolower(Tools::substr(strrchr($image['name'], '.'), 1)); $img_name = Tools::encrypt($image['name'].sha1(microtime())).'.'.$type; Configuration::set('PS_IMAGE_QUALITY','png_all'); if (ImageManager::resize($tmp_name, dirname(__FILE__).'/images/'.$img_name, $image_w, $image_h)) $res = true; } if (isset($temp_name)) @unlink($tmp_name); if (!$res) { $this->context->smarty->assign('error', $this->l('An error occurred during the image upload.')); return false; } return $img_name; } public function getContent() { if (Tools::isSubmit('submitModule')) { Configuration::updateValue('PS_QUICK_VIEW', (int)Tools::getValue('quick_view')); foreach($this->getConfigurableModules() as $module) { if (!isset($module['is_module']) || !$module['is_module'] || !Validate::isModuleName($module['name']) || !Tools::isSubmit($module['name'])) continue; $module_instance = Module::getInstanceByName($module['name']); if ($module_instance === false || !is_object($module_instance)) continue; $is_installed = (int)Validate::isLoadedObject($module_instance); if ($is_installed) { if (($active = (int)Tools::getValue($module['name'])) == $module_instance->active) continue; if ($active) $module_instance->enable(); else $module_instance->disable(); } else if ((int)Tools::getValue($module['name'])) $module_instance->install(); } } if (Tools::isSubmit('newItem')) $this->addItem(); elseif (Tools::isSubmit('updateItem')) $this->updateItem(); elseif (Tools::isSubmit('removeItem')) $this->removeItem(); $html = $this->renderConfigurationForm(); $html .= $this->renderThemeConfiguratorForm(); return $html; } protected function addItem() { $title = Tools::getValue('item_title'); $content = Tools::getValue('item_html'); if (!Validate::isCleanHtml($title, (int)Configuration::get('PS_ALLOW_HTML_IFRAME')) || !Validate::isCleanHtml($content, (int)Configuration::get('PS_ALLOW_HTML_IFRAME'))) { $this->context->smarty->assign('error', $this->l('Invalid content')); return false; } if (!$current_order = (int)Db::getInstance()->getValue(' SELECT item_order + 1 FROM `'._DB_PREFIX_.'themeconfigurator` WHERE id_shop = '.(int)$this->context->shop->id.' AND id_lang = '.(int)Tools::getValue('id_lang').' AND hook = \''.pSQL(Tools::getValue('item_hook')).'\' ORDER BY item_order DESC' )) $current_order = 1; $image_w = is_numeric(Tools::getValue('item_img_w')) ? (int)Tools::getValue('item_img_w') : ''; $image_h = is_numeric(Tools::getValue('item_img_h')) ? (int)Tools::getValue('item_img_h') : ''; if(!empty($_FILES['item_img']['name'])) { if (!$image = $this->uploadImage($_FILES['item_img'], $image_w, $image_h)) return false; } else { $image = ''; $image_w = ''; $image_h = ''; } if (!Db::getInstance()->Execute(' INSERT INTO `'._DB_PREFIX_.'themeconfigurator` ( `id_shop`, `id_lang`, `item_order`, `title`, `title_use`, `hook`, `url`, `target`, `image`, `image_w`, `image_h`, `html`, `active` ) VALUES ( \''.(int)$this->context->shop->id.'\', \''.(int)Tools::getValue('id_lang').'\', \''.(int)$current_order.'\', \''.pSQL($title).'\', \''.(int)Tools::getValue('item_title_use').'\', \''.pSQL(Tools::getValue('item_hook')).'\', \''.pSQL(Tools::getValue('item_url')).'\', \''.(int)Tools::getValue('item_target').'\', \''.pSQL($image).'\', \''.pSQL($image_w).'\', \''.pSQL($image_h).'\', \''.pSQL($content).'\', 1) ')) { if (!Tools::isEmpty($image)) $this->deleteImage($image); $this->context->smarty->assign('error', $this->l('An error occured while saving data.')); return false; } $this->context->smarty->assign('confirmation', $this->l('New item added successfull.')); return true; } public function renderConfigurationForm() { $inputs = array(); foreach ($this->getConfigurableModules() as $module) { $desc = ''; if (isset($module['is_module']) && $module['is_module']) { $module_instance = Module::getInstanceByName($module['name']); if (Validate::isLoadedObject($module_instance) && method_exists($module_instance, 'getContent')) $desc = ''.$this->l('Configure').''; } if (!$desc && isset($module['desc']) && $module['desc']) $desc = $module['desc']; $inputs[] = array( 'type' => 'switch', 'label' => $module['label'], 'name' => $module['name'], 'desc' => $desc, 'values' => array( array( 'id' => 'active_on', 'value' => 1, 'label' => $this->l('Enabled') ), array( 'id' => 'active_off', 'value' => 0, 'label' => $this->l('Disabled') ) ), ); } $inputs[] = array( 'type' => 'free', 'label' => $this->l('Live configurator'), 'name' => 'live-conf' ); $fields_form = array( 'form' => array( 'legend' => array( 'title' => $this->l('Settings'), 'icon' => 'icon-cogs' ), 'input' => $inputs, 'submit' => array( 'title' => $this->l('Save'), 'class' => 'btn btn-primary') ), ); $helper = new HelperForm(); $helper->show_toolbar = false; $helper->table = $this->table; $lang = new Language((int)Configuration::get('PS_LANG_DEFAULT')); $helper->default_form_language = $lang->id; $helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0; $this->fields_form = array(); $helper->identifier = $this->identifier; $helper->submit_action = 'submitModule'; $helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false).'&configure='.$this->name.'&tab_module='.$this->tab.'&module_name='.$this->name; $helper->token = Tools::getAdminTokenLite('AdminModules'); $helper->tpl_vars = array( 'fields_value' => array_merge($this->getConfigFieldsValues(), array('live-conf' => ' Live configurator')), 'languages' => $this->context->controller->getLanguages(), 'id_language' => $this->context->language->id ); return $helper->generateForm(array($fields_form)); } protected function renderThemeConfiguratorForm() { $id_shop = (int)$this->context->shop->id; $items = array(); $this->context->smarty->assign('htmlcontent', array( 'admin_tpl_path' => $this->admin_tpl_path, 'hooks_tpl_path' => $this->hooks_tpl_path, 'info' => array( 'module' => $this->name, 'name' => $this->displayName, 'version' => $this->version, 'psVersion' => _PS_VERSION_, 'context' => (Configuration::get('PS_MULTISHOP_FEATURE_ACTIVE') == 0) ? 1 : ($this->context->shop->getTotalShops() != 1) ? $this->context->shop->getContext() : 1 ) )); foreach ($this->languages as $language) { $hooks[$language['id_lang']] = array('home', 'top', 'left', 'right', 'footer'); foreach ($hooks[$language['id_lang']] as $hook) $items[$language['id_lang']][$hook] = Db::getInstance()->ExecuteS(' SELECT * FROM `'._DB_PREFIX_.'themeconfigurator` WHERE id_shop = '.(int)$id_shop.' AND id_lang = '.(int)$language['id_lang'].' AND hook = \''.pSQL($hook).'\' ORDER BY item_order ASC' ); } $this->context->smarty->assign('htmlitems', array( 'items' => $items, 'lang' => array( 'default' => $this->default_language, 'all' => $this->languages, 'lang_dir' => _THEME_LANG_DIR_, 'user' => $this->context->language->id ), 'postAction' => 'index.php?tab=AdminModules&configure='.$this->name.'&token='.Tools::getAdminTokenLite('AdminModules').'&tab_module=other&module_name='.$this->name.'', 'id_shop' => $id_shop )); return $this->display(__FILE__, 'views/templates/admin/admin.tpl'); } protected function getConfigurableModules() { return array( array( 'label' => $this->l('Display the reinsurance block'), 'name' => 'blockreinsurance', 'value' => (int)(Validate::isLoadedObject($module = Module::getInstanceByName('blockreinsurance')) && $module->isEnabledForShopContext()), 'is_module' => true, ), array( 'label' => $this->l('Display the social following links'), 'name' => 'blocksocial', 'value' => (int)(Validate::isLoadedObject($module = Module::getInstanceByName('blocksocial')) && $module->isEnabledForShopContext()), 'is_module' => true, ), array( 'label' => $this->l('Display contact information'), 'name' => 'blockcontactinfos', 'value' => (int)(Validate::isLoadedObject($module = Module::getInstanceByName('blockcontactinfos')) && $module->isEnabledForShopContext()), 'is_module' => true, ), array( 'label' => $this->l('Display social buttons on the products page'), 'name' => 'addsharethis', 'value' => (int)(Validate::isLoadedObject($module = Module::getInstanceByName('addsharethis')) && $module->isEnabledForShopContext()), 'is_module' => true, ), array( 'label' => $this->l('Display facebook block on the home page'), 'name' => 'blockfacebook', 'value' => (int)(Validate::isLoadedObject($module = Module::getInstanceByName('blockfacebook')) && $module->isEnabledForShopContext()), 'is_module' => true, ), array( 'label' => $this->l('Customer cms information block'), 'name' => 'blockcmsinfo', 'value' => (int)(Validate::isLoadedObject($module = Module::getInstanceByName('blockcmsinfo')) && $module->isEnabledForShopContext()), 'is_module' => true, ), array( 'label' => $this->l('Enable Quick view'), 'name' => 'quick_view', 'value' => (int)Tools::getValue('PS_QUICK_VIEW', Configuration::get('PS_QUICK_VIEW')) ), array( 'label' => $this->l('Enable top banner'), 'name' => 'blockbanner', 'value' => (int)(Validate::isLoadedObject($module = Module::getInstanceByName('blockbanner')) && $module->isEnabledForShopContext()), 'is_module' => true, ), array( 'label' => $this->l('Enable product payment logos'), 'name' => 'productpaymentlogos', 'value' => (int)(Validate::isLoadedObject($module = Module::getInstanceByName('productpaymentlogos')) && $module->isEnabledForShopContext()), 'is_module' => true, ) ); } public function getConfigFieldsValues() { $values = array(); foreach ($this->getConfigurableModules() as $module) $values[$module['name']] = $module['value']; return $values; } }