Contact
Site: US UK AU |
Nexcess Blog

Scripting Magento

November 26, 2010 1 Comment RSS Feed

Magento Scripting
There are times when the web-based administration of Magento hits a snag and no longer works as quickly as we’d like it to. Perhaps product exports or backups time out, or refreshing the URL rewrite table seems to run for hours with little progress. Or maybe you simply want to automate these functions using a cron job. In times like these it’s helpful to be able to whip up a script that does what we want from the command line. This post discusses topics relevant to writing custom php scripts for administering Magento from the command line.

Magento’s Class Namespace

The first thing to understand is the pattern for calling class instances in Magento. When you’re looking through the code and you see something like Mage::getModel(‘dataflow/profile’), you may feel at a bit of a loss as to what class or section of code is being called. These calls are made in the format of “module/package_classname”. This format can be translated in the class namespace, Mage_Module_???_Package_Classname. The ??? is determined based on the context of the call. The resulting class can only be one of three types:

  1. Model
  2. Helper
  3. Block

So in our example above, the call:

Mage::getModel('dataflow/profile');

…translates into the class Mage_Dataflow_Model_Profile. With the class name in hand, you can look up the properties and methods of the class on Magento’s website: http://docs.magentocommerce.com/, in the code itself, or using your own internal documentation. Here are a few other examples:

$product = Mage::getModel('customer/address');
// Translates into Mage_Customer_Model_Address

$url = $this->helper('customer')->getLoginPostUrl();
// Translates into Mage_Customer_Helper_Data ("data" is appended by default to helpers")

$url = $this->helper('giftmessage/url')->getSaveUrl();
// Translates into Mage_Giftmessage_Helper_Url

<block type="catalog/product_list" name="product_list" template="catalog/product/list.phtml" />
<!-- even XML translates into Mage_Catalog_Block_Product_List -->

Running Database Queries

You need the following two items to run a query against the Magento database:

  1. A resource model
  2. A database connection from that resource model

After that, you are simply dealing with the Magento PDO Adapter, which extends the Zend PDO Adapter. The PHP PDO section of the PHP Manual explains all the syntax needed to script database queries.

Here’s an example:

$db = Mage::getResourceSingleton('core/resource')->getConnection('core/write');
// sets up Resource model and db connection in one statement

$table_prefix = Mage::getConfig()->getTablePrefix();
// returns the table prefix if there is one configured

$result = $db->query("SELECT *  FROM {$table_prefix}core_config_data WHERE path LIKE '%base_url'");
// returns the base URLs configured for each store

Scripting in Magento’s Environment

Now we’re ready to write custom php scripts. Magento scripts are essentially the standard index.php file with one difference. Instead of the Mage::run() method call, we use the Mage::app() method. Any type of automated maintenance can be scripted in this manner. From exporting products to updating product categories. Here is the basic template:

<?php
// if this is not run from the Magento root, use chdir() to move execution back.
//chdir('../magento/');

require_once('app/Mage.php');
umask (0);
Mage::app(); // can set the run code/type, just like in the Mage::run() call

// add your own code below:

?>

Here are a couple of scripts I use frequently:

export.php – The slow creep of Magento’s import/export functions is notorious. The following script runs the same export profile as is run from the back end, but much more quickly and without the same timeout issues as when run from a browser:

<?php

$profileId = 1; // Enter the export profile number from System > Import/Export > Profiles

require_once('app/Mage.php');
umask(0);
Mage::app('admin');

$profile = Mage::getModel('dataflow/profile');
$userModel = Mage::getModel('admin/user');
$userModel->setUserId(0);
Mage::getSingleton('admin/session')->setUser($userModel);
$profile->load($profileId);
if (!$profile->getId()) {
Mage::getSingleton('adminhtml/session')->addError('ERROR: Incorrect profile id');
}

Mage::register('current_convert_profile', $profile);
$profile->run();

echo "EXPORT COMPLETE.\n";
?>

backup.php – This script creates a compressed Magento db backup in var/backups. It’s the same as running System > Tools > Backup, but is generally faster and doesn’t time out if your database is very large. As with the export script, it can also be run as a cron job.

<?php
//This script creates a Magento db backup in var/backups

require_once('app/Mage.php');
umask(0);
Mage::app('admin');

$session = Mage::getSingleton('adminhtml/session');

$backupDb = Mage::getModel('backup/db');
$backup = Mage::getModel('backup/backup')
->setTime(time())
->setType('db')
->setPath(Mage::getBaseDir("var") . DS . "backups");

Mage::register('backup_model', $backup);

$backupDb->createBackup($backup);
echo "BACKUP COMPLETE.\n"

?>

Magento 1.4.x Built In Shell Scripts

Magento 1.4 comes with its own shell scripts. The “MAGENTO_ROOT/shell/” directory contains four files:

  1. abstract.php
  2. compiler.php
  3. indexer.php
  4. log.php

1. Abstract.php is the abstract class definition for Mage_Shell that runs the other scripts and gives you the ability to write your own.

2. Indexer.php is… you guessed it… a command line interface to Magento’s index management.

Usage:

php -f indexer.php -- [options]

--status <indexer>            Show Indexer(s) Status
--mode <indexer>              Show Indexer(s) Index Mode
--mode-realtime <indexer>     Set index mode type "Update on Save"
--mode-manual <indexer>       Set index mode type "Manual Update"
--reindex <indexer>           Reindex Data
info                          Show allowed indexers
reindexall                    Reindex Data by all indexers
help                          This help

<indexer>     Comma separated indexer codes or value "all" for all indexers

3. Log.php lets you manage the visitor logs, which is essential for keeping your database at a reasonable size, and by extension, your time-to-first-byte latency as low as possible:

Usage:

php -f log.php -- [options]
php -f log.php -- clean --days 1

clean             Clean Logs
--days <days>     Save log, days. (Minimum 1 day, if defined - ignoring system value)
status            Display statistics per log tables
help              This help

4. Compiler.php is the command line interface to Magento’s compiler. If you were to run an strace on a Magento php process, you will see that for EVERY single connection, Magento searches its directories in the following order: (1) app/code/local (2) app/code/community (3) app/code/core (4) lib. The Magento Compiler essentially copies all of the class and code files to a single path (include/src) and then changes the include_path accordingly. It also aggregates the most commonly used php files.

Usage:

php -f compiler.php -- [options]

state         Show Compilation State
compile       Run Compilation Process
clear         Disable Compiler include path and Remove compiled files
enable        Enable Compiler include path
disable       Disable Compiler include path
help          This help

I hope this post helps you to write your own custom scripts for Magento.

Posted in: Magento