1

My theme and business requirements stipulate that the super attributes for configurable products be presented in a specific order. While this can be changed in the Admin while editing a product by drag-and-dropping the attributes around, I want to be able to control this during import by CSV.

I found that Mage_ImportExport_Model_Import_Entity_Product_Type_Configurable::saveData hard codes the position property for super attribute in catalog_product_super_attribute here:

$superAttributes['attributes'][$productId][$attrParams['id']] = array(
    'product_super_attribute_id' => $productSuperAttrId, 'position' => 0
);

How can I allow this to be ordered on import?

1 Answer 1

1

First, overwrite the Mage_ImportExport_Model_Import_Entity_Product_Type_Configurable class:

<importexport>
    <rewrite>
        <import_entity_product_type_configurable>Company_Namespace_Model_ImportExport_Import_Entity_Product_Type_Configurable</import_entity_product_type_configurable>
    </rewrite>
</importexport>

Then add a few support methods:

protected $_superAttributeIds = array();
protected $_superAttributePositions = array();
protected $_attributeSetIds = array();

 /**
 * @theloveofcode.com - Get all of the IDs of the super attributes
 *
 * @return array
 */
protected function _getSuperAttributeIds() {
    if (empty($this->_superAttributeIds)) {
        foreach ($this->_superAttributes as $_superAttribute) {
            $this->_superAttributeIds[] = $_superAttribute['id'];
        }
    }

    return $this->_superAttributeIds;
}

/**
 * @theloveofcode.com - Get the ID for a given attribute set by name
 *
 * @param $_attributeSetName
 *
 * @return array
 */
protected function _getAttributeSetByName($_attributeSetName) {
    if (!array_key_exists($_attributeSetName, $this->_attributeSetIds)) {
        $attributeSet = Mage::getModel("eav/entity_attribute_set")->getCollection()
            ->addFieldToFilter('entity_type_id', Mage::getSingleton('eav/config')->getEntityType(Mage_Catalog_Model_Product::ENTITY)->getId())
            ->addFieldToFilter('attribute_set_name', 'Lenses')
            ->getFirstItem();

        if ($attributeSet) {
            $this->_attributeSetIds[ $_attributeSetName ] = $attributeSet->getId();
            return $attributeSet->getId();
        }
    } else {
        return $this->_attributeSetIds[ $_attributeSetName ];
    }

    Mage::throwException('Attribute Set ID not found using name "'. $_attributeSetName .'"');
}

 /**
 * @theloveofcode.com - Get the position for a given attribute in a given attribute set
 *
 * @param $_attributeSetName
 * @param $_attributeId
 *
 * @return mixed
 */
protected function _getSuperAttributePosition($_attributeSetName, $_attributeId) {
    if (empty($this->_superAttributePositions)) {
        $attributeIds = $this->_getSuperAttributeIds();
        $attributeSetId = $this->_getAttributeSetByName($_attributeSetName);

        $read = Mage::getSingleton('core/resource')->getConnection('core_read');
        $sql = "
            SELECT `attribute_id`, `sort_order`
            FROM `{$read->getTableName('eav_entity_attribute')}`
            WHERE {$read->prepareSqlCondition('`attribute_id`', $attributeIds)}
            AND {$read->prepareSqlCondition('`attribute_set_id`', $attributeSetId)}
        ";

        $results = $read->fetchAssoc($sql);
        if ($results) {
            foreach ($results as $attributeId => $attributeData) {
                $this->_superAttributePositions[ $attributeId ] = $attributeData['sort_order'];
            }
        } else {
            Mage::throwException('Could not load super attribute positions.');
        }
    }

    if (array_key_exists($_attributeId, $this->_superAttributePositions)) {
        return $this->_superAttributePositions[ $_attributeId ];
    }

    Mage::throwException('Could not find super attribute position.');
}

Then, copy the saveData method, and replace this...

$superAttributes['attributes'][$productId][$attrParams['id']] = array(
    'product_super_attribute_id' => $productSuperAttrId, 'position' => 0
);

With this...

// @theloveofcode.com - start - Use the super attribute position
if (!empty($productSuperData['attr_set_code']) && !empty($attrParams['id'])) {
    $superAttrPos = $this->_getSuperAttributePosition($productSuperData['attr_set_code'], $attrParams['id']);
} else {
    $superAttrPos = 0;
}
$superAttributes['attributes'][$productId][$attrParams['id']] = array(
    'product_super_attribute_id' => $productSuperAttrId, 'position' => $superAttrPos
);
// @theloveofcode.com - end

This will get the sort order for each attribute in the Attribute Set for the product that's being imported, and apply that same sort order to the super attributes on the configurable product. (Note: The attributes must be in the same Group within the Attribute Set.)

Your Answer

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

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