4

On a current project, we have one store view per country that the shop targets. Here's an example list of store views:

  • Switzerland (German)
  • Germany (German)
  • UK (English)
  • USA (English)
  • Australia (English)

All store views share one catalog, so the products are the same across all Store Views. Products are created in German initially. Now we need to add translations for some product attributes for the different languages, for example the product's descriptions need to be translated from German into English for the Store Views targeting English speaking countries.

The way that I have previously solved this (when there was just one Store View per language) was by opening each product in the Admin Panel and manually updating its description. But this is obviously too much work when there are multiple Store Views per language, because then I'd have to manually update the description once per Store View, using the same values for all English Store Views.

Is there a way of updating a product attribute's value for multiple Store Views at once? So that I can enter the product description in English just once, and it will be updated for all Store Views where the language is English?

I doubt that this can be solved using Magento Core so I'm open for suggestions using extensions or external tools.

Thanks!

4

If you wanted this as a feature you can write a module, and observe the save product event and loop through all the stores and either:

  • condition based looking for "english" if they are named like that
  • hardcode the id's
  • provide a configuration option in the admin to select the english stores.
  • add an attribute to the store object

Another way to do it as a one off:

<?php

require '../app/Mage.php';

$englishStore = 1; // English Store (the one you want to copy from)
$attribute = "short_description"; // Attribute to copy

foreach (Mage::app()->getWebsites() as $website) {
    foreach ($website->getGroups() as $group) {
        $stores = $group->getStores();
        foreach ($stores as $store) {
            //store object
            //print_r($store->getData());

            // if english found in name or change this so it's hardcoded store id's
            if (strstr($store->getData('name'),"english")) {

                $StoreToUpdateCollection = Mage::getModel('catalog/product')->getCollection()
                    ->addAttributeToSelect('*')
                    ->addAttributeToFilter('store_id', $store->getData('store_id'));

                foreach ($StoreToUpdateCollection as $product) {

                    // get the description from the base English store
                    $englishProduct = Mage::getModel('catalog/product')->setStoreId($englishStore)->loadByAttribute('sku', $product->getData('sku'));
                    $newValue = $englishProduct->getData($attribute);

                    // update the attributes for the current store for the product ID
                    Mage::getSingleton('catalog/product_action')->updateAttributes(
                        array($product->getData('id')),
                        array($attribute => $newValue),
                        $store->getData('store_id')
                    );
                }


            }


        }
    }
}

I have not tested the updating part, would suggest trying this on a dev version.

  • 1
    Nice idea. I can add something to it. You don't need to loop through the websites then through the store views. You can loop directly through the store views: $stores = Mage::getModel('core/store')->getCollection()->addFieldToFilter('store_id', array('neq'=>0));. Also, you don't need to hard code the store views. You can identify if a store id uses the same locale as the current store id. You can get the locale through Mage::getStoreConfig('general/locale/code', $store->getId());. Other than that ... good idea. – Marius Mar 20 '15 at 14:29
  • Thanks for the suggestions. It looks like I'll have to create something myself. But I can't believe I'm the only person who has ever run into this problem though? :) So I'll wait for a few more days and see if anybody else has another solution. – Louis B. Mar 20 '15 at 17:42
2

I could not find an extension that does exactly what I need, so I created one myself: MobWeb_CopyStoreViewValues.

It uses the catalog_product_save_before observer as suggested by @joel-davey:

class MobWeb_CopyStoreViewValues_Model_Observer
{
    public function catalogProductSaveBefore($observer)
    {
        // Load the helper & config
        $helper = Mage::helper('copystoreviewvalues');
        $config = $helper->getConfig();

        // Load the saved product from the observer
        $event = $observer->getEvent();
        $product = $event->getProduct();
        $productId = $product->getId();
        $productStoreViewId = $product->getStoreId();

        // If the product is not a configurable product, don't do anything
        if($product->getTypeId() !== "configurable") {
            return $observer;
        }

        // Check if the current store view is a "source" store view whose attribute values need to copied
        // to any "target" store views
        if(array_key_exists($productStoreViewId, $config['storeViewRelationships'])) {

            // Loop through the "target" store views and copy the attribute values from the "source" store views
            // over to the "target" store views
            foreach($config['storeViewRelationships'][$productStoreViewId] AS $targetStoreViewId) {

                // Loop through the attributes that need to be copied
                foreach($config['copyAttributes'] AS $sourceAttributeCode) {

                    // Get the product's attribute value from the source store view
                    $sourceAttributeValue = $product->getData($sourceAttributeCode);

                    // If the current attribute uses the default value from the "default values" (Store View 0),
                    // it will be empty for the source Store View, so we don't need to update any target Store Views,
                    // since they will inherit the values from the "default values" anyway
                    if(!$sourceAttributeValue || empty($sourceAttributeValue)) {
                        continue;
                    }

                    // Also check if the new attribute value is different than what is currently saved in the database.
                    // If not, don't update any attributes
                    $sourceAttributeValueOld = Mage::getResourceModel('catalog/product')->getAttributeRawValue($productId, $sourceAttributeCode, $productStoreViewId);
                    if($sourceAttributeValueOld === $sourceAttributeValue) {
                        continue;
                    }

                    // Update the product's attribute value in the target store view
                    Mage::getSingleton('catalog/product_action')->updateAttributes(
                        array($productId),
                        array($sourceAttributeCode => $sourceAttributeValue),
                        $targetStoreViewId
                    );

                    $helper->log(sprintf('Copied value for attribute "%s" from Store View %s to Store View %s: %s', $sourceAttributeCode, $productStoreViewId, $targetStoreViewId, $sourceAttributeValue));
                }
            }
        }

        return $observer;
    }
}

And the hardcoded configuration, for reference:

public function getConfig()
{
    $config = array();

    // Which store view values should be copied to which other store views?
    // Format: "Source ID" => "Target IDs"
    $config['storeViewRelationships']= array(
        // '3' => array('1', '2')
    );

    // Which attribute codes should be copied from the source to the target store view(s)?
    $config['copyAttributes'] = array(
        // 'name',
        // 'description',
        // 'short_description',
    );

    return $config;
}
  • I believe this is exactly what I'm looking for as well. Would the hardcoded configuration be inside the Observer.php file too? Additionally, I'm trying to copy from my default store which has a storeId = 1 to my new storeId = 13. I just asked the question yesterday, here: magento.stackexchange.com/questions/135254/… – thismethod Sep 8 '16 at 17:54
  • Also i'm confused with your event observer method... how come there is no etc folder or Helper folder? Shouldn't there be a config.xml and system.xml files inside /etc folder. I understand there might not need to be a /Helper. – thismethod Sep 8 '16 at 18:01
  • If you look at the Github repository at github.com/mobweb/MobWeb_CopyStoreViewValues you should actually see all the files you mentioned in the proper directories. :) I suggest you click on the "Download ZIP" link accessible under the "Clone or Download" button near the top right. Then you should get a ZIP file with all the files. Alternatively use something like Modman or Modgit to install the extension from the repository. Hope that helps! – Louis B. Sep 9 '16 at 7:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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