array('class' => '.flashsale-countdown-box', 'property' => 'width', 'field' => 'box_width'), 1 => array('class' => '.flashsale-countdown-box', 'property' => 'border-width', 'field' => 'box_border_width'), 2 => array('class' => '.flashsale-countdown-box', 'property' => 'border-style', 'field' => 'box_border_style'), 3 => array('class' => '.flashsale-countdown-box', 'property' => 'border-color', 'field' => 'box_border_color'), 4 => array('class' => '.flashsale-countdown-box', 'property' => 'background-color', 'field' => 'box_background_color'), 5 => array('class' => '.flashsale-countdown-box .content i.icon-clock-o', 'property' => 'color', 'field' => 'icon_color'), 6 => array('class' => '.flashsale-countdown-box .content i.icon-clock-o', 'property' => 'font-size', 'field' => 'icon_font_size'), 7 => array('class' => '.flashsale-countdown-box .content i.icon-clock-o', 'property' => 'display', 'field' => 'icon_display'), 8 => array('class' => '.flashsale-countdown-box .content span.title', 'property' => 'color', 'field' => 'title_color'), 9 => array('class' => '.flashsale-countdown-box .content span.title', 'property' => 'font-size', 'field' => 'title_font_size'), 10 => array('class' => '.flashsale-countdown-box .content span.countdown', 'property' => 'color', 'field' => 'countdown_color'), 11 => array('class' => '.flashsale-countdown-box .content span.countdown', 'property' => 'font-size', 'field' => 'countdown_font_size'), ); protected static $cache_flash_sales = array(); public function __construct() { $this->name = 'flashsales'; $this->tab = 'front_office_features'; $this->version = '2.0.0'; $this->author = 'Agencya'; $this->module_key = '36c6c0e545ecf7134526a92f293d06da'; $this->bootstrap = true; parent::__construct(); $this->displayName = $this->l('Flash Sales - Extended'); $this->description = $this->l('Add, edit, customize your flash sales effectively and intuitively to boost your sales!'); $this->ps_versions_compliancy = array('min' => '1.5.0', 'max' => '1.6.9'); } public function install($delete_params = true) { if (!parent::install() || !$this->registerHook('actionAdminControllerSetMedia') || !$this->registerHook('header') || !$this->registerHook('displayHome') || !$this->registerHook('displayHomeTab') || !$this->registerHook('displayHomeTabContent') || !$this->registerHook('rightColumn') || !$this->registerHook('leftColumn') || !$this->registerHook('displayProductListReviews') || !$this->registerHook('actionObjectDeleteAfter') || !$this->registerHook('displayRightColumnProduct')) return false; // Install database if ($delete_params) if (!$this->installDb()) return false; // Instal conf if (!$this->installConf()) return false; $languages = Language::getLanguages(); // Install Tab $tab = new Tab(); foreach ($languages as $lang) $tab->name[$lang['id_lang']] = $this->l('Flash Sales'); $tab->class_name = 'AdminFlashSales'; $tab->id_parent = (int)Tab::getIdFromClassName('AdminPriceRule'); $tab->module = $this->name; if (!$tab->add()) return false; // Install Meta $meta = new Meta(); $meta->page = 'module-'.$this->name.'-page'; $meta->configurable = 1; foreach ($languages as $language) { if ($language['iso_code'] == 'fr') { $meta->title[(int)$language['id_lang']] = 'Ventes flash'; $meta->description[(int)$language['id_lang']] = ''; $meta->url_rewrite[(int)$language['id_lang']] = 'ventes-flash'; } else { $meta->title[(int)$language['id_lang']] = 'Flash sales'; $meta->description[(int)$language['id_lang']] = ''; $meta->url_rewrite[(int)$language['id_lang']] = 'flash-sales'; } } $meta->add(); if (version_compare(_PS_VERSION_, '1.6', '>=')) { $themes = Theme::getThemes(); $theme_meta_value = array(); foreach ($themes as $theme) { $theme_meta_value[] = array( 'id_theme' => $theme->id, 'id_meta' => (int)$meta->id, 'left_column' => (int)$theme->default_left_column, 'right_column' => (int)$theme->default_right_column ); } if (count($theme_meta_value) > 0) Db::getInstance()->insert('theme_meta', (array)$theme_meta_value, false, true, DB::INSERT_IGNORE); } $this->_clearCache('*'); return true; } public function installDb() { $sql = array(); include(dirname(__FILE__).'/sql/install.php'); foreach ($sql as $s) if (!Db::getInstance()->execute($s)) return false; return true; } public function installConf() { if (!Configuration::updateValue('FLASHSALE_PRODUCTS_NB', '8') || !Configuration::updateValue('FLASHSALE_DEL_SPECIFICPRICE', '1') || !Configuration::updateValue('FLASHSALE_DISPLAY_TOPMENU', '0')) return false; $values = array(); $languages = Language::getLanguages(false); foreach ($languages as $language) { $values['FLASHSALE_PAGE_TITLE'] = array($language['id_lang'] => $language['iso_code'] == 'fr' ? 'Ventes Flash' : 'Flash Sales'); $values['FLASHSALE_COUNTDOWN_STRING'] = array($language['id_lang'] => $language['iso_code'] == 'fr' ? 'Vente flash' : 'Flash sale'); foreach ($values as $key => $value) if (!Configuration::updateValue($key, $value)) return false; } return true; } public function uninstall($delete_params = true) { // Uninstall Module if (!parent::uninstall()) return false; // Delete specific prices & database if ($delete_params) if (!$this->deleteSpecificPrice() || !$this->uninstallDb()) return false; // Delete conf if (!$this->uninstallConf()) return false; // Delete Tabs $tabs = Tab::getCollectionFromModule($this->name); foreach ($tabs as $tab) $tab->delete(); // Delete Meta $metas = Meta::getMetaByPage('module-'.$this->name.'-page', (int)$this->context->language->id); $meta = new Meta((int)$metas['id_meta']); if ($meta->delete() && version_compare(_PS_VERSION_, '1.6', '>=')) Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'theme_meta` WHERE id_meta='.(int)$meta->id); // Delete top-menu link if (class_exists('MenuTopLinks')) { $shop_id = (int)Shop::getContextShopID(); $shop_group_id = Shop::getGroupFromShop($shop_id); $conf = Configuration::get('MOD_BLOCKTOPMENU_ITEMS', null, $shop_group_id, $shop_id); $id_linksmenutop = $this->addTopMenuLink(); MenuTopLinks::remove($id_linksmenutop, $shop_id); Configuration::updateValue('MOD_BLOCKTOPMENU_ITEMS', (string)str_replace(array('LNK'.$id_linksmenutop.',', 'LNK'.$id_linksmenutop), '', $conf), false, $shop_group_id, $shop_id); } // Clear cache $this->_clearCache('*'); return true; } public function deleteSpecificPrice() { $ids_flash_sale = FlashSale::getFlashSalesLite(); foreach ($ids_flash_sale as $id_flash_sale) { $flash_sale = new FlashSale((int)$id_flash_sale); $flash_sale->deleteSpecificPrice(); } return true; } public function uninstallDb() { $sql = array(); include(dirname(__FILE__).'/sql/uninstall.php'); foreach ($sql as $s) if (!Db::getInstance()->execute($s)) return false; return true; } public function uninstallConf() { Configuration::deleteByName('FLASHSALE_PAGE_TITLE'); Configuration::deleteByName('FLASHSALE_COUNTDOWN_STRING'); Configuration::deleteByName('FLASHSALE_PRODUCTS_NB'); Configuration::deleteByName('FLASHSALE_DEL_SPECIFICPRICE'); Configuration::deleteByName('FLASHSALE_DISPLAY_TOPMENU'); return true; } public function reset() { if (!$this->uninstall(false)) return false; if (!$this->install(false)) return false; return true; } public function getContent() { if (Tools::isSubmit('submitFlashSales')) { $this->updateConfigFieldsValues(); $topmenu = Module::getInstanceByName('blocktopmenu'); if ($topmenu && $topmenu->active) $this->updateTopMenuDisplay(); $this->updateCssFile(); if (!count($this->_post_errors)) Tools::redirectAdmin($this->context->link->getAdminLink('AdminModules', false).'&configure='.$this->name.'&conf=4&token='.Tools::getAdminTokenLite('AdminModules')); else foreach ($this->_post_errors as $err) $this->_html .= $this->displayError($err); } if (version_compare(_PS_VERSION_, '1.6', '<')) { $this->_html .= '
'; $this->_html .= $this->renderFlashSalesForm(); $this->_html .= '
'; } else $this->_html .= $this->renderFlashSalesForm(); return $this->_html; } public function renderFlashSalesForm() { $languages = Language::getLanguages(); $topmenu = Module::getInstanceByName('blocktopmenu'); $css_file = Tools::file_get_contents(_PS_MODULE_DIR_.$this->name.'/views/css/design.css'); $css_fields = $this->loadCssFields($css_file); $this->context->smarty->assign(array( 'languages' => Language::getLanguages(true, Context::getContext()->shop->id), 'default_language' => (int)Configuration::get('PS_LANG_DEFAULT'), 'currentIndex' => $this->context->link->getAdminLink('AdminModules', true).'&configure='.$this->name.'&tab_module='.$this->tab.'&module_name='.$this->name, 'currentToken' => Tools::getAdminTokenLite('AdminModules'), 'css_file' => $css_file, 'css_fields' => $css_fields, 'topmenu' => (bool)($topmenu && $topmenu->active), 'tpl_general' => _PS_MODULE_DIR_.$this->name.'/views/templates/admin/settings/general.tpl', 'tpl_display' => _PS_MODULE_DIR_.$this->name.'/views/templates/admin/settings/display.tpl', 'tpl_css' => _PS_MODULE_DIR_.$this->name.'/views/templates/admin/settings/css.tpl', )); if (version_compare(_PS_VERSION_, '1.6', '<')) { $this->context->controller->addCss($this->_path.'views/css/admin-theme.css', 'all'); $this->context->controller->addJS(array( _MODULE_DIR_.'flashsales/views/js/tools/bootstrap.js', _MODULE_DIR_.'flashsales/views/js/tools/jquery.autosize.js', _MODULE_DIR_.'flashsales/views/js/tools/functions.js' )); } $this->context->controller->addJqueryPlugin('colorpicker'); $this->context->controller->addJS(_MODULE_DIR_.$this->name.'/views/js/settings.js'); return $this->context->smarty->createTemplate(_PS_MODULE_DIR_.$this->name.'/views/templates/admin/settings/form.tpl', $this->context->smarty)->fetch(); } protected function updateConfigFieldsValues() { $config = $this->getConfigFieldsValues(); foreach ($config as $key => $val) { if (is_array($val) && count($val)) foreach ($val as $v) if (!Validate::isCleanHTML($v)) { $this->_post_errors[] = sprintf($this->l('Unvalid lang field : "%s"'), $key); return false; } Configuration::updateValue($key, $val); } } protected function loadCssFields($content) { if (empty($content)) return array(); $fields = array(); foreach ($this->_css_fields as $css_field) { $pos = stripos($content, $css_field['class']); $pos = stripos($content, $css_field['property'], $pos); $pos = stripos($content, ':', $pos); $start = $pos + 1; $end = stripos($content, ';', $start); $output = Tools::substr($content, $start, $end - $start); // replace pattern $pattern = array('/px/', '/%/', '/inline-block/', '/solid/', '/none/'); $replace = array('', '', 1, 1, 0); $output = preg_replace($pattern, $replace, $output); // delete spaces $output = trim($output); $fields[$css_field['field']] = $output; } return $fields; } protected function updateCssFile() { $content = strip_tags(Tools::getValue('css_file')); // replace correct end of line $content = str_replace("\r\n", PHP_EOL, $content); // Magic Quotes shall... not.. PASS! if (_PS_MAGIC_QUOTES_GPC_) $content = Tools::stripslashes($content); if (Validate::isCleanHTML($content)) { $path = _PS_MODULE_DIR_.$this->name.'/views/css/design.css'; if (!file_put_contents($path, $content)) $this->_post_errors[] = sprintf($this->l('File "%s" cannot be created'), dirname($path)); } else $this->_post_errors[] = $this->l('Your css cannot contain JavaScript code.'); } protected function updateTopMenuDisplay() { $shop_id = (int)Shop::getContextShopID(); $shop_group_id = Shop::getGroupFromShop($shop_id); $conf = Configuration::get('MOD_BLOCKTOPMENU_ITEMS', null, $shop_group_id, $shop_id); $display = Tools::getValue('flashsale_display_topmenu'); Configuration::updateValue('FLASHSALE_DISPLAY_TOPMENU', (int)$display); $id_linksmenutop = $this->addTopMenuLink(); if (!$display) { MenuTopLinks::remove($id_linksmenutop, $shop_id); Configuration::updateValue('MOD_BLOCKTOPMENU_ITEMS', (string)str_replace(array('LNK'.$id_linksmenutop.',', 'LNK'.$id_linksmenutop), '', $conf), false, $shop_group_id, $shop_id); } else { $menu_items = Tools::strlen($conf) ? explode(',', $conf) : array(); if (!in_array('LNK'.$id_linksmenutop, $menu_items)) $menu_items[] = 'LNK'.$id_linksmenutop; Configuration::updateValue('MOD_BLOCKTOPMENU_ITEMS', (string)implode(',', $menu_items), false, (int)$shop_group_id, (int)$shop_id); } return true; } protected function addTopMenuLink() { $id_linksmenutop = 0; $labels = array(); $page_link = array(); $languages = Language::getLanguages(); foreach ($languages as $language) { $labels[(int)$language['id_lang']] = $language['iso_code'] == 'fr' ? 'Ventes Flash' : 'Flash Sales'; $page_link[(int)$language['id_lang']] = $this->context->link->getModuleLink($this->name, 'page', array(), null, (int)$language['id_lang']); $links = MenuTopLinks::gets((int)$language['id_lang'], null, (int)Shop::getContextShopID()); foreach ($links as $link) { if ($link['link'] == $page_link[(int)$language['id_lang']]) { $id_linksmenutop = (int)$link['id_linksmenutop']; break 2; } } } if ($id_linksmenutop == 0) { MenuTopLinks::add($page_link, $labels, 0, (int)Shop::getContextShopID()); $id_linksmenutop = $this->addTopMenuLink(); } return $id_linksmenutop; } public function getConfigFieldsValues() { $fields = array(); $languages = Language::getLanguages(); foreach ($languages as $language) { $fields['FLASHSALE_PAGE_TITLE'][$language['id_lang']] = Tools::getValue('flashsale_page_title_'.$language['id_lang'], Configuration::get('FLASHSALE_PAGE_TITLE', (int)$language['id_lang'])); $fields['FLASHSALE_COUNTDOWN_STRING'][$language['id_lang']] = Tools::getValue('flashsale_countdown_string_'.$language['id_lang'], Configuration::get('FLASHSALE_COUNTDOWN_STRING', (int)$language['id_lang'])); } $fields['FLASHSALE_PRODUCTS_NB'] = (int)Tools::getValue('flashsale_products_nb', Configuration::get('FLASHSALE_PRODUCTS_NB')); $fields['FLASHSALE_DEL_SPECIFICPRICE'] = (bool)Tools::getValue('flashsale_del_specificprice', Configuration::get('FLASHSALE_DEL_SPECIFICPRICE')); return $fields; } public function hookActionAdminControllerSetMedia() { $this->context->controller->addCSS($this->_path.'views/css/admin-design.css', 'all'); } public function hookHeader($params) { // TODO add to other hooks $this->_clearCache('*'); $this->context->controller->addJS($this->_path.'views/js/countdown.js'); $this->context->controller->addCSS($this->_path.'views/css/design.css', 'all'); $this->context->controller->addCSS($this->_path.'views/css/global.css', 'all'); } public function hookActionObjectDeleteAfter($params) { $object = $params['object']; if (get_class($object) === 'Product') Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'flash_sale_products` WHERE `id_product` = '.(int)$object->id); elseif (get_class($object) === 'Category') Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'flash_sale_products` WHERE `id_category` = '.(int)$object->id); elseif (get_class($object) === 'Manufacturer') Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'flash_sale_products` WHERE `id_manufacturer` = '.(int)$object->id); elseif (get_class($object) === 'SpecificPrice') Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'flash_sale_specific_prices` WHERE `id_specific_price` = '.(int)$object->id); $this->_clearCache('*'); return true; } public function hookdisplayHome($params) { if (!$this->isCached('home.tpl', $this->getCacheId('home'))) { if (!isset(flashsales::$cache_flash_sales['home'])) { $flash_sales = FlashSale::getFlashSales((int)$this->context->language->id, 'home'); if (is_array($flash_sales) && count($flash_sales)) { foreach ($flash_sales as $key => $flash_sale) { if (!$this->getProducts('home', (int)$flash_sale['id_flash_sale'])) { unset($flash_sales[$key]); continue; } $banner = _PS_MODULE_DIR_.$this->name.'/views/img/banner/'.(int)$flash_sale['id_flash_sale'].'.jpg'; $flash_sales[$key]['banner'] = file_exists($banner) ? _MODULE_DIR_.$this->name.'/views/img/banner/'.(int)$flash_sale['id_flash_sale'].'.jpg' : false; } if (!count($flash_sales)) $flash_sales = false; } flashsales::$cache_flash_sales['home'] = $flash_sales; } if (flashsales::$cache_flash_sales['home'] === false) return false; $this->smarty->assign(array( 'flash_sales' => flashsales::$cache_flash_sales['home'], 'txt' => Configuration::get('FLASHSALE_COUNTDOWN_STRING', (int)$this->context->language->id), 'tpl_countdown' => _PS_MODULE_DIR_.$this->name.'/views/templates/hook/countdown.tpl', )); } return $this->display(__FILE__, 'home.tpl', $this->getCacheId('home')); } public function hookDisplayHomeTab($params) { if (version_compare(_PS_VERSION_, '1.6', '<')) return false; if (!$this->isCached('home-tab.tpl', $this->getCacheId('home-tab'))) { if (!isset(flashsales::$cache_flash_sales['home_tab'])) flashsales::$cache_flash_sales['home_tab'] = $this->getProducts('home_tab'); if (flashsales::$cache_flash_sales['home_tab'] === false) return false; } return $this->display(__FILE__, 'home-tab.tpl', $this->getCacheId('home-tab')); } public function hookdisplayHomeTabContent($params) { if (version_compare(_PS_VERSION_, '1.6', '<')) return false; if (!$this->isCached('home-tab-content.tpl', $this->getCacheId('home-tab-content'))) { if (!isset(flashsales::$cache_flash_sales['home_tab'])) flashsales::$cache_flash_sales['home_tab'] = $this->getProducts('home_tab'); if (flashsales::$cache_flash_sales['home_tab'] === false) return false; $this->smarty->assign(array( 'flash_sales' => flashsales::$cache_flash_sales['home_tab'], 'homeSize' => Image::getSize(ImageType::getFormatedName('home')) )); } return $this->display(__FILE__, 'home-tab-content.tpl', $this->getCacheId('home-tab-content')); } public function hookRightColumn($params) { if (!$this->isCached('column.tpl', $this->getCacheId('column'))) { if (!isset(flashsales::$cache_flash_sales['column'])) flashsales::$cache_flash_sales['column'] = $this->getProducts('column'); if (flashsales::$cache_flash_sales['column'] === false) return false; $this->smarty->assign(array( 'flash_sales' => flashsales::$cache_flash_sales['column'], 'mediumSize' => Image::getSize(ImageType::getFormatedName('medium')), 'smallSize' => Image::getSize(ImageType::getFormatedName('small')), 'homeSize' => Image::getSize(ImageType::getFormatedName('home')) )); } return $this->display(__FILE__, 'column.tpl', $this->getCacheId('column')); } public function hookLeftColumn($params) { return $this->hookRightColumn($params); } public function hookDisplayProductListReviews($params) { $id_product = (int)$params['product']['id_product']; if (!($specific_price = FlashSale::getProductSpecificPrice($id_product))) return; $this->smarty->assign(array( 'to' => (int)strtotime($specific_price['to']), 'txt' => Configuration::get('FLASHSALE_COUNTDOWN_STRING', (int)$this->context->language->id), 'id_product' => $id_product )); return $this->display(__FILE__, 'countdown.tpl'); } public function hookDisplayRightColumnProduct($params) { if (!isset($params['product']['id_product'])) $params['product']['id_product'] = (int)Tools::getValue('id_product'); return $this->hookDisplayProductListReviews($params); } public function getProducts($filter = null, $id_flash_sale = null) { if (Configuration::get('PS_CATALOG_MODE')) return false; $nb = (int)Configuration::get('FLASHSALE_PRODUCTS_NB'); return FlashSale::getAllProducts((int)$this->context->language->id, $id_flash_sale, $filter, false, 0, ($nb ? $nb : 8)); } public function _clearCache($template, $cache_id = null, $compile_id = null) { Tools::clearCache(Context::getContext()->smarty, $this->getTemplatePath('homefeatured.tpl')); parent::_clearCache('column.tpl', 'column'); parent::_clearCache('home-tab-content.tpl', 'home-tab-content'); parent::_clearCache('home-tab.tpl', 'home-tab'); parent::_clearCache('home.tpl', 'home'); } } ?>