When Reindexing in Magento Fails, Use The Command Line

One of the things that you have to get used to when running Magento is dealing with the indexes that it relies on. Usually you can do this from the admin panel by going to System -> Index Management.

When indexing fails from the admin panel you get a message saying that it failed with no reason why it failed. Now in most cases you cannot ignore this. You may find that most (if not all) of your products has disappeared from the front end of the website.

While I am not entirely sure of the cause of the re-indexing failing, the one way I have discovered how to successfully re-index is to turn off your web server and run a special command line script to do your re-indexing. Not only does this almost always complete, but if it does fail it will give you an error message (I have only ever seen it give an Integrity Constraint Violation).

The command line script is located in the shell/ directory of your Magento install. The script is called indexer.php and there are a number of options you can use to do just about anything you could with the admin panel.

I would recommend playing around with on a development server so that you can become familiar with how it works so when you are ready to use it when it is crunch time.

Some Common Uses

php indexer.php                   - Displays help information on how to use the script
php indexer.php --status          - Shows the status of all the indexes
php indexer.php info              - Shows the "codes" for the individual indexes
php indexer.php --reindex <code>  - Re-indexes the <code> index
php indexer.php reindexall        - Re-indexes all the indexes

Set All Your Magento Categories to is_anchor

I recently was tasked to set every category inside our Magento installation have its is_anchor attribute set to true. We have over 600 categories so it would be a huge task to do this by hand so I put together a quick script that did this in less than a minute.

error_reporting(E_ALL);
ini_set('display_errors', '1');

// Load Up Magento Core
define('MAGENTO', realpath('/path/to/magento'));

require_once(MAGENTO . '/app/Mage.php');

$app = Mage::app();

$categories = Mage::getModel('catalog/category')
 ->getCollection()
 ->addAttributeToSelect('*')
 ->addAttributeToFilter('is_anchor', 0)
 ->addAttributeToFilter('entity_id', array("gt" =&gt; 1))
 ->;setOrder('entity_id')
 ;

foreach($categories as $category) {
 echo $category-&gt;getId() . "\t" . $category->getName() . "\n";
 $category->setIsAnchor(1);
 $category->save();
}

The first thing I did was pull in Magento’s functionality so I could load up a collection of categories. You will notice that I only got categories that had their is_anchor property set to 0 and an entity_id greater than 1.

From there I did a foreach on all the categories and set the category is_anchor property to 1 and saved it. I decided to echo out the category name so I could watch the script process the categories.

Give Your Command Line Script Full Access to Magento

In the past year, I have had the pleasure of having to write a lot of scripts that accomplish certain tasks inside Magento. It is not immediately obvious how to do this, but once you know how, you will love the power that it gives you.

In your PHP script simply put the following at the top:

<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');

// Load Up Magento Core
define('MAGENTO', realpath('/path/to/magento'));

require_once(MAGENTO . '/app/Mage.php');

$app = Mage::app();

?>

You can now do anything you would normally do inside Magento. I usually end up loading and manipulating a models in my scripts. You will notice at the top that I set error reporting to be outputted. I like to do this to ensure that errors are being displayed on the command line (it will override any other settings).