Magento - Export & Import Custom Product Options

CATEGORIES: Magento, PHP, Programming

Please note this code is out dated an no longer relevant.

I recently had the need to export my Magento products and import them into another Magento store.... Simple I thought. Just go to System -> Import/Export and export all my products and import them into the new store. FAIL.

Turns out that Magento doesn't include your custom options with a product export. It also turns out that if you have a custom attribute with a custom backend model, that it won't import that attribute value either – even if you have the backend model setup. After some searching I found that I wasn't alone (far from it) in the need to export/import product options. There was a lot of discussion on the Magento forum and a helpful blog post that had some info on importing the options, but no solution for exporting & importing. So I rolled my own... maybe it'll help someone else.

In reality my solution was rather simplistic and fits my needs, it may not work for others and your millage may vary. It also assumes you re exporting/importing all your products.

The first thing I do is export my products and import them into the new store. Then I export the options and then import the options on the new store.

Again, this is rather simplistic, but here's what I do. I grab all the options for all the products, dump them into an array, serialize the array and push it to a file download. You could export a nice XML file if you wanted, but I didn't have the need or time to generate and parse XML.

I just dumped this code into an existing module controller I had, you can do the same or create a new module... up to you.

    /**
     * Product options export action
     */
    public function exportAction()
    {
        // get the product collection
        $productCollection = Mage::getModel('catalog/product')->getCollection();
 
        $optionArray = array();
        foreach($productCollection as $product) {
            // load the product object
            $product->load($product->getId());
 
            // set the sku var to use as array key
            $productSku = $product->getSku();
 
            // get the product's options
            $options = $product->getOptions();
 
            foreach($options as $optionKey => $option) {
                // add the option data to the array
                $optionArray[$productSku][$optionKey] = $option->getData();
                $optionArray[$productSku][$optionKey]['values'] = array();
 
                // remove the option and product ids since these
                // can/will change on import
                unset($optionArray[$productSku][$optionKey]['option_id']);
                unset($optionArray[$productSku][$optionKey]['product_id']);
 
                // loop over any values for the option
                foreach($option->getValues() as $valueKey => $value) {
                    // add the value to the option
                    $optionArray[$productSku][$optionKey]['values'][$valueKey] = $value->getData();
 
                    // remove ids from the array
                    unset($optionArray[$productSku][$optionKey]['values'][$valueKey]['option_type_id']);
                    unset($optionArray[$productSku][$optionKey]['values'][$valueKey]['option_id']);
                }
            }
        }
 
        //Zend_Debug::dump($optionArray);
        //exit;
        $content = serialize($optionArray);
 
        // promt to download the options as a text file
        header('HTTP/1.0 200 OK');
        header("Content-Type: text/plain");
        header('Cache-Control: public, must-revalidate, max-age=0');
        header('Pragma: no-cache');
        header('Pragma: private');
        header("Cache-control: private");
        header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
        header("Content-Disposition: attachment; filename=product_options.txt");
        header('Content-Length:'.strlen($content));
        header("Content-Transfer-Encoding: binary\n");
        header('Accept-Ranges: bytes');
 
        echo $content;
    }

Then I take the options file that I saved from the previous method and save it to my var/import folder of the new store and run the next action (again, I just added this to an existing module's controller).

    /**
     * Import product options action
     */
    public function optionsAction()
    {
        $optionText = file_get_contents('var/import/product_options.txt');
        $productArray = unserialize($optionText);
 
        // iterate over the individual products in the array
        foreach($productArray as $productSku => $options) {
            // get the product model
            $product = Mage::getModel('catalog/product');
            $product->load($product->getIdBySku($productSku));
 
            /**
             * Remove existing custom options attached to the product
             * 
             * @link http://magentodev.blogspot.com/2009/05/how-to-import-products-with-custo...
             */
            foreach ($product->getOptions() as $option) {
                $option->getValueInstance()->deleteValue($option->getId());
                $option->deletePrices($option->getId());
                $option->deleteTitles($option->getId());
                $option->delete();
            }
 
            // add the options to the product
            foreach($options as $option) {
                $opt = Mage::getModel('catalog/product_option');
                $opt->setProduct($product);
                $opt->addOption($option);
                $opt->saveOptions();
            }
        }
    }

I haven't fully tested this but it works for my limited usage and small number of products.