Some of our simple products were not correctly assigned to a configurable product. And, some of them were visible independently in the front end. My task was to assign simple products to correct configurable product and make associated products to not visible individually. It was easy to find configurable product and associated simple products because of the SKU they had. All simple products had sku configurableSKU__*.
So after some trials this code worked for me.
<?php /** * Associate simple products to configurable products * Re-written By Damodar because of memory issue with previous code. * * @category Technooze * @package Add simple products to configurable products * @copyright Copyright (c) 2012 Technooze.com * @author Damodar Bashyal * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * */ require_once dirname(__FILE__) . '/../app/Mage.php'; class Mage_Shell_setChildren { public function run() { // because of the memory issue, i need to use cache file $cacheFile = 'configurable.txt'; // display a startup message echo "\n\rOpening file..."; // check to see if file exists, if not attempt to create it if(!file_exists($cacheFile)){ $fh = fopen($cacheFile, 'w+') or die("can't open file - {$cacheFile}"); fclose($fh); } // read file into array $file_contents = file($cacheFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); // if the file content is empty, then look into database and write into file if(empty($file_contents)){ echo "\n\rNo Ids found in file, so looking into database"; $collectionConfigurable = Mage::getResourceModel('catalog/product_collection') ->addAttributeToFilter('type_id', array('eq' => 'configurable')) //->addAttributeToFilter('has_been_fixed', array('eq' => '0')) //->addAttributeToFilter('sku', array('eq' => '10SOC04RD')) ; $configurableIds = array(); if($total = count($collectionConfigurable)){ foreach ($collectionConfigurable as $parent) { $configurableIds[] = $parent->getId(); } } // write in a file, so we can read file instead of quering database later file_put_contents($cacheFile, implode("\n",$configurableIds)); } else { $total = count($file_contents); $configurableIds = $file_contents; echo "\n\rIds found in cache file, so using those Ids"; } // free some memory unset($file_contents); $loop = 1; echo "\n\rFound total: {$total} configurable product IDs"; // now iterate through the ids and update products. foreach ($configurableIds as $k => $id) { $parent = Mage::getModel('catalog/product')->load($id); echo "\n\r" . $loop++ . '. Processing SKU - ' . $parent->getSku() . ' - ' . $parent->getId() . "\n\r"; // get existing associated product ids $childIds = $parent->getTypeInstance()->getUsedProductIds(); // look for simple products that could be associated products of this configurable product $collectionPosChildren = Mage::getResourceModel('catalog/product_collection') ->addAttributeToFilter('type_id', array('eq' => 'simple')) ->addAttributeToFilter('sku', array('like' => $parent->getSku() . "__%")); // get ids of associated products and set the as not visible individually foreach ($collectionPosChildren as $product) { $childIds[] = $product->getId(); $product = $product->load($product->getId()); echo "\n\rsetting simple product ({$product->getSku()}) as not visible individually!"; $product->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_NOT_VISIBLE); $product->save(); } // we don't need this $product variable, so unset it to free memory unset($product); // make the array of associated products ids unique $childIds = array_unique($childIds); // save parent id on variable as it's lost after next step, not sure why $parentId = $parent->getId(); // now load the resource model for this configurable product and save it with associated product ids $product = Mage::getResourceModel( 'catalog/product_type_configurable' )->load( $parent, $parent->getId() ); echo "\n\rSaving configurable product...\n\r"; $product->saveProducts( $parentId, $childIds ); // now lets remove this id from our cache file and overwrite with remaining ids unset($configurableIds[$k]); echo "\n\rUpdating cache file...\n\r"; file_put_contents($cacheFile, implode("\n",$configurableIds)); $k++; echo "\n\r{$k} of {$total} completed!!!\n\r\n\r\n\r"; } echo "\n\r\n\rDone!!!\n\r\n\r"; } } umask(0); /* not Mage::run(); */ Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID); error_reporting(E_ALL ^ E_NOTICE); $shell = new Mage_Shell_setChildren(); $shell->run(); //end of file: shell/associateSimples.php
This is how i run in the php command line:
shell > php associateSimples.php
Sample output:
1. Processing SKU - SOC22WH - 420 ID - 420 2. Processing SKU - FOK22WH - 469 ID - 469
WP posted on - Monday 26th of November 2012 09:24:35 PM
Ovidiu U posted on - Monday 29th of October 2012 08:01:28 PM
I'm getting this error on your script:
Saving configurable product...
PHP Fatal error: Call to a member function getTypeInstance() on a non-object in /var/www/html/www.lenjerii1701.com/app/code/core/Mage/Catalog/Model/Resource/Product/Type/Configurable.php on line 62
This is called by $product->saveProducts( $parentId, $childIds );
Any Ideea why is this happening?
Andrew posted on - Tuesday 4th of December 2012 11:09:59 AM
the issue is something has changed in Magento, you need to pass the parent product model, not just the ID.
like this:
$product->saveProducts( $parentProduct, $childIds );
Julian posted on - Thursday 24th of January 2013 10:19:28 AM
I have some regarding problem, I need to add one certain simple to all existing configs. I tried several options on API or Magmi but nothing worked out so far. The task is to add that certain simple to all configs wihtout deleting existing associated simples, or doing a complete new import. Maybe one of you have an idea how to solve that issue.
Best
Hamid posted on - Friday 25th of January 2013 07:38:40 PM
The simple products are then nicely associated to the configurable product.
Keep in mind the logic of the names is as following:
configurable: mainconfig
simple product1: mainconfig1
simple product2: mainconfig2
Or you can change it ofcourse by changing:
addAttributeToFilter('sku', array('like' => $parent->getSku() . "%"));
Good luck.
Nicholas posted on - Thursday 11th of April 2013 11:12:44 PM
Saving configurable product...
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`hyperion_hyperionsupps`.`catalog_product_super_link`, CONSTRAINT `FK_CAT_PRD_SPR_LNK_PARENT_ID_CAT_PRD_ENTT_ENTT_ID` FOREIGN KEY (`parent_id`) REFERENCES `catalog_product_entity` (`entity_id`)' in /home/hyperion/public_html/test/lib/Zend/Db/Statement/Pdo.php:228
Stack trace:
#0 /home/hyperion/public_html/test/lib/Zend/Db/Statement/Pdo.php(228): PDOStatement->execute(Array)
#1 /home/hyperion/public_html/test/lib/Varien/Db/Statement/Pdo/Mysql.php(110): Zend_Db_Statement_Pdo->_execute(Array)
#2 /home/hyperion/public_html/test/lib/Zend/Db/Statement.php(300): Varien_Db_Statement_Pdo_Mysql->_execute(Array)
#3 /home/hyperion/public_html/test/lib/Zend/Db/Adapter/Abstract.php(479): Zend_Db_Statement->execute(Array)
#4 /home/hyperion/public_html/test/lib/Zend/Db/Adapter/Pdo/Abstract.php(238): Zend_Db_Adapter_Abstract->query('INSERT INTO `ca...', Array)
in /home/hyperion/public_html/test/lib/Zend/Db/Statement/Pdo.php on line 234
Naujasdizainas posted on - Monday 13th of May 2013 12:17:25 PM
after
require_once dirname(__FILE__) . '/../app/Mage.php';
ADD
//Truncate catalog_product_super_link
$_db = Mage::getSingleton('core/resource')->getConnection('core_read');
$_db->query("TRUNCATE catalog_product_super_link");