toutpratique/modules/flashsales/flashsales.php
2017-01-09 09:41:17 -08:00

676 lines
22 KiB
PHP

<?php
/**
* 2014 - Agencya SARL
*
* NOTICE OF LICENSE
*
* The source code of this module is under a commercial license.
* Each license is unique and can be installed and used on only one shop.
* Any reproduction or representation total or partial of the module, one or more of its components,
* by any means whatsoever, without express permission from us is prohibited.
* If you have not received this module from us, thank you for contacting us.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade this module to newer
* versions in the future.
*
* @author Agencya
* @copyright 2014 - Agencya SARL
* @license commercial
* International Registered Trademark & Property of Agencya SARL
*/
if (!defined('_PS_VERSION_'))
exit;
if (!defined('_MYSQL_ENGINE_'))
define('_MYSQL_ENGINE_', 'MyISAM');
require_once(_PS_MODULE_DIR_.'flashsales/models/FlashSale.php');
if (version_compare(_PS_VERSION_, '1.6.0.7', '<'))
require_once(_PS_MODULE_DIR_.'flashsales/models/Uploader.php');
class flashsales extends Module {
private $_html = '';
private $_post_errors = array();
private $_css_fields = array(
0 => 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')
|| !$this->registerHook('displayFlashsalesBlock'))
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 .= '<div id="flashsale-content" class="bootstrap">';
$this->_html .= $this->renderFlashSalesForm();
$this->_html .= '</div>';
}
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)
{
if(is_object($params['product'])) {
$params['product'] = (array) $params['product'];
}
if(isset($params['product']['id_product'])) {
$id_product = (int)$params['product']['id_product'];
} elseif (isset($params['product']['id'])) {
$id_product = (int)$params['product']['id'];
} else {
return;
}
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 hookDisplayFlashsalesBlock($params)
{
return $this->display(__FILE__, 'feature-block.tpl');
}
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');
}
}
?>