Tag Archive - app

Have Your Magento Caches Update Themselves

Magento has a lot of caches. They are (in my opinion) the biggest reason Magento is usable as a platform (If you think Magento runs slowly now – turn them off for a little bit).

One thing that I as a programmer find odd is that the caches in Magento are intelligent enough to flag themselves as invalidated, however they generally require that they be refreshed by hand. This can be especially irritating when you are running Magento Enterprise Edition and your full page cache is constantly being invalidated due to product and category updates.

In order to improve our site performance I wanted to find a practical way to run with the full page cache on all the time without requiring me to babysit it 24 hours a day. I figured I had to find the code that was triggered when you told the admin panel to update the cache.

It turns out that like most things in Magento, unless you know how it works, it is not immediately obvious where this code is located. One tool I have found invaluable is Commerce Bug by Alan Storm. This tool told me that the cache admin page is controller by the controller that is located at:

/app/code/core/Mage/Adminhtml/controllers/CacheController.php

Now in this controller you will find a number of actions. The one that is going to help us is massRefreshAction(). Inside you will see that there is code that actually refreshes the cache

$tags = Mage::app()->getCacheInstance()->cleanType($type);

This is close but not quite what we need yet. The $type is a string code for the cache. We don’t want to always refresh the cache. Just the ones that have been flagged as invalidated.

Looking deeper into the ->getCacheInstance() class that is returned shows us an interesting function that is available called ->getInvalidatedTypes(). BINGO! That is exactly what we are looking for.

Looking at what this function returns we find an array of objects that contain the codes of caches that have been invalidated. Now all we have to do is iterate through this list and refresh those caches.

The final script will look like the following:

$types = Mage::app()->getCacheInstance()->getInvalidatedTypes();
foreach($types as $type) {
     Mage::app()->getCacheInstance()->cleanType($type->getId());
}

Now that we have a script that is refreshing the caches, we just need this script to run every so often and it will refresh any caches as required. I set it to run every 2 minutes, but your mileage may vary.

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" => 1))
 ->setOrder('entity_id')
 ;

foreach($categories as $category) {
 echo $category->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).