Сбросить «Использовать значение по умолчанию» для определенного вида магазина во всех продуктах

16

Каким-то образом в некоторых моих продуктах было выбрано «Использовать значение по умолчанию».

В моем магазине 2 языка, английский и французский. Французский использует значение Store по умолчанию, так что теперь, когда я обновляю продукты, он не появляется на внешнем интерфейсе, если я вручную не перехожу на продукт в представлении French store и выбираю «Use Default Value»,

Кажется, что нет атрибута для массового действия, я сталкивался с некоторыми сценариями и запросами MySQL, однако неясно, сбрасывают ли эти решения все представления магазина, чтобы использовать значение по умолчанию.

Желаемым результатом является установка «Использовать значение по умолчанию» в определенном представлении магазина (на французском языке) для всех продуктов.

Как мне сбросить большое количество товаров (или все товары) на «Использовать значение по умолчанию» в определенном представлении магазина?

SR_Magento
источник

Ответы:

7

К сожалению, в этом случае не работает ни один из эффективных способов обновления атрибута продукта. $product->getResource()->saveAttribute()обновляет атрибут для всех представлений магазина, даже если вы установили идентификатор магазина для $productобъекта. Mage::getSingleton('catalog/product_action')->updateAttributes()только обновляет значение в определенном хранилище, но не может установить для атрибута значение по умолчанию (см. также этот вопрос переполнения стека для справки). Следовательно, мы должны использовать медленный, интенсивный способ памяти через $product->save().

Я предполагаю, что вы знаете, какие атрибуты вы хотели бы обновить. В следующем примере я установил для visibilityатрибута значение по умолчанию. Следующий скрипт должен сделать свое дело (убедитесь, что вы изменили его в соответствии со своими потребностями):

<?php

error_reporting(E_ALL);
ini_set('display_errors', '1');

require_once 'app/Mage.php';
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
set_time_limit(0);

function useDefaultValueCallback($args)
{
    // change to the ID of your french store view
    $specificStoreViewId = 7;
    $product = Mage::getModel('catalog/product');
    $product->setData($args['row']);
    $product->setStoreId($specificStoreViewId);
    // change according to your needs
    $product->setData('visibility', false);
    $product->save();
}

$products = Mage::getModel('catalog/product')->getCollection();
Mage::getSingleton('core/resource_iterator')->walk($products->getSelect(), array('useDefaultValueCallback'));
Саймон
источник
Есть ли способ поставить галочку «использовать значение по умолчанию» без изменения данных атрибута? Потому что здесь, если я воспользуюсь $product->setData('visibility', false);им, отметим этот флажок, но также установим видимость «true», чего я не хочу
Jurģis Toms Liepiņš
1
@ JurģisTomsLiepiņš Если вы отметите флажок, он использует значение по умолчанию, которое является значением из родительской области. Следовательно, если вы установите флажок, и он переключится на «true», значение родительской области также будет «true». Для дальнейших вопросов, пожалуйста, задайте новый вопрос.
Симон
Я задал новый вопрос , я надеюсь, что вы можете прояснить / прояснить некоторые вещи для меня
Юрис Томс Лиепиньш
Я успешно использую setData в false (при вызове из cli). Но я заметил, что когда я вызываю ту же функцию из маршрута контроллера внешнего интерфейса, она не работает! Кто-то уже сталкивался с этой проблемой?
DarkCowboy
@DarkCowboy Это, вероятно, проблема с разрешением. Я не думаю, что вы можете сохранить продукт в контроллере интерфейса. Для дальнейших вопросов, пожалуйста, откройте новый.
Симон
24

Предполагая, что идентификатор хранилища для французского хранилища равен 2, вы должны выполнить следующие запросы mysql:

DELETE FROM `catalog_product_entity_text` where store_id = 2;
DELETE FROM `catalog_product_entity_datetime` where store_id = 2;
DELETE FROM `catalog_product_entity_decimal` where store_id = 2;
DELETE FROM `catalog_product_entity_int` where store_id = 2;
DELETE FROM `catalog_product_entity_varchar` where store_id = 2;

Это в основном удаляет значения атрибутов для всех атрибутов и продуктов, для которых для идентификатора магазина установлено значение 2. Когда Magento не может найти значение атрибута для продукта по определенному идентификатору магазина, выбирается значение по умолчанию.

