Restablezca "Usar valor predeterminado" para ver la tienda específica en todos los productos

16

De alguna manera, algunos de mis productos tenían el "Usar valor predeterminado" deseleccionado.

Mi tienda tiene 2 idiomas, inglés y francés. French utiliza el valor de la tienda predeterminada, por lo que ahora, cuando actualizo los productos, no aparece en la parte frontal a menos que acceda manualmente al producto en la vista de la tienda francesa y seleccione "Usar valor predeterminado",

No parece haber un atributo para una acción masiva, he encontrado algunos scripts y consultas MySQL, sin embargo, no está claro si esas soluciones restablecen todas las vistas de la tienda para usar el valor predeterminado.

El resultado deseado es establecer "Usar valor predeterminado" en una vista de tienda específica (francés) en todos los productos.

¿Cómo restablezco una gran cantidad de productos (o todos los productos) a "Usar valor predeterminado" en una vista de tienda específica?

SR_Magento
fuente

Respuestas:

7

Desafortunadamente, ninguna de las formas eficientes de actualizar un atributo de producto funciona en este caso. $product->getResource()->saveAttribute()actualiza el atributo para todas las vistas de la tienda, incluso si configura la ID de la tienda en el $productobjeto. Mage::getSingleton('catalog/product_action')->updateAttributes()solo actualiza el valor en una tienda específica, pero no puede configurar el atributo para usar el valor predeterminado (consulte también esta pregunta de Desbordamiento de pila para obtener una referencia). Por lo tanto, tenemos que usar la forma lenta e intensiva de memoria a través de $product->save().

Supongo que sabes qué atributos te gustaría actualizar. Para el siguiente ejemplo, configuré el visibilityatributo para usar el valor predeterminado. El siguiente script debería hacer el truco (asegúrese de cambiarlo de acuerdo a sus necesidades):

<?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'));
Simón
fuente
¿Hay alguna forma de marcar el "uso del valor predeterminado" sin cambiar los datos del atributo? Porque aquí, si lo uso $product->setData('visibility', false);, marcaré la casilla, pero también estableceré la visibilidad en "verdadero", lo que no quiero
Jurģis Toms Liepiņš
1
@ JurģisTomsLiepiņš Si marca la casilla, utiliza el valor predeterminado, que es el valor del ámbito primario. Por lo tanto, si marca la casilla y cambia a "verdadero", el valor de alcance principal también es "verdadero". Para más preguntas, por favor haga una nueva pregunta.
Simon
Hice una nueva pregunta , espero que pueda aclarar / aclarar algunas cosas para mí
Jurģis Toms Liepiņš
Utilizo setData en falso con éxito (cuando se llama desde cli). Pero noté que cuando llamo a la misma función desde una ruta de controlador de interfaz, ¡no funciona! ¿Alguien ya se enfrentó a este problema?
DarkCowboy
@DarkCowboy Esto es probablemente un problema de permiso. No creo que pueda guardar un producto en un controlador frontend. Para más preguntas, abra una nueva.
Simon
24

Suponiendo que la identificación de la tienda para la tienda francesa es 2, debe ejecutar las siguientes consultas 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;

Básicamente, esto elimina los valores de atributo para todos los atributos y productos para los cuales la identificación de la tienda está establecida en 2. Cuando Magento no puede encontrar el valor de atributo para un producto contra la identificación de la tienda en particular, elige el valor predeterminado.

Paras Sood
fuente
1
Esto no es verdad. Si uno establece el valor del atributo falsecomo lo hice, la opción "Usar valor predeterminado" estará marcada. Aunque su solución podría funcionar, personalmente no me gusta usar consultas directas de SQL.
Simon
Ok, disculpas, leí mal tu respuesta y pensé que estabas pidiendo a OP que pusiera todos los valores predeterminados en lugar de falsos. Su solución funciona :)
Paras Sood
55
Tenga en cuenta que "Esto no es cierto" se refiere a un comentario sobre la respuesta de Simon que ahora se ha eliminado. La solución funciona.
Fabian Schmengler
@fschmengler ¿Paras respondería al trabajo por mostrar las imágenes en la parte frontal? Tengo el mismo problema con mi nueva tienda, todos los productos e imágenes están allí, pero no están seleccionados para usar como predeterminados.
método
@ este método no, esto es algo diferente. Es posible que ya haya una pregunta, de lo contrario, haga una nueva
Fabian Schmengler, el
7

Unirme un poco tarde, pero realmente no me gustó ninguna de las respuestas anteriores.

  1. La respuesta de Simons de caminar sobre la colección de productos es increíblemente lenta e ineficiente, sin embargo, al menos está usando Magento
  2. La respuesta de ParasSood de hacer modificaciones directas en la base de datos es un poco aterradora, y no es muy útil si quieres que esto quede envuelto como un poco de funcionalidad automatizada.

Aquí está mi intento, no completamente probado, pero parece hacer lo que necesito que haga.

/**
 * 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
    );
}
Luke Rodgers
fuente
¿Por qué estamos arrojando un error de sintaxis en la línea 14? @Luke Rodgers
Suplemento
Cual es el error
Luke Rodgers
Ahora está arreglado, pero esto nunca se ejecuta correctamente y termina en mi desarrollo. ambiente. ¿Alguna sugerencia?
Suplemento
No puedo ayudar sin el error real :)
Luke Rodgers
¿Alguna guía sobre cómo debo usar este código? ¿Puedo usarlo como un script independiente?
Kris Wen
3

Puede usar core_block_abstract_to_html_before adminhtml event para agregar las casillas de verificación requeridas para cada atributo en el formulario de actualización masiva de administrador.

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());
                }
            }
        }
}

Luego, deberá usar el evento catalog_product_attribute_update_before para eliminar los valores de las tablas EAV para una vista de tienda específica, solo para aquellos atributos que tienen la casilla de verificación que inyectó anteriormente con core_block_abstract_to_html_before establecido como marcado.

Espero que ayude.

Este módulo hace exactamente eso: http://mageinn.com/product/adminextra/ También es posible restablecer el atributo ' url_key ' con ese módulo.

kolucciy
fuente