How to Create a Magento 1.9 Custom Module

There are several free and paid modules for Magento available online. However, if you need to make changes or the module is not fulfilling your requirement for more functionalities, you should have basic knowledge of how they are created and how they work, etc.

For example, you should know where to place the files, what is the sequence of calling methods and functions or scripts, and so on.

Hence, we are starting this basic tutorial on how to create a simple module which will help us understand the structure of Magento 1.x modules and you can learn to modify them to suit your needs. In this tutorial, you will be introduced to the coding mechanism of Magento modules which will simply help you write a log file every time a product is saved.

(If you are using Magento 2 and want to create a custom module, head over here.)

Before we start:

As a newbie Magento developer, this is the first thing to understand and learn: Disable the Cache. You can do this by going to Admin Panel > System > Cache Management > Select All > Actions: Disable > Submit

The Directories:

Let’s start with the basic structure; the core files and codes of Magento which can be found in the app/code directory. The app/code/core contains the functionalities for products, categories, customers, payments, etc. The modules that have been provided by third parties (i.e. not Magento’s Core Team) can be found in the app/code/community directory. There is an empty directory as well that is the app/code/local directory. This is the place where we are going to work.

Structuring the Directory:

The first step is to create the necessary directories which we will be using. Navigate to the app/code/local directory to add some new files and folders.

Module Namespace: The first directory we will create is a “namespace.” This can be anything from the company, author, or developer’s name. Magento uses “Mage” as its namespace,  so we’ll use the same for this tutorial. Therefore, create the directory app/code/local/Mage.
Module Name: Next directory is a name of the module. The module we are creating in this tutorial will write a log entry each time a product is saved, so the logical and matching name would be ProductLogUpdate. Create the directory app/code/local/Mage/ProductLogUpdate.

Now we should see the structure of our module in the following sequence (but remember that these file and folder names are case-sensitive, so make sure you pay attention to it):

Magento Custom Module

Module Configuration:

Next step is to configure our module as per the requirements. The configuration files can be found inside our module’s directory, i.e., ProductLogUpdate in a directory named as etc. So let’s create it along with a new XML file:
app/code/local/Mage/ProductLogUpdate/etc/config.xml
This XML will inform Magento about the location of the module and the files inside our module as well as other things like the version of the module, events to observe, models etc. The config.xml file contains the following initial code:

<?xml version="1.0"?>
<config>
<modules>
<Mage_ProductLogUpdate>
<version>0.0.1</version>
</Mage_ProductLogUpdate>
</modules>
</config>

<config> Root node for Magento module configuration.
<modules> Contains basic information about Magento module.
<Mage_ProductLogUpdate> NameSpace_ModuleName This should be exactly same as the namespace and the module name separated by an underscore.
<version> Version of module.

Activation of Module:

Now we are going to inform Magento that our module exists which we did by creating a new XML file in app/etc/modules. The name of this file can be anything, but for our ease, we are going to name this file with the namespace and the module name separated by an underscore, keeping case-sensitivity in mind. Let’s create app/etc/modules/Mage_ProductLogUpdate.xml with the following content:

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

<active> Whether our module is active: true or false.
<codePool> Which code pool to use: core, community or local.

Now we have a fully functional module enabled in Magento. To check it out, log into the Magento Admin Panel and navigate to System > Configuration > Advanced > Advanced and view the Disable Module Output listing. We should see our Mage_ProductLogUpdate module. If not, carefully run through the steps again and diagnose the mistakes. Now, our module’s structure looks like:

Magento Module Development

Event Observer:

After installation, activation, and checking of the module, we are moving closer to completing our task. For this, we are using an Event Observer. Event observers are the best way to extend Magento’s functionalities without having to rewrite or override any core classes, methods, or functions. Here in this module, we are going to observe the event whenever a product is saved. So the code of the event we are interested in is catalog_product_save_after.
(Determining which event code to use when defining an observer, you have to get an idea and basic understanding about the Magento Model Layers)

We are now going to modify our config.xml to include the event observer:

<?xml version="1.0"?>
<config>
<modules>
<Mage_ProductLogUpdate>
<version>0.0.1</version>
</Mage_ProductLogUpdate>
</modules>
<global>
<events>
<catalog_product_save_after>
<observers>
<mage_productlogupdate>
<class>mage_productlogupdate/observer</class>
<method>logUpdate</method>
<type>singleton</type>
</mage_productlogupdate>
</observers>
</catalog_product_save_after>
</events>
</global>
</config>