Парас Суд
источник
1
Это неправда. Если установить значение атрибута равным, falseкак я, опция «использовать значение по умолчанию» будет отмечена. Хотя ваше решение может работать, я лично не люблю использовать прямые запросы SQL.
Саймон
Хорошо, извините, я неправильно прочитал ваш ответ и подумал, что вы просите OP ввести все значения по умолчанию вместо false. Ваше решение работает :)
Paras Sood
5
Обратите внимание, что «Это не правда» относится к комментарию к ответу Саймона, который теперь удален. Решение работает.
Фабиан Шменглер
@fschmengler Будет ли Paras отвечать за работу по показу изображений на передней части? У меня та же проблема с моим новым магазином, все продукты и изображения есть, но они не выбраны для использования по умолчанию.
метод
@ этот метод нет, это что-то другое. Там уже может быть вопрос, в противном случае, пожалуйста, задайте новый
Фабиан Шменглер
7

Присоединяюсь немного поздно, но мне не очень понравился ни один из приведенных выше ответов.

  1. Ответ Саймонса на прогулку по коллекции продуктов безумно медленен и неэффективен, однако, по крайней мере, он использует Magento.
  2. Ответ ParasSood на внесение прямых изменений в базу данных немного страшен и не очень удобен, если вы хотите, чтобы это было немного автоматизировано.

Вот моя попытка, не полностью проверенная, но, кажется, она делает то, что мне нужно.

/**
 * If given store code will reset only that store, otherwise will set all stores to "use default"
 *
 * If given product ids will reset only those products, otherwise all products will be set to "use default"
 *
 * @param $attributeCode
 * @param null $storeCode
 * @param null $productIds
 *
 */
public function forceProductsToUseDefault($attributeCode, $storeCode = null, $productIds = null)
{
    $conditions = array();

    if (is_null($storeCode)) {
        $conditions['store_id != ?'] = Mage_Core_Model_App::ADMIN_STORE_ID;
    } else {
        $store = Mage::app()->getStore($storeCode);
        if (!$store instanceof Mage_Core_Model_Store || !$store->getId()) {
            Mage::throwException("Store with code not found: $storeCode");
        }
        $conditions['store_id = ?' ] = $store->getId();
    }

    if (!is_null($productIds)) {
        $conditions['entity_id in(?)'] = $productIds;
    }

    $attribute = Mage::getModel('eav/entity_attribute')
        ->loadByCode(Mage_Catalog_Model_Product::ENTITY, $attributeCode);
    if (!$attribute instanceof Mage_Eav_Model_Entity_Attribute_Abstract || !$attribute->getId()) {
        Mage::throwException("Attribute with code not found: $attributeCode");
    }
    $conditions['attribute_id = ?'] = $attribute->getId();

    $coreResource = Mage::getSingleton('core/resource');

    $coreResource->getConnection('core_write')->delete(
        $coreResource->getTableName(array('catalog/product', $attribute->getData('backend_type'))),
        $conditions
    );
}
Люк Роджерс
источник
Почему мы бросаем синтаксическую ошибку в строке 14? @ Люк Роджерс
Дополнение
В чем ошибка?
Люк Роджерс
Это исправлено сейчас, но это никогда не работает должным образом и заканчивается на моем dev. окружающая обстановка. Какие-либо предложения?
Дополнение
Не могу обойтись без фактической ошибки :)
Люк Роджерс
любое руководство о том, как я должен использовать этот код? Могу ли я использовать его как автономный скрипт?
Крис Вэнь
3

Вы можете использовать core_block_abstract_to_html_before adminhtml событие, чтобы добавить необходимые флажки для каждого атрибута в форме массового обновления администратора.

protected $_controllers = array(
    'attribute', 
    'catalog_product_action_attribute'
    );


public function htmlBefore(Varien_Event_Observer $observer)
{
        $block = $observer->getBlock();

        if (!isset($block)) {
            return $this;
        }

        $request = Mage::app()->getRequest();
        $storeId = $request->getParam('store');

        if ($storeId != 0) {
            if(in_array($request->getControllerName(), $this->_controllers) 
                    && $request->getActionName() == 'edit') {
                // Add use_default checkboxes
                if ($block instanceof Mage_Adminhtml_Block_Catalog_Form_Renderer_Fieldset_Element) {
                    $block->getDataObject()->setId('empty');
                    $block->getDataObject()->setStoreId($storeId);
                    $block->getDataObject()->setExistsStoreValueFlag($block->getAttribute()->getAttributeCode());
                }
            }
        }
}

Тогда вам нужно будет использовать событие catalog_product_attribute_update_before, чтобы удалить значения из таблиц EAV для определенного представления магазина, только для тех атрибутов, у которых есть флажок, который вы вставили ранее с core_block_abstract_to_html_before установленным как проверено.

Надеюсь, это поможет.

Этот модуль делает именно это: http://mageinn.com/product/adminextra/ С этим модулем также можно сбросить атрибут ' url_key '.

kolucciy
источник