Magento Base URLs and dev/staging installations

One of the earlier problems I came across when setting up Magento, was that the Base URLs for the websites/stores are stored in the database. We wanted a scenario where we can have a staging site, and a development site, and transfer the database between them. With the way Magento works, this would require updating the Base URLs each time, and means that we couldn’t easily share a single database between a local development copy and a shared development copy running from our svn.

My first idea to workaround this was to create a small tool, that updated the Base URLs stored in the database, however this didn’t solve the issue of sharing one database between different installs. I looked into the Magento code, and saw that there is a function Mage::getBaseUrl (which in turn calls Mage_Core_Model_Store->getBaseUrl). If I could override this function on the development copies, I could replace the live Base URLs stored in the database with whatever local address we were using.

One of the best places to find development information seems to be on other people’s blogs, and this was one of the reasons why we thought it a good idea to blog our development here. I found http://www.belanur.de/blog/2008/09/05/overriding-core-models-with-a-custom-module/ invaluable when it came to learn how to override classes/function in Magento.

On to the code. The code is split into 4 files. Two XML configurations, and the php with the new getBaseUrl call. The other file is a ini config file for specifying how the Base URLs should map to the development/staging URLs.

Assuming you have a working configured Magento install. The following paths are all referenced relative to the main Magento folder.

File: app/etc/modules/Maglife_All.xml
This file activates our module. Magento merges this xml with its own xml to create a config.

<?xml version="1.0"?>
<config>
    <modules>
      <Maglife_Core>
        <active>true</active>
        <codePool>local</codePool>
      </Maglife_Core>
    </modules>
</config>

File: app/code/local/Maglife/Core/etc/config.xml
This file specifies to Magento what the module does. In this case it says the model / class we want to override and points to the replacement file (the line Maglife_Core_Model_Store translates to the path Maglife/Core/Model/Store.php which contains our code). This is at least my current understanding as I haven’t found any comprehensive documentation on the various xml tags yet.

<?xml version="1.0"?>
<config>
    <global>
        <models>
            <core>
                <rewrite>
                    <store>Maglife_Core_Model_Store</store>
                </rewrite>
            </core>
        </models>
    </global>
</config>

File: app/code/local/Maglife/Core/Model/Store.php
This contains the actual code. We call the parent getBaseUrl function, and then if the ENV variable is set, we replace the base url with a url provided in the urls.ini file (passed in the MAGENTO_DEVURLS variable).

<?php

class Maglife_Core_Model_Store extends Mage_Core_Model_Store
{

    public function getBaseUrl($type=self::URL_TYPE_LINK, $secure=null)
    {
        $store_code = $this->getCode();
        $url = parent::getBaseUrl($type, $secure);
        if ($url_ini = @$_SERVER['MAGENTO_DEVURLS'])
        {
            if ($urls = parse_ini_file($url_ini))
            {
                $host = parse_url($url, PHP_URL_HOST);
                if (isset($urls[$host]))
                {
                    $url = str_replace('://'.$host.'/', '://'.$urls[$host].'/', $url);
                }
            }
        }
        return $url;
    }

}

?>

File: urls.ini (can call this anything you like)

livestore.example.com = staging-livestore.example.com
livestore2.example.com = staging-livestore2.example.com

Then in my apache config on the staging/dev site I have the line

SetEnv MAGENTO_DEVURLS /path/to/urls.ini

and that’s it. I can now copy our live database to the staging server for example, without having to manually alter the Base URL config data in the database. I hope this is some use to others.

Magento Blog

We chose the Magento software for a new e-commerce project, and decided it would be a good idea to document our findings and ideas for others to use. Magento documentation is a little thin in places, and we have found a good deal of information from reading other people’s blogs.