Управление несколькими магазинами в модуле prestashop

У меня есть модуль Prestashop 1.6. Он работает для одного магазина, однако мне нужно заставить его работать в других магазинах, которые я создал с помощью функции мультимагазина.

Под «заставить это работать» я подразумеваю, что я хотел бы иметь возможность разделять конфигурации для каждого отдельного магазина, чтобы у каждого магазина была своя собственная конфигурация плагина, не разделяя единую конфигурацию с каждым магазином на веб-сайте. В настоящее время плагин имеет только одну конфигурацию, если я изменю ее в одном из магазинов, это изменение повлияет на все остальные магазины.

Это код:

<?php
/**
 * 2007-2015 PrestaShop
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Academic Free License (AFL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/afl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to [email protected] so we can send you a copy immediately.
 *
 * @author    PrestaShop SA <[email protected]>
 * @copyright 2007-2015 PrestaShop SA
 * @license   http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
 * International Registered Trademark & Property of PrestaShop SA
 */

class Homecategories extends Module
{
    public function __construct()
    {
        $this->name = 'homecategories';
        $this->tab = 'front_office_features';
        $this->version = '1.0';
        $this->need_instance = 0;

        parent::__construct();

        $this->page = basename(__FILE__, '.php');
        $this->displayName = $this->l('Homepage Categories Customized');
        $this->description = $this->l('Displays categories on your homepage');
    }

    public function install() {
        Configuration::updateValue('HOMEPAGE_CATEGORIES_IDS', '');
        Configuration::updateValue('HOMEPAGE_CATEGORIES_PROD_COUNT', 4);
        return parent::install() &&
        $this->registerHook('displayHomeTab') &&
        $this->registerHook('displayHomeTabContent') &&
        $this->registerHook('displayHeader');
    }

    public function uninstall() {
        $this->unregisterHook('displayHomeTab') &&
        $this->unregisterHook('displayHomeTabContent') &&
        $this->unregisterHook('displayHeader') &&
        parent::uninstall();
    }

    public function hookDisplayHeader() {
        $this->context->controller->addCSS(_PS_THEME_DIR_.'/css/category.css', 'all');
        $this->context->controller->addCSS(_THEME_CSS_DIR_.'product_list.css');
    }

    public function hookDisplayHome($params) {
        $root_cat = Category::getRootCategory($this->context->cookie->id_lang);
        $prodCount = (int)Configuration::get('HOMEPAGE_CATEGORIES_PROD_COUNT');
        $categoryIds = Configuration::get('HOMEPAGE_CATEGORIES_IDS');
        if(!empty($categoryIds) && trim($categoryIds) != '') {
            $idsArray = explode(',', $categoryIds);
            $allProducts = array();

            foreach($idsArray as $id) {
                $category = new Category($id, (int)$this->context->language->id);

                $products = $category->getProducts((int)$this->context->language->id, 1, 10000);
                shuffle($products);
                for($i = 0; $i<$prodCount; $i++) {
                    $allProducts[] = $products[$i];
                }
            }

            $this->context->smarty->assign(
                array(
                    'products' => $allProducts,
                    'prodCount' => $prodCount,
                    'add_prod_display' => Configuration::get('PS_ATTRIBUTE_CATEGORY_DISPLAY'),
                )
            );
        }
        return $this->display(__FILE__, '/views/templates/hooks/homecategories.tpl');
    }



    public function renderForm() {
        $fields_form = array(
            'form' => array(
                'legend' => array(
                    'title' => $this->l('Settings'),
                    'icon' => 'icon-cogs'
                ),
                'description' => $this->l('Display custom categories on home page.'),
                'input' => array(
                    array(
                        'type' => 'text',
                        'label' => $this->l('Categories ID'),
                        'name' => 'HOMEPAGE_CATEGORIES_IDS',
                        'class' => 'fixed-width-xs',
                        'desc' => ''//$this->l('Insert how many products you\'d like to display for each category.'),
                    ),
                    array(
                        'type' => 'text',
                        'label' => $this->l('Products per category'),
                        'name' => 'HOMEPAGE_CATEGORIES_PROD_COUNT',
                        'class' => 'fixed-width-xs',
                        'desc' => ''//$this->l('Insert how many products you\'d like to display for each category.'),
                    )
                ),
                'submit' => array(
                    'title' => $this->l('Save'),
                )
            ),
        );

        $helper = new HelperForm();
        $helper->show_toolbar = false;
        $helper->table = $this->table;
        $lang = new Language((int)Configuration::get('PS_LANG_DEFAULT'));
        $helper->default_form_language = $lang->id;
        $helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0;
        $this->fields_form = array();
        $helper->id = (int)Tools::getValue('id_carrier');
        $helper->identifier = $this->identifier;
        $helper->submit_action = 'submitHomepageCategories';
        $helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false).'&configure='.$this->name.'&tab_module='.$this->tab.'&module_name='.$this->name;
        $helper->token = Tools::getAdminTokenLite('AdminModules');
        $helper->tpl_vars = array(
            'fields_value' => $this->getConfigFieldsValues(),
            'languages' => $this->context->controller->getLanguages(),
            'id_language' => $this->context->language->id
        );

        return $helper->generateForm(array($fields_form));
    }

    public function getConfigFieldsValues() {
        return array(
            'HOMEPAGE_CATEGORIES_PROD_COUNT' => Tools::getValue('HOMEPAGE_CATEGORIES_PROD_COUNT', (int)Configuration::get('HOMEPAGE_CATEGORIES_PROD_COUNT')),
            'HOMEPAGE_CATEGORIES_IDS' => Tools::getValue('HOMEPAGE_CATEGORIES_IDS', Configuration::get('HOMEPAGE_CATEGORIES_IDS')),
        );
    }

    public function getContent() {
        $output = '';
        $errors = array();
        if (Tools::isSubmit('submitHomepageCategories')) {
            $ids = str_replace('/\s+/g', '', Tools::getValue('HOMEPAGE_CATEGORIES_IDS'));
            $idsArray = explode(',', $ids);
            foreach($idsArray as $id) {
                if(!Validate::isInt($id) || (int)$id < 0) {
                    $errors[] = $this->l('All IDs must be positive integers. Unrecognized value: ') . $id;
                }
            }
            $prodCount = trim(Tools::getValue('HOMEPAGE_CATEGORIES_PROD_COUNT'));
            if (!Validate::isInt($prodCount) || (int)$prodCount <= 0)
                $errors[] = $this->l('Product count must be a positive non-zero integer.');
            if (isset($errors) && count($errors))
                $output = $this->displayError(implode('<br />', $errors));
            else {
                Configuration::updateValue('HOMEPAGE_CATEGORIES_IDS', $ids);
                Configuration::updateValue('HOMEPAGE_CATEGORIES_PROD_COUNT', (int)$prodCount);
                Tools::clearCache(Context::getContext()->smarty, $this->getTemplatePath('homecategories.tpl'));
                $errors[] = $ids;
                $output = $this->displayConfirmation($this->l('Your settings have been updated.'));
            }
        }

        return $output.$this->renderForm();
    }


    public function hookDisplayHomeTabContent($params) {
        return $this->hookDisplayHome($params);
    }
    public function hookLeftColumn($params) {
        return $this->hookDiplayHome($params);
    }

    public function hookRightColumn($params) {
        return $this->hookDisplayHome($params);
    }

    public function hookDisplayTopColumn($params) {
        return $this->hookDisplayHome($params);
    }

    public function hookDisplayHomeTab($params) {
        return $this->display(__FILE__, 'tab.tpl', $this->getCacheId('homefeatured-tab'));
    }
}

Что я пробовал:

  • Я попытался добавить идентификатор магазина, как описано в документации, изменив каждое вхождение

    Configuration::get('KEY'); 
    

    to

    Configuration::get('KEY', null, null, (int)$this->context->shop->id);
    

    а также

    Configuration::updateValue('KEY', 'VALUE');
    

    to

    Configuration::updateValue('KEY', 'VALUE', false, null, (int)$this->context->shop->id)
    

    Это не сработало, ценности по-прежнему распределялись между магазинами.

  • Поскольку первый вариант не работал, я подумал о том, чтобы дать полям разные имена, назвав их KEY_1 для магазина 1, KEY_2 для магазина 2 и т. д. Я думал, что это решит проблему, поэтому я изменил каждое вхождение

    Configuration::get('KEY'); 
    

    to

    Configuration::get('KEY_' . (int)$this->context->shop->id);
    

    а также

    Configuration::updateValue('KEY_' . (int)$this->context->shop->id, 'VALUE');
    

    to

    Configuration::updateValue('KEY', 'VALUE', false, null, (int)$this->context->shop->id)
    

