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/www/nueva/modules/pmproductvideoreviews/pmproductvideoreviews.php
<?php
/**
 * rec.reviews
 *
 * @author    Presta-Module.com <support@presta-module.com> - https://www.presta-module.com
 * @copyright Presta-Module 2023 - https://www.presta-module.com
 * @license   see file: LICENSE.txt
 *
 * @version   1.0.4
 *
 *           ____     __  __
 *          |  _ \   |  \/  |
 *          | |_) |  | |\/| |
 *          |  __/   | |  | |
 *          |_|      |_|  |_|
 */

if (!defined('_PS_VERSION_')) {
    exit;
}
require_once dirname(__FILE__) . '/vendor/autoload.php';
use RecReviews\Client as RecReviewsClient;
use PrestaModule\ProductVideoReviews\Utils;
use PrestaModule\ProductVideoReviews\Ratings;
class pmproductvideoreviews extends Module
{
    private $container;
    private $emailSupport;
    public static $moduleVersion;
    public $adminTab = [
        'name' => [
            'en' => 'Video reviews',
            'fr' => 'Avis vidéo',
        ],
        'class_name' => 'AdminRecReviews',
        'visible' => true,
        'parent_class_name' => 'AdminParentCustomer',
    ];
    public function __construct()
    {
        $this->name = 'pmproductvideoreviews';
        $this->tab = 'advertising_marketing';
        $this->version = '1.0.4';
        $this->author = 'Presta-Module';
        $this->module_key = '5e991133e38608ca5e0f0b138936ee07';
        $this->need_instance = 0;
        $this->emailSupport = 'support@presta-module.com';
        self::$moduleVersion =  $this->version;
        $this->bootstrap = true;
        parent::__construct();
        $this->displayName = $this->l('rec.reviews');
        $this->description = $this->l('Allow your customers to record themselves on video to give an authentic review of your products. Post these videos on your store and increase your conversion rate with certified and original reviews that will make you stand out from the competition.');
        $this->confirmUninstall = $this->l('Are you sure you want to remove the module ?');
        $this->ps_versions_compliancy['min'] = '1.7.4.0';
        if (Tools::getValue('module_name') == $this->name || Tools::getValue('configure') == $this->name) {
            if (RecReviewsClient::MODULE_SOURCE == 'addons') {
                $this->ps_versions_compliancy['max'] = '1.7.8.99';
                if ($this->container === null) {
                    $this->container = new \PrestaShop\ModuleLibServiceContainer\DependencyInjection\ServiceContainer($this->name, $this->getLocalPath());
                }
            }
        }
    }
    public function install()
    {
        include dirname(__FILE__) . '/sql/install.php';
        $hooks = [
            'displayHeader',
            'displayBackOfficeHeader',
            'actionOrderStatusUpdate',
            'actionValidateOrder',
            'displayFooterProduct',
            'actionObjectLanguageAddAfter',
            'actionEmailSendBefore',
        ];
        if (RecReviewsClient::MODULE_SOURCE == 'addons') {
            $this->getService('ps_accounts.installer')->install();
        }
        return parent::install()
            && $this->registerHook($hooks)
            && $this->installTab()
            && $this->initModuleConf();
    }
    public function uninstall()
    {
        include dirname(__FILE__) . '/sql/uninstall.php';
        return parent::uninstall() && Configuration::updateValue('PVR_OAUTH', '') && Configuration::updateValue('PVR_RBM_SUB_ID', '');
    }
    public function getLanguageIsoCode()
    {
        return $this->context->language !== null ? $this->context->language->iso_code : 'en';
    }
    public function getTosLink()
    {
        $iso_lang = $this->getLanguageIsoCode();
        switch ($iso_lang) {
            case 'fr':
                $url = 'https://www.prestashop.com/fr/prestashop-account-cgu';
                break;
            default:
                $url = 'https://www.prestashop.com/en/prestashop-account-terms-conditions';
                break;
        }
        return $url;
    }
    public function getContent()
    {
        if (Shop::getContext() != Shop::CONTEXT_SHOP) {
            $this->context->controller->warnings[] = $this->l('You must select a specific shop in order to continue, configuration cannot be edited for all shops simultaneously.');
            return;
        }
        if (RecReviewsClient::MODULE_SOURCE == 'addons') {
            if (PHP_VERSION_ID < 70205) {
                $this->context->controller->warnings[] = $this->l('This module and its dependencies require at least PHP 7.2.5 to work. Please upgrade your PHP version to continue.');
                return;
            }
            if (version_compare(_PS_VERSION_, '8.0.0', '>=')) {
                $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('MBO install returned false');
                        }
                    } catch (\Exception $e) {
                        $this->context->controller->errors[] = sprintf($this->l('An error occurred while attempting to install the MBO module: %s'), $e->getMessage());
                        return;
                    }
                }
            }
        }
        Utils::generateCronUrl();
        if (empty(Configuration::get('PVR_API_SHOP_ID'))) {
            Utils::generateDashboardShopLink();
        }
        if (((bool)Tools::isSubmit('submit' . $this->name . 'Module')) == true) {
            $this->postProcess();
        }
        if ((bool)Tools::isSubmit('linkRbm') == true) {
            if ((!Tools::getIsset('firstName') || !Tools::getIsset('lastName')) || (!Tools::getValue('firstName') || !Tools::getValue('lastName'))) {
                $this->context->controller->errors[] = $this->l('First or last name missing. Please fill in the required fields');
            } else {
                return $this->initRbmLink();
            }
        }
        if (RecReviewsClient::MODULE_SOURCE == 'addons') {
            try {
                $facade = $this->getService('ps_accounts.facade');
                $accountsService = $facade->getPsAccountsService();
            } catch (\PrestaShop\PsAccountsInstaller\Installer\Exception\InstallerException $e) {
                $accountsInstaller = $this->getService('ps_accounts.installer');
                $accountsInstaller->install();
                $facade = $this->getService('ps_accounts.facade');
                $accountsService = $facade->getPsAccountsService();
            }
            if (!empty(Configuration::get('PVR_API_SHOP_ID')) && !$accountsService->isAccountLinked()) {
                Configuration::updateValue('PVR_RBM_SUB_ID', null);
                Configuration::updateValue('PVR_API_SHOP_ID', null);
                Configuration::updateValue('PVR_OAUTH', '');
                return Tools::redirectAdmin(Context::getContext()->link->getAdminLink('AdminModules') . '&configure=pmproductvideoreviews');
            }
            try {
                $contextPsAccount = $facade->getPsAccountsPresenter()->present($this->name);
                Media::addJsDef([
                    'contextPsAccounts' => $contextPsAccount,
                ]);
                $billingFacade = $this->getService('ps_billings.facade')
                    ->present([
                        'logo' => 'https://dashboard.recreviews.com/images/logo-black.svg',
                        'tosLink' => 'https://dashboard.recreviews.com/conditions',
                        'privacyLink' => 'https://dashboard.recreviews.com/privacy',
                        'emailSupport' => 'support@recreviews.com',
                    ]);
                $recReviewsLogo = Tools::file_get_contents(dirname(__FILE__) . '/views/img/recreviews.png');
                $billingFacade['psBillingContext']['context']['partnerLogo'] = 'data:image/png;base64,' . base64_encode($recReviewsLogo);
                Media::addJsDef($billingFacade);
                $this->context->smarty->assign('urlBilling', "https://unpkg.com/@prestashopcorp/billing-cdc/dist/bundle.js");
                $this->context->smarty->assign('urlAccountsCdn', $accountsService->getAccountsCdn());
                $this->context->smarty->assign('img_path', _MODULE_DIR_ . $this->name . '/views/img/');
                $this->context->smarty->assign('isAddons', RecReviewsClient::MODULE_SOURCE == 'addons');
                if (RecReviewsClient::MODULE_SOURCE == 'addons') {
                    $this->context->smarty->assign('isAccountLinked', $accountsService->isAccountLinked());
                    $this->context->smarty->assign('submitLabel', sprintf($this->l('Continue with %s'), $billingFacade['psBillingContext']['context']['user']['email']));
                    $this->context->smarty->assign('helpLabel', $this->l('By clicking on this button, you will create an account on our service and start a free trial. Make sure your first and last name are correctly spelled, as they will be used for the transfer of image rights.'));
                    $this->context->smarty->assign('firstNameLabel', $this->l('First name'));
                    $this->context->smarty->assign('lastNameLabel', $this->l('Last name'));
                    $this->context->smarty->assign('termsLabel', $this->l('I agree to the terms of use and privacy policy of Rec.Reviews'));
                    $this->context->smarty->assign('accountCreationUrl', $this->context->link->getAdminLink('AdminModules') . '&configure=pmproductvideoreviews');
                }
                $this->context->smarty->assign('generatedLink', '');
                $this->context->smarty->assign('onboardingLink', RecReviewsClient::ONBOARDING_URL);
            } catch (Exception $e) {
                $this->context->controller->errors[] = sprintf($this->l('An error occurred. Please try again or contact our support (%s)', $e->getMessage()));
                return;
            }
        }
        $this->context->smarty->assign('module_dir', $this->_path);
        if (!empty(Utils::isOauthed())) {
            $api_token = json_decode(Configuration::get('PVR_OAUTH'));
            $jsDefs['unlink_message'] = $this->l('Warning: Please note that unsubscribing will remove the link between your store and our services. All the reviews previously collected will be definitively lost.');
            Media::addJsDef([$this->name => $jsDefs]);
            $this->context->smarty->assign([
                'dashboard' => !empty(Configuration::get('PVR_API_SHOP_ID')) ? RecReviewsClient::API_URL . 'dashboard/' . Configuration::get('PVR_API_SHOP_ID') . '/' : '#',
                'img_path' => _MODULE_DIR_ . $this->name . '/views/img/',
                'moderation_wating' => count(RecReviewsClient::getReviewData($api_token->access_token, ['published' => false])),
                'is_active_connection' => Utils::isOauthed(),
            ]);
            $output = $this->context->smarty->fetch($this->local_path . 'views/templates/admin/gis_linked.tpl');
            return $output . $this->renderForm();
        } else {
            if (RecReviewsClient::MODULE_SOURCE == 'prestamodule') {
                if (Tools::getIsset('code') && Tools::getIsset('state') && Tools::getIsset('client_id')) {
                    $moduleConfiguration = json_decode(Configuration::get('PVR_OAUTH'));
                    $oAuthQueryParams = '';
                    if (Tools::getValue('state') != $moduleConfiguration->state) {
                        $this->context->controller->errors[] = $this->l('An error occurred while verifying the authorization request. Please try again.');
                        $this->context->smarty->assign([
                            'generatedLink' => RecReviewsClient::API_URL . 'oauth/authorize?' . $oAuthQueryParams,
                            'onboardingLink' => RecReviewsClient::ONBOARDING_URL,
                            'linkTitle' => $this->l('Link my subscription'),
                            'isError' => false,
                            'register_link' => RecReviewsClient::API_URL,
                            'is_oauth' => Utils::isOauthed(),
                            'img_path' => _MODULE_DIR_ . $this->name . '/views/img/',
                        ]);
                        $output = $this->context->smarty->fetch($this->local_path . 'views/templates/admin/onboarding.tpl');
                    }
                    $moduleConfiguration->code = Tools::getValue('code');
                    $moduleConfiguration->clientId = Tools::getValue('client_id');
                    Configuration::updateValue('PVR_OAUTH', json_encode($moduleConfiguration));
                    $tokenData = RecReviewsClient::getClient()->getAccessToken($moduleConfiguration->code, Utils::generatePublicModuleUrl(), $moduleConfiguration->clientId, $moduleConfiguration->codeVerifier);
                    if (empty($tokenData)) {
                        $this->context->controller->errors[] = $this->l('An error occurred while verifying the authorization request. Please try again.');
                        return;
                    }
                    $moduleConfiguration->access_token = $tokenData->access_token;
                    $moduleConfiguration->refresh_token = $tokenData->refresh_token;
                    $moduleConfiguration->expires_in = time() + $tokenData->expires_in;
                    $moduleConfiguration->token_type = $tokenData->token_type;
                    Configuration::updateValue('PVR_OAUTH', json_encode($moduleConfiguration));
                    Utils::updateApiModuleConfiguration();
                    Utils::generateDashboardShopLink();
                    return Tools::redirectAdmin(Context::getContext()->link->getAdminLink('AdminModules') . '&configure=' . $this->name);
                } else {
                    $moduleConfiguration['state'] = RecReviewsClient::codeVerifierGen(40);
                    $moduleConfiguration['codeVerifier'] = RecReviewsClient::codeVerifierGen();
                    Configuration::updateValue('PVR_OAUTH', json_encode($moduleConfiguration));
                    $oAuthQueryParams = http_build_query([
                        'redirect_uri' => Utils::generatePublicModuleUrl(),
                        'response_type' => 'code',
                        'code_challenge' => RecReviewsClient::createCodeChallengeFromVerifier($moduleConfiguration['codeVerifier']),
                        'code_challenge_method' => 'S256',
                        'scope' => '',
                        'state' => $moduleConfiguration['state'],
                        'cms_name' => 'PrestaShop',
                        'shop_url' => rtrim((string) Context::getContext()->link->getBaseLink(), '/'),
                    ]);
                    $this->context->smarty->assign([
                        'generatedLink' => RecReviewsClient::API_URL . 'oauth/authorize?' . $oAuthQueryParams,
                        'onboardingLink' => RecReviewsClient::ONBOARDING_URL,
                        'linkTitle' => $this->l('Link my subscription'),
                        'isError' => false,
                        'register_link' => RecReviewsClient::API_URL,
                        'is_oauth' => Utils::isOauthed(),
                        'img_path' => _MODULE_DIR_ . $this->name . '/views/img/',
                        'isAddons' => false,
                    ]);
                    $output = $this->context->smarty->fetch($this->local_path . 'views/templates/admin/onboarding.tpl');
                }
            } else {
                if (!empty(Configuration::get('PVR_RBM_SUB_ID'))) {
                    $tokenData = RecReviewsClient::getClient()->getAccessTokenRbm(Configuration::get('PVR_RBM_SUB_ID'));
                    if (!empty($tokenData)) {
                        Configuration::updateValue('PVR_OAUTH', json_encode($tokenData));
                        Utils::updateApiModuleConfiguration();
                        Utils::generateDashboardShopLink();
                    }
                    return Tools::redirectAdmin(Context::getContext()->link->getAdminLink('AdminModules') . '&configure=pmproductvideoreviews');
                } else {
                    $output = $this->context->smarty->fetch($this->local_path . 'views/templates/admin/onboarding.tpl');
                }
            }
            return $output;
        }
    }
    protected function renderForm()
    {
        $helper = new HelperForm();
        $helper->show_toolbar = false;
        $helper->table = $this->table;
        $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->identifier = $this->identifier;
        $helper->submit_action = 'submit' . $this->name . 'Module';
        $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,
        ];
        if (RecReviewsClient::MODULE_SOURCE == 'addons') {
            if (empty(Configuration::get('PVR_RBM_SUB_ID'))) {
                $facade = $this->getService('ps_accounts.facade');
                $psAccountsService = $facade->getPsAccountsService();
                $rmb_id = RecReviewsClient::getRmbSubscriptionId($psAccountsService->getToken(), $psAccountsService->getShopUuidV4());
                if (!empty($rmb_id)) {
                    Configuration::updateValue('PVR_RBM_SUB_ID', $rmb_id);
                }
            }
        }
        return $helper->generateForm([$this->getConfigForm()]);
    }
    protected function getConfigForm()
    {
        $form = [
            'form' => [
                'tabs' => [
                    'basic-settings' => $this->l('Configuration'),
                    'voucher' => $this->l('Incentive vouchers'),
                ],
                'input' => [
                    [
                        'type' => 'hidden',
                        'name' => 'selected_tab',
                    ],
                    [
                        'type' => 'subtitle',
                        'content' => $this->l('Order status for notification'),
                        'name' => '',
                        'tab' => 'basic-settings',
                    ],
                    [
                        'type' => 'select',
                        'label' => $this->l('Order status for notification'),
                        'name' => 'PVR_STATUS_SELECTION',
                        'desc' => $this->l('Choose the order status that will trigger the email inviting your customer to rate and record his product review on video'),
                        'tab' => 'basic-settings',
                        'class' => 'module_field',
                        'options' => [
                            'query' => Utils::getOrderStates((int)Context::getContext()->language->id, 'delivery'),
                            'id' => 'id_order_state',
                            'name' => 'name',
                        ],
                    ],
                    [
                        'type' => 'subtitle',
                        'content' => $this->l('Synchronization of video reviews'),
                        'name' => '',
                        'tab' => 'basic-settings',
                    ],
                    [
                        'type' => 'text',
                        'label' => $this->l('CRON URL'),
                        'name' => 'PVR_CRON_URL',
                        'desc' => $this->l('Install a CRON task on your server to automatically synchronize the publication status of video reviews between your rec.reviews dashboard and your store, at a given frequency. Use the CRON URL given below.'),
                        'class' => 'module_field_suffix ',
                        'tab' => 'basic-settings',
                        'prefix' => $this->renderTemplate($this->local_path . 'views/templates/admin/copy.tpl', ['url' => Configuration::get('PVR_CRON_URL')]),
                    ],
                    [
                        'type' => 'subtitle',
                        'content' => $this->l('Offer an incentive voucher'),
                        'name' => '',
                        'tab' => 'voucher',
                    ],
                    [
                        'type' => 'switch',
                        'label' => $this->l('Activate'),
                        'name' => 'PVR_ENABLE_VOUCHER',
                        'tab' => 'voucher',
                        'hint' => $this->l('Select "Yes" if you want to offer a voucher in exchange for submitting a review'),
                        'is_bool' => true,
                        'values' => [
                            [
                                'id' => 'voucher_on',
                                'value' => 1,
                            ],
                            [
                                'id' => 'voucher_off',
                                'value' => 0,
                            ],
                        ],
                    ],
                    [
                        'type' => 'voucherOptions',
                        'content' => $this->l('Indicate below if you want to offer:'),
                        'options' => [
                            $this->l('One voucher per order: the customer will get a voucher each time he/she rates at least one product of an order (only one voucher per order, no matter how many products of the order are rated)'),
                            $this->l('One voucher per customer: after rating a product, the customer receives a voucher only if he has never rated a product (only one voucher per customer account)'),
                        ],
                        'name' => '',
                        'form_group_class' => 'pvr-incentive-block',
                        'tab' => 'voucher',
                    ],
                    [
                        'type' => 'select',
                        'label' => $this->l('Voucher awarding mode'),
                        'name' => 'PVR_VOUCHER_GENERATE',
                        'tab' => 'voucher',
                        'form_group_class' => 'pvr-incentive-block',
                        'class' => 'module_field',
                        'options' => [
                            'query' => [
                                [
                                    'voucher_mode' => 'order',
                                    'name' => $this->l('One voucher per order'),
                                ],
                                [
                                    'voucher_mode' => 'customer',
                                    'name' => $this->l('One voucher per customer'),
                                ],
                            ],
                            'id' => 'voucher_mode',
                            'name' => 'name',
                        ],
                    ],
                    [
                        'type' => 'subtitle',
                        'content' => $this->l('How to obtain a voucher'),
                        'name' => '',
                        'tab' => 'voucher',
                        'form_group_class' => 'pvr-incentive-block',
                    ],
                    [
                        'type' => 'textarea',
                        'label' => $this->l('Text inviting to rate in exchange for a voucher'),
                        'required' => true,
                        'name' => 'PVR_VOUCHER_INCENTIVE_TEXT',
                        'desc' => $this->l('Tip: Enter the string {voucher_amount} where you want the voucher amount to appear and its value will be replaced dynamically.'),
                        'lang' => 1,
                        'cols' => 50,
                        'rows' => 10,
                        'tab' => 'voucher',
                        'form_group_class' => 'pvr-incentive-block',
                    ],
                    [
                        'type' => 'textarea',
                        'label' => $this->l('Text informing about the minimum purchase amount required to use the voucher'),
                        'required' => true,
                        'name' => 'PVR_VOUCHER_MIN_AMOUNT_DESC',
                        'desc' => $this->l('Tip: Enter the string {order_amount} where you want the minimum purchase requirement to appear and its value will be replaced dynamically.'),
                        'lang' => 1,
                        'cols' => 50,
                        'rows' => 10,
                        'tab' => 'voucher',
                        'form_group_class' => 'pvr-incentive-block',
                    ],
                    [
                        'type' => 'subtitle',
                        'content' => $this->l('Voucher configuration'),
                        'name' => '',
                        'tab' => 'voucher',
                        'form_group_class' => 'pvr-incentive-block',
                    ],
                    [
                        'type' => 'text',
                        'label' => $this->l('Voucher code prefix'),
                        'name' => 'PVR_VOUCHER_PREFIX',
                        'tab' => 'voucher',
                        'required' => 1,
                        'form_group_class' => 'pvr-incentive-block',
                        'desc' => $this->l('Invalid characters: numbers and !<>,;?=+()@#"�{}_$%:'),
                        'class' => 'module_field',
                    ],
                    [
                        'type' => 'select',
                        'label' => $this->l('Voucher type'),
                        'name' => 'PVR_VOUCHER_TYPE',
                        'tab' => 'voucher',
                        'form_group_class' => 'pvr-incentive-block',
                        'options' => [
                            'query' => [
                                [
                                    'voucher_type' => 'percent',
                                    'name' => $this->l('Percentage'),
                                ],
                                [
                                    'voucher_type' => 'amount',
                                    'name' => $this->l('Amount'),
                                ],
                            ],
                            'id' => 'voucher_type',
                            'name' => 'name',
                        ],
                    ],
                    [
                        'type' => 'text',
                        'label' => $this->l('Value'),
                        'name' => 'PVR_VOUCHER_AMOUNT',
                        'tab' => 'voucher',
                        'required' => true,
                        'form_group_class' => 'pvr-incentive-block pvr-incentive-amount-block',
                        'class' => 'fixed-width-md',
                    ],
                    [
                        'type' => 'select',
                        'label' => $this->l('Currency'),
                        'name' => 'PVR_VOUCHER_CURRENCY',
                        'form_group_class' => 'pvr-incentive-block pvr-incentive-amount-block',
                        'tab' => 'voucher',
                        'options' => [
                            'query' => Currency::getCurrencies(),
                            'id' => 'id',
                            'name' => 'iso_code',
                        ],
                    ],
                    [
                        'type' => 'select',
                        'label' => $this->l('Tax'),
                        'name' => 'PVR_VOUCHER_TAX',
                        'form_group_class' => 'pvr-incentive-block pvr-incentive-amount-block',
                        'tab' => 'voucher',
                        'options' => [
                            'query' => [
                                [
                                    'voucher_tax' => '0',
                                    'name' => $this->l('Tax excluded'),
                                ],
                                [
                                    'voucher_tax' => '1',
                                    'name' => $this->l('Tax included'),
                                ],
                            ],
                            'id' => 'voucher_tax',
                            'name' => 'name',
                        ],
                    ],
                    [
                        'type' => 'text',
                        'label' => $this->l('Value'),
                        'name' => 'PVR_VOUCHER_PERCENT',
                        'tab' => 'voucher',
                        'required' => true,
                        'suffix' => '%',
                        'form_group_class' => 'pvr-incentive-block pvr-incentive-percent-block',
                        'class' => 'fixed-width-md',
                    ],
                    [
                        'type' => 'text',
                        'label' => $this->l('Maximum number of uses of the same voucher'),
                        'name' => 'PVR_VOUCHER_QTY',
                        'tab' => 'voucher',
                        'required' => true,
                        'form_group_class' => 'pvr-incentive-block',
                        'class' => 'fixed-width-md',
                        'hint' => $this->l('Enter the number of times the same voucher can be used by the customer'),
                    ],
                    [
                        'type' => 'categories',
                        'name' => 'PVR_VOUCHER_CAT',
                        'label' => $this->l('Categories'),
                        'tab' => 'voucher',
                        'tree' => [
                            'id' => 'category',
                            'selected_categories' => json_decode(Configuration::get('PVR_VOUCHER_CAT')),
                            'root_category' => 1,
                            'use_checkbox' => true,
                            'use_search' => true,
                        ],
                        'form_group_class' => 'pvr-incentive-block',
                        'class' => 'module_field',
                    ],
                    [
                        'type' => 'text',
                        'label' => $this->l('Minimum purchase amount required to use the voucher'),
                        'name' => 'PVR_VOUCHER_MIN_AMOUNT',
                        'tab' => 'voucher',
                        'required' => true,
                        'form_group_class' => 'pvr-incentive-block',
                        'class' => 'fixed-width-md',
                        'hint' => $this->l('Enter the minimum purchase amount required for the voucher to be valid. Enter 0 if there is no required minimum."'),
                    ],
                    [
                        'type' => 'text',
                        'label' => $this->l('Validity period'),
                        'name' => 'PVR_VOUCHER_VALIDITY',
                        'tab' => 'voucher',
                        'required' => true,
                        'form_group_class' => 'pvr-incentive-block',
                        'class' => 'fixed-width-md',
                        'hint' => $this->l('Enter the minimum purchase amount required for the voucher to be valid. Enter 0 if there is no required minimum."'),
                        'suffix' => $this->l('Days'),
                    ],
                    [
                        'type' => 'switch',
                        'label' => $this->l('Highlight the voucher'),
                        'name' => 'PVR_VOUCHER_HIGHLIGHT',
                        'tab' => 'voucher',
                        'form_group_class' => 'pvr-incentive-block',
                        'is_bool' => true,
                        'hint' => $this->l('Select "Yes" to highlight the voucher in the cart summary, if it has not already been added.'),
                        'values' => [
                            [
                                'id' => 'highlight_on',
                                'value' => 1,
                            ],
                            [
                                'id' => 'highlight_off',
                                'value' => 0,
                            ],
                        ],
                    ],
                    [
                        'type' => 'switch',
                        'label' => $this->l('Disallow cumulation with other discounts'),
                        'name' => 'PVR_VOUCHER_CUMULATE',
                        'tab' => 'voucher',
                        'is_bool' => true,
                        'form_group_class' => 'pvr-incentive-block',
                        'values' => [
                            [
                                'id' => 'allow_with_ohter_on',
                                'value' => 1,
                            ],
                            [
                                'id' => 'allow_with_ohter_off',
                                'value' => 0,
                            ],
                        ],
                    ],
                ],
                'submit' => [
                    'title' => $this->l('Save'),
                    'class' => 'pvrSubmit',
                ],
            ],
        ];
        if (RecReviewsClient::MODULE_SOURCE == 'addons') {
            $form['form']['tabs']['subscription'] = $this->l('Subscription');
            $form['form']['input'][] = ['type' => 'rmb_sub', 'name' => 'rmb_sub', 'tab' => 'subscription', 'col' => 12];
        }
        if (RecReviewsClient::MODULE_SOURCE == 'prestamodule') {
            $form['form']['tabs']['subscription'] = $this->l('Subscription');
            $form['form']['input'][] = ['type' => 'disconnect', 'name' => 'disconnect', 'tab' => 'subscription'];
        }
        return $form;
    }
    protected function getConfigFormValues()
    {
        if (Tools::getIsset('selected_tab')) {
            $selectedTab = Tools::getValue('selected_tab');
        }
        return [
            'PVR_EMAIL_DELAY' => Configuration::get('PVR_EMAIL_DELAY'),
            'PVR_STATUS_SELECTION' => Configuration::get('PVR_STATUS_SELECTION'),
            'PVR_ENABLE_VOUCHER' => Configuration::get('PVR_ENABLE_VOUCHER'),
            'PVR_VOUCHER_PREFIX' => Configuration::get('PVR_VOUCHER_PREFIX'),
            'PVR_VOUCHER_TYPE' => Configuration::get('PVR_VOUCHER_TYPE'),
            'PVR_VOUCHER_AMOUNT' => Configuration::get('PVR_VOUCHER_AMOUNT'),
            'PVR_VOUCHER_PERCENT' => Configuration::get('PVR_VOUCHER_PERCENT'),
            'PVR_VOUCHER_CURRENCY' => Configuration::get('PVR_VOUCHER_CURRENCY'),
            'PVR_VOUCHER_TAX' => Configuration::get('PVR_VOUCHER_TAX'),
            'PVR_VOUCHER_DESC' => Configuration::get('PVR_VOUCHER_DESC'),
            'PVR_VOUCHER_GENERATE' => Configuration::get('PVR_VOUCHER_GENERATE'),
            'PVR_VOUCHER_QTY' => Configuration::get('PVR_VOUCHER_QTY'),
            'PVR_VOUCHER_MIN_AMOUNT' => Configuration::get('PVR_VOUCHER_MIN_AMOUNT'),
            'PVR_VOUCHER_MIN_AMOUNT_DESC' => json_decode(Configuration::get('PVR_VOUCHER_MIN_AMOUNT_DESC'), true),
            'PVR_VOUCHER_CAT' => json_decode(Configuration::get('PVR_VOUCHER_CAT')),
            'PVR_VOUCHER_VALIDITY' => Configuration::get('PVR_VOUCHER_VALIDITY'),
            'PVR_VOUCHER_HIGHLIGHT' => Configuration::get('PVR_VOUCHER_HIGHLIGHT'),
            'PVR_VOUCHER_CUMULATE' => Configuration::get('PVR_VOUCHER_CUMULATE'),
            'PVR_VOUCHER_INCENTIVE_TEXT' => json_decode(Configuration::get('PVR_VOUCHER_INCENTIVE_TEXT'), true),
            'PVR_OAUTH' => Configuration::get('PVR_OAUTH'),
            'PVR_ENABLE_BATTLE' => Configuration::get('PVR_ENABLE_BATTLE'),
            'PVR_LAST_REVIEW_SYNC' => Configuration::get('PVR_LAST_REVIEW_SYNC'),
            'PVR_CRON_TOKEN' => Configuration::get('PVR_CRON_TOKEN'),
            'PVR_CRON_URL' => Configuration::get('PVR_CRON_URL'),
            'PVR_API_SHOP_ID' => Configuration::get('PVR_API_SHOP_ID'),
            'selected_tab' => !empty($selectedTab) ? $selectedTab : 'gis',
        ];
    }
    protected function postProcess()
    {
        if (Tools::isSubmit('submitDisconnect')) {
            $api_token = json_decode(Configuration::get('PVR_OAUTH'));
            if (RecReviewsClient::revoke($api_token->access_token, [])) {
                Configuration::updateValue('PVR_RBM_SUB_ID', null);
                Configuration::updateValue('PVR_API_SHOP_ID', null);
                Configuration::updateValue('PVR_OAUTH', '');
            }
        }
        if (Tools::isSubmit('submitRbmDisconnect')) {
            Configuration::updateValue('PVR_RBM_SUB_ID', null);
            Configuration::updateValue('PVR_API_SHOP_ID', null);
            Configuration::updateValue('PVR_OAUTH', '');
        }
        $form_values = $this->getConfigFormValues();
        $text_fields = [
            'PVR_VOUCHER_INCENTIVE_TEXT',
            'PVR_VOUCHER_MIN_AMOUNT_DESC',
        ];
        $requiered_field = [
            'PVR_VOUCHER_PREFIX',
            'PVR_VOUCHER_PERCENT',
            'PVR_VOUCHER_AMOUNT',
            'PVR_VOUCHER_QTY',
            'PVR_VOUCHER_MIN_AMOUNT',
            'PVR_VOUCHER_VALIDITY',
        ];
        $tree_field = [
            'PVR_VOUCHER_CAT',
        ];
        foreach (array_keys($form_values) as $key) {
            if (in_array($key, $text_fields)) {
                $content = [];
                foreach (Language::getLanguages(false) as $langs) {
                    $id_lang = $langs['id_lang'];
                    $field_content = Tools::getValue($key . '_' . $id_lang);
                    if (!empty($field_content)) {
                        $content[$id_lang] = Tools::getValue($key . '_' . $id_lang);
                    } else {
                        $content[$id_lang] = Utils::defaultSentences($key);
                    }
                }
                Configuration::updateValue($key, json_encode($content), true);
            } else {
                if (in_array($key, $requiered_field)) {
                    $field_content = Tools::getValue($key);
                    if (!empty($field_content)) {
                        Configuration::updateValue($key, $field_content);
                    } else {
                        $default_value = Utils::defaultValueField($key);
                        Configuration::updateValue($key, $default_value);
                    }
                } elseif (in_array($key, $tree_field)) {
                    if (is_array(Tools::getValue($key))) {
                        Configuration::updateValue($key, json_encode(Tools::getValue($key)));
                    }
                } else {
                    if ($key != 'PVR_OAUTH' && $key != 'PVR_CRON_TOKEN' && $key != 'PVR_API_SHOP_ID') {
                        Configuration::updateValue($key, Tools::getValue($key));
                    }
                }
            }
            $this->context->controller->confirmations[] = $this->l('Configuration updated');
        }
        if (!empty(Utils::isOauthed())) {
            Utils::updateApiModuleConfiguration();
        }
    }
    public function hookBackOfficeHeader()
    {
        if (Tools::getValue('module_name') == $this->name || Tools::getValue('configure') == $this->name) {
            $this->context->controller->addJS($this->_path . 'views/js/owl.carousel.js');
            $this->context->controller->addJS($this->_path . 'views/js/back.js');
            $this->context->controller->addCSS($this->_path . 'views/css/admin/back.css');
            $this->context->controller->addCSS($this->_path . 'views/css/admin/owl.carousel.min.css');
            $this->context->controller->addCSS($this->_path . 'views/css/admin/owl.theme.default.min.css');
        }
    }
    public function hookDisplayHeader()
    {
        $jsDefs = [];
        $jsDefs['ajaxUrl'] = Context::getContext()->link->getModuleLink($this->name, 'ajax', []);
        $jsDefs['token'] = Tools::getToken(false);
        $jsDefs['pvr_script'] = _MODULE_DIR_ . $this->name . '/views/js/' . $this->name . '.js';
        Media::addJsDef([$this->name => $jsDefs]);
        Context::getContext()->controller->addCSS(_MODULE_DIR_ . $this->name . '/views/css/front/front.css');
        Context::getContext()->controller->addCSS(_MODULE_DIR_ . $this->name . '/views/css/front/stars.css');
        Context::getContext()->controller->addCSS(_MODULE_DIR_ . $this->name . '/views/css/front/battle.css');
        Context::getContext()->controller->addCSS(_MODULE_DIR_ . $this->name . '/views/css/front/player.css');
        Context::getContext()->controller->addCSS(_MODULE_DIR_ . $this->name . '/views/css/front/distribution.css');
        Context::getContext()->controller->addCSS(_MODULE_DIR_ . $this->name . '/views/css/front/progress.css');
        Context::getContext()->controller->addCSS(_MODULE_DIR_ . $this->name . '/views/css/front/grid.css');
        Context::getContext()->controller->addCSS(_MODULE_DIR_ . $this->name . '/views/css/front/spinner.css');
        Context::getContext()->controller->addJS(_MODULE_DIR_ . $this->name . '/views/js/' . $this->name . '.js');
    }
    public function hookActionOrderStatusUpdate($params)
    {
        try {
            if (!empty(Utils::isOauthed())) {
                $api_token = json_decode(Configuration::get('PVR_OAUTH'));
                $order = new Order((int)$params['id_order']);
                if (Validate::isLoadedObject($order)) {
                    if ((int)Configuration::get('PVR_STATUS_SELECTION') == $params['newOrderStatus']->id) {
                        $data = [
                            'order' => [
                                'reference' => $order->reference,
                                'validStatus' => true,
                            ],
                        ];
                        RecReviewsClient::sendUpdateStatus($api_token->access_token, $data);
                    }
                }
            }
        } catch (Exception $e) {
            PrestaShopLogger::addLog($e->getMessage(), 1, $e->getCode(), null, null, true);
        }
    }
    public function hookActionValidateOrder($params)
    {
        try {
            if (!empty(Utils::isOauthed())) {
                if (!empty($params['order']) && Validate::isLoadedObject($params['order']) && $params['order']->module != $this->name && $params['order']->getCurrentState() != Configuration::get('PS_OS_ERROR')) {
                    $api_token = json_decode(Configuration::get('PVR_OAUTH'));
                    $gender = new Gender($params['customer']->id_gender);
                    $lang = new Language((int)$params['customer']->id_lang);
                    $phone = '';
                    $gender = $gender->type == 0 ? 'M' : 'F';
                    $order_api_date = [];
                    $voucher_api_data = [];
                    $api_data = [];
                    $data = [];
                    $products = $params['order']->getProductsDetail();
                    if (!empty($params['order']->id_address_invoice)) {
                        $address = new Address((int)$params['order']->id_address_invoice);
                        if (!empty($address->phone)) {
                            $phone = $address->phone;
                        } elseif (!empty($address->phone_mobile)) {
                            $phone = $address->phone_mobile;
                        }
                    }
                    if (is_array($products) && !empty($products)) {
                        foreach ($products as $product) {
                            $product_obj = new Product((int)$product['product_id']);
                            $image_size = ImageType::getFormattedName('large');
                            $currency = new Currency((int)$params['order']->id_currency);
                            $image_url = Utils::getProductImage($product_obj, $image_size, (int)$params['customer']->id_lang);
                            $data['products'][] = [
                                'id' => $product['product_id'],
                                'name' => $product_obj->name[(int)$params['customer']->id_lang],
                                'image' => !empty($image_url) ? $image_url : $this->context->shop->getBaseURL(true, false) . _PS_IMG_ . Configuration::get('PS_LOGO', null, null, Context::getContext()->shop->id),
                                'ratingUrl' => rtrim((string) Context::getContext()->link->getBaseLink(), '/'),
                                'price' => number_format((float)$product['product_price'], 2, '.', ''),
                                'currency' => (string)$currency->iso_code,
                            ];
                        }
                    }
                    $order_api_date = [
                        'order' => [
                            'reference' => $params['order']->reference,
                            'order_date' => $params['order']->date_add . ' ' . Configuration::get('PS_TIMEZONE'),
                            'products' => $data['products'],
                        ],
                        'customer' => [
                            'id' => $params['customer']->id,
                            'first_name' => $params['customer']->firstname,
                            'last_name' => $params['customer']->lastname,
                            'email' => $params['customer']->email,
                            'birthdate' => !empty($params['customer']->birthday) && $params['customer']->birthday != '0000-00-00' ? str_replace('/', '-', $params['customer']->birthday) : null,
                            'gender' => $gender,
                            'lang' => $lang->iso_code,
                            'id_shop_lang' => (int)$params['customer']->id_lang,
                            'phone' => !empty($phone) ? $phone : '0000000000',
                        ],
                    ];
                    $api_data = array_merge($order_api_date, $voucher_api_data);
                    RecReviewsClient::sendOrderData($api_token->access_token, $api_data);
                }
            }
        } catch (Exception $e) {
            PrestaShopLogger::addLog($e->getMessage(), 1, $e->getCode(), null, null, true);
        }
    }
    public function hookDisplayFooterProduct($params)
    {
        $product_id = !empty($params['product']->id) ? $params['product']->id : Tools::getValue('idProduct');
        if (empty($product_id)) {
            return;
        }
        $sort = Tools::getValue('pvrRwSort', 'recent');
        $reviews = [];
        $show_more_value = Tools::getValue('show_more_value', (int)Configuration::get('PVR_PRODUCT_REVIEW_LINES'));
        $show_more_value_with_sort = Tools::getValue('show_more_value_with_sort');
        $product_obj = new Product((int)$product_id, 1);
        $reviews = Ratings::getProductReviews($product_id);
        if (empty($reviews)) {
            return;
        }
        $distribution_data = Utils::getDistribution($product_id, $reviews);
        $reviews_details = Utils::formatReviewsDetail($reviews, $product_id);
        $show_more_data = Utils::showMoreData($reviews, (int)$reviews_details['total_reviews'], $show_more_value);
        Context::getContext()->smarty->assign([
            'total_review' => !empty($reviews_details['total_reviews']) ? $reviews_details['total_reviews'] : [],
            'reviews' => !empty($show_more_data['display_reviews']) ? $show_more_data['display_reviews'] : [],
            'reviews_detail' => !empty($reviews_details['reviews_detail']) ? $reviews_details['reviews_detail'] : [],
            'product_id' => $product_id,
            'pvrRwSort' => $sort,
            'max_rating' => 5,
            'has_half_star' => false,
            'token' => Tools::getToken(false),
            'review_average_int' => !empty($reviews_details['average']['review_average_int']) ? $reviews_details['average']['review_average_int'] : [],
            'review_average_float' => !empty($reviews_details['average']['review_average_float']) ? $reviews_details['average']['review_average_float'] : [],
            'max_distribution_block' => 5,
            'max_rating_block' => !empty($reviews_details['average']['has_half']) ? 10 : 5,
            'has_half_stars' => !empty($reviews_details['average']['has_half']) ? $reviews_details['average']['has_half'] : [],
            'distribution_data' => !empty($distribution_data['distribution']) ? $distribution_data['distribution'] : [],
            'percentage' => !empty($reviews_details['average']['review_average_float']) ? ((float)$reviews_details['average']['review_average_float'] * 100) / 5 : 0,
            'percent_per_note' => !empty($distribution_data['percent_note']) ? $distribution_data['percent_note'] : [],
            'battle' => !empty($reviews_details['battles']) ? $reviews_details['battles'] : [],
            'battle_details' => !empty($reviews_details['battle_details']) ? $reviews_details['battle_details'] : [],
            'show_more_value' => !empty($show_more_data['show_more_value']) ? $show_more_data['show_more_value'] : 4,
            'has_show_more' => !empty($show_more_data['has_show_more']) ? $show_more_data['has_show_more'] : false,
            'review_per_ligne' => (int)Configuration::get('PVR_PRODUCT_REVIEW_LINES'),
            'logo_path' => _MODULE_DIR_ . $this->name . '/views/img/recreviews-logo.svg',
            'product_name' => $product_obj->name[(int)Context::getContext()->language->id],
            'show_more_value_default' => (int)Configuration::get('PVR_PRODUCT_REVIEW_LINES'),
        ]);
        return $this->fetch('module:' . $this->name . '/views/templates/hook/product-footer.tpl');
    }
    public function hookActionObjectLanguageAddAfter()
    {
        $this->updateTexts();
    }
    public function hookActionEmailSendBefore($params)
    {
        $recShopId = Configuration::get('PVR_API_SHOP_ID');
        if (empty($recShopId) || empty(Module::isInstalled('pmproductvideoreviews')) || empty(Module::isEnabled('pmproductvideoreviews'))) {
            return;
        }
        $orderRef = Utils::handleOrderReferenceForRecorderLink($params['templateVars']);
        if (!empty($orderRef)) {
            $params['templateVars']['{rec_recorder_url}'] = RecReviewsClient::API_URL . 'record-review-from-email/' . (string)$recShopId . '?' . http_build_query([
                'order' => $orderRef,
                'email' => $params['to'],
            ]);
        }
    }
    protected function updateTexts()
    {
        Language::loadLanguages();
        $availableLanguages = Language::getLanguages(false);
        $voucherMinAmountDesc = json_decode(Configuration::get('PVR_VOUCHER_MIN_AMOUNT_DESC'), true);
        $voucherIncentiveText = json_decode(Configuration::get('PVR_VOUCHER_INCENTIVE_TEXT'), true);
        foreach ($availableLanguages as $availableLang) {
            if (!isset($voucherMinAmountDesc[$availableLang['id_lang']])) {
                $voucherMinAmountDesc[$availableLang['id_lang']] = Utils::defaultSentences('PVR_VOUCHER_MIN_AMOUNT_DESC');
            }
            if (!isset($voucherIncentiveText[$availableLang['id_lang']])) {
                $voucherIncentiveText[$availableLang['id_lang']] = Utils::defaultSentences('PVR_VOUCHER_INCENTIVE_TEXT');
            }
        }
        Configuration::updateValue('PVR_VOUCHER_MIN_AMOUNT_DESC', json_encode($voucherMinAmountDesc));
        Configuration::updateValue('PVR_VOUCHER_INCENTIVE_TEXT', json_encode($voucherIncentiveText));
    }
    private function installTab()
    {
        $tabId = (int)Tab::getIdFromClassName($this->adminTab['class_name']);
        if (!$tabId) {
            $tabId = null;
        }
        $tab = new Tab($tabId);
        $tab->active = 1;
        $tab->class_name = $this->adminTab['class_name'];
        foreach (Language::getLanguages() as $lang) {
            $tab->name[$lang['id_lang']] = !empty($this->adminTab['name'][$lang['iso_code']]) ? $this->adminTab['name'][$lang['iso_code']] : $this->adminTab['name']['en'];
        }
        if (!empty($this->adminTab['parent_class_name'])) {
            $tab->id_parent = (int) Tab::getIdFromClassName($this->adminTab['parent_class_name']);
        } else {
            $tab->id_parent = 0;
        }
        $tab->module = $this->name;
        return $tab->save();
    }
    private function initModuleConf()
    {
        $this->updateTexts();
        Configuration::updateValue('PVR_EMAIL_DELAY', 5);
        Configuration::updateValue('PVR_STATUS_SELECTION', 5);
        Configuration::updateValue('PVR_ENABLE_VOUCHER', false);
        Configuration::updateValue('PVR_VOUCHER_PREFIX', 'REVIEW-');
        Configuration::updateValue('PVR_VOUCHER_TYPE', 'amount');
        Configuration::updateValue('PVR_VOUCHER_AMOUNT', '10');
        Configuration::updateValue('PVR_VOUCHER_PERCENT', '10');
        Configuration::updateValue('PVR_VOUCHER_CURRENCY', '1');
        Configuration::updateValue('PVR_VOUCHER_TAX', true);
        Configuration::updateValue('PVR_VOUCHER_DESC', 'Voucher for video reviews');
        Configuration::updateValue('PVR_VOUCHER_GENERATE', 'order');
        Configuration::updateValue('PVR_VOUCHER_QTY', '1');
        Configuration::updateValue('PVR_VOUCHER_MIN_AMOUNT', '10');
        Configuration::updateValue('PVR_VOUCHER_CAT', []);
        Configuration::updateValue('PVR_VOUCHER_VALIDITY', '365');
        Configuration::updateValue('PVR_VOUCHER_HIGHLIGHT', false);
        Configuration::updateValue('PVR_VOUCHER_CUMULATE', false);
        Configuration::updateValue('PVR_PRODUCT_REVIEW_LINES', '4');
        Configuration::updateValue('PVR_PRODUCT_NB_LOAD_ITEM', '4');
        Configuration::updateValue('PVR_ENABLE_BATTLE', true);
        return true;
    }
    public function getService($serviceName)
    {
        if ($this->container === null) {
            $this->container = new \PrestaShop\ModuleLibServiceContainer\DependencyInjection\ServiceContainer(
                $this->name,
                $this->getLocalPath()
            );
        }
        return $this->container->getService($serviceName);
    }
    public function initRbmLink()
    {
        $facade = $this->getService('ps_accounts.facade');
        $presentedAccount = $facade->getPsAccountsPresenter()->present($this->name);
        $data = [
            'email' => $presentedAccount['user']['email'],
            'userId' => $presentedAccount['user']['uuid'],
            'shopUrl' => $presentedAccount['currentShop']['frontUrl'],
            'shopId' => $presentedAccount['currentShop']['uuid'],
            'shopName' => Configuration::get('PS_SHOP_NAME'),
            'lang' => $this->context->language->iso_code == 'fr' ? 'fr' : 'en',
            'logo' => $this->context->shop->getBaseURL(true, false) . _PS_IMG_ . Configuration::get('PS_LOGO', null, null, Context::getContext()->shop->id),
            'firstName' => Tools::getValue('firstName'),
            'lastName' => Tools::getValue('lastName'),
        ];
        $client = RecReviewsClient::getClient();
        $createdData = $client->createLimitedTrialSubscription($data);
        if (empty($createdData['subscription']) || empty($createdData['shop'])) {
            $this->context->controller->errors[] = $this->l('An error occurred');
        } else {
            Configuration::updateValue('PVR_RBM_SUB_ID', $createdData['subscription']);
            Configuration::updateValue('PVR_API_SHOP_ID', $createdData['shop']);
        }
        return Tools::redirectAdmin(Context::getContext()->link->getAdminLink('AdminModules') . '&configure=pmproductvideoreviews');
    }
    protected function renderTemplate($template, $params = [])
    {
        $templateContent = '';
        $scope = $this->context->smarty->createData(
            $this->context->smarty
        );
        $scope->assign($params);
        $tpl = $this->context->smarty->createTemplate(
            $this->getTemplatePath($template) . $template,
            $scope
        );
        return $tpl->fetch();
    }
}