Current File : /var/www/vinorea/modules/ipexportimport/classes/export/EIACategoriesExport.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 EIACategoriesExport extends EIAExport
{

    protected $xmlMainTag = 'Category';
    protected $xmlMainTagPl = 'Categories';

    public function __construct($module)
    {
        parent::__construct($module);
        $this->entityNamePl = $module->l('Categories', 'EIACategoriesExport');
    }

    private function getImageLink($id_cat)
    {
        if (file_exists(_PS_CAT_IMG_DIR_ . $id_cat . '.jpg')) {
            $uri_path = _THEME_CAT_DIR_ . $id_cat . '.jpg';
            return $this->context->link->protocol_content . Tools::getMediaServer($uri_path) . $uri_path;
        }
        return '';
    }

    protected function getDataFromDb()
    {
        // Columns that do not exist directly in the DB
        $absentColumns = array(
            'category_link' => 'category.id_category',
            'category_image' => 'category.id_category',
            'image_url' => 'category.id_category',
        );

        if (in_array($this->fileType, ['csv', 'xml', 'json']) && isset($this->selectedColumns['category_image'])) {
            unset($this->selectedColumns['category_image']);
        }

        if ($this->auto) {
            $categories = $this->inputs['categories'];
            $filter_categories = $this->inputs['category_whether_filter'];
        } else {
            $categories = Tools::getValue('categories');
            $filter_categories = Tools::getValue('category_whether_filter');
        }
        
        $eIHelper = new EIAHelper($this->module);
        
        $this->sql = '
            SELECT SQL_CALC_FOUND_ROWS ';
        if (in_array($this->fileType, ['xml'])) {
            $fieldsInTree = $eIHelper->getFieldsInTree('categories');
            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`, ";
                } else {
                    $this->sql .= "
                        $k `$col`, ";
                }
            }
        }

        $this->sql = rtrim($this->sql, ', ');

        $this->sql .= '
            FROM 
            ' . _DB_PREFIX_ . 'category category
                LEFT JOIN
            ' . _DB_PREFIX_ . 'category_shop category_shop ON category.id_category = category_shop.id_category
                    AND category_shop.id_shop = ' . $this->shopId . '
                LEFT JOIN
            ' . _DB_PREFIX_ . 'category_lang category_lang ON category.id_category = category_lang.id_category
                    AND category_lang.id_shop = ' . $this->shopId . '
                    AND category_lang.id_lang = ' . $this->langId . '
                LEFT JOIN 
            ' . _DB_PREFIX_ . 'category_lang parent ON category.id_parent = parent.id_category
                    AND parent.id_shop = ' . $this->shopId . '
                    AND parent.id_lang = ' . $this->langId . '
                LEFT JOIN
            ' . _DB_PREFIX_ . 'shop default_shop ON category.id_shop_default = default_shop.id_shop
                LEFT JOIN
            ' . _DB_PREFIX_ . 'shop_group default_shop_group ON default_shop.id_shop_group = default_shop_group.id_shop_group
                LEFT JOIN (
                    SELECT cg.id_category, GROUP_CONCAT(cg.id_group SEPARATOR "' . $this->multivalueSeparator . '") ids, GROUP_CONCAT(gl.name SEPARATOR "' . $this->multivalueSeparator . '") names
                    FROM ' . _DB_PREFIX_ . 'category_group cg
                    JOIN ' . _DB_PREFIX_ . 'group_lang gl ON cg.id_group = gl.id_group AND gl.id_lang = ' . $this->langId . '
                    GROUP BY cg.id_category
                ) category_group ON category.id_category = category_group.id_category
                LEFT JOIN (
                    SELECT gr.id_category, GROUP_CONCAT(CONCAT(gr.id_group, ":", gr.reduction) SEPARATOR "' . $this->multivalueSeparator . '") reductions
                    FROM ' . _DB_PREFIX_ . 'group_reduction gr
                    #JOIN ' . _DB_PREFIX_ . 'group_lang gl ON gr.id_group = gl.id_group AND gl.id_lang = ' . $this->langId . '
                    GROUP BY gr.id_category
                ) group_reduction ON group_reduction.id_category = category.id_category
            ';

        $this->sql .= '
                WHERE 1
            ';

        // Filter By Category
        $categoriesCond = '';
        if ($filter_categories === '1' && $categories) {
            $categoriesCond = ' category.id_category IN (' . implode(',', $categories) . ')';
            $categoriesCond = ' 
                    AND (' . $categoriesCond . ')';
        }
        $this->sql .= $categoriesCond;

        // 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 !== 'category.id_category') {
            $this->sql .= ', category.id_category ASC';
        }

        $this->sql .= ' LIMIT ' . $this->offset . ', ' . $this->limit;

//        d($this->sql);
        return Db::getInstance()->executeS($this->sql);
    }

    protected function writeToCsv()
    {
        $handle = $this->openCsvFile();
        foreach ($this->data as $value) {
            if (!empty($value[$this->selectedColumns['category_link']])) {
                $value[$this->selectedColumns['category_link']] = $this->context->link->getCategoryLink($value[$this->selectedColumns['category_link']], null, $this->langId);
            }
            if (!empty($value[$this->selectedColumns['image_url']])) {
                $value[$this->selectedColumns['image_url']] = $this->getImageLink($value[$this->selectedColumns['image_url']]);
            }
            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['category_link']])) {
                $value[$this->selectedColumns['category_link']] = $this->context->link->getCategoryLink($value[$this->selectedColumns['category_link']], null, $this->langId);
            }
            if (!empty($value[$this->selectedColumns['image_url']])) {
                $value[$this->selectedColumns['image_url']] = $this->getImageLink($value[$this->selectedColumns['image_url']]);
            }
        }
        $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['Link'])) {
                $value['Link'] = $this->context->link->getCategoryLink($value['Link'], null, $this->langId);
            }
            if (!empty($value['Image_URL'])) {
                $value['Image_URL'] = $this->getImageLink($value['Image_URL']);
            }
        }
        $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 . ' />');
        }
//        ddd($data);
        $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 Categories Document')
                ->setSubject('Office 2007 XLSX Categories Document')
                ->setDescription('Categories document for Office 2007 XLSX, generated using PHP classes.')
                ->setKeywords('office 2007 openxml php')
                ->setCategory('Categories result file');
            $spreadsheet->setActiveSheetIndex(0);

            if (empty($this->data)) {
                $sheet->setCellValue('A1', $this->module->l('No Data', 'EIACategoriesExport'));
            } else {
                $excelColumns = EIAHelper::createColumnsArray(count($this->data[0]));
                $sheet->getDefaultColumnDimension()->setWidth(21);
                if (isset($this->selectedColumns['category_image'])) {
                    $sheet->getDefaultRowDimension()->setRowHeight(42);
                } else {
                    $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('Categories', 'EIACategoriesExport'));

                $headers = array_keys($this->data[0]);

                foreach ($headers as $key => $header) {
                    $sheet->setCellValue($excelColumns[$key] . '1', $header);
                }

                if (isset($this->selectedColumns['category_link'])) {
                    $sheet->getColumnDimension($excelColumns[array_search($this->selectedColumns['category_link'], $headers)])->setWidth(30);
                }
                if (isset($this->selectedColumns['image_url'])) {
                    $sheet->getColumnDimension($excelColumns[array_search($this->selectedColumns['image_url'], $headers)])->setWidth(30);
                }
                if (isset($this->selectedColumns['category_lang.description'])) {
                    $sheet->getColumnDimension($excelColumns[array_search($this->selectedColumns['category_lang.description'], $headers)])->setWidth(50);
                }
            }
        }

        $image_type = $this->getImageType('medium');
        $font = $sheet->getStyle('A1')->getFont();
        foreach ($this->data as $key => $value) {
            $i = 0;
            foreach ($value as $k => $val) {
                if ($k === $this->selectedColumns['category_link']) {
                    $link = $this->context->link->getCategoryLink($val, null, $this->langId);
                    $cell = $excelColumns[$i] . ($this->offset + $key + 2);
                    $sheet->setCellValue($cell, $link);
                    if ($link) {
                        $sheet->getCell($cell)->getHyperlink()->setUrl($link);
                        $sheet->getStyle($cell)->getFont()->getColor()->setARGB('FF0000FF');
                    }
                } elseif ($k === $this->selectedColumns['category_image'] && $val) {
                    $image_path = realpath(_PS_CAT_IMG_DIR_ . $val . '-' . $image_type . '.jpg');
                    if (file_exists($image_path)) {
                        $drawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
                        $drawing->setPath(realpath($image_path));
                        $height = \PhpOffice\PhpSpreadsheet\Shared\Drawing::pointsToPixels(42);
                        $drawing->setHeight($height);
                        $width = \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToCellDimension($drawing->getWidth(), $font);
                        $sheet->getColumnDimension($excelColumns[$i])->setWidth($width);
                        $drawing->setCoordinates($excelColumns[$i] . ($this->offset + $key + 2));
                        $drawing->setWorksheet($sheet);
                        $drawing->getShadow()->setVisible(true);
                    }
                } elseif ($k === $this->selectedColumns['image_url'] && $val) {
                    $link = $this->getImageLink($val);
                    $cell = $excelColumns[$i] . ($this->offset + $key + 2);
                    $sheet->setCellValue($cell, $link);
                    if ($link) {
                        $sheet->getCell($cell)->getHyperlink()->setUrl($link);
                        $sheet->getStyle($cell)->getFont()->getColor()->setARGB('FF0000FF');
                    }
                } 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);
    }
}