<global> Configure our module’s behavior in the global scope.
<events> Defining an event observer.
<catalog_product_save_after> The code of the event we want to observe.
<observers> Defining an observer for this event.
<mage_productlogupdate> Unique identifier within the catalog_product_save_after node. By convention, we write the module’s name in lowercase.
<class> The model to be instantiated.
<method> The method of the class to be called.
<type> The type of class to instantiate.

Model’s Directory:

In the event observer, we made a reference to our model’s class mage_productlogupdate/observer and method logUpdate that we have not yet created. First, we need to inform Magento about the model of our module by updating config.xml with the following code:

<?xml version="1.0"?>
<config>
<modules>
<Mage_ProductLogUpdate>
<version>0.0.1</version>
</Mage_ProductLogUpdate>
</modules>
<global>
<models>
<mage_productlogupdate>
<class>Mage_ProductLogUpdate_Model</class>
</mage_productlogupdate>
</models>
<events>
<catalog_product_save_after>
<observers>
<mage_productlogupdate>
<class>mage_productlogupdate/observer</class>
<method>logUpdate</method>
<type>singleton</type>
</mage_productlogupdate>
</observers>
</catalog_product_save_after>
</events>
</global>
</config>

<models> Defining models.
<mage_productlogupdate> Unique identifier in the model’s node. By convention, we put the module’s name in lowercase.
<class> The path to our model’s directory, with directory separators replaced by underscores.

Now we will create our model which will be instantiated when the event is dispatched. Create a new PHP file in app/code/local/Mage/ProductLogUpdate/Model/Observer.php with the following content:

<?php
/* Our class name should follow the directory structure of our Observer.php model, starting from the namespace, replacing directory separators with underscores. The directory of ousr Observer.php is following:
 app/code/local/Mage/ProductLogUpdate/Model/Observer.php */
class Mage_ProductLogUpdate_Model_Observer
{
// Magento passes a Varien_Event_Observer object as the first parameter of dispatched events.
public function logUpdate(Varien_Event_Observer $observer)
{
// Retrieve the product being updated from the event observer
$product = $observer->getEvent()->getProduct();
// Write a new line to var/log/product-updates.log
$name = $product->getName();
$sku = $product->getSku();
Mage::log("{$name} ({$sku}) updated", null, 'product-updates.log');
}
}
?>

We are done, Hurray!

Finally, our module is complete. It’s time to try it. Log into your Magento Admin Panel, create or update a product and then check the var/log folder to see your product-updates.log file populated.

If nothing appears or the directory doesn’t exist, ensure that sufficient permissions are granted to Magento to write on this directory and also check that logging is enabled in Admin Panel > System > Configuration > Developer > Log Settings > Enabled.

The final directory structure of our complete module should now look like this:
Magento Module

About Author

Fayyaz is a Magento Community Manager at Cloudways - A Managed Magento Hosting Platform. He writes about Magento Tutorials at Magenticians as well as share his knowledge with the Magento Community. Fayyaz is a food lover and enjoys driving. You can email him at m.fayyaz@cloudways.com

12 Comments

  1. Bruno Brandão on

    Really good article! I adapted the code to create a module with another Magento event and everything works fine!
    Thx

  2. Hey..
    I want to know about uninstall script of magento custom module..
    for example at the installation of custom module i have created custom attribute of product

    $installer = Mage::getResourceModel(‘catalog/setup’, ‘catalog_setup’);
    $installer->startSetup();

    $installer->addAttribute(
    ‘catalog_product’,
    ‘_length’,
    array(
    ‘type’ => ‘decimal’,
    ‘label’ => ‘Length’,
    ‘required’ => false,
    ‘visible_on_front’ => true,
    ‘sort_order’ => 26
    )
    );
    $installer->endSetup();

    how to remove this attribute when my custom module is uninstalled from magento connect.
    please help

  3. Patrick Oliveras on

    That’s a neat article you got, it’s a shame that support for Magento 1.x will stop next year. Any more resources you could point out for developing modules for 1.x ? Cheers!

Leave A Reply