1

I'm developing a module that creates configurable products, it's simple products and the attributes used to create this configurable (if not exists). All seems fine, products are created, associated and the attribute seems to be created correctly. But the association is "broken", the configurable product is not displayed in search or categories (even with 'Catalog, Search', status 'Enabled', in stock, etc).

I also found out that if I save the attribute created programatically again, in my admin panel, the link between simple products and their configurable disapear (they don't show linked in the admin panel anymore).

All products (configurable and simple) are firstly created with this method:

private function createBaseProduct($sku)
    {
        $_product = Mage::getModel('catalog/product');
        $_product->setSku($sku);
        $_product->setAttributeSetId(4);
        $_product->setTypeId('simple');
        $_product->setWebsiteIDs(array(1));
        $_product->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH);
        $_product->setStatus(1);
        $_product->setTaxClassId(0);
        $_product->setStockData(array(
            'use_config_manage_stock' => 0,
            'manage_stock' => 1,
            'is_in_stock' => 1,
            'qty' => 100
        ));
        return $_product;
    }

In case the product is configurable, it then goes to this method:

private function setData($configurable, $configAttrCode)
    {
    --> new CustomAttribute($configAttrCode); // Create custom attribute if not exists
        $configurable->setTypeId('configurable');
        $configurable->setStockData(array(
            'use_config_manage_stock' => 0,
            'manage_stock' => 0,
            'is_in_stock' => 1,
            'qty' => 0,
        ));
    --> $configurable = $this->setAssociativeAttributes($configurable); 
        $configurableAttributesData = $configurable->getTypeInstance()->getConfigurableAttributesAsArray();
        $configurable->setCanSaveConfigurableAttributes(true);
        $configurable->setConfigurableAttributesData($configurableAttributesData);
        return $configurable;
    }

Where the class CustomAttribute is responsible for the custom attribute's creation (if not exists). It works like this:

public function __construct($attrCode)
{   
    $attrData = array(
            'group'             => '',
            'type'              => 'varchar',
            'backend'           => '',
            'frontend'          => '',
            'label'             => ucfirst($attrCode),
            'input'             => 'select',
            'class'             => '',
            'source'            => '',
            'global'            => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,
            'visible'           => true,
            'required'          => false,
            'user_defined'      => true,
            'default'           => '0',
            'searchable'        => false,
            'filterable'        => false,
            'comparable'        => false,
            'visible_on_front'  => false,
            'is_configurable'   => true,
            'unique'            => false,
        );
        $installer = new Mage_Eav_Model_Entity_Setup('core_setup');
        $installer->startSetup();
        $installer->addAttribute(Mage_Catalog_Model_Product::ENTITY, $attrCode, $attributeData);
        $this->addAttributeToDefaultSet();
        $installer->endSetup();
}

After that, the method setAssociativeAttributes() set the attributes IDs of the configurable product being created:

 private function setAssociativeAttributes()
    {
        $configurable->getTypeInstance()->setUsedProductAttributeIds($this->configurableAttrsIds);
        return $configurable;
    }

Then, the configurable product returned in setData() is saved using $product->save(). Later, simple product's are created (using the createBaseProduct() method), and assigned to it's custom attribute option (the option is also created if not exists):

private function setCustomAttribute($product, $attrCode, $optionLabel)
{
    $customAttribute = new CustomAttribute($attrCode);
    $customAttribute->addOptionIfNotExists($optionLabel, $attrCode);
    $optionId = $customAttribute->getOptionId($optionLabel);
    $product->setData($attrCode, $optionId);
}

Where $product is the child product being created and the method $customAttribute->addOptionIfNotExists() do:

public function addOptionIfNotExists($optionLabel, $attrCode)
    {
        $value['option'] = array($optionLabel);
        $order['option'] = 0;
        $optionData = array(
            'value' => $value,
            'order' => $order
        );
        $attribute = Mage::getSingleton('eav/config')
            ->getAttribute(Mage_Catalog_Model_Product::ENTITY, $attrCode);
        $attribute->setData('option', $optionData);
        $attribute->save();
    }

In the end, the simple product is associated to it's configurable using this method:

public function associateChildProduct($configurableId, $childProduct)
    {
        $configurable = Mage::getModel('catalog/product')->load($configurableId); 
        $childProducts = $configurable->getTypeInstance()->getUsedProducts();
        array_push($childProducts, $childProduct);
        $childProductsIds = array();
        foreach($childProducts as $product) {
            array_push($childProductsIds, $product->getId());
        }
        Mage::getResourceSingleton('catalog/product_type_configurable')
            ->saveProducts($configurable, $childProductsIds);
    }

And all seems fine in the admin panel, but the configurable product isn't displayed in search (if I try to access it via URL it opens correctly, even the variations are displayed).

Obs.: if I save the attribute via admin panel, delete simple products and create new ones using "Quick create" (with the same values) the configurable product is displayed in search and categories.

1 Answer 1

1

I was able to debug the problem and discover that the configurable product wasn't being displayed because it's entity_id wasn't being added to the table catalog_product_index_price. This problem seems to be caused because the attribute used in the configurable product's creation had the backend_type set to varchar, instead int (Reference).

So I changed my code for attribute's creation to:

public function __construct($attrCode)
{   
    $attrData = array(
            'group'             => '',
        --> 'type'              => 'int',
            'backend'           => '',
            'frontend'          => '',
            'label'             => ucfirst($attrCode),
            'input'             => 'select',
            'class'             => '',
            'source'            => '',
            'global'            => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,
            'visible'           => true,
            'required'          => false,
            'user_defined'      => true,
            'default'           => '0',
            'searchable'        => false,
            'filterable'        => false,
            'comparable'        => false,
            'visible_on_front'  => false,
            'is_configurable'   => true,
            'unique'            => false,
        );
        $installer = new Mage_Eav_Model_Entity_Setup('core_setup');
        $installer->startSetup();
        $installer->addAttribute(Mage_Catalog_Model_Product::ENTITY, $attrCode, $attributeData); 
        $this->addAttributeToDefaultSet();
        $installer->endSetup();
}

Where in the indicated line the attribute's backend_type is set to int. After this, the configurable product is now being correctly displayed in category and search :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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