Files
b2b.redline.com.pl/modules/pdproductattributeslist/pdproductattributeslist.php

687 lines
29 KiB
PHP

<?php
/**
*
* @author Patryk Marek <info@prestadev.pl>
* @copyright 2013 - 2017 Patryk Marek
* @link http://prestadev.pl
* @package Product attributes list for PrestaShop 1.5.x and 1.6.x and 1.7.x
* @version 1.0.3
* @license Do not edit, modify or copy this file, if you wish to customize it, contact us at info@prestadev.pl
* @date 28-10-2017
*
*/
if (!defined('_PS_VERSION_')) {
exit;
}
class PdProductAttributesList extends Module
{
private $html = '';
private $postErrors = array();
public function __construct()
{
$this->name = 'pdproductattributeslist';
$this->tab = 'front_office_features';
$this->version = '2.0.0';
$this->author = 'PrestaDev.pl';
$this->need_instance = 0;
$this->module_key = '5f46066c31c75e2acfdf9483396e7ar6';
$this->secure_key = Tools::encrypt($this->name);
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('Product attributes list on product page');
$this->description = $this->l('Allow to display product attributes list on product page as a tab or in product footer hook');
$this->ps_version_17 = (version_compare(substr(_PS_VERSION_, 0, 3), '1.7', '=')) ? true : false;
$this->ps_version_8 = (version_compare(substr(_PS_VERSION_, 0, 3), '8.0', '>=')) ? true : false;
}
public function install()
{
if (!parent::install()
|| !$this->registerHook('displayProductTab')
|| !$this->registerHook('displayHeader')
|| !$this->registerHook('displayFooterProduct')
|| !$this->registerHook('displayProductTabContent')
|| !$this->registerHook('displayProductExtraContent')
|| !$this->registerHook('displayCustomAttributesListTable')
|| !Configuration::updateValue('PD_PAL_ONLY_IN_STOCK', 0)
|| !Configuration::updateValue('PD_PAL_DISPLAY_T_HEADING', 1)
|| !Configuration::updateValue('PD_PAL_DISPLAY_B_HEADING', 1)
|| !Configuration::updateValue('PD_PAL_SHOW_ATTRIBUT_TETEXTURE_IMG', 1)
|| !Configuration::updateValue('PD_PAL_DISPLAY_LAYOUT', 0)
|| !Configuration::updateValue('PD_PAL_PLACEMENT', 1)) {
return false;
}
return true;
}
public function uninstall()
{
if (!parent::uninstall()) {
return false;
}
return true;
}
/*
** Form Config Methods
**
*/
public function getContent()
{
if (Tools::isSubmit('btnSubmit')) {
$this->postValidation();
if (!count($this->postErrors)) {
$this->postProcess();
} else {
foreach ($this->postErrors as $err) {
$this->html .= $this->displayError($err);
}
}
} else {
$this->html .= '<br />';
}
$this->html .= '<h2>'.$this->displayName.' (v'.$this->version.')</h2><p>'.$this->description.'</p>';
$this->html .= $this->renderForm();
$this->html .= '<br />';
$this->html .= $this->displayExtraForm();
return $this->html;
}
public function renderForm()
{
$switch = version_compare(_PS_VERSION_, '1.6.0', '>=') ? 'switch' : 'radio';
$fields_form_1 = array(
'form' => array(
'legend' => array(
'title' => $this->l('Module Configuration'),
'icon' => 'icon-cogs'
),
'input' => array(
array(
'type' => $switch,
'label' => $this->l('Display block heading'),
'desc' => $this->l('Displays block heading'),
'class' => 't',
'name' => 'PD_PAL_DISPLAY_B_HEADING',
'values' => array(
array(
'id' => 'yes',
'value' => 1,
'label' => $this->l('Yes')
),
array(
'id' => 'no',
'value' => 0,
'label' => $this->l('No')
),
)
),
array(
'type' => 'radio',
'label' => $this->l('Display layout'),
'desc' => $this->l('Display layout of product combinations'),
'class' => 't',
'name' => 'PD_PAL_DISPLAY_LAYOUT',
'values' => array(
array(
'id' => '0',
'value' => 0,
'label' => $this->l('Table')
),
array(
'id' => '1',
'value' => 1,
'label' => $this->l('Grid')
)
)
),
array(
'type' => 'radio',
'label' => $this->l('Table placement'),
'desc' => $this->l('Displays table in product page tab or custom hook in product page (see instructions bellow)'),
'class' => 't',
'name' => 'PD_PAL_PLACEMENT',
'values' => array(
array(
'id' => '0',
'value' => 0,
'label' => $this->l('Custom hook (displayCustomAttributesListTable)')
),
array(
'id' => '1',
'value' => 1,
'label' => $this->l('Product tab')
),
array(
'id' => '2',
'value' => 2,
'label' => $this->l('Product footer')
),
)
),
),
'submit' => array(
'title' => $this->l('Save settings'),
)
),
);
$helper = new HelperForm();
$helper->module = $this;
$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 = 'btnSubmit';
$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
);
return $helper->generateForm(array($fields_form_1));
}
private function displayExtraForm()
{
$this->html .= '
<fieldset class="panel">
<div class="panel-heading">
<i class="icon-cogs"></i>
'.$this->l('Instalation instructions for custom hook table').'
</div>
<div class="form-wrapper">
'.$this->l('Please open file on which You want to add module').'
'.$this->l('for editing and add in place where you want to display table code:').'
<textarea name="code" cols="100" rows="2">{hook h=\'displayCustomAttributesListTable\'}</textarea>
</div>
</fieldset>';
}
public function getConfigFieldsValues()
{
$return = array();
$return['PD_PAL_DISPLAY_T_HEADING'] = Tools::getValue('PD_PAL_DISPLAY_T_HEADING', Configuration::get('PD_PAL_DISPLAY_T_HEADING'));
$return['PD_PAL_DISPLAY_B_HEADING'] = Tools::getValue('PD_PAL_DISPLAY_B_HEADING', Configuration::get('PD_PAL_DISPLAY_B_HEADING'));
$return['PD_PAL_PLACEMENT'] = Configuration::get('PD_PAL_PLACEMENT');
$return['PD_PAL_ONLY_IN_STOCK'] = Configuration::get('PD_PAL_ONLY_IN_STOCK');
$return['PD_PAL_DISPLAY_LAYOUT'] = Configuration::get('PD_PAL_DISPLAY_LAYOUT');
$return['PD_PAL_SHOW_ATTRIBUT_TETEXTURE_IMG'] = Configuration::get('PD_PAL_SHOW_ATTRIBUT_TETEXTURE_IMG');
return $return;
}
private function postValidation()
{
}
private function postProcess()
{
Configuration::updateValue('PD_PAL_DISPLAY_B_HEADING', Tools::getValue('PD_PAL_DISPLAY_B_HEADING'));
Configuration::updateValue('PD_PAL_DISPLAY_T_HEADING', Tools::getValue('PD_PAL_DISPLAY_T_HEADING'));
Configuration::updateValue('PD_PAL_PLACEMENT', Tools::getValue('PD_PAL_PLACEMENT'));
Configuration::updateValue('PD_PAL_ONLY_IN_STOCK', Tools::getValue('PD_PAL_ONLY_IN_STOCK'));
Configuration::updateValue('PD_PAL_DISPLAY_LAYOUT', Tools::getValue('PD_PAL_DISPLAY_LAYOUT'));
Configuration::updateValue('PD_PAL_SHOW_ATTRIBUT_TETEXTURE_IMG', Tools::getValue('PD_PAL_SHOW_ATTRIBUT_TETEXTURE_IMG'));
$this->html .= $this->displayConfirmation($this->l('Settings updated'));
}
public function hookDisplayHeader($params)
{
if (!empty(Context::getContext()->controller->php_self)) {
$controller = Context::getContext()->controller->php_self;
} else {
$controller = Tools::getValue('controller');
}
if ($controller == 'product' || $controller == 'category') {
$this->context->controller->addJquery();
$this->context->controller->addJqueryPlugin('fancybox');
$this->context->controller->addJqueryPlugin('growl', null, false);
$this->context->controller->registerStylesheet('growl-css', 'js/jquery/plugins/growl/jquery.growl.css');
Media::addJsDef(array(
'pdproductattributeslist_add_ok' => $this->l(' was added!'),
'pdproductattributeslist_title_error' => $this->l('Error'),
'pdproductattributeslist_title_ok' => $this->l('Success'),
'pdproductattributeslist_pcs' => $this->l('pcs.'),
'pdproductattributeslist_product' => $this->l('Product: '),
'pdproductattributeslist_variant' => $this->l('in variant:'),
'pdproductattributeslist_max_qty' => $this->l(' max quantity is: '),
'pdproductattributeslist_add_error' => $this->l('There no products quantities selected!'),
'pdproductattributeslist_secure_key' => $this->secure_key,
'pdproductattributeslist_ajax_link' => $this->context->link->getModuleLink('pdproductattributeslist', 'ajax', array()),
));
}
$this->context->controller->registerStylesheet('modules-pdproductattributeslist-front', 'modules/'.$this->name.'/views/css/pdproductattributeslist.css', array('media' => 'all', 'priority' => 150));
$this->context->controller->registerStylesheet('modules-pdproductattributeslist-front-tablesorter', 'modules/'.$this->name.'/views/css/theme.default.min.css', array('media' => 'all', 'priority' => 150));
$this->context->controller->registerStylesheet('modules-pdproductattributeslist-front-tablesorter-bootstrap-3', 'modules/'.$this->name.'/views/css/theme.bootstrap_3.min.css', array('media' => 'all', 'priority' => 150));
$this->context->controller->registerStylesheet('modules-pdproductattributeslist-front-tablesorter-bootstrap-4', 'modules/'.$this->name.'/views/css/theme.bootstrap_4.min.css', array('media' => 'all', 'priority' => 150));
$this->context->controller->registerStylesheet('modules-pdproductattributeslist-front-tablesorter-bootstrap', 'modules/'.$this->name.'/views/css/theme.bootstrap.min.css', array('media' => 'all', 'priority' => 150));
$this->context->controller->registerJavascript('modules-pdproductattributeslist-tablesorter', 'modules/'.$this->name.'/views/js/jquery.tablesorter.min.js', array('position' => 'bottom', 'priority' => 150));
$this->context->controller->registerJavascript('modules-pdproductattributeslist-tablesorter-widgets', 'modules/'.$this->name.'/views/js/jquery.tablesorter.widgets.min.js', array('position' => 'bottom', 'priority' => 150));
$this->context->controller->registerJavascript('modules-pdproductattributeslist', 'modules/'.$this->name.'/views/js/pdproductattributeslist.js', array('position' => 'bottom', 'priority' => 150));
}
public function hookDisplayProductExtraContent($params)
{
$placement = Configuration::get('PD_PAL_PLACEMENT');
$product = $this->context->controller->getProduct();
if ($product->hasAttributes() == 0) {
return array();
}
if (($this->ps_version_17 || $this->ps_version_8) && $placement == 1 && Tools::getValue('ajax', 'false') == 'false') {
$tabz[] = (new PrestaShop\PrestaShop\Core\Product\ProductExtraContent())->setTitle($this->l('Select product combination'))->setContent($this->hookDisplayProductTabContent($params));
return $tabz;
} else {
return array();
}
}
public function hookDisplayProductTabContent($params)
{
$placement = Configuration::get('PD_PAL_PLACEMENT');
$display_layout = Configuration::get('PD_PAL_DISPLAY_LAYOUT');
if ($placement == 1) {
$id_lang = (int)$this->context->language->id;
$id_shop = (int)$this->context->shop->id;
$product = $this->context->controller->getProduct();
$product_combinations = $this->getAttributeCombinations($product->id, $id_lang, $id_shop);
//dump($product_combinations);
$this->context->smarty->assign(array(
'product_combinations' => $product_combinations,
'block_heading'=> Configuration::get('PD_PAL_DISPLAY_B_HEADING'),
'cartSize' => Image::getSize(ImageType::getFormattedName('cart')),
'homeSize' => Image::getSize(ImageType::getFormattedName('home')),
'is_catalog' => (bool) Configuration::isCatalogMode(),
'show_prices' => (bool) Configuration::showPrices(),
'ps_version_17' => $this->ps_version_17,
'ps_version_8' => $this->ps_version_8
));
if ($display_layout == 0) {
return $this->display(__FILE__, 'hookDisplayProductTabContent.tpl');
} else {
return $this->display(__FILE__, 'hookDisplayProductTabContentGrid.tpl');
}
}
}
public function hookDisplayProductTab($params)
{
$placement = Configuration::get('PD_PAL_PLACEMENT');
if ($placement == 1) {
$context = Context::getContext();
$cart = new Cart((int)$context->cart->id);
$product = $this->context->controller->getProduct();
$this->context->smarty->assign(array(
'ps_version_15' => $this->ps_version_15,
'ps_version_16' => $this->ps_version_16,
'ps_version_17' => $this->ps_version_17
));
return $this->display(__FILE__, 'hookDisplayProductTab.tpl');
}
}
public function hookDisplayFooterProduct($params)
{
$placement = Configuration::get('PD_PAL_PLACEMENT');
$display_layout = Configuration::get('PD_PAL_DISPLAY_LAYOUT');
if ($placement == 2) {
$id_lang = (int)$this->context->language->id;
$id_shop = (int)$this->context->shop->id;
$product = $this->context->controller->getProduct();
$product_combinations = $this->getAttributeCombinations($product->id, $id_lang, $id_shop);
//dump($product_combinations);
$this->context->smarty->assign(array(
'product_combinations' => $product_combinations,
'block_heading'=> Configuration::get('PD_PAL_DISPLAY_B_HEADING'),
'cartSize' => Image::getSize(ImageType::getFormattedName('cart')),
'homeSize' => Image::getSize(ImageType::getFormattedName('home')),
'is_catalog' => (bool) Configuration::isCatalogMode(),
'show_prices' => (bool) Configuration::showPrices(),
'ps_version_17' => $this->ps_version_17,
'ps_version_8' => $this->ps_version_8
));
if ($display_layout == 0) {
return $this->display(__FILE__, 'hookDisplayProductTabContent.tpl');
} else {
return $this->display(__FILE__, 'hookDisplayProductTabContentGrid.tpl');
}
}
}
public function hookDisplayCustomAttributesListTable($params)
{
$id_product = (int)$params['product']->id;
$product = new Product($id_product);
$id_lang = (int)$this->context->language->id;
$id_shop = (int)$this->context->shop->id;
$product_combinations = $this->getAttributeCombinations($id_product, $id_lang, $id_shop);
$this->context->smarty->assign(array(
'product_combinations' => $product_combinations,
'block_heading'=> Configuration::get('PD_PAL_DISPLAY_B_HEADING'),
'cartSize' => Image::getSize(ImageType::getFormattedName('cart')),
'homeSize' => Image::getSize(ImageType::getFormattedName('home')),
'is_catalog' => (bool) Configuration::isCatalogMode(),
'show_prices' => (bool) Configuration::showPrices(),
'ps_version_17' => $this->ps_version_17,
'ps_version_8' => $this->ps_version_8
));
return $this->display(__FILE__, 'hookDisplayCustomAttributesListTable.tpl');
}
private function getAttributeCombinations($id_product, $id_lang, $id_shop)
{
$sql = 'SELECT pa.`id_product_attribute`, pa.`id_product`, pa.`reference`, pa.`ean13`, pa.`mpn`, pas.`weight` as weight_impact, p.`weight` as weight_base, pa.`minimal_quantity`,
ag.`id_attribute_group`, ag.`is_color_group`, agl.`public_name` AS group_name, al.`name` AS attribute_name, al.`name` AS attribute_name_html,
a.`id_attribute`, a.`color`, pa.`available_date`
FROM `'._DB_PREFIX_.'product_attribute` pa
INNER JOIN `'._DB_PREFIX_.'product_attribute_shop` pas ON (pas.id_product_attribute = pa.id_product_attribute AND pas.id_shop = '.(int)$id_shop.')
LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac ON pac.`id_product_attribute` = pa.`id_product_attribute`
LEFT JOIN `'._DB_PREFIX_.'attribute` a ON a.`id_attribute` = pac.`id_attribute`
LEFT JOIN `'._DB_PREFIX_.'attribute_group` ag ON ag.`id_attribute_group` = a.`id_attribute_group`
LEFT JOIN `'._DB_PREFIX_.'attribute_lang` al ON (a.`id_attribute` = al.`id_attribute` AND al.`id_lang` = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'attribute_group_lang` agl ON (ag.`id_attribute_group` = agl.`id_attribute_group` AND agl.`id_lang` = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'product` p ON (p.`id_product` = '.(int)$id_product.')
WHERE pa.`id_product` = '.(int)$id_product.'
ORDER BY pa.`id_product_attribute`';
$results = Db::getInstance()->ExecuteS($sql);
$return = array();
$product = new Product($id_product, false, $id_lang, $id_shop);
$context = Context::getContext();
$specific_price_output = null;
$only_in_stock = Configuration::get('PD_PAL_ONLY_IN_STOCK');
if (is_array($results) && count($results) > 1) {
foreach ($results as $k => $r) {
if (!isset($return[$r['id_product_attribute']]['attribute_name'])) {
$return[$r['id_product_attribute']]['attribute_name'] = '';
}
if (!isset($return[$r['id_product_attribute']]['attribute_name_html'])) {
$return[$r['id_product_attribute']]['attribute_name_html'] = '';
}
$return[$r['id_product_attribute']]['id_attribute'] = $r['id_attribute'];
$return[$r['id_product_attribute']]['color'] = $r['color'];
$return[$r['id_product_attribute']]['id_product'] = $id_product;
$return[$r['id_product_attribute']]['id_product_attribute'] = $r['id_product_attribute'];
$return[$r['id_product_attribute']]['attribute_name'] .= rtrim(Tools::ucfirst($r['group_name']).': '.Tools::ucfirst($r['attribute_name']).', ', ',');
$return[$r['id_product_attribute']]['attribute_name_html'] .= '<b>'.$r['attribute_name'].'</b><br />';
$return[$r['id_product_attribute']]['reference'] = $r['reference'] ? $r['reference'] : '';
$return[$r['id_product_attribute']]['ean13'] = $r['ean13'] ? $r['ean13'] : '';
$return[$r['id_product_attribute']]['mpn'] = $r['mpn'] ? $r['mpn'] : '';
$return[$r['id_product_attribute']]['minimal_quantity'] = $r['minimal_quantity'];
$return[$r['id_product_attribute']]['price'] = Product::getPriceStatic(
(int)$id_product,
true,
(int)$r['id_product_attribute'],
2,
null,
false,
true,
1,
false,
null,
null,
null,
$specific_price_output,
true,
true,
$context,
true
);
$return[$r['id_product_attribute']]['price_tax_excl'] = Product::getPriceStatic(
(int)$id_product,
false,
(int)$r['id_product_attribute'],
2,
null,
false,
true,
1,
false,
null,
null,
null,
$specific_price_output,
true,
true,
$context,
true
);
$return[$r['id_product_attribute']]['price_old'] = Product::getPriceStatic(
(int)$id_product,
true,
(int)$r['id_product_attribute'],
2,
null,
false,
false,
1,
false,
null,
null,
null,
$specific_price_output,
true,
true,
$context,
true
);
$return[$r['id_product_attribute']]['price_old_tax_excl'] = Product::getPriceStatic(
(int)$id_product,
false,
(int)$r['id_product_attribute'],
2,
null,
false,
false,
1,
false,
null,
null,
null,
$specific_price_output,
true,
true,
$context,
true
);
$return[$r['id_product_attribute']]['quantity'] = StockAvailable::getQuantityAvailableByProduct($id_product, (int)$r['id_product_attribute'], $id_shop);
$return[$r['id_product_attribute']]['images'] = Image::getBestImageAttribute($id_shop, $id_lang, $id_product, (int)$r['id_product_attribute']);
if ((!isset($return[$r['id_product_attribute']]['color']) && Tools::isEmpty($return[$r['id_product_attribute']]['color'])) && (file_exists(_PS_COL_IMG_DIR_.$r['id_attribute'].'.jpg'))) {
$return[$r['id_product_attribute']]['color_texture_link'] = _THEME_COL_DIR_.$r['id_attribute'].'.jpg';
} else {
$return[$r['id_product_attribute']]['color_texture_link'] = '';
}
$return[$r['id_product_attribute']]['combination_link'] = $context->link->getProductLink(
$product,
$product->link_rewrite,
null,
null,
$context->language->id,
$context->shop->id,
$r['id_product_attribute']
);
$return[$r['id_product_attribute']]['available_date'] = $r['available_date'];
}
foreach ($return as &$r) {
$r['product_name'] = $product->name;
$r['attribute_name'] = rtrim($r['attribute_name'], ', ');
$r['name'] = rtrim((string)$r['attribute_name'], ', ');
// if ($only_in_stock && $return[$r['id_product_attribute']]['quantity'] <= 0) {
// unset($r['id_product_attribute']);
// }
$images = Image::getImages($id_lang, $id_product, $r['id_product_attribute'], $id_shop);
if (!$images) {
$images = Image::getImages($id_lang, $id_product, null, $id_shop);
}
foreach ($images as &$i) {
$i['large_default'] = $context->link->getImageLink($product->link_rewrite, $i['id_image'], 'large_default');
$i['home_default'] = $context->link->getImageLink($product->link_rewrite, $i['id_image'], 'home_default');
}
$r['images'] = $images;
}
} else {
$images = Image::getImages($id_lang, $id_product, null, $id_shop);
foreach ($images as &$i) {
$i['large_default'] = $context->link->getImageLink($product->link_rewrite, $i['id_image'], 'large_default');
$i['home_default'] = $context->link->getImageLink($product->link_rewrite, $i['id_image'], 'home_default');
}
$return[0] = [
'product_name' => $product->name,
'name' => $product->name,
'attribute_name' => $this->l('--'),
'attribute_name_html' => $this->l('--'),
'images' => $images,
'reference' => $product->reference,
'ean13' => $product->ean13,
'mpn' => $product->mpn,
'id_product' => $product->id,
'id_product_attribute' => 0,
'minimal_quantity' => '',
'price' => Product::getPriceStatic(
(int)$id_product,
true,
0,
2,
null,
false,
true,
1,
false,
null,
null,
null,
$specific_price_output,
true,
true,
$context,
true
),
'price_tax_excl' => Product::getPriceStatic(
(int)$id_product,
false,
0,
2,
null,
false,
true,
1,
false,
null,
null,
null,
$specific_price_output,
true,
true,
$context,
true
),
'price_old' => Product::getPriceStatic(
(int)$id_product,
true,
0,
2,
null,
false,
false,
1,
false,
null,
null,
null,
$specific_price_output,
true,
true,
$context,
true
),
'price_old_tax_excl' => Product::getPriceStatic(
(int)$id_product,
false,
0,
2,
null,
false,
false,
1,
false,
null,
null,
null,
$specific_price_output,
true,
true,
$context,
true
),
'quantity' => StockAvailable::getQuantityAvailableByProduct($id_product, 0, $id_shop),
'available_date' => $product->available_date,
];
}
return $return;
}
}