How to change the Magento ‘Shipping & Handling’ output

Written on April 1, 2014

I see a lot of advice which recommends overriding Magento’s classes when you need to change a core file. Alan Storm recommends, and rightly so, that we should extend from Magento’s core classes when making changes as opposed to overriding them. To summarise Alan’s article the main reasons for this are to make the code changes more easy to follow, especially if new developers take on your code-base, and also to allow for easy upgrades of Magento’s core files when the team release core patches. If you override core files then any patches made to that file will not be applied to your override in the local pool.

Today I needed to change the output of the Shipping & Handling ($description) text that gets output in the cart and checkout tables. Now it would have been very easy to simply change the text in app/code/core/Mage/Sales/Model/Quote/Address/Total/Shipping.php:

/**
* Add shipping totals information to address object
*
* @param   Mage_Sales_Model_Quote_Address $address
* @return  Mage_Sales_Model_Quote_Address_Total_Shipping
*/
    public function fetch(Mage_Sales_Model_Quote_Address $address)
    {
        $amount = $address->getShippingAmount();
        if ($amount != 0 || $address->getShippingDescription()) {
            $title = Mage::helper('sales')->__('Shipping & Handling');
            if ($address->getShippingDescription()) {
                $title .= ' (' . $address->getShippingDescription() . ')';
            }
            $address->addTotal(array(
                'code' => $this->getCode(),
                'title' => $title,
                'value' => $address->getShippingAmount()
            ));
        }
        return $this;
    }

But then that would be changing core files which would lose our ability to upgrade in the future.

Another option would be to copy that file to our local code pool and then make the changes there but, again, that would reduce our ability to manage upgrades. So the best way to do this is to make our own module which extends the Mage_Sales_Model_Quote_Address_Total_Shipping class.

How to change the Shipping & Handling text in Magento by extending from the original class

First of all we need to make our module and tell Magento that it exists. We do this by creating this file: app/etc/modules/$Company_$ModuleName.xml. Where $Company is the name of your company (this can be anything you like but namespacing as your company is good practice) and $ModuleName is the name of your module. Note that throughout this example, all code is case-sensitive.

In our module file we will need the following:

<?xml version="1.0"?>
<config>
    <modules>
        <$Company_$ModuleName>
            <active>true</active>
            <codePool>local</codePool>
        </$Company_$ModuleName>
    </modules>
</config>

Then we need to create our module’s config.xml file here: app/code/local/$Company/$ModuleName/etc/config.xml. The contents of that file will be:

<?xml version="1.0"?>
<config>
    <modules>
        <$Company_$ModuleName>
            <version>0.0.1</version>
        </$Company_$ModuleName>
    </modules>
<global>
    <models>
        <$Company_$ModuleName>
            <class>$Company_$ModuleName_Model</class>
        </$Company_$ModuleName>
        <sales>
            <rewrite>
                <quote_address_total_shipping>$Company_$ModuleName_Model_Quote_Address_Total_Shipping</quote_address_total_shipping>
            </rewrite>
        </sales>
    </models>
</global>
</config>

Then finally we need to create the following file: app/code/local/$Company/$ModuleName/Model/Quote/Address/Total/Shipping.php within which we will extend our class and make our changes like so:

<?php
/**
* Magento
*
* ...
*/

class $Company_$ModuleName_Model_Quote_Address_Total_Shipping extends Mage_Sales_Model_Quote_Address_Total_Shipping
{
    /**
    * Add shipping totals information to address object
    *
    * @param Mage_Sales_Model_Quote_Address $address
    * @return Mage_Sales_Model_Quote_Address_Total_Shipping
    */
    public function fetch(Mage_Sales_Model_Quote_Address $address)
    {
        $amount = $address->getShippingAmount();
        if ($amount != 0 || $address->getShippingDescription()) {
            $title = Mage::helper('sales')->__('Your new text here');
            if ($address->getShippingDescription()) {
                $title .= ' (' . $address->getShippingDescription() . ')';
            }
            $address->addTotal(array(
                'code' => $this->getCode(),
                'title' => $title,
                'value' => $address->getShippingAmount()
            ));
        }
        return $this;
    }
}

That’s it. 3-steps to changing a core file in Magento whilst keeping our upgradability intact.