HEX
Server: Apache
System: Linux srv13.cpanelhost.cl 3.10.0-962.3.2.lve1.5.38.el7.x86_64 #1 SMP Thu Jun 18 05:28:41 EDT 2020 x86_64
User: cca63905 (4205)
PHP: 7.3.20
Disabled: NONE
Upload Files
File: /home4/cca63905/public_html/nueva/modules/btecommercecopilot/btecommercecopilot.php
<?php
/**
 * Ecommerce copilot
 *
 * @author    businesstech.fr <modules@businesstech.fr> - https://www.businesstech.fr/
 * @copyright Business Tech 2023 - https://www.businesstech.fr/
 * @license   see file: LICENSE.txt
 *
 * @version   1.0.3
 *
 *           ____    _______
 *          |  _ \  |__   __|
 *          | |_) |    | |
 *          |  _ <     | |
 *          | |_) |    | |
 *          |____/     |_|
 */

use btecommercecopilot\Configuration\moduleConfiguration;
use btecommercecopilot\Form\Modifier\ProductFormModifier;
use btecommercecopilot\ModuleLib\clientAi;
use btecommercecopilot\ModuleLib\moduleTools;
use PrestaShop\ModuleLibServiceContainer\DependencyInjection\ServiceContainer;
use PrestaShop\PrestaShop\Core\Addon\Module\ModuleManagerBuilder;
if (!defined('_PS_VERSION_')) {
    exit;
}
require_once dirname(__FILE__) . '/vendor/autoload.php';
class btecommercecopilot extends Module
{
    protected $config_form = false;
    public static $moduleObject = null;
    public static $compare80 = false;
    public static $compare810 = false;
    public static $iShopId = 1;
    public static $iCurrentLanguage = 1;
    public $tabs = [];
    public static $apiUrl = '';
    private $container;
    public function __construct()
    {
        $this->name = 'btecommercecopilot';
        $this->tab = 'administration';
        $this->version = '1.0.4';
        $this->author = 'Business Tech';
        $this->need_instance = 0;
        $this->bootstrap = true;
        $this->module_key = '4796715c09b3c6cde13634130f47a828';
        parent::__construct();
        $this->displayName = $this->l('E-commerce Copilot');
        $this->description = $this->l('Call on a copilot to help you write your e-commerce content. E-commerce Copilot saves you time by allowing you to use GPT4 artificial intelligence to generate descriptions and other texts.');
        self::$moduleObject = $this;
        self::$compare810 = version_compare(_PS_VERSION_, '8.1.0', '>=');
        self::$compare80 = version_compare(_PS_VERSION_, '8.0.0', '>=');
        self::$iShopId = $this->context->shop->id;
        self::$iCurrentLanguage = $this->context->language->id;
        self::$apiUrl = 'https://copilot.presta-module.com/';
        $this->ps_versions_compliancy = ['min' => '1.7.7', 'max' => _PS_VERSION_];
        if ($this->container === null) {
            $this->container = new ServiceContainer($this->name, $this->getLocalPath());
        }
        $this->tabs = [
            [
                'name' => [
                    'en' => $this->l('E-Commerce Copilot'),
                ],
                'class_name' => 'btecommercecopilot',
                'icon' => 'store',
            ],
            [
                'name' => [
                    'en' => $this->l('Copilot for writing content'),
                ],
                'class_name' => 'AdminIndividualProductGeneration',
                'parent_class_name' => 'btecommercecopilot',
                'icon' => 'store',
            ],
            [
                'name' => [
                    'en' => $this->l('Copilot for translating content'),
                ],
                'class_name' => 'AdminIndividualProductTranslation',
                'parent_class_name' => 'btecommercecopilot',
                'icon' => 'store',
            ],
        ];
    }
    public function install()
    {
        return parent::install() && $this->registerHook('displayBackOfficeHeader') && moduleTools::getDefaultPrompt();
    }
    public function uninstall()
    {
        return parent::uninstall() && $this->uninstallTab() && \Configuration::updateValue('ECOP_INIT_INSTALL', false);
    }
    public function getContent()
    {
        $this->installTab();
        $moduleManager = ModuleManagerBuilder::getInstance()->build();
        if (empty(\Configuration::get('ECOP_INIT_INSTALL'))) {
            $this->installMbo();
            $this->installServicesDependencies($moduleManager);
            $accountsService = null;
            \Configuration::updateValue('ECOP_INIT_INSTALL', true);
        }
        $psAcccountLink = '';
        try {
            $accountsFacade = $this->getService('btecommercecopilot.ps_accounts_facade');
            $accountsService = $accountsFacade->getPsAccountsService();
            $PsAccountData = $accountsFacade->getPsAccountsPresenter()->present($this->name);
            \Configuration::updateValue('ECOP_SHOP_UUID', $PsAccountData['currentShop']['uuid']);
        } catch (\PrestaShop\PsAccountsInstaller\Installer\Exception\InstallerException $e) {
            $accountsInstaller = $this->getService('btecommercecopilot.ps_accounts_installer');
            $accountsInstaller->install();
            $accountsFacade = $this->getService('btecommercecopilot.ps_accounts_facade');
            $accountsService = $accountsFacade->getPsAccountsService();
        }
        try {
            Media::addJsDef([
                'contextPsAccounts' => $accountsFacade->getPsAccountsPresenter()
                    ->present($this->name),
            ]);
            $this->context->smarty->assign('urlAccountsCdn', $accountsService->getAccountsCdn());
            $psAcccountLink = $this->context->smarty->fetch($this->local_path . 'views/templates/admin/buildfor/psAccountLink.tpl');
        } catch (Exception $e) {
            $this->context->controller->errors[] = $e->getMessage();
            return '';
        }
        $billingFacade = $this->getService('btecommercecopilot.ps_billings_facade');
        $billingService = $this->getService('btecommercecopilot.ps_billings_service');
        $currentSubscription = $billingService->getCurrentSubscription();
        if (!empty($currentSubscription['success'])) {
            \Configuration::updateValue('ECOP_HAS_BF_SUB', true);
        } else {
            \Configuration::updateValue('ECOP_HAS_BF_SUB', false);
        }
        $partnerLogo = $this->getLocalPath() . 'views/img/partnerLogo.png';
        Media::addJsDef($billingFacade->present([
            'logo' => $partnerLogo,
            'tosLink' => self::$apiUrl . 'terms-of-services',
            'privacyLink' => self::$apiUrl . 'privacy',
            'emailSupport' => 'modules@businesstech.fr',
        ]));
        $this->context->smarty->assign('urlBilling', 'https://unpkg.com/@prestashopcorp/billing-cdc/dist/bundle.js');
        if (!empty(self::$compare810)) {
            if (!empty($this->productPageV2Enabled())) {
                $this->registerHook('actionProductFormBuilderModifier');
            } else {
                $this->registerHook('displayAdminProductsMainStepLeftColumnMiddle');
            }
        } else {
            $this->registerHook('displayAdminProductsMainStepLeftColumnMiddle');
        }
        if (((bool) Tools::isSubmit('submitEcommercecopilotModule')) == true) {
            $this->postProcess();
        }
        $this->context->smarty->assign('module_dir', $this->_path);
        if (!$accountsService->isAccountLinked()) {
            return $psAcccountLink;
        } else {
            $this->context->smarty->assign('canUse', moduleTools::checkConsumption());
            $this->context->smarty->assign('wordsAvailable', moduleTools::getAverageWords());
            $this->context->smarty->assign('getConsumptionRatio', moduleTools::getConsumptionRatio());
            $output = $this->context->smarty->fetch($this->local_path . 'views/templates/admin/about.tpl');
            return $output . $this->renderForm();
        }
    }
    public function hookActionProductFormBuilderModifier(array $params)
    {
        if (!empty(self::$compare810)) {
            if (empty($this->context->currentLocale)) {
                $localeRepo = $this->get(Controller::SERVICE_LOCALE_REPOSITORY);
                $this->context->currentLocale = $localeRepo->getLocale(
                    $this->context->language->getLocale()
                );
            }
            $productFormModifier = $this->get(ProductFormModifier::class);
            $productFormModifier->modify((int) $params['id'], $params['form_builder']);
        }
    }
    protected function renderForm()
    {
        $helper = new HelperForm();
        $helper->show_toolbar = false;
        $helper->module = $this;
        $helper->default_form_language = $this->context->language->id;
        $helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG', 0);
        $helper->submit_action = 'submitEcommercecopilotModule';
        $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 = [
            'fields_value' => $this->getConfigFormValues(), 
            'languages' => $this->context->controller->getLanguages(),
            'id_language' => $this->context->language->id,
        ];
        return $helper->generateForm([$this->getConfigForm()]);
    }
    protected function getConfigForm()
    {
        return [
            'form' => [
                'legend' => [
                    'title' => '<img src="' . _MODULE_DIR_ . 'btecommercecopilot/logo.png' . '">' . $this->displayName . ' (' . $this->l('Version : ') . $this->version . ' ' . $this->l('by : ') . $this->author . ')',
                    'icon' => 'icon-module',
                ],
                'tabs' => [
                    'advanced-settings' => '<i class="icon-cogs"></i>&nbsp;' . $this->l('Basic settings'),
                    'prompt-settings' => '<i class="icon-book"></i>&nbsp;' . $this->l('Prompt customization'),
                    'generator-settings' => '<i class="icon-link"></i>&nbsp;' . $this->l('Copilot access'),
                    'billing-settings' => '<i class="icon-credit-card"></i>&nbsp;' . $this->l('Subscription'),
                ],
                'input' => [
                    [
                        'type' => 'billing',
                        'name' => 'billing',
                        'tab' => 'billing-settings',
                    ],
                    [
                        'type' => 'switch',
                        'label' => $this->l('Enable advanced creativity mode'),
                        'name' => 'ECOP_ADV_CREATIVE_MODE',
                        'is_bool' => true,
                        'desc' => $this->l('The advanced creativity mode allows AI to be more creative and original. However, we advise you to proofread the generated text carefully to ensure that it remains coherent and relevant. In addition, please note that this mode consumes more tokens and the AI will take longer to generate the text.'),
                        'tab' => 'advanced-settings',
                        'values' => [
                            [
                                'id' => 'advanced_creativity',
                                'value' => 1,
                            ],
                            [
                                'id' => 'advanced_creativity',
                                'value' => 0,
                            ],
                        ],
                    ],
                    [
                        'type' => 'form_section',
                        'name' => 'form_section',
                        'tab' => 'advanced-settings',
                        'translations' => [
                            'label' => $this->l('About product brand and features'),
                        ],
                    ],
                    [
                        'type' => 'module_information',
                        'name' => 'info',
                        'translations' => [
                            'explain_text' => $this->l('The module takes care of sending instructions (the "prompts") to the AI, asking it to generate the various types of product description.'),
                            'explain_text_2' => $this->l('We\'ve also prepared an instruction asking the AI to mention the product brand (in both the short and long descriptions) and another asking it to list the product features (in the long description only). By default, we don\'t include them in the prompts sent to the AI, as this makes the prompts longer and therefore consumes more tokens. However, if you want to include them, then activate the corresponding options below.'),
                        ],
                        'alert' => 'info',
                        'tab' => 'advanced-settings',
                    ],
                    [
                        'type' => 'switch',
                        'label' => $this->l('Include product brand'),
                        'name' => 'ECOP_USE_BRAND',
                        'is_bool' => true,
                        'desc' => $this->l('Activate this option to indicate (if available) the product brand to the AI and ask it to mention it in the short and long product descriptions.'),
                        'tab' => 'advanced-settings',
                        'values' => [
                            [
                                'id' => 'use_brand',
                                'value' => 1,
                            ],
                            [
                                'id' => 'use_brand',
                                'value' => 0,
                            ],
                        ],
                    ],
                    [
                        'type' => 'switch',
                        'label' => $this->l('Include product features'),
                        'name' => 'ECOP_USE_FEATURE',
                        'is_bool' => true,
                        'desc' => $this->l('Activate this option to indicate the product feature(s) (if any) to the AI and ask it to list them in the long product description.'),
                        'tab' => 'advanced-settings',
                        'values' => [
                            [
                                'id' => 'use_feature',
                                'value' => 1,
                            ],
                            [
                                'id' => 'use_feature',
                                'value' => 0,
                            ],
                        ],
                    ],
                    [
                        'type' => 'module_information',
                        'name' => 'info',
                        'tab' => 'generator-settings',
                        'translations' => [
                            'explain_text' => $this->l('Once you\'ve set up your module, click on the buttons below to ask your copilot for help! Ask it to generate content or a translation. You can also find your copilot at any time through your PrestaShop menu, in the "E-commerce Copilot" section.'),
                        ],
                        'alert' => 'info',
                    ],
                    [
                        'type' => 'module_button_link',
                        'tab' => 'generator-settings',
                        'translations' => [
                            'label' => $this->l('I need my copilot to write content'),
                        ],
                        'link' => $this->context->link->getAdminLink('AdminIndividualProductGeneration'),
                        'name' => '',
                    ],
                    [
                        'type' => 'module_button_link',
                        'tab' => 'generator-settings',
                        'translations' => [
                            'label' => $this->l('I need my copilot for a translation'),
                        ],
                        'link' => $this->context->link->getAdminLink('AdminIndividualProductTranslation'),
                        'name' => '',
                    ],
                    [
                        'type' => 'module_information',
                        'name' => 'info',
                        'translations' => [
                            'explain_text' => $this->l('We\'ve already written the necessary prompts for the AI to generate the various contents, so that you don\'t have to do it yourself. Then, if you\'ve already configured the "Basic settings" tab, you can start using your copilot right away, through the "E-commerce copilot" section of your PrestaShop menu.'),
                            'explain_text_2' => $this->l('However, if you\'d like to write your own customized prompts, you can do so using the options below.'),
                            'explain_text_3' => $this->l('For each content item for which you want to send your own prompt to the AI, activate the corresponding option and enter your text in the field that appears. It doesn\'t matter what language you write your prompt in.'),
                        ],
                        'alert' => 'info',
                        'tab' => 'prompt-settings',
                    ],
                    [
                        'type' => 'form_section',
                        'name' => 'form_section',
                        'tab' => 'prompt-settings',
                        'translations' => [
                            'label' => $this->l('Product prompts'),
                        ],
                    ],
                    [
                        'type' => 'switch',
                        'label' => $this->l('Use custom prompt for long product descriptions'),
                        'name' => 'ECOP_CUSTOM_LONG_DESC_PROMPT',
                        'is_bool' => true,
                        'tab' => 'prompt-settings',
                        'values' => [
                            [
                                'id' => 'custom_prompt_long_desc',
                                'value' => 1,
                            ],
                            [
                                'id' => 'custom_prompt_long_desc',
                                'value' => 0,
                            ],
                        ],
                    ],
                    [
                        'type' => 'textarea',
                        'label' => $this->l('Your prompt for long product descriptions'),
                        'name' => 'ECOP_LONG_DESC_PROMPT',
                        'desc' => $this->l('Important: you must include the {product_name} tag to tell the AI the name of the product (this tag will then be dynamically replaced by the real product name). If you\'ve enabled the addition of brand name and/or features in the prompt via the previous tab, you don\'t need to mention them here.'),
                        'tab' => 'prompt-settings',
                        'value' => Configuration::get('ECOP_LONG_DESC_PROMPT'),
                        'required' => true,
                        'form_group_class' => 'custom_product_long_prompt',
                    ],
                    [
                        'type' => 'switch',
                        'label' => $this->l('Use custom prompt for short product descriptions'),
                        'name' => 'ECOP_CUSTOM_SHORT_DESC_PROMPT',
                        'is_bool' => true,
                        'tab' => 'prompt-settings',
                        'values' => [
                            [
                                'id' => 'custom_prompt_short_desc',
                                'value' => 1,
                            ],
                            [
                                'id' => 'custom_prompt_short_desc',
                                'value' => 0,
                            ],
                        ],
                    ],
                    [
                        'type' => 'textarea',
                        'label' => $this->l('Your prompt for short product descriptions'),
                        'name' => 'ECOP_SHORT_DESC_PROMPT',
                        'desc' => $this->l('Important: you must include the {product_name} tag to tell the AI the name of the product (this tag will then be dynamically replaced by the real name of the product). If you\'ve enabled the addition of brand name in the prompt via the previous tab, you don\'t need to mention it here.'),
                        'tab' => 'prompt-settings',
                        'value' => Configuration::get('ECOP_SHORT_DESC_PROMPT'),
                        'required' => true,
                        'form_group_class' => 'custom_product_short_prompt',
                    ],
                    [
                        'type' => 'switch',
                        'label' => $this->l('Use custom prompt for product meta-descriptions'),
                        'name' => 'ECOP_CUSTOM_META_DESC_PROMPT',
                        'is_bool' => true,
                        'tab' => 'prompt-settings',
                        'values' => [
                            [
                                'id' => 'custom_prompt_meta_desc',
                                'value' => 1,
                            ],
                            [
                                'id' => 'custom_prompt_meta_desc',
                                'value' => 0,
                            ],
                        ],
                    ],
                    [
                        'type' => 'textarea',
                        'label' => $this->l('Your prompt for product meta-descriptions'),
                        'name' => 'ECOP_META_DESC_PROMPT',
                        'desc' => $this->l('Important: you must include the {product_name} tag to tell the AI the name of the product (this tag will then be dynamically replaced by the real name of the product).'),
                        'tab' => 'prompt-settings',
                        'value' => Configuration::get('ECOP_META_DESC_PROMPT'),
                        'required' => true,
                        'form_group_class' => 'custom_product_meta_prompt',
                    ],
                    [
                        'type' => 'form_section',
                        'name' => 'form_section',
                        'tab' => 'prompt-settings',
                        'translations' => [
                            'label' => $this->l('Category prompts'),
                        ],
                    ],
                    [
                        'type' => 'switch',
                        'label' => $this->l('Use custom prompt for category descriptions'),
                        'name' => 'ECOP_CUSTOM_CAT_LONG_DESC_PROMPT',
                        'is_bool' => true,
                        'tab' => 'prompt-settings',
                        'values' => [
                            [
                                'id' => 'custom_cat_prompt_long_desc',
                                'value' => 1,
                            ],
                            [
                                'id' => 'custom_cat_prompt_long_desc',
                                'value' => 0,
                            ],
                        ],
                    ],
                    [
                        'type' => 'textarea',
                        'label' => $this->l('Your prompt for category descriptions'),
                        'name' => 'ECOP_CAT_DESC_PROMPT',
                        'desc' => $this->l('Important: you must include the {category_name} tag to tell the AI the name of the category (this tag will then be dynamically replaced by the real name of the category).'),
                        'tab' => 'prompt-settings',
                        'value' => Configuration::get('ECOP_CAT_DESC_PROMPT'),
                        'required' => true,
                        'form_group_class' => 'custom_cat_desc_prompt',
                    ],
                    [
                        'type' => 'switch',
                        'label' => $this->l('Use custom prompt for addtionnal category description'),
                        'name' => 'ECOP_CUSTOM_CAT_ADD_DESC_PROMPT',
                        'is_bool' => true,
                        'tab' => 'prompt-settings',
                        'values' => [
                            [
                                'id' => 'custom_cat_prompt_add_desc',
                                'value' => 1,
                            ],
                            [
                                'id' => 'custom_cat_prompt_add_desc',
                                'value' => 0,
                            ],
                        ],
                    ],
                    [
                        'type' => 'textarea',
                        'label' => $this->l('Your prompt for addtionnal category descriptions'),
                        'name' => 'ECOP_CAT_ADD_DESC_PROMPT',
                        'desc' => $this->l('Important: you must include the {category_name} tag to tell the AI the name of the category (this tag will then be dynamically replaced by the real name of the category).'),
                        'tab' => 'prompt-settings',
                        'value' => Configuration::get('ECOP_CAT_ADD_DESC_PROMPT'),
                        'required' => true,
                        'form_group_class' => 'custom_cat_add_desc_prompt',
                    ],
                    [
                        'type' => 'switch',
                        'label' => $this->l('Use custom prompt for category meta-description'),
                        'name' => 'ECOP_CUSTOM_CAT_META_DESC_PROMPT',
                        'is_bool' => true,
                        'tab' => 'prompt-settings',
                        'values' => [
                            [
                                'id' => 'custom_prompt_cat_meta_desc',
                                'value' => 1,
                            ],
                            [
                                'id' => 'custom_prompt_cat_meta_desc',
                                'value' => 0,
                            ],
                        ],
                    ],
                    [
                        'type' => 'textarea',
                        'label' => $this->l('Your prompt for category meta-descriptions'),
                        'name' => 'ECOP_META_CAT_DESC_PROMPT',
                        'desc' => $this->l('Important: you must include the {category_name} tag to tell the AI the name of the category (this tag will then be dynamically replaced by the real name of the category).'),
                        'tab' => 'prompt-settings',
                        'value' => Configuration::get('ECOP_META_CAT_DESC_PROMPT'),
                        'required' => true,
                        'form_group_class' => 'custom_category_meta_prompt',
                    ],
                    [
                        'type' => 'form_section',
                        'name' => 'form_section',
                        'tab' => 'prompt-settings',
                        'translations' => [
                            'label' => $this->l('CMS page prompts'),
                        ],
                    ],
                    [
                        'type' => 'switch',
                        'label' => $this->l('Use custom prompt for CMS pages'),
                        'name' => 'ECOP_CUSTOM_CMS_PROMPT',
                        'is_bool' => true,
                        'tab' => 'prompt-settings',
                        'values' => [
                            [
                                'id' => 'custom_prompt_cms',
                                'value' => 1,
                            ],
                            [
                                'id' => 'custom_prompt_cms',
                                'value' => 0,
                            ],
                        ],
                    ],
                    [
                        'type' => 'textarea',
                        'label' => $this->l('Your prompt for CMS pages'),
                        'name' => 'ECOP_CMS_CONTENT',
                        'desc' => $this->l('Important: you must include the {cms_name} tag to tell the AI the name of the CMS page (this tag will then be dynamically replaced by the real name of the CMS page).'),
                        'tab' => 'prompt-settings',
                        'value' => Configuration::get('ECOP_CMS_CONTENT'),
                        'required' => true,
                        'form_group_class' => 'custom_cms_prompt',
                    ],
                ],
                'submit' => [
                    'title' => $this->l('Save'),
                ],
            ],
        ];
    }
    protected function getConfigFormValues()
    {
        return [
            'ECOP_ADV_CREATIVE_MODE' => Configuration::get('ECOP_ADV_CREATIVE_MODE'),
            'ECOP_LONG_DESC_PROMPT' => Configuration::get('ECOP_LONG_DESC_PROMPT'),
            'ECOP_SHORT_DESC_PROMPT' => Configuration::get('ECOP_SHORT_DESC_PROMPT'),
            'ECOP_META_DESC_PROMPT' => Configuration::get('ECOP_META_DESC_PROMPT'),
            'ECOP_CAT_DESC_PROMPT' => Configuration::get('ECOP_CAT_DESC_PROMPT'),
            'ECOP_CAT_ADD_DESC_PROMPT' => Configuration::get('ECOP_CAT_ADD_DESC_PROMPT'),
            'ECOP_META_CAT_DESC_PROMPT' => Configuration::get('ECOP_META_CAT_DESC_PROMPT'),
            'ECOP_USE_BRAND' => Configuration::get('ECOP_USE_BRAND'),
            'ECOP_USE_FEATURE' => Configuration::get('ECOP_USE_FEATURE'),
            'ECOP_CUSTOM_LONG_DESC_PROMPT' => Configuration::get('ECOP_CUSTOM_LONG_DESC_PROMPT'),
            'ECOP_CUSTOM_SHORT_DESC_PROMPT' => Configuration::get('ECOP_CUSTOM_SHORT_DESC_PROMPT'),
            'ECOP_CUSTOM_META_DESC_PROMPT' => Configuration::get('ECOP_CUSTOM_META_DESC_PROMPT'),
            'ECOP_CUSTOM_CAT_LONG_DESC_PROMPT' => Configuration::get('ECOP_CUSTOM_CAT_LONG_DESC_PROMPT'),
            'ECOP_CUSTOM_CAT_ADD_DESC_PROMPT' => Configuration::get('ECOP_CUSTOM_CAT_ADD_DESC_PROMPT'),
            'ECOP_CUSTOM_CAT_META_DESC_PROMPT' => Configuration::get('ECOP_CUSTOM_CAT_META_DESC_PROMPT'),
            'ECOP_CUSTOM_CMS_PROMPT' => Configuration::get('ECOP_CUSTOM_CMS_PROMPT'),
            'ECOP_CMS_CONTENT' => Configuration::get('ECOP_CMS_CONTENT'),
        ];
    }
    protected function postProcess()
    {
        Configuration::updateValue('ECOP_ACTIVATE_PREVIEW', true);
        $form_values = $this->getConfigFormValues();
        if (!empty(\Tools::getValue('ECOP_CUSTOM_LONG_DESC_PROMPT'))) {
            if (empty(Tools::getValue('ECOP_LONG_DESC_PROMPT'))) {
                $this->context->controller->errors[] = $this->l('Prompt is required. You wanted to write the prompt for long product descriptions yourself, but it seems not to have been saved. Go back to the "Prompt customization" tab, write your prompt and save it.');
                return;
            } else {
                if (empty(moduleTools::checkProductNameTag(Tools::getValue('ECOP_LONG_DESC_PROMPT')))) {
                    $this->context->controller->errors[] = $this->l('The custom prompt for long product descriptions is invalid: the {product_name} tag is missing. Go to the "Prompt customization" tab and include it.');
                    return;
                }
            }
        }
        if (!empty(\Tools::getValue('ECOP_CUSTOM_SHORT_DESC_PROMPT'))) {
            if (empty(Tools::getValue('ECOP_SHORT_DESC_PROMPT'))) {
                $this->context->controller->errors[] = $this->l('Prompt is required. You wanted to write the prompt for short product descriptions yourself, but it seems not to have been saved. Go back to the "Prompt customization" tab, write your prompt and save it.');
                return;
            } else {
                if (empty(moduleTools::checkProductNameTag(Tools::getValue('ECOP_SHORT_DESC_PROMPT')))) {
                    $this->context->controller->errors[] = $this->l('The custom prompt for short product descriptions is invalid: the {product_name} tag is missing. Go to the "Prompt customization" tab and include it.');
                    return;
                }
            }
        }
        if (!empty(\Tools::getValue('ECOP_CUSTOM_META_DESC_PROMPT'))) {
            if (empty(Tools::getValue('ECOP_META_DESC_PROMPT'))) {
                $this->context->controller->errors[] = $this->l('Prompt is required. You wanted to write the prompt for product meta-descriptions yourself, but it seems not to have been saved. Go back to the "Prompt customization" tab, write your prompt and save it.');
                return;
            } else {
                if (empty(moduleTools::checkProductNameTag(Tools::getValue('ECOP_META_DESC_PROMPT')))) {
                    $this->context->controller->errors[] = $this->l('The custom prompt for product meta-descriptions is invalid: the {product_name} tag is missing. Go to the "Prompt customization" tab and include it.');
                    return;
                }
            }
        }
        if (!empty(\Tools::getValue('ECOP_CUSTOM_CAT_LONG_DESC_PROMPT'))) {
            if (empty(Tools::getValue('ECOP_CAT_DESC_PROMPT'))) {
                $this->context->controller->errors[] = $this->l('Prompt is required. You wanted to write the prompt for category descriptions yourself, but it seems not to have been saved. Go back to the "Prompt customization" tab, write your prompt and save it.');
                return;
            } else {
                if (empty(moduleTools::checkCategoryNameTag(Tools::getValue('ECOP_CAT_DESC_PROMPT')))) {
                    $this->context->controller->errors[] = $this->l('The custom prompt for category descriptions is invalid: the {category_name} tag is missing. Go to the "Prompt customization" tab and include it.');
                    return;
                }
            }
        }
        if (!empty(\Tools::getValue('ECOP_CUSTOM_CAT_ADD_DESC_PROMPT'))) {
            if (empty(Tools::getValue('ECOP_CAT_ADD_DESC_PROMPT'))) {
                $this->context->controller->errors[] = $this->l('Prompt is required. You wanted to write the prompt for additional category descriptions yourself, but it seems not to have been saved. Go back to the "Prompt customization" tab, write your prompt and save it.');
                return;
            } else {
                if (empty(moduleTools::checkCategoryNameTag(Tools::getValue('ECOP_CAT_ADD_DESC_PROMPT')))) {
                    $this->context->controller->errors[] = $this->l('The custom prompt for additional category descriptions is invalid: the {category_name} tag is missing. Go to the "Prompt customization" tab and include it.');
                    return;
                }
            }
        }
        if (!empty(\Tools::getValue('ECOP_CUSTOM_CAT_META_DESC_PROMPT'))) {
            if (empty(Tools::getValue('ECOP_META_CAT_DESC_PROMPT'))) {
                $this->context->controller->errors[] = $this->l('Prompt is required. You wanted to write the prompt for category meta-descriptions yourself, but it seems not to have been saved. Go back to the "Prompt customization" tab, write your prompt and save it.');
                return;
            } else {
                if (empty(moduleTools::checkCategoryNameTag(Tools::getValue('ECOP_META_CAT_DESC_PROMPT')))) {
                    $this->context->controller->errors[] = $this->l('The custom prompt for category meta-descriptions is invalid: the {category_name} tag is missing. Go to the "Prompt customization" tab and include it.');
                    return;
                }
            }
        }
        if (!empty(\Tools::getValue('ECOP_CUSTOM_CMS_PROMPT'))) {
            if (empty(Tools::getValue('ECOP_CMS_CONTENT'))) {
                $this->context->controller->errors[] = $this->l('Prompt is required. You wanted to write the prompt for CMS pages yourself, but it seems not to have been saved. Go back to the "Prompt customization" tab, write your prompt and save it.');
                return;
            } else {
                if (empty(moduleTools::checkCmsNameTag(Tools::getValue('ECOP_CMS_CONTENT')))) {
                    $this->context->controller->errors[] = $this->l('The custom prompt for CMS pages is invalid: the {cms_name} tag is missing. Go to the "Prompt customization" tab and include it.');
                    return;
                }
            }
        }
        foreach (array_keys($form_values) as $key) {
            Configuration::updateValue($key, Tools::getValue($key));
        }
        $this->context->controller->confirmations[] = $this->l('The configuration has been successfully updated.');
    }
    public function hookDisplayBackOfficeHeader($params)
    {
        if (Tools::getValue('configure') == $this->name) {
            $this->context->controller->addJS($this->_path . 'views/js/back.js');
            $this->context->controller->addCSS($this->_path . 'views/css/back.css');
        }
        $request = $this->getSfRequest();
        if (empty($request)) {
            return null;
        }
        if (empty(self::$compare810)) {
            if (Tools::getValue('controller') == 'AdminProducts' && !empty($request->get('id'))) {
                $this->context->controller->addJS($this->_path . 'views/js/catalog-generator.js');
                $this->context->controller->addCSS($this->_path . 'views/css/back.css');
            }
        } elseif (!empty(self::$compare810)) {
            if (!empty($this->productPageV2Enabled())) {
                if (Tools::getValue('controller') == 'AdminProducts' && !empty(Tools::getValue('id_product'))) {
                    $this->context->controller->addJS($this->_path . 'views/js/catalog-generator-81.js');
                    $this->context->controller->addCSS($this->_path . 'views/css/back.css');
                }
            } else {
                if (Tools::getValue('controller') == 'AdminProducts' && !empty($request->get('id'))) {
                    $this->context->controller->addJS($this->_path . 'views/js/catalog-generator.js');
                    $this->context->controller->addCSS($this->_path . 'views/css/back.css');
                }
            }
        }
    }
    public function hookDisplayAdminProductsMainStepLeftColumnMiddle($params)
    {
        $product = new Product((int) $params['id_product']);
        if (!Validate::isLoadedObject($product)) {
            return;
        }
        \Media::addJsDef([
            'ecop' => [
                'hide' => $this->l('Hide', 'btecommercecopilot'),
                'show' => $this->l('Show', 'btecommercecopilot'),
            ]
        ]);
        $this->context->smarty->assign([
            'btCopModuleUrl' => Context::getContext()->link->getAdminLink('AdminModules') . '&configure=btecommercecopilot',
            'Btlanguages' => array_reverse(Language::getLanguages(false)),
            'isPs81' => self::$compare810,
            'moduleName' => $this->displayName,
            'isSubValid' => clientAi::checkSubscriptionStatus(),
            'author' => $this->author,
            'version' => $this->version,
            'btCopLoader' => _MODULE_DIR_ . 'btecommercecopilot/views/img/evis-loader.png',
            'canUse' => moduleTools::checkConsumption(),
            'logoModule' => _MODULE_DIR_ . 'btecommercecopilot/logo.png',
            'wordsAvailable' => moduleTools::getAverageWords(),
            'getConsumptionRatio' => moduleTools::getConsumptionRatio(),
            'BtCopGenerateLongDesc' => $this->context->link->getAdminLink('AdminModules', true, [], [
                'configure' => $this->name,
                'action' => 'generateAiDesc',
                'idProduct' => $params['id_product'],
                'generateType' => 'long-description',
            ]),
            'BtCopGenerateShortDesc' => $this->context->link->getAdminLink('AdminModules', true, [], [
                'configure' => $this->name,
                'action' => 'generateAiDesc',
                'idProduct' => $params['id_product'],
                'generateType' => 'short-description',
            ]),
            'BtCopGenerateMetaDesc' => $this->context->link->getAdminLink('AdminModules', true, [], [
                'configure' => $this->name,
                'action' => 'generateAiDesc',
                'idProduct' => $params['id_product'],
                'generateType' => 'meta-description',
            ]),
            'BtCopTranslateLongDesc' => $this->context->link->getAdminLink('AdminModules', true, [], [
                'configure' => $this->name,
                'action' => 'translateAiDesc',
                'idProduct' => $params['id_product'],
                'generateType' => 'long-description',
            ]),
            'BtCopTranslateShortDesc' => $this->context->link->getAdminLink('AdminModules', true, [], [
                'configure' => $this->name,
                'action' => 'translateAiDesc',
                'idProduct' => $params['id_product'],
                'generateType' => 'short-description',
            ]),
            'BtCopTranslateMetaDesc' => $this->context->link->getAdminLink('AdminModules', true, [], [
                'configure' => $this->name,
                'action' => 'translateAiDesc',
                'idProduct' => $params['id_product'],
                'generateType' => 'meta-description',
            ]),
            'BtCopSave' => $this->context->link->getAdminLink('AdminModules', true, [], [
                'configure' => $this->name,
                'action' => 'saveProductDataAfterPreview',
                'idProduct' => $params['id_product'],
            ]),
        ]);
        return $this->context->smarty->fetch($this->local_path . 'views/templates/admin/generator/productAdmin.tpl');
    }
    public function ajaxProcessGenerateAiDesc()
    {
        try {
            $isoLang = !empty(Tools::getValue('langIso')) ? Tools::getValue('langIso') : Context::getContext()->language->iso_code;
            $generateType = Tools::getValue('generateType');
            $idProduct = Tools::getValue('idProduct');
            $success = false;
            $return = [];
            if (empty($isoLang) || empty($generateType) || empty($idProduct)) {
                return;
            }
            $idLang = \Language::getIdByIso($isoLang);
            if (empty($idLang)) {
                return;
            }
            $lang = new \Language((int) $idLang);
            $apiAction = moduleConfiguration::getTypeOfIA('long-description');
            $clientAi = new clientAi((string) $apiAction);
            $productName = moduleTools::getProductTitle($idProduct, $idLang);
            if ($generateType == 'long-description') {
                $generatedDescrption = $clientAi->generateProductDescription($productName, $lang->name, $idProduct, $idLang);
            } elseif ($generateType == 'short-description') {
                $generatedDescrption = $clientAi->generateProductShortDescription($productName, $lang->name, $idProduct);
            } elseif ($generateType == 'meta-description') {
                $generatedDescrption = $clientAi->generateProductMetaDescription($productName, $lang->name, $idProduct);
            }
            if (!empty($generatedDescrption)) {
                $success = true;
            }
            if ($success) {
                $return = [
                    'description' => $generatedDescrption,
                    'typeOfGeneration' => $generateType,
                ];
            } else {
                $return = [
                    'description' => '',
                    'typeOfGeneration' => $generateType,
                ];
            }
        } catch (\Exception $e) {
            \PrestaShopLogger::addLog($e->getMessage(), 3, $e->getCode(), null, null, true);
        }
        exit(json_encode($return));
    }
    public function ajaxProcessTranslateAiDesc()
    {
        try {
            $isoLangForm = Tools::getValue('langIsoFrom');
            $langIdTo = Tools::getValue('langIdTo');
            $generateType = Tools::getValue('generateType');
            $idProduct = Tools::getValue('idProduct');
            $success = false;
            $noDescriptionToTranslate = false;
            $return = [];
            $translatedData = null;
            if (empty($isoLangForm) || empty($generateType) || empty($idProduct)) {
                return;
            }
            $idLangFrom = \Language::getIdByIso($isoLangForm);
            if (empty($idLangFrom) || empty($langIdTo)) {
                return;
            }
            $languageTo = new \Language((int) $langIdTo);
            $clientAi = new clientAi('completions');
            if ($generateType == 'long-description' || $generateType == 'short-description' || $generateType == 'meta-description') {
                $hasDescription = moduleTools::hasProductDescriptionToTranslate($idProduct, (int) $idLangFrom, $generateType);
                if (empty($hasDescription)) {
                    $languageFrom = new \Language((int) $idLangFrom);
                    $return = [
                        'hasInvalidData' => true,
                        'errorMessage' => $this->l('The product has no', 'AdminIndividualProductTranslationController') . ' ' . $generateType . ' ' . $this->l('in the source language:', 'AdminIndividualProductTranslationController') . ' ' . $languageFrom->name,
                        'hasGeneratedData' => false,
                        'step' => 1,
                        'description' => '',
                        'output' => '',
                    ];
                    exit(json_encode($return));
                } else {
                    $translatedData = $clientAi->translateProductData($idProduct, (int) $idLangFrom, $languageTo, $generateType);
                    if (!empty($translatedData)) {
                        if (moduleTools::updateProductDescriptions($idProduct, $langIdTo, $generateType, $translatedData)) {
                            $success = true;
                        }
                    } else {
                        $noDescriptionToTranslate = true;
                    }
                }
            }
            if ($success) {
                $return = [
                    'description' => $translatedData,
                    'typeOfGeneration' => $generateType,
                    'noDescriptionToTranslate' => $noDescriptionToTranslate,
                ];
            } else {
                $return = [
                    'description' => '',
                    'typeOfGeneration' => $generateType,
                    'noDescriptionToTranslate' => $noDescriptionToTranslate,
                ];
            }
        } catch (\Exception $e) {
            \PrestaShopLogger::addLog($e->getMessage(), 3, $e->getCode(), null, null, true);
        }
        exit(json_encode($return));
    }
    public function ajaxProcessSaveProductDataAfterPreview()
    {
        try {
            $updatedDescription = \Tools::getValue('description_generated');
            $generateType = \Tools::getValue('generateType');
            $generateAction = \Tools::getValue('generateAction');
            $idProduct = Tools::getValue('idProduct');
            $isoLang = Tools::getValue('langIso');
            $langIdTo = Tools::getValue('langIdTo');
            $idLang = \Language::getIdByIso($isoLang);
            $success = false;
            $return = null;
            if ($generateAction == 'generate') {
                if (moduleTools::updateProductDescriptions($idProduct, $idLang, $generateType, $updatedDescription)) {
                    $success = true;
                }
            } elseif ($generateAction == 'translate') {
                if (moduleTools::updateProductDescriptions($idProduct, $langIdTo, $generateType, $updatedDescription)) {
                    $success = true;
                }
            }
            if ($success) {
                $return = [
                    'saved' => true,
                    'description' => $updatedDescription,
                    'typeOfGeneration' => $generateType,
                ];
            } else {
                $return = [
                    'saved' => false,
                    'description' => '',
                    'typeOfGeneration' => $generateType,
                ];
            }
        } catch (\Exception $e) {
            \PrestaShopLogger::addLog($e->getMessage(), 3, $e->getCode(), null, null, true);
        }
        exit(json_encode($return));
    }
    private function installTab()
    {
        foreach ($this->tabs as $tab_data) {
            $tabId = (int) Tab::getIdFromClassName($tab_data['class_name']);
            if (!$tabId) {
                $tabId = null;
            }
            $tab = new Tab($tabId);
            $tab->active = true;
            $tab->class_name = $tab_data['class_name'];
            $tab->name = $tab_data['name'];
            foreach (\Language::getLanguages() as $lang) {
                $tab->name[$lang['id_lang']] = !empty($tab_data['name'][$lang['iso_code']]) ? $tab_data['name'][$lang['iso_code']] : $tab_data['name']['en'];
            }
            if (!empty($tab_data['parent_class_name'])) {
                $tab->id_parent = (int) Tab::getIdFromClassName($tab_data['parent_class_name']);
            } else {
                $tab->id_parent = 0;
            }
            $tab->icon = $tab_data['icon'];
            $tab->module = $this->name;
            $tab->save();
        }
        return true;
    }
    private function uninstallTab()
    {
        foreach ($this->tabs as $tab_data) {
            $idTab = (int) Tab::getIdFromClassName($tab_data['class_name']);
            if ($idTab) {
                $tab = new Tab($idTab);
                try {
                    $tab->delete();
                } catch (Exception $e) {
                    echo $e->getMessage();
                    return false;
                }
            }
        }
        return true;
    }
    public function getSfContainer()
    {
        // Note Team Validation - Requiert une globale pour obtenir l'objet Request
        global $kernel;
        if (empty($kernel)) {
            throw new Exception('Symfony kernel is not defined');
        }
        return $kernel->getContainer();
    }
    protected function getSfRequest()
    {
        try {
            $request = null;
            if (version_compare(_PS_VERSION_, '1.7.4.0', '>=')) {
                $request = $this->getSfContainer()->get('request_stack')->getCurrentRequest();
            } else {
                $request = $this->getSfContainer()->get('request');
            }
            if (!is_object($request)) {
                return null;
            }
            return $request;
        } catch (Exception $e) {
        }
        return null;
    }
    private function installServicesDependencies($moduleManager)
    {
        try {
            if (!$moduleManager->isInstalled('ps_accounts')) {
                $moduleManager->install('ps_accounts');
            } elseif (!$moduleManager->isEnabled('ps_accounts')) {
                $moduleManager->enable('ps_accounts');
                $moduleManager->upgrade('ps_accounts');
            } else {
                $moduleManager->upgrade('ps_accounts');
            }
        } catch (\PrestaShop\PrestaShop\Core\Addon\Module\Exception\UnconfirmedModuleActionException $e) {
            $this->context->smarty->assign(
                'error_message',
                'Please upgrade the module PrestaShop Account to use the "' . $this->displayName . '"'
            );
            return $this->context->smarty->fetch($this->local_path . 'views/templates/admin/errors.tpl');
        } catch (\PrestaShop\PsAccountsInstaller\Installer\Exception\InstallerException $e) {
            $this->context->smarty->assign('error_message', $e->getMessage());
            return $this->context->smarty->fetch($this->local_path . 'views/templates/admin/errors.tpl');
        } catch (\Throwable $e) {
            $this->context->smarty->assign(
                'error_message',
                'Please upgrade the module "PrestaShop Account" to use the "' . $this->displayName . '"'
            );
            return $this->context->smarty->fetch($this->local_path . 'views/templates/admin/errors.tpl');
        }
        try {
            if (!$moduleManager->isInstalled('ps_eventbus')) {
                $moduleManager->install('ps_eventbus');
            } elseif (!$moduleManager->isEnabled('ps_eventbus')) {
                $moduleManager->enable('ps_eventbus');
                $moduleManager->upgrade('ps_eventbus');
            } else {
                $moduleManager->upgrade('ps_eventbus');
            }
        } catch (\PrestaShop\PrestaShop\Core\Addon\Module\Exception\UnconfirmedModuleActionException $e) {
            $this->context->smarty->assign(
                'error_message',
                'Please upgrade the module PrestaShop Account to use the "' . $this->displayName . '"'
            );
            return $this->context->smarty->fetch($this->local_path . 'views/templates/admin/errors.tpl');
        } catch (\PrestaShop\PsAccountsInstaller\Installer\Exception\InstallerException $e) {
            $this->context->smarty->assign('error_message', $e->getMessage());
            return $this->context->smarty->fetch($this->local_path . 'views/templates/admin/errors.tpl');
        } catch (\Throwable $e) {
            $this->context->smarty->assign(
                'error_message',
                'Please upgrade the module "PrestaShop Account" to use the "' . $this->displayName . '"'
            );
            return $this->context->smarty->fetch($this->local_path . 'views/templates/admin/errors.tpl');
        }
    }
    private function installMbo()
    {
        if (!empty(self::$compare80)) {
            $mboStatus = (new \Prestashop\ModuleLibMboInstaller\Presenter())->present();
            if (empty($mboStatus)) {
                $this->context->controller->errors[] = $this->l('Could not locate the MBO installer library. Please reach out to our support.');
                return;
            }
            if (empty($mboStatus['isPresentOnDisk']) || empty($mboStatus['isInstalled'])) {
                try {
                    $mboInstaller = new \Prestashop\ModuleLibMboInstaller\Installer(_PS_VERSION_);
                    $result = $mboInstaller->installModule();
                    if (!$result) {
                        throw new \Exception('Install returned false');
                    }
                } catch (\Exception $e) {
                    $this->context->controller->errors[] = $this->l(sprintf('An error occurred while attempting to install the MBO module: %s', $e->getMessage()));
                    return;
                }
            }
        }
    }
    public function getService($serviceName)
    {
        return $this->container->getService($serviceName);
    }
    private function productPageV2Enabled()
    {
        return $this->getContainer()->get('prestashop.core.admin.feature_flag.repository')->isEnabled('product_page_v2');
    }
}