3

I want to use below script to create a set of categories. The script works fine but I have an issue and I am wondering if their is an option to set the ID for a new category?

Problem is that I am not able to add a sub category for a category that is not in the database yet. I do not know the ID of that category yet because it's in the same import as the new sub category.. Hope this makes sense

    setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
        $count = 0;

    $file = fopen('./var/import/import_cat.csv', 'r');
    while (($line = fgetcsv($file)) !== FALSE) { $count++;
      //$line is an array of the csv elements

      if (!empty($line[0]) && !empty($line[1])) { 

          $data['general']['path'] = $line[0];
          $data['general']['name'] = $line[1];
          $data['general']['meta_title'] = "";
          $data['general']['meta_description'] = $line[5];
          $data['general']['is_active'] = $line[2];
          $data['general']['url_key'] = "";
          $data['general']['display_mode'] = "PRODUCTS";
          $data['general']['is_anchor'] = 0;
          $data['general']['navigation_description'] = $line[3];
          $data['general']['is_primary_category'] = $line[4];

          $data['category']['parent'] = $line[0]; // 3 top level
          $storeId = 0;

          createCategory($data,$storeId);
          sleep(0.5);
          unset($data);
        }

    }  


     function createCategory($data,$storeId) {

    echo "Starting {$data['general']['name']} [{$data['category']['parent']}] ...";

      $category = Mage::getModel('catalog/category');
      $category->setStoreId($storeId);

      # Fix must be applied to run script
      #http://www.magentocommerce.com/boards/appserv/main.php/viewreply/157328/

          if (is_array($data)) {
              $category->addData($data['general']);

              if (!$category->getId()) {

                  $parentId = $data['category']['parent'];
                  if (!$parentId) {
                      if ($storeId) {
                          $parentId = Mage::app()->getStore($storeId)->getRootCategoryId();
                      }
                      else {
                          $parentId = Mage_Catalog_Model_Category::TREE_ROOT_ID;
                      }
                  }
                  $parentCategory = Mage::getModel('catalog/category')->load($parentId);
                  $category->setPath($parentCategory->getPath());

              }

                    /**
                     * Check "Use Default Value" checkboxes values
                     */
                    if ($useDefaults = $data['use_default']) {
                        foreach ($useDefaults as $attributeCode) {
                            $category->setData($attributeCode, null);
                        }
                    }             

              $category->setAttributeSetId($category->getDefaultAttributeSetId());

              if (isset($data['category_products']) &&
                  !$category->getProductsReadonly()) {
                  $products = array();
                  parse_str($data['category_products'], $products);
                  $category->setPostedProducts($products);
              }

              try {
                  $category->save();
                  echo "Suceeded 
"; } catch (Exception $e){ echo "Failed
"; } } }
  • Hi Sander, did you ever get this to work? – 7ochem Jan 6 '16 at 11:00
1

With this information you would think that the solution would be something like :

$this->startSetup();
Mage::register('isSecureArea', 1);

Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);

$category = Mage::getModel('catalog/category');
$category->setPath('1/2') // set parent to be root category
    ->setStoreId(Mage_Core_Model_App::ADMIN_STORE_ID)
    ->setName('Category Name')
    ...
    ->save();
$this->endSetup();

But this code doesn't work either. Indeed after looking into Mage::app() (Mage_Core_Model_App Line 804) I noticed a IF condition that would always return the default store if you're in a setup script.

The trick is to fake that you're not in a setup script, my working solution is:

$this->startSetup();
Mage::register('isSecureArea', 1);

// Force the store to be admin
Mage::app()->setUpdateMode(false);
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);

$category = Mage::getModel('catalog/category');
$category->setPath('1/2') // set parent to be root category
    ->setStoreId(Mage_Core_Model_App::ADMIN_STORE_ID)
    ->setName('Category Name')
    ...
    ->save();
$this->endSetup();
0

I assume you have defined the "parent" in your CSV file somehow. I see that position 0 would contain a "path". You should keep track of a mapping of the inserted ID's of all categories to their "path".

Lets say your path for a third level category ("Sub Sub Category") is defined like this:

"Main Category/Sub Category"

After $category->save(); you should get the category's ID:

try {
    $category->save();

    echo "Suceeded (ID: " . $category->getId() . ")\n";

    $path = explode('/', $data['general']['path']);
    $path[] = $data['general']['name']; // Add the current category to the path
    $path = implode('/', $path);
    $catPathIdMapping[$path] = $category->getId();
} catch...

Then when creating another category, to look up the parent ID:

$parentId = $catPathIdMapping[ $data['general']['path'] ];

At the end your mapping would look like:

array (
  'Main Category A' => 1,
  'Main Category A/Sub Category A' => 2,
  'Main Category A/Sub Category A/Sub Sub Category A' => 3,
  'Main Category A/Sub Category A/Sub Sub Category B' => 4,
  'Main Category A/Sub Category A/Sub Sub Category C' => 5,
  'Main Category A/Sub Category B' => 6,
  'Main Category A/Sub Category B/Sub Sub Category A' => 7,
  'Main Category A/Sub Category B/Sub Sub Category B' => 8,
  'Main Category B' => 9,
  'Main Category B/Sub Category A' => 10,
)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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