Current File : /var/www/vinorea/modules/ipexportimport/classes/export/EIACombinationsExport.php |
<?php
/**
*
* NOTICE OF LICENSE
*
* @author SmartPresta <tehran.alishov@gmail.com>
* @copyright 2024 SmartPresta
* @license http://opensource.org/licenses/afl-3.0.php Commercial License!
*/
if (!defined('_PS_VERSION_')) {
exit;
}
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
class EIACombinationsExport extends EIAExport
{
protected $xmlMainTag = 'Combination';
protected $xmlMainTagPl = 'Combinations';
public function __construct($module)
{
parent::__construct($module);
$this->entityNamePl = $module->l('Combinations', 'EIACombinationsExport');
}
private function getImageLink($id_image)
{
$theme = Shop::isFeatureActive() && file_exists(_PS_PROD_IMG_DIR_ . Image::getImgFolderStatic($id_image) . $id_image . '-' . (int) Context::getContext()->shop->id_theme . '.jpg') ? '-' . Context::getContext()->shop->id_theme : '';
$uri_path = _THEME_PROD_DIR_ . Image::getImgFolderStatic($id_image) . $id_image . $theme . '.jpg';
return $this->context->link->protocol_content . Tools::getMediaServer($uri_path) . $uri_path;
}
protected function getDataFromDb()
{
// Columns that do not exist directly in the DB
$absentColumns = array(
'image_urls' => 'image.ids'
);
$low = !empty(Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS("SHOW COLUMNS FROM `" . _DB_PREFIX_ . "product_attribute_shop` LIKE 'low_stock_threshold'"));
$newColumns = [
'combination.isbn' => !empty(Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS("SHOW COLUMNS FROM `" . _DB_PREFIX_ . "product_attribute` LIKE 'isbn'")),
'combination.mpn' => !empty(Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS("SHOW COLUMNS FROM `" . _DB_PREFIX_ . "product_attribute` LIKE 'mpn'")),
'combination_shop.low_stock_threshold' => $low,
'combination_shop.low_stock_alert' => $low,
'stock_available.physical_quantity' => !empty(Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS("SHOW COLUMNS FROM `" . _DB_PREFIX_ . "stock_available` LIKE 'physical_quantity'")),
'stock_available.reserved_quantity' => !empty(Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS("SHOW COLUMNS FROM `" . _DB_PREFIX_ . "stock_available` LIKE 'reserved_quantity'")),
'stock_available.location' => !empty(Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS("SHOW COLUMNS FROM `" . _DB_PREFIX_ . "stock_available` LIKE 'location'")),
];
if ($this->auto) {
$combinations = pSQL(implode(',', $this->datatables['combinations']['data']));
$combinationsType = $this->datatables['combinations']['type'];
$quantityOperator = pSQL($this->inputs['quantity_operator']);
$quantity = (int) $this->inputs['quantity'];
$categories = $this->inputs['categories'];
$filterCategories = $this->inputs['category_whether_filter'];
$categories_without = $this->inputs['category_without'];
$attributes = pSQL(implode(',', $this->datatables['attributes']['data']));
$attributesType = $this->datatables['attributes']['type'];
$discount = $this->inputs['discount'];
} else {
$combinations = pSQL(Tools::getValue('combinations_data'));
$combinationsType = Tools::getValue('combinations_type');
$quantityOperator = pSQL(Tools::getValue('quantity_operator'));
$quantity = (int) Tools::getValue('quantity');
$categories = Tools::getValue('categories');
$filterCategories = Tools::getValue('category_whether_filter');
$categories_without = Tools::getValue('category_without');
$attributes = pSQL(Tools::getValue('attributes_data'));
$attributesType = Tools::getValue('attributes_type');
$discount = Tools::getValue('discount');
}
$eIHelper = new EIAHelper($this->module);
$this->sql = '
SELECT SQL_CALC_FOUND_ROWS ';
if (in_array($this->fileType, ['xml'])) {
$fieldsInTree = $eIHelper->getFieldsInTree('combinations');
foreach ($this->selectedColumns as $k => $col) {
if (array_key_exists($k, $absentColumns)) {
$this->sql .= "
{$absentColumns[$k]} `{$fieldsInTree[$k]}`, ";
} else {
$this->sql .= "
$k AS `{$fieldsInTree[$k]}`, ";
}
}
} else {
foreach ($this->selectedColumns as $k => $col) {
if (array_key_exists($k, $absentColumns)) {
$this->sql .= "
{$absentColumns[$k]} `$col`, ";
} elseif (array_key_exists($k, $newColumns) && !$newColumns[$k]) {
$this->sql .= "
'' `$col`, ";
} else {
$this->sql .= "
$k `$col`, ";
}
}
}
$this->sql = rtrim($this->sql, ', ');
// Filter By Category
$categoriesCond = $categoriesCond2 = '';
if ($filterCategories === '1') {
if ($categories) {
$categoriesCond = ' WHERE id_category IN (' . implode(',', $categories) . ')';
$categoriesCond2 .= 'category.id_product IS NOT NULL';
if ($categories_without !== '0') {
$categoriesCond2 .= ' OR for_null_category.id_product IS NULL';
}
$categoriesCond2 = '
AND (' . $categoriesCond2 . ')';
} else {
if ($categories_without !== '0') {
$categoriesCond2 .= '
AND (for_null_category.id_product IS NULL)';
}
}
}
// Filter By Attribute
$attributesCond = $attributesCond2 = '';
if ($attributes) {
if ($attributesType === 'unselected') {
$attributesCond = ' WHERE id_attribute NOT IN (' . $attributes . ')';
} else {
$attributesCond = ' WHERE id_attribute IN (' . $attributes . ')';
}
$attributesCond2 .= 'attributes.id_product_attribute IS NOT NULL';
$attributesCond2 = '
AND (' . $attributesCond2 . ')';
}
$this->sql .= '
FROM
' . _DB_PREFIX_ . 'product_attribute combination
LEFT JOIN
' . _DB_PREFIX_ . 'product_attribute_shop combination_shop ON combination.id_product_attribute = combination_shop.id_product_attribute
AND combination_shop.id_shop = ' . $this->shopId . '
LEFT JOIN
' . _DB_PREFIX_ . 'product product ON combination.id_product = product.id_product
LEFT JOIN
' . _DB_PREFIX_ . 'product_lang product_lang ON combination.id_product = product_lang.id_product
AND product_lang.id_shop = ' . $this->shopId . '
AND product_lang.id_lang = ' . $this->langId . '
LEFT JOIN (
SELECT
pac.id_product_attribute,
GROUP_CONCAT(CONCAT_WS(":", IFNULL(agl.name, ""), al.name) ORDER BY agl.name, al.name, a.color SEPARATOR "' . $this->multivalueSeparator . '") name_values,
GROUP_CONCAT(ag.group_type ORDER BY agl.name, al.name, a.color SEPARATOR "' . $this->multivalueSeparator . '") `types`,
GROUP_CONCAT(agl.name ORDER BY agl.name, al.name, a.color SEPARATOR "' . $this->multivalueSeparator . '") `groups`,
GROUP_CONCAT(agl.public_name ORDER BY agl.name, al.name, a.color SEPARATOR "' . $this->multivalueSeparator . '") `public_name`,
GROUP_CONCAT(IF(a.color = "", al.name, CONCAT_WS(":", al.name, a.color)) ORDER BY agl.name, al.name, a.color SEPARATOR "' . $this->multivalueSeparator . '") `values`
FROM (
SELECT DISTINCT id_product_attribute
FROM ' . _DB_PREFIX_ . 'product_attribute_combination' .
$attributesCond . '
) temp
JOIN ' . _DB_PREFIX_ . 'product_attribute_combination pac ON temp.id_product_attribute = pac.id_product_attribute
JOIN ' . _DB_PREFIX_ . 'attribute a ON pac.id_attribute = a.id_attribute
JOIN ' . _DB_PREFIX_ . 'attribute_shop ash ON a.id_attribute = ash.id_attribute AND ash.id_shop = ' . $this->shopId . '
JOIN ' . _DB_PREFIX_ . 'attribute_lang al ON a.id_attribute = al.id_attribute AND al.id_lang = ' . $this->langId . '
JOIN ' . _DB_PREFIX_ . 'attribute_group ag ON a.id_attribute_group = ag.id_attribute_group
JOIN ' . _DB_PREFIX_ . 'attribute_group_shop agsh ON a.id_attribute_group = agsh.id_attribute_group AND agsh.id_shop = ' . $this->shopId . '
JOIN ' . _DB_PREFIX_ . 'attribute_group_lang agl ON a.id_attribute_group = agl.id_attribute_group AND agl.id_lang = ' . $this->langId . '
GROUP BY pac.id_product_attribute
) attributes ON combination.id_product_attribute = attributes.id_product_attribute
LEFT JOIN (
SELECT DISTINCT id_product
FROM ' . _DB_PREFIX_ . 'category_product ' . $categoriesCond . '
) category ON product.id_product = category.id_product
LEFT JOIN (
SELECT DISTINCT id_product FROM ' . _DB_PREFIX_ . 'category_product
) for_null_category ON product.id_product = for_null_category.id_product
LEFT JOIN (
SELECT
pai.id_product_attribute,
GROUP_CONCAT(IF(pai.id_image = 0, "", pai.id_image) ORDER BY i.position SEPARATOR "' . $this->multivalueSeparator . ' ") ids,
GROUP_CONCAT(il.`legend` ORDER BY i.position SEPARATOR "' . $this->multivalueSeparator . ' ") `texts`,
GROUP_CONCAT(i.`position` ORDER BY i.position SEPARATOR "' . $this->multivalueSeparator . ' ") `positions`
FROM ' . _DB_PREFIX_ . 'product_attribute_image pai
LEFT JOIN ' . _DB_PREFIX_ . 'image i ON pai.id_image = i.id_image
LEFT JOIN ' . _DB_PREFIX_ . 'image_lang il ON pai.id_image = il.id_image AND il.id_lang = ' . $this->langId . '
GROUP BY pai.id_product_attribute
) image ON combination.id_product_attribute = image.id_product_attribute
LEFT JOIN ' . _DB_PREFIX_ . 'stock_available stock_available ON combination.id_product = stock_available.id_product
AND combination.id_product_attribute = stock_available.id_product_attribute
' . StockAvailable::addSqlShopRestriction(null, $this->shopId, 'stock_available') . '
LEFT JOIN (
SELECT
wpl.id_product,
wpl.id_product_attribute,
GROUP_CONCAT(CONCAT_WS(":", w.`reference`, w.`name`, wpl.location) SEPARATOR "' . $this->multivalueSeparator . '") name_ref_loc
FROM ' . _DB_PREFIX_ . 'warehouse_product_location wpl
LEFT JOIN ' . _DB_PREFIX_ . 'warehouse w ON wpl.id_warehouse = w.id_warehouse
WHERE wpl.id_product_attribute <> 0
GROUP BY wpl.id_product, wpl.id_product_attribute
) warehouse ON combination.id_product = warehouse.id_product AND combination.id_product_attribute = warehouse.id_product_attribute
';
$this->sql .= '
WHERE 1
';
// Filter By Combination
$combinationCond = '';
if ($combinations) {
if ($combinationsType === 'unselected') {
$combinationCond = 'combination.id_product_attribute NOT IN (' . $combinations . ')';
} else {
$combinationCond = 'combination.id_product_attribute IN (' . $combinations . ')';
}
}
if ($combinationCond) {
$this->sql .= '
AND (' . $combinationCond . ') ';
}
// Filter By Category
$this->sql .= $categoriesCond2;
// Filter By Quantity
if ($quantityOperator !== 'none' && ($quantity || $quantity == '0')) {
$this->sql .= '
AND stock_available.quantity ' . EIAHelper::getOperator($quantityOperator) . $quantity;
}
// Filter By Attribute
$this->sql .= $attributesCond2;
// Filter By Discount
$discountCond = '';
if ($discount === 'discounted') {
$discountCond = '
AND EXISTS (SELECT *
FROM ' . _DB_PREFIX_ . 'specific_price
WHERE id_product_attribute = combination.id_product_attribute
AND id_shop = ' . $this->shopId . '
AND (`from` < NOW() OR `from` = "0000-00-00 00:00:00")
AND (`to` > NOW() OR `to` = "0000-00-00 00:00:00"))
';
} elseif ($discount === 'nondiscounted') {
$discountCond = '
AND NOT EXISTS (SELECT *
FROM ' . _DB_PREFIX_ . 'specific_price
WHERE id_product_attribute = combination.id_product_attribute
AND id_shop = ' . $this->shopId . '
AND (`from` < NOW() OR `from` = "0000-00-00 00:00:00")
AND (`to` > NOW() OR `to` = "0000-00-00 00:00:00"))
';
}
$this->sql .= $discountCond;
// Filter by fields data
$this->sql .= $eIHelper->getFieldsFilterString($this->auto, $this->inputs);
// Sort By ...
$this->sql .= ' ORDER BY ' . $this->sort . $this->sortWay;
if ($this->sort !== 'combination.id_product_attribute') {
$this->sql .= ', combination.id_product_attribute ASC';
}
$this->sql .= ' LIMIT ' . $this->offset . ', ' . $this->limit;
// die($this->sql);
return Db::getInstance()->executeS($this->sql);
}
protected function writeToCsv()
{
$handle = $this->openCsvFile();
foreach ($this->data as $value) {
if (!empty($value[$this->selectedColumns['image_urls']])) {
$link = '';
foreach (explode($this->multivalueSeparator, $value[$this->selectedColumns['image_urls']]) as $v) {
$link .= $this->getImageLink(trim($v)) . $this->multivalueSeparator;
}
$value[$this->selectedColumns['image_urls']] = rtrim($link, $this->multivalueSeparator);
}
fputcsv($handle, $value, $this->dlm, $this->encl);
}
$this->closeCsvFile($handle);
}
protected function writeToJson()
{
if (file_exists($this->file)) {
$data = json_decode(Tools::file_get_contents($this->file), true);
} else {
$data = [];
}
foreach ($this->data as &$value) {
if (!empty($value[$this->selectedColumns['image_urls']])) {
$link = '';
foreach (explode($this->multivalueSeparator, $value[$this->selectedColumns['image_urls']]) as $v) {
$link .= $this->getImageLink(trim($v)) . $this->multivalueSeparator;
}
$value[$this->selectedColumns['image_urls']] = rtrim($link, $this->multivalueSeparator);
}
}
$data = array_merge($data, $this->data);
file_put_contents($this->file, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
}
protected function writeToXml()
{
foreach ($this->data as &$value) {
if (!empty($value['Image_URLs'])) {
$link = '';
foreach (explode($this->multivalueSeparator, $value['Image_URLs']) as $v) {
$link .= $this->getImageLink(trim($v)) . $this->multivalueSeparator;
}
$value['Image_URLs'] = rtrim($link, $this->multivalueSeparator);
}
}
// ddd($this->data);
$this->makeXmlHierarchy();
if (file_exists($this->file)) {
$data = $this->arrayToXml(array_merge(array('arrType' => $this->xmlMainTag), $this->data), null, simplexml_load_file($this->file));
} else {
$data = $this->arrayToXml(array_merge(array('arrType' => $this->xmlMainTag), $this->data), '<?xml version="1.0" encoding="UTF-8"?><' . $this->xmlMainTagPl . ' />');
}
$domxml = new DOMDocument('1.0');
$domxml->preserveWhiteSpace = false;
$domxml->formatOutput = true;
/* @var $xml SimpleXMLElement */
$domxml->loadXML($data);
$domxml->save($this->file, LIBXML_NOEMPTYTAG);
}
protected function writeToExcel()
{
require_once dirname(__FILE__) . '/../../vendor/autoload.php';
if (file_exists($this->file)) {
$spreadsheet = IOFactory::load($this->file);
$sheet = $spreadsheet->getActiveSheet();
$excelColumns = EIAHelper::createColumnsArray(count($this->data[0]));
} else {
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
// Set document properties
$spreadsheet->getProperties()->setCreator('Tehran Alishov')
->setLastModifiedBy('Tehran Alishov')
->setTitle('Office 2007 XLSX Combinations Document')
->setSubject('Office 2007 XLSX Combinations Document')
->setDescription('Combinations document for Office 2007 XLSX, generated using PHP classes.')
->setKeywords('office 2007 openxml php')
->setCategory('Combinations result file');
$spreadsheet->setActiveSheetIndex(0);
if (empty($this->data)) {
$sheet->setCellValue('A1', $this->module->l('No Data', 'EIACombinationsExport'));
} else {
$excelColumns = EIAHelper::createColumnsArray(count($this->data[0]));
$sheet->getDefaultColumnDimension()->setWidth(21);
$sheet->getDefaultRowDimension()->setRowHeight(30);
$spreadsheet->getDefaultStyle()->getAlignment()
->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER)
->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER);
$sheet->getStyle('A1:' . end($excelColumns) . (count($this->data)))
->getAlignment()->setWrapText(true);
$sheet->getStyle('A1:' . end($excelColumns) . '1')
->getFont()->setBold(true);
$sheet->getStyle('A1:' . end($excelColumns) . '1')
->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
->getStartColor()->setARGB('FFDCF0FF');
$sheet->getStyle('A1:' . end($excelColumns) . '1')->getBorders()
->getAllBorders()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN);
// Rename worksheet
$sheet->setTitle($this->module->l('Combinations', 'EIACombinationsExport'));
$headers = array_keys($this->data[0]);
foreach ($headers as $key => $header) {
$sheet->setCellValue($excelColumns[$key] . '1', $header);
}
if (isset($this->selectedColumns['image_urls'])) {
$sheet->getColumnDimension($excelColumns[array_search($this->selectedColumns['image_urls'], $headers)])->setWidth(40);
}
}
}
foreach ($this->data as $key => $value) {
$i = 0;
foreach ($value as $k => $val) {
if ($k === $this->selectedColumns['image_urls'] && $val) {
$link = '';
$val = explode($this->multivalueSeparator, $val);
foreach ($val as $v) {
$link .= $this->getImageLink(trim($v)) . $this->multivalueSeparator;
}
$link = rtrim($link, $this->multivalueSeparator);
$cell = $excelColumns[$i] . ($this->offset + $key + 2);
$sheet->setCellValue($cell, $link);
if (count($val) === 1 && $link) {
$sheet->getCell($cell)->getHyperlink()->setUrl($link);
$sheet->getStyle($cell)->getFont()->getColor()->setARGB('FF0000FF');
}
} elseif ($k === $this->selectedColumns['combination.ean13'] && $val) {
$sheet->setCellValueExplicit($excelColumns[$i] . ($this->offset + $key + 2), $val, \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING);
} else {
$sheet->setCellValue($excelColumns[$i] . ($this->offset + $key + 2), $val);
}
$i++;
}
}
$sheet->setSelectedCell('A1');
// Write to file
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->save($this->file);
}
}