Delete Magento product attribute values via shell script

Sometimes handling multiple store views/stores/websites within a single Magento installation may mess up attribute values on the different scope levels. We’ve recently faced similar problem with product prices. Some price values were changed on the scope level after data migration and it was almost impossible to detect and remove such values from the Magento admin panel. So we’ve decided to create a shell script for that purpose and share it with you.

Shell script, provided below, allows you to remove product attribute values for all scopes except the admin one (store_id = 0). The usage of direct query here makes it really fast to operate. Let’s check the code:

<?php
/**
 * Atwix
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Open Software License (OSL 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/osl-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 license@magentocommerce.com so we can send you a copy immediately.

 * @category    Atwix Mod
 * @author      Atwix Core Team
 * @copyright   Copyright (c) 2016 Atwix (http://www.atwix.com)
 * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */
require_once 'abstract.php';

class Atwix_Shell_Remove_Product_Attribute_Store_Values extends Mage_Shell_Abstract
{

    /**
     * Parse string with id's and return array
     *
     * @param string $string
     * @return array
     */
    protected function _parseString($string)
    {
        $codes = array();
        if (!empty($string)) {
            $codes = explode(',', $string);
            $codes = array_map('trim', $codes);
        }
        return $codes;
    }
    /**
     * Run script
     *
     */
    public function run()
    {
        if ($this->getArg('attributes')) {
            $codes = $this->_parseString($this->getArg('attributes'));
            $successCount = 0;
            foreach ($codes as $code){
                try {
                    $attribute = Mage::getSingleton('eav/config')->getAttribute(Mage_Catalog_Model_Product::ENTITY, $code);
                    $attributeId = $attribute->getId();
                    if ($attributeId > 0) {
                        $table = $attribute->getBackendTable();
                        $resource = Mage::getSingleton('core/resource');
                        $write = $resource->getConnection('core_write');

                        $write->query("DELETE FROM $table WHERE `attribute_id` = $attributeId AND `store_id` > 0");

                        echo "Store values were removed for attribute " . $attribute->getFrontendLabel() . PHP_EOL;
                        $successCount++;
                    } else {
                        echo "No attributes found by code $code" . PHP_EOL;
                    }
                } catch (Exception $e) {
                    echo $e->getMessage() . PHP_EOL;
                }
            }
            if ($successCount) {
                echo "Please, run full reindex" . PHP_EOL;
            }
        } else {
            echo $this->usageHelp() . PHP_EOL;
        }
    }

    /**
     * Retrieve Usage Help Message
     *
     */
    public function usageHelp()
    {
        return <<<USAGE

        ----------------------------- WARNING: USE WITH CAUTION! --------------------------------------------

        Usage:  php -f remove_store_scope_product_attribute_values.php -- [options]

        --attributes <attribute_code>         Delete all product attribute values for all scopes except admin
        help                                  This help

        <attribute_code>                      Comma separated attribute codes

        -----------------------------------------------------------------------------------------------------

USAGE;
    }

}

$shell = new Atwix_Shell_Remove_Product_Attribute_Store_Values();
$shell->run();

The name of the script is a bit long: remove_store_scope_product_attribute_values.php, so you can rename it as you wish. You can run it from the shell like this:

php -f your_magento_location/shell/remove_store_scope_product_attribute_values.php --attributes attribute1,attribute2

Multiple product attribute codes may be specified. Codes are parsed and each attribute value is deleted in a single query. So the core of the script is here:

$attribute = Mage::getSingleton('eav/config')->getAttribute(Mage_Catalog_Model_Product::ENTITY, $code);
$attributeId = $attribute->getId();
if ($attributeId > 0) {
    $table = $attribute->getBackendTable();
    $resource = Mage::getSingleton('core/resource');
    $write = $resource->getConnection('core_write');

    $write->query("DELETE FROM $table WHERE `attribute_id` = $attributeId AND `store_id` > 0");
}

We’re simply loading product attribute by code, getting that attribute’s EAV table name and deleting everything from it with the specified attribute ID and store ID greater than 0. Script won’t delete static attribute values, but those are not present in the EAV tables and have single scope.

Shell scripts are secure, as they can be run only with the SSH access. This script is addressing sensitive EAV data, and you should do it with caution. Full reindex should be performed after the script is run in order to get the results, as most of the data may be located in the index and the flat tables.

The script may be extended to affect other EAV entities: categories, customers, addresses. And with a simple code adjustment, it may delete values from the specific store IDs only.

More about the structure of the shell scripts can be found in this article.

Thanks for reading us!

Read more: