16

Somehow a number of my products had the "Use Default Value" deselected.

My store has 2 languages, English and French. French uses the Default Store value, so now when I update products it doesn't appear on the front end unless I manually go onto the product on the French store view and select "Use Default Value",

There doesn't appear to be an attribute for a mass action, I've come across some scripts and MySQL queries however it is not clear if those solutions reset all store views to use the default value.

The desired result is to set "Use Default Value" on a specific store view (French) on all products.

How do I reset a large number of products (or all products) to "Use Default Value" on a specific store view?

7

Unfortunately, none of the efficient ways to update a product attribute work in this case. $product->getResource()->saveAttribute() updates the attribute for all store views even if you set the store ID on the $product object. Mage::getSingleton('catalog/product_action')->updateAttributes() only updates the value in a specific store, but it cannot set the attribute to use the default value (see also this Stack Overflow question for a reference). Hence, we have to use the slow, memory intensive way via $product->save().

I assume that you know which attributes you would like to update. For the following example, I set the visibility attribute to use the default value. The following script should then do the trick (make sure you change it according to your needs):

<?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'));
  • Is there a way to tick the "use default value" without changing the attribute data? Because here, if I use $product->setData('visibility', false); it will tick the box, but also set visibility to "true", which I dont want – Jurģis Toms Liepiņš Nov 11 '17 at 19:55
  • 1
    @JurģisTomsLiepiņš If you tick the box, it uses the default value, which is the value from the parent scope. Hence, if you tick the box and it switches to "true", your parent scope value is "true" as well. For further questions, please ask a new question. – Simon Nov 13 '17 at 7:05
  • I asked a new question, I hope you can clarify/clear some things for me – Jurģis Toms Liepiņš Nov 13 '17 at 10:15
  • I use the setData to false successfully (when called from cli). But I noticed when I call the same function from a frontend controller route, it doesn't work! Is someone already faced this issue? – DarkCowboy Jan 16 '18 at 7:47
  • @DarkCowboy This is probably a permission issue. I do not think that you can save a product in a frontend controller. For further questions, please open a new one. – Simon Jan 17 '18 at 11:54
24

Assuming the store id for the french store is 2, you should run the below mysql queries:

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;

This basically deletes the attribute values for all attributes and products for which the store id is set to 2. When Magento cannot find the attribute value for a product against the particular store id, it picks the default value.

  • 1
    This is not true. If one sets the attribute value to false as I did, the "use default value" option will be ticked. Though your solution might work, I personally do not like to use direct SQL queries. – Simon Aug 24 '14 at 11:06
  • Ok apologies, I misread your answer and thought you were asking OP to put in all the default values instead of false. Your solution works :) – Paras Sood Aug 24 '14 at 11:21
  • 5
    Please note that "This is not true" refers to a comment on Simon's answer that has now been removed. The solution works. – Fabian Schmengler Sep 8 '15 at 9:15
  • @fschmengler Would Paras answer work for showing the images on the front end? I have the same problem with my new store all the products and images are there but they are not selected to use as default. – thismethod Sep 8 '16 at 23:44
  • @thismethod no, this is something different. There might be a question for it already, otherwise please ask a new one – Fabian Schmengler Sep 9 '16 at 5:47
7

Joining a bit late, but I didn't really like either of the above answers.

  1. Simons answer of walking over the product collection is insanely slow and inefficient, however it is at least using Magento
  2. ParasSood's answer of doing direct modifications on the database is a little scary, and not very usable if you want this wrapped as a bit of automated functionality.

Here's my attempt, not fully tested but it seems to do what I need it to do.

/**
 * 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
    );
}
  • Why are we throwing a syntax error on line 14? @Luke Rodgers – Supplement Sep 15 '16 at 23:30
  • What's the error? – Luke Rodgers Sep 16 '16 at 13:51
  • It's fixed now but this never properly runs and finishes on my dev. environment. Any suggestions? – Supplement Sep 16 '16 at 18:41
  • Can't help without the actual error :) – Luke Rodgers Sep 17 '16 at 18:34
  • any guide on how should i use this code? can i use it as an standalone script? – Kris Wen Jun 11 at 19:24
3

You can use core_block_abstract_to_html_before adminhtml event to add the required checkboxes for every attribute in admin mass update form.

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

Then you would need to use catalog_product_attribute_update_before event to delete the values from the EAV tables for a specific store view, only for those attributes that have the checkbox you injected earlier with core_block_abstract_to_html_before set as checked.

Hope that helps.

This module does exactly that: http://mageinn.com/product/adminextra/ It is also possible to reset 'url_key' attribute with that module.

protected by Community Mar 2 '16 at 7:44

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.