4

I'm creating Magento attribute options via a script, but I need to then be able to get the new ID and use it straight away in the same script.

At the moment it's not pulling the id through - if I kill the script and re-start it it picks up the created option and returns the ID, but not as part of the same script.

Here is the code I am using:

       $attr = Mage::getModel('catalog/product')->getResource()->getAttribute($key);
       if ($attr->usesSource()) {
               $vattr_id = $attr->getSource()->getOptionId($value);
       }else{
               echo "No Source";
               $vattr_id = false;
       }


    if($vattr_id){
            return $vattr_id;
    }else{

            $attr_model = Mage::getModel('catalog/resource_eav_attribute');
            $attr = $attr_model->loadByCode('catalog_product', $key);
            $attr_id = $attr->getAttributeId();

            $option['attribute_id'] = $attr_id;
            $option['value'][$value][0] = $value;
            $option['value'][$value][1] = $value;

            $setup = new Mage_Eav_Model_Entity_Setup('core_setup');
            $setup->addAttributeOption($option);
            $attr = Mage::getModel('catalog/product')->getResource()->getAttribute($key);
            if ($attr->usesSource()) {
                   $vattr_id = $attr->getSource()->getOptionId($value);
                    echo "AttrID: $vattr_id";
            }

    }

Running this (with the required Mage::app() etc), creates the option, you can see it in the Magento backend, but the $vattr_id is NULL. If I reload the script, then it finds the attribute option in that first block as it should.

I guess it's something to do with how Magento is caching the models, but not sure where I need to look to clear these?

Thanks!

  • Any reason why you aren't doing this with an install script? – Jonathan Hussey Nov 4 '14 at 11:26
  • Hi Jonathan, It's part of a data importer, we pull in XML feeds, populate the data etc, and part of that is checking for new attribute options that don't already exist and creating them - we don't know what they are until the import runs, sometimes there are many, sometimes none, so it's just a standardlone importer. – Liam Wiltshire Nov 4 '14 at 12:04
  • You seem to have a good answer provided to you. Does it work for you? If so, can you accept it? If not, can you clarify what isn't working? – Melvyn Nov 7 '14 at 19:54
4

I am using slightly different approach to save attribute option value

$arg_value = 'your option label';
$attribute = Mage::getModel('eav/config')->getAttribute('catalog_product', 'your attribute code');
        $flag=0;

    foreach ( $attribute->getSource()->getAllOptions(true, true) as $option )
    {

        if($arg_value == $option['label'])
        {

            unset($attribute);
            $flag=1;
            return $option['value'] ; 
        }
    }
    if($flag==0){
        $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_table        = $attribute_options_model->setAttribute($attribute);
        $options                = $attribute_options_model->getAllOptions(false);

        $value['option'] = array($arg_value,$arg_value);
        $result = array('value' => $value);
        $attribute->setData('option',$result);
        $attribute->save();

        $attribute = Mage::getModel('eav/config')->getAttribute('catalog_product', $arg_attribute);
        foreach ( $attribute->getSource()->getAllOptions(true, true) as $option )
        {
            if($arg_value == $option['label'])
            {
                unset($attribute);
                return $option['value'] ; 
            }
        }

    }

this will create new option value if it not exist and return id of option.

  • Just building this functionality into an import routine and came across this code, what does $arg_attribute refer to? – James Mar 10 '16 at 16:43
  • 1
    @b3njamin $arg_attribute is refer to your attribute_code – Mufaddal Mar 11 '16 at 5:30
  • using flag here is unnecessary because if option found it will be returned – Tofeeq Apr 18 '16 at 8:39
2

I have a potentially slightly cleaner solution:

<?php # sql/module_setup/upgrade-0.4.0-0.5.0.php

$options = array('First new option',
                 'Second new option',
                 'nth new option');


$option = array('attribute_id' => 
    Mage::getModel('eav/entity_attribute')->getIdByCode(
         Mage_Catalog_Model_Product::ENTITY, 
         'attribute_code_here'
    )
 );

for ($i = 0; $i < count($options); $i++) {
    $option['values'][1000+$i] = $options[$i];
}

$installer = $this;
$installer->startSetup();

$setup = new Mage_Eav_Model_Entity_Setup('core_setup');
$setup->addAttributeOption($option);

$installer->endSetup();

You could even go as far as removing the for loop and manually coding the array but I prefer this, myself. Adjust the options, adjust the attribute code (find attribute_code_here) and you're set. Old options are left in place. The 1000+$i is used to determine the sort order, adjust as needed.

1

I also tried to get the id of an just created attribute option, to set it in a product. In my custom class i use this method to add an new option to an select attribute:

public function addAttributeOption($optionName)
{
    $newOptions = array();
    $newOptions['attribute_id'] = $this->myAttributeId;
    $newOptions['value']['dummy-array-name'][0] = $optionName;

    $setup = new \Mage_Eav_Model_Entity_Setup('core_setup');
    $setup->addAttributeOption($newOptions);
    $setup->endSetup();
}

But i must destroy my class object with unset() before i can get the ids like with a method like this:

public function getAttributeOptionNameId($optionName)
{
    $sourceModel = \Mage::getModel('catalog/product')
        ->getResource()
        ->getAttribute($this->myAttributeName)
        ->getSource();
    $valuesIds = array_map(array($sourceModel, 'getOptionId'), array($optionName));
    return $valuesIds;
}
0

I tried all kinds of other solutions (clearing the caches, destroying the source and attribute objects etc.), but the only one that worked was re-creating the source object using the same code that is used in Mage_Eav_Model_Entity_Attribute_Abstract::getSource():

$source = Mage::getModel($authorAttr->getSourceModel());
if (!$source) {
    throw Mage::exception('Mage_Eav',
        Mage::helper('eav')->__('Source model "%s" not found for attribute "%s"',$this->getSourceModel(), $this->getAttributeCode())
    );
}
$authorSrc = $source->setAttribute($authorAttr);

The option set is in the object attributes, so after the source object has been recreated the options are reloaded and the new attribute can be found.

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.