Question

I am currently developing a product configurator. I am submitting a form which sends the admin option values of my custom attributes via POST to a controller action. If I use the current store's attribute option labels all is working just fine, the product collection is filtered correctly and a simple product which is associated to a configurable product is returned. Sadly I am using the admin values for form and URL generation because the default swedish store values contain too many special characters.

So my question is: how do I get the right product from my collection when using the admin option values or more specific, how do I get the admin option value's ID like using this for the default store's values:

$id = Mage::getResourceModel('catalog/product')
                                    ->getAttribute($key)
                                    ->getSource()
                                    ->getOptionId($value); 

I already tried filtering by addStoreFilter(0), but that didn't work either. I already read that it could have something to do with flat tables being used in default store but not for admin, but I am rather unexperienced with Magento, so I don't really understand the difference using flat tables and what that really means.

Here is my last question concerning the filtering for reference: addFieldToFilter doesn't return the right product for selected attribute values

Here is my getProduct() function:

public function getProduct($attributes)
    {

        Mage::Log($attributes);

        $productModel = Mage::getModel('catalog/product');

        //Get Product Collection
        $collection = $productModel->getCollection()


        //Filter for Selected Product
        $collection->addAttributeToSelect('status');
        $collection->addAttributeToSelect('doorconfig_enable');
        $collection->addAttributeToFilter('doorconfig_enable',array('eq' => 1));

        foreach ($attributes as $key => $value) 
        {
            $collection->addAttributeToSelect($key);

            $id = Mage::getResourceModel('catalog/product')
                                    ->getAttribute($key)
                                    ->getSource()
                                    ->getOptionId($value);

            $collection->addAttributeToFilter($key,
                array(
                        'eq' => $id
                     )
            );

        }

        $selection = $collection->getSelect()->__toString();

        Mage::Log($selection);

        Mage::log($collection->getSize(),null,'custom.log');

        $product = $collection->getFirstItem();

        return $product;

    }
Was it helpful?

Solution

Like all of Magento, the answer's in the source — all you need to do is go digging (or hop to then end of this post).

First, find the class for the attribute source

$source = Mage::getResourceModel('catalog/product')
->getAttribute('color')
->getSource();        
var_dump(get_class($source));
exit;

In modern versions of Magento, this should point to the class Mage_Eav_Model_Entity_Attribute_Source_Table, which is located at

#File: app/code/core/Mage/Eav/Model/Entity/Attribute/Source/Table.php
class Mage_Eav_Model_Entity_Attribute_Source_Table extends Mage_Eav_Model_Entity_Attribute_Source_Abstract
{
    //...
}

Next, we'll look for the definition of the getOptionId method on this class and/or it's parent classes. We'll find it in the Mage_Eav_Model_Entity_Attribute_Source_Abstract class

#File: app/code/core/Mage/Eav/Model/Entity/Attribute/Source/Abstract.php
public function getOptionId($value)
{
    foreach ($this->getAllOptions() as $option) {
        if (strcasecmp($option['label'], $value)==0 || $option['value'] == $value) {
            return $option['value'];
        }
    }
    return null;
}

Examining this method, we can see if works by foreaching over a list of options from the getAllOptions method. So let's look at this method's definition.

#File: app/code/core/Mage/Eav/Model/Entity/Attribute/Source/Table.php
public function getAllOptions($withEmpty = true, $defaultValues = false)
{
    $storeId = $this->getAttribute()->getStoreId();
    if (!is_array($this->_options)) {
        $this->_options = array();
    }
    if (!is_array($this->_optionsDefault)) {
        $this->_optionsDefault = array();
    }
    if (!isset($this->_options[$storeId])) {
        $collection = Mage::getResourceModel('eav/entity_attribute_option_collection')
            ->setPositionOrder('asc')
            ->setAttributeFilter($this->getAttribute()->getId())
            ->setStoreFilter($this->getAttribute()->getStoreId())
            ->load();
        $this->_options[$storeId]        = $collection->toOptionArray();
        $this->_optionsDefault[$storeId] = $collection->toOptionArray('default_value');
    }
    $options = ($defaultValues ? $this->_optionsDefault[$storeId] : $this->_options[$storeId]);
    if ($withEmpty) {
        array_unshift($options, array('label' => '', 'value' => ''));
    }

    return $options;
}

Ah ha! Now we're on to something. This appears to be the method that loads all the option information. Specifically, we're interested in

$storeId = $this->getAttribute()->getStoreId();

So, Magento gets the store ID for the options to load from the attribute. This means you should be able to do something like the following (replacing color and red with your own variables, of course)

    //get the attribute
    $attribute = Mage::getResourceModel('catalog/product')
    ->getAttribute('color');

    //set the store id on the attribute
    $attribute->setStoreId(Mage_Core_Model_App::ADMIN_STORE_ID);

    //get the source
    $source = $attribute->getSource();

    //get the id
    $id = $source->getOptionId('red');
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top