Результат был таким же.

Я сбросил $this->context->shop и обнаружил, что атрибут id всегда равен 1, независимо от того, в каком магазине я нахожусь. Кажется, что идентификатор магазина всегда один и тот же, даже если я меняю магазин, так что это свойство совсем небезопасно.

Что я должен делать? Я что-то пропустил? Как я могу создать разные конфигурации для каждого магазина вместо того, чтобы иметь только одну общую для всех магазинов?


person BackSlash    schedule 24.05.2017    source источник
comment
с помощью Configuration::get('KEY'); и Configuration::updateValue('KEY', 'VALUE'); он получит и обновит ключ на основе вашего текущего контекста. Это означает, что для изменения значений на другое хранилище в админке вы просто выбираете это хранилище в доступном поле выбора. Вы уверены, что меняете контекст магазина в бэк-офисе?   -  person sadlyblue    schedule 24.05.2017
comment
@sadlyblue На самом деле я думал, что это происходит автоматически. Я имею в виду, что у меня есть основной магазин на mydomain.com и еще один магазин на sub1.domain.com. Нужно ли мне вручную изменять контекст магазина, даже если я посещаю sub1.domain.com/admin вместо domain.com/admin?   -  person BackSlash    schedule 24.05.2017
comment
Да, действительно нужно сменить магазин, в избранном (обычно вверху рядом с уведомлениями). если у вашего сотрудника есть доступ ко всем магазинам, по умолчанию он всегда будет основным в контексте, независимо от домена, из которого вы входите. С другой стороны, вы можете написать свой модуль, чтобы иметь все параметры вместо изменения магазина контекста, используя Configuration::updateValue('KEY', 'VALUE', false, null, (int)$id_shop)и Configuration::get($key, null, null, $id_shop) в foreach со всеми магазинами.   -  person sadlyblue    schedule 24.05.2017
comment
@sadlyblue Спасибо, это действительно было так. Есть ли способ установить контекст магазина по умолчанию на основе домена? Я имею в виду, что, по моему мнению, если я получаю доступ к sub1.domain.com, магазин должен изменить сам контекст на sub1, иначе в чем преимущество наличия выделенного поддомена, если контекст не меняется?   -  person BackSlash    schedule 24.05.2017
comment
нет, если вы не кодируете что-то для администратора. во фронт-офисе, то есть автоматически. ваш контекстный магазин основан на вашем домене/субдомене, но только на внешнем интерфейсе.   -  person sadlyblue    schedule 24.05.2017
comment
@sadlyblue Круто. Что ж, спасибо за помощь, если вы не возражаете, напишите ответ, я приму его.   -  person BackSlash    schedule 24.05.2017


Ответы (1)


Используя Configuration::get('KEY'); и Configuration::updateValue('KEY', 'VALUE');, он получит и обновит ключ на основе вашего текущего контекста. Это означает, что чтобы изменить значения для другого магазина, в админке вы просто выбираете этот магазин в доступном поле выбора (обычно вверху рядом с уведомлениями).

Магазин контекста сотрудника не основан на URL-адресе, по которому вы получаете доступ к администратору. По умолчанию он будет основным, если вы ранее не выбрали другой.

С другой стороны, вы можете написать свой модуль, чтобы иметь все параметры вместо изменения магазина контекста, используя Configuration::updateValue('KEY', 'VALUE', false, null, (int)$id_shop) и Configuration::get($key, null, null, $id_shop) в foreach со всеми магазинами.

Контекстный магазин во фронт-офисе (интерфейс), с другой стороны, устанавливается в зависимости от URL-адреса, по которому вы к нему обращаетесь.

person sadlyblue    schedule 24.05.2017