1

I have a batch of products, which I need to add custom products for. To do so, I have created a file in the root directory to call as import functionality.

Here, I created my own class to handle all the stuff in: So I create a Attribute Set, a group and attributes, place the attributes in the group and the group in the Attribute set and assign the attributeSet to the Product. This part works flawlessly, I can confirm this in the management tool.

The next part works fine too: adding the options to the attributes. Although probably not the best code, it works flawlessly to add the options to the attributes. Again, I can confirm this in the attributes and product management tool.

However, I now want to set the selected value for the attributes for my product. This I've been messing with for over 5 hours now without any success whatsoever: All I want is the the added attributes, which come from an external source e.g. 'special_color' and 'special_name' actually are set for the given product to 'green' and 'hardwood'.

But whatever I've tried, in the product management page, they all show nicely, as drop-down selections to be assigned manually, but not 1 set to the correct value for that attribute.

Below my function, Ive commented where it stopped working (basically just $product->setData):

function setOrAddOptionAttribute($arg_attribute, $arg_value, $product, $setid) {
    $attribute_model = Mage::getModel('eav/entity_attribute');
    $attribute_options_model = Mage::getModel('eav/entity_attribute_source_table');

    $attribute_code = $attribute_model->getIdByCode('catalog_product', $arg_attribute);
    $attribute = $attribute_model->load($attribute_code);

    $attribute_options_model->setAttribute($attribute);
    $options = $attribute_options_model->getAllOptions(false);

    // determine if this option exists
    $value_exists = false;
    $option_id = false;
    foreach($options as $option) {
        if ($option['label'] == $arg_value) {
            $option_id = $option['value'];
            $value_exists = true;
            echo 'EXIST!!!!! '.$arg_value . ' == '.$option_id;
            break;
        }
    }

    // if this option does not exist, add it.
    if (!$value_exists) {
        $attribute->setData('option', array(
            'value' => array(
                'option' => array($arg_value,$arg_value)
            )
        ));
        $attribute->save();
    }

    //experimental: get the value id for justcreated item
    $options = $attribute_options_model->getAllOptions(true);
    foreach($options as $option) {
        if ($option['label'] == $arg_value) {
            $option_id = $option['value'];
            break;
        }
    }

    echo '$product->setData($attribute->getId() ['.$attribute->getId().'], $option_id['.$option_id.'])';
    if($option_id){
        /* THIS TINY PART WONT WORK: */
     //   $product->load($product->getId());
        $product->setData($attribute->getId(), $option_id);
        $product->save();
    }
}

The $product that is passed into the setOrAddOptionAttribute function, originates from a loop with this data:

function getProducts(){
    return Mage::getModel('catalog/product')->getCollection()->addAttributeToSelect(array('name','ean','sku'));
}

I've tried using the setData with the attribute_code ($arg_attribute) and actual value ($arg_value) as strings, got the appropriate Id's for them, and even combined them. I also tried loading the product again but that doesn't change anything either.

I could use some serious help with this, please! Even if it's just what to insert into the $product->setData? (id's, names, code)?

To me it seems the data is correctly set in the $product, considering I tried using

$product->setData('my_attribute_name_here', 'myvalue')

or

$product->setMyAttributeNameHere('myvalue')

and to fetch the set value using $product->getMyAttributeNameHere() to verify, which returns my set data. However, it won't save to database.

I tried $product->save();
aswel as $product->getResource()->saveAttribute($product, $arg_attribute);

Nothing works tho, any suggestions?

[SOLVED] Apparently doing a separate product load in the $products loop solved the problem.

foreach($products as $product) {
  $product = Mage::getModel('catalog/product')->load($product->getEntityId());
  ...
}
  • What does not work? The load or setting the data? It's logical setting the data won't work, as you are setting a numerical key. You should setData($attribute->getCode(), ...). But if the loading don't work, then you are hitting the object cache in Varien_Object. – Melvyn Jan 13 '15 at 18:16
  • @Melvyn setting the data, all I want to do is save the selected values for my attributes for the product, for some reason whenever I use setData() and save(), it never does anything. the attributes wont show up with the a set value in in the management portal – MrGogo Jan 14 '15 at 9:30
  • Look into addAttributeUpdate(). – Melvyn Jan 14 '15 at 14:12
  • Welcome to SE. Please respect the format of this website. If you find a solution to your problem post it in the answers area and mark the answer as accepted. – Marius Jan 15 '15 at 7:26
1

Ok, here's a test script I used to verify if newly added attributes are working, by setting defaults on a specific product. As you can see, I used Mage_Catalog_Model_Product->addAttributeUpdate(). This was done on a Magento 1.3, but the test script worked flawlessly. Perhaps it helps you to track down the issue.

<?php
/**
 * Setup test product for verification of functionality
 */
require_once(dirname(__FILE__).'/PATH/TO/app/Mage.php');
umask(0);
Mage::setIsDeveloperMode(true);
Mage::app('YOUR_STORE_CODE_HERE');

function lookupAttributeId($needle, $haystack)
{
    foreach($haystack AS $dict)
    {
        if( $dict['label'] == $needle)
            return $dict['value'];
    }

    return false;
}
function getAttributesByValueAsString($code, $values=array())
{
    $tmp = array();
    /** @var array $allOptions */
    $allOptions = Mage::getResourceModel('eav/entity_attribute_collection')
        ->setCodeFilter($code)
        ->getFirstItem()
        ->getSource()
        ->getAllOptions();

    foreach($values AS $value)
    {
        if( ($id = lookupAttributeId($value, $allOptions)) !== false )
            $tmp[] = $id;
        else
            fprintf(STDERR, 'Value %s not found%s', $value, PHP_EOL);
    }

    return implode(',', $tmp);
}
$product_id = 12167; // HARDCODED
/** @var Mage_Catalog_Model_Product $product */
$product = Mage::getModel('catalog/product')->load($product_id);
// Attributes below are specific for this store.
// first argument is attribute name, second is an array of labels. This
// specific attribute is a multi-select.
$attributesBevatGeen = getAttributesByValueAsString(
    'bevat_geen',
    array('Soja', 'Suiker')
);
$attributesIsWel = getAttributesByValueAsString(
    'is_wel',
    array('Organisch', 'Veganistisch')
);

// webonly is a boolean and therefore different.
$product->addAttributeUpdate('webonly', '1', 5);
$product->addAttributeUpdate('bevat_geen', $attributesBevatGeen, 5);
$product->addAttributeUpdate('is_wel', $attributesIsWel, 5);

// Reindex required for frontend. Should not affect backend as backend does
// direct EAV queries.
// won't include it, as indexes are quite different in 1.3 Magento.
// include(dirname(__FILE__). DIRECTORY_SEPARATOR . 'reindex.php');

printf('Product can be viewed at: %scatalog/product/view/id/%d%s', Mage::getBaseUrl(), $product_id, PHP_EOL);
  • thankfully after a lot of trying and googling I solved it (as added in original post), but appreciate the assistance :) – MrGogo Jan 14 '15 at 16:21
0

Use this code:

$updater = Mage::getSingleton('catalog/product_action');
$updater->updateAttributes(array($productId), array($attributeCode => $attributeValue), $storeId);

Hope it will help.

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.