* @copyright 2007-2014 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;
use PrestaShop\PrestaShop\Core\Module\WidgetInterface;
class StCompare extends Module implements WidgetInterface
{
private $templateFile = array();
private $_html = '';
public $fields_form;
public $fields_value;
private $_prefix_st = 'ST_COMP_';
private $_st_themes = false;
public $validation_errors = array();
private static $video_position = array();
protected static $access_rights = 0775;
private $_hooks = array();
private $_items = array();
function __construct()
{
$this->name = 'stcompare';
$this->tab = 'front_office_features';
$this->version = '1.0.1';
$this->author = 'SUNNYTOO.COM';
$this->need_instance = 0;
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->getTranslator()->trans('Product Comparison', array(), 'Admin.Theme.Panda');
$this->description = $this->getTranslator()->trans('Adds a product comparison feature to your PrestaShop 1.7 site.', array(), 'Admin.Theme.Panda');
$this->ps_versions_compliancy = array('min' => '1.7', 'max' => _PS_VERSION_);
$this->controllers = array('compare');
$this->initPages();
$this->initHookArray();
$this->templateFile = array(
'module:stcompare/views/templates/hook/link.tpl',
'module:stcompare/views/templates/hook/fly.tpl',
'module:stcompare/views/templates/hook/header.tpl',
);
}
private function initPages()
{
$this->_items = array(
array(
'id' => 'picture',
'val' => '1',
'name' => $this->getTranslator()->trans('Picture', array(), 'Admin.Theme.Panda')
),
array(
'id' => 'name',
'val' => '2',
'name' => $this->getTranslator()->trans('Name', array(), 'Admin.Theme.Panda')
),
array(
'id' => 'price',
'val' => '4',
'name' => $this->getTranslator()->trans('Price', array(), 'Admin.Theme.Panda')
),
array(
'id' => 'rating',
'val' => '8',
'name' => $this->getTranslator()->trans('Rating', array(), 'Admin.Theme.Panda')
),
array(
'id' => 'short_desc',
'val' => '16',
'name' => $this->getTranslator()->trans('Short description', array(), 'Admin.Theme.Panda')
),
array(
'id' => 'stock',
'val' => '32',
'name' => $this->getTranslator()->trans('Stock', array(), 'Admin.Theme.Panda')
),
array(
'id' => 'main_variants',
'val' => '64',
'name' => $this->getTranslator()->trans('Main variants (Color)', array(), 'Admin.Theme.Panda')
),
array(
'id' => 'add_to_cart',
'val' => '128',
'name' => $this->getTranslator()->trans('Add to cart button', array(), 'Admin.Theme.Panda')
),
);
}
private function initHookArray()
{
$this->_hooks = array(
'Header' => array(
array(
'id' => 'displayNav1',
'val' => '1',
'name' => $this->getTranslator()->trans('Topbar left - displayNav1', array(), 'Admin.Theme.Panda'),
'in_header' => 1,
),
array(
'id' => 'displayNav2',
'val' => '1',
'name' => $this->getTranslator()->trans('Topbar right - displayNav2', array(), 'Admin.Theme.Panda'),
'in_header' => 1,
),
array(
'id' => 'displayNav3',
'val' => '1',
'name' => $this->getTranslator()->trans('Topbar center - displayNav3', array(), 'Admin.Theme.Panda'),
'in_header' => 1,
),
array(
'id' => 'displayTop',
'val' => '1',
'name' => $this->getTranslator()->trans('displayTop', array(), 'Admin.Theme.Panda'),
'in_header' => 1,
),
array(
'id' => 'displayHeaderCenter',
'val' => '1',
'name' => $this->getTranslator()->trans('displayHeaderCenter', array(), 'Admin.Theme.Panda'),
'in_header' => 1,
),
array(
'id' => 'displayHeaderLeft',
'val' => '1',
'name' => $this->getTranslator()->trans('displayHeaderLeft', array(), 'Admin.Theme.Panda'),
'in_header' => 1,
),
array(
'id' => 'displayHeaderBottom',
'val' => '1',
'name' => $this->getTranslator()->trans('displayHeaderBottom', array(), 'Admin.Theme.Panda'),
'in_header' => 1,
),
array(
'id' => 'displayMainMenuWidget',
'val' => '1',
'name' => $this->getTranslator()->trans('Main menu widget', array(), 'Admin.Theme.Transformer'),
'in_header' => 1,
),
),
'Product page' => array(
array(
'id' => 'displayProductNameRight',
'val' => '1',
'name' => $this->getTranslator()->trans('displayProductNameRight', array(), 'Admin.Theme.Panda'),
'in_product_page' => 1,
),
array(
'id' => 'displayUnderProductName',
'val' => '1',
'name' => $this->getTranslator()->trans('displayUnderProductName', array(), 'Admin.Theme.Panda'),
'in_product_page' => 1,
),
array(
'id' => 'displayProductPriceRight',
'val' => '1',
'name' => $this->getTranslator()->trans('displayProductPriceRight', array(), 'Admin.Theme.Panda'),
'in_product_page' => 1,
),
array(
'id' => 'displayProductCartRight',
'val' => '1',
'name' => $this->getTranslator()->trans('displayProductCartRight', array(), 'Admin.Theme.Panda'),
'in_product_page' => 1,
),
array(
'id' => 'displayLeftColumnProduct',
'val' => '1',
'name' => $this->getTranslator()->trans('displayLeftColumnProduct', array(), 'Admin.Theme.Panda'),
'in_product_page' => 1,
),
array(
'id' => 'displayProductLeftColumn',
'val' => '1',
'name' => $this->getTranslator()->trans('displayProductLeftColumn', array(), 'Admin.Theme.Panda'),
'in_product_page' => 1,
),
array(
'id' => 'displayProductCenterColumn',
'val' => '1',
'name' => $this->getTranslator()->trans('displayProductCenterColumn', array(), 'Admin.Theme.Panda'),
'in_product_page' => 1,
),
array(
'id' => 'displayProductRightColumn',
'val' => '1',
'name' => $this->getTranslator()->trans('displayProductRightColumn', array(), 'Admin.Theme.Panda'),
'in_product_page' => 1,
),
array(
'id' => 'displayRightColumnProduct',
'val' => '1',
'name' => $this->getTranslator()->trans('displayRightColumnProduct', array(), 'Admin.Theme.Panda'),
'in_product_page' => 1,
),
),
);
}
private function saveHook()
{
foreach($this->_hooks AS $key => $values)
{
if (!$key)
continue;
foreach($values AS $value)
{
$id_hook = Hook::getIdByName($value['id']);
$key = str_replace(' ','_', $key);
if (Tools::getValue($key.'_'.$value['id']))
{
if ($id_hook && Hook::getModulesFromHook($id_hook, $this->id))
continue;
if (!$this->isHookableOn($value['id']))
$this->validation_errors[] = $this->getTranslator()->trans('This module cannot be transplanted to ', array(), 'Admin.Theme.Panda').$value['id'];
else
$rs = $this->registerHook($value['id'], Shop::getContextListShopID());
}
else
{
if($id_hook && Hook::getModulesFromHook($id_hook, $this->id))
{
$this->unregisterHook($id_hook, Shop::getContextListShopID());
$this->unregisterExceptions($id_hook, Shop::getContextListShopID());
}
}
}
}
// clear module cache to apply new data.
Cache::clean('hook_module_list');
}
function install()
{
if (!parent::install()
|| !Configuration::updateValue($this->_prefix_st.'MAX', 10)
|| !Configuration::updateValue($this->_prefix_st.'HEADER_STYLE', 0)
|| !Configuration::updateValue($this->_prefix_st.'PRODUCT_STYLE', 0)
|| !Configuration::updateValue($this->_prefix_st.'WIDTH', 0)
|| !Configuration::updateValue($this->_prefix_st.'ITEMS', 255)
|| !Configuration::updateValue($this->_prefix_st.'FLY_OUT', 1)
|| !$this->registerHook('displayHeader')
|| !$this->registerHook('displayNav2')
|| !$this->registerHook('actionProductSearchAfter')
|| !$this->registerHook('displayProductCenterColumn')
|| !$this->registerHook('actionStAssemble')
)
return false;
return true;
}
public function getContent()
{
$this->initFieldsForm();
if (isset($_POST['savestcompare']))
{
foreach($this->fields_form as $form)
foreach($form['form']['input'] as $field)
if(isset($field['validation']))
{
$ishtml = ($field['validation']=='isAnything') ? true : false;
$errors = array();
$value = Tools::getValue($field['name']);
if (isset($field['required']) && $field['required'] && $value==false && (string)$value != '0')
$errors[] = sprintf(Tools::displayError('Field "%s" is required.'), $field['label']);
elseif($value)
{
$field_validation = $field['validation'];
if (!Validate::$field_validation($value))
$errors[] = sprintf(Tools::displayError('Field "%s" is invalid.'), $field['label']);
}
// Set default value
if ($value === false && isset($field['default_value']))
$value = $field['default_value'];
if(count($errors))
{
$this->validation_errors = array_merge($this->validation_errors, $errors);
}
elseif($value==false)
{
switch($field['validation'])
{
case 'isUnsignedId':
case 'isUnsignedInt':
case 'isInt':
case 'isBool':
$value = 0;
break;
default:
$value = '';
break;
}
Configuration::updateValue($this->_prefix_st.strtoupper($field['name']), $value);
}
else
Configuration::updateValue($this->_prefix_st.strtoupper($field['name']), $value, $ishtml);
}
$items = 0;
foreach($this->_items as $v)
$items += (int)Tools::getValue('items_'.$v['id']);
Configuration::updateValue($this->_prefix_st.'ITEMS', $items);
$this->saveHook();
if(count($this->validation_errors))
$this->_html .= $this->displayError(implode('
',$this->validation_errors));
else
$this->_html .= $this->displayConfirmation($this->getTranslator()->trans('Settings updated', array(), 'Admin.Theme.Transformer'));
$this->_clearCache('*');
}
$helper = $this->initForm();
return $this->_html.$helper->generateForm($this->fields_form);
}
protected function initFieldsForm()
{
$this->fields_form[0]['form'] = array(
'legend' => array(
'title' => $this->displayName,
'icon' => 'icon-cogs'
),
'input' => array(
/*array(
'type' => 'text',
'label' => $this->getTranslator()->trans('Product comparison:', array(), 'Admin.Theme.Panda'),
'name' => 'max',
'class' => 'fixed-width-lg',
'validation' => 'isUnsignedId',
'desc' => $this->getTranslator()->trans('Set the maximum number of products that can be selected for comparison. Set to "0" to disable this feature.', array(), 'Admin.Theme.Panda'),
),*/
array(
'type' => 'checkbox',
'label' => $this->getTranslator()->trans('Compare items', array(), 'Admin.Theme.Panda'),
'name' => 'items',
'values' => array(
'query' => $this->_items,
'id' => 'id',
'name' => 'name'
),
),
array(
'type' => 'switch',
'label' => $this->getTranslator()->trans('Display a "Add to compare " in the fly-out button:', array(), 'Admin.Theme.Panda'),
'name' => 'fly_out',
'is_bool' => true,
'values' => array(
array(
'id' => 'fly_out_on',
'value' => 1,
'label' => $this->getTranslator()->trans('Yes', array(), 'Admin.Theme.Panda')),
array(
'id' => 'fly_out_off',
'value' => 0,
'label' => $this->getTranslator()->trans('No', array(), 'Admin.Theme.Panda')),
),
'validation' => 'isBool',
),
array(
'type' => 'radio',
'label' => $this->getTranslator()->trans('How to display link on the header:', array(), 'Modules.Stcompare.Admin'),
'name' => 'header_style',
'default_value' => 1,
'values' => array(
array(
'id' => 'header_style_both',
'value' => 0,
'label' => $this->getTranslator()->trans('Icon + Text', array(), 'Admin.Theme.Panda')),
array(
'id' => 'header_style_name',
'value' => 1,
'label' => $this->getTranslator()->trans('Text', array(), 'Admin.Theme.Panda')),
array(
'id' => 'header_style_flag',
'value' => 2,
'label' => $this->getTranslator()->trans('Icon', array(), 'Admin.Theme.Panda')),
),
'validation' => 'isUnsignedInt',
),
array(
'type' => 'radio',
'label' => $this->getTranslator()->trans('How to display link on the product page:', array(), 'Modules.Stcompare.Admin'),
'name' => 'product_style',
'default_value' => 1,
'values' => array(
array(
'id' => 'product_style_both',
'value' => 0,
'label' => $this->getTranslator()->trans('Icon + Text', array(), 'Admin.Theme.Panda')),
array(
'id' => 'product_style_name',
'value' => 1,
'label' => $this->getTranslator()->trans('Text', array(), 'Admin.Theme.Panda')),
array(
'id' => 'product_style_flag',
'value' => 2,
'label' => $this->getTranslator()->trans('Icon', array(), 'Admin.Theme.Panda')),
),
'validation' => 'isUnsignedInt',
),
array(
'type' => 'text',
'label' => $this->getTranslator()->trans('Row mini width:', array(), 'Admin.Theme.Panda'),
'name' => 'width',
'class' => 'fixed-width-lg',
'prefix' => 'px',
'validation' => 'isUnsignedId',
),
),
'submit' => array(
'title' => $this->getTranslator()->trans('Save', array(), 'Admin.Actions')
)
);
$this->fields_form[1]['form'] = array(
'legend' => array(
'title' => $this->getTranslator()->trans('Hook manager', array(), 'Admin.Theme.Panda'),
'icon' => 'icon-cogs'
),
'description' => $this->getTranslator()->trans('Check the hook that you would like this module to display on.', array(), 'Admin.Theme.Panda').'
'.$this->getTranslator()->trans('Click here to see hook position', array(), 'Admin.Theme.Panda').'.',
'input' => array(
),
'submit' => array(
'title' => $this->getTranslator()->trans('Save', array(), 'Admin.Actions')
),
);
foreach($this->_hooks AS $key => $values)
{
if (!is_array($values) || !count($values))
continue;
$this->fields_form[1]['form']['input'][] = array(
'type' => 'checkbox',
'label' => $key,
'name' => $key,
'lang' => true,
'values' => array(
'query' => $values,
'id' => 'id',
'name' => 'name'
)
);
}
}
protected function initForm()
{
$helper = new HelperForm();
$helper->show_toolbar = false;
$helper->table = $this->table;
$helper->module = $this;
$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;
$helper->identifier = $this->identifier;
$helper->submit_action = 'savestcompare';
$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' => $this->getConfigFieldsValues(),
'languages' => $this->context->controller->getLanguages(),
'id_language' => $this->context->language->id
);
$items = Configuration::get($this->_prefix_st.'ITEMS');
foreach($this->_items as $v) {
$helper->tpl_vars['fields_value']['items_'.$v['id']] = (int)$v['val']&(int)$items;
}
return $helper;
}
private function getConfigFieldsValues()
{
$fields_values = array(
'max' => Configuration::get($this->_prefix_st.'MAX'),
'fly_out' => Configuration::get($this->_prefix_st.'FLY_OUT'),
'header_style' => Configuration::get($this->_prefix_st.'HEADER_STYLE'),
'product_style' => Configuration::get($this->_prefix_st.'PRODUCT_STYLE'),
'width' => Configuration::get($this->_prefix_st.'WIDTH'),
);
foreach($this->_hooks AS $key => $values)
{
if (!$key)
continue;
foreach($values AS $value)
{
$fields_values[$key.'_'.$value['id']] = 0;
if($id_hook = Hook::getIdByName($value['id']))
if(Hook::getModulesFromHook($id_hook, $this->id))
$fields_values[$key.'_'.$value['id']] = 1;
}
}
return $fields_values;
}
public function hookDisplayHeader($params)
{
$arr = array();
if (isset($this->context->cookie->stcompareids) && $this->context->cookie->stcompareids) {
$arr = explode(',', $this->context->cookie->stcompareids);
}
Media::addJsDef(array(
'stcompare' => array(
'url' => $this->context->link->getModuleLink('stcompare', 'compare'),
'ids' => $arr,
),
));
$this->context->smarty->assign($this->getWidgetVariables());
$this->context->controller->addJS($this->_path.'views/js/front.js');
$this->context->controller->addCSS($this->_path.'views/css/front.css');
if (!$this->isCached($this->templateFile[2], $this->getCacheId()))
{
$custom_css = '';
if($width = (int)Configuration::get($this->_prefix_st.'WIDTH'))
$custom_css .= '.stcompare_table td{min-width: '.$width.'px;}';
$this->smarty->assign('custom_css', preg_replace('/\s\s+/', ' ', $custom_css));
}
return $this->fetch($this->templateFile[2], $this->getCacheId());
}
public function renderWidget($hookName = null, array $configuration = [])
{
if (strpos(strtolower($hookName), 'display') === false) {
return;
}
$in_header = $in_product_page = false;
foreach ($this->_hooks as $sub_hooks) {
foreach ($sub_hooks as $v) {
if (Tools::strtolower($v['id'])==Tools::strtolower($hookName)) {
$in_header = isset($v['in_header']);
$in_product_page = isset($v['in_product_page']);
break 2;
}
}
}
$vars = array();
$arr = array();
if (isset($this->context->cookie->stcompareids) && $this->context->cookie->stcompareids) {
$arr = explode(',', $this->context->cookie->stcompareids);
}
$vars['stcompare_header_style'] = Configuration::get($this->_prefix_st.'HEADER_STYLE');
$vars['stcompare_product_style'] = Configuration::get($this->_prefix_st.'PRODUCT_STYLE');
if($in_product_page)
{
$id_product=(int)Tools::getValue('id_product');
$vars = array(
'id_product' => $id_product,
'stcompare_with_number' => true,
'fromnocache' => true,
);
if($id_product)
$vars['classname'] = 'btn_inline '.(in_array($id_product, $arr) ? ' st_added ' : '');
}
$vars['stcompare_total'] = count(array_unique($arr));
$this->smarty->assign($vars);
return $this->fetch($in_header ? $this->templateFile[0] : $this->templateFile[1]);
}
public function getWidgetVariables($hookName = null, array $configuration = [])
{
return array(
'stcompare' => array(
'url' => $this->context->link->getModuleLink('stcompare', 'compare'),
'fly_out' => Configuration::get($this->_prefix_st.'FLY_OUT'),
),
);
}
public function hookActionProductSearchAfter($params){
$this->context->smarty->assign($this->getWidgetVariables());
return ;
}
public function hookActionStAssemble($product)
{
$arr = array();
if (isset($this->context->cookie->stcompareids) && $this->context->cookie->stcompareids) {
$arr = explode(',', $this->context->cookie->stcompareids);
}
return array(
'compared' => in_array($product['id_product'], $arr),
);
}
}