How to Create a Magento Module
Magento is one of the most powerful eStore or ecommerce web applications, which empowers hundreds of thousands of shopping sites on the internet. And the primary reason for that is the availability of community extensions or modules. The community extensions or modules help customize the functionality of the eShop, and provide users with a feature-rich online shopping experience. There are plenty of modules one can choose from depending on his requirements. However, there can be a time when they might not work as you may want them to. That’s where the need to create your own Magento Module arises, and that’s what we are going to tell you about in a short little tutorial.
This will help you understand the structure of a Magento module, which will help you modify any module to suit your own requirements. Moreover, you will also be able to start developing your own Magento modules from scratch.
In today’s tutorial on the Magento Module, we will explore the coding of Magento in a “Hello World“-style module. The main purpose of this module is to write a little info to a log file each and every time a product is saved. This would be a very basic module in which we will be covering a few exciting topics, including:
- The app/code directories,
- The structure and creation of a Magento module,
- Event observers,
- Logging
Initial Requirements
Before we begin to reveal how to create a Magento module, we assume that you are familiar with Magento, and already have it up and running on a live or local server, and you can add new or remove existing files from it. For this tutorial, the version of Magento has nothing to do with it, as we will only be going through the fundamental aspects of a Magento Module that are the same in all versions and editions, be it the Community, the Professional or the Enterprise one.
DISABLE OR CLEAR THE CACHE
This should be the first and foremost step a Magento developer should take: disable or clear the cache. This can be done from Cache Management located under the System drop down menu inside the Magento Admin Panel. Once you are on the cache management page, select all the available check boxes and select ‘Disable’ from the drop down menu present in the menu bar available just above the given options with check boxes, and hit the submit button.
Though the files we just disabled via Cache Management are essential to boost performance in a production environment, the cache is not a good friend of developers, and causes many technical difficulties. However, if you want, you can still leave it enabled, but only and only at your own risk.
The app/code Directory
You may find many individual modules present inside the app/code directory, and this is where the main root of Magento lies. Inside this directory, the modules are divided into three parts, which are; core, community and local.
CORE
Basically, the app/code/core directory comprises all the functionality for products, categories, customers, payments, etc. Unless you have sound coding skills and know what you are doing (and even afterwards), it is advised to stay away from the app/code/core directory, as these files are something which should not be altered.
In addition to this, Magento has been structured in such a way that you can modify or enhance the functionality of any of the core files without altering them directly. This lets you keep your Magento Store intact and it also remains upgrade-proof. Moreover, to understand the functioning better, we suggest you go step by step without touching the code of the existing files.
COMMUNITY
As the name ‘Community’ suggests, the app/code/community directory is where you will get to see the modules that have been provided by third parties, which obviously excludes the ones provided by Magento’s core team. There are hundreds of modules that come along with Magento Connect, and once you incorporate them into your store via the built-in “Package Manager,” this is where they get placed.
LOCAL
Though Magento comes with an empty app/code/local directory, which is provided specifically to add custom-made modules to your Magento store, there are chances when you’ll not see this directory at all. In that case, you need to create the ‘local’ folder inside the app/code/directory. That’s because this is where we will be keeping our tailor-made modules.
Now you are through with the directory structure. So open your code editor and navigate to the app/code/local directory because we will be adding some new directories and files to it.
MODULE NAMESPACE
Our main work starts from here. To start with your module development, you need to create a directory, i.e., known as “namespace.” However, you can name it anything you want, but the general rule that all developers follow is to name it based on the company’s name or the module’s author. For example, Magento uses “Mage” as its namespace. And to make you familiar with this concept, we will use “codingace” as our namespace. So, create a directory that looks something like this: ‘app/code/local/codingace.’
MODULE NAME
Now we will create another directory that would be something that describes our module. The module we will be creating today will write log entries each and every time a product is saved, so depending on its task, the logical name should be something like LogProductUpdate. So create another directory app/code/local/codingace/LogProductUpdate.
Now our module directory structure is completed. And it should look something like; app >> code >> local >> codingace. However, there’s one more thing that you always need to keep in mind, i.e., that the directory and file names are case sensitive, so capitalize the directory names where you feel the need to.
1 2 3 4 5 | app – code – local – Codingace – LogProductUpdate |
Configuring Our Module
Now we will proceed ahead and start configuring our module. The configuration files of any module are placed inside the module, but in a new directory, which should be named ‘etc’, so create that along with a new XML file: app/code/local/Codingace/LogProductUpdate/etc/config.xml.
The main function of this XML file is to inform Magento about the location of the files used in a particular module, along with many other things, like module version number and events to observe. For now, let’s create a simple config.xml file, which should contain comments that describe the specific meaning of each and every listed section.
<?xml version="1.0" encoding="UTF-8"?>
<!-- The root node for Magento module configuration -->
<config>
<!--
The module's node contains basic
information about each Magento module
-->
<modules>
<!--
This must exactly match the namespace and module's folder
names, with directory separators replaced by underscores
-->
<Codingace_LogProductUpdate>
<!-- The version of our module, starting at 0.0.1 -->
<version>0.0.1</version>
</SeoSemanticxhtml_LogProductUpdate>
</modules>
</config>
Activating Our Module
Now our next step is to inform Magento about the existence of our module, which we will do by creating a fresh XML file in the app/etc/modules directory. You can name this XML file anything you would like to, as Magento will be reading all the XML files placed inside this directory, and will be considering only the content. However, generally, the rule that all developers follow is to give the file and module the same name. So we will now create Codingace_LogProductUpdate.xml and will place it inside the ‘app/etc/modules/’ directory.
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<Codingace_LogProductUpdate>
<!-- Whether our module is active: true or false -->
<active>true</active>
<!-- Which code pool to use: core, community or local -->
<codePool>local</codePool>
</Codingace_LogProductUpdate>
</modules>
</config>
Cross Check
As in the above step, we have activated our fully functional module in Magento. Though it doesn’t do anything yet, it is still a valid Magento module. So it is advisable for you to log in to your Magento admin panel and try to see if it has been configured correctly till now or not. For this, once you log in to the Magento admin panel, navigate and go to System >> Configuration >> Advanced >> Advanced, and view the “Disable Modules Output” listing. There you should be able to see the Codingace_LogProductUpdate module listed as enabled or activated. However, if you did not find it listed, then you might have done something wrong with the codes we have written above, so carefully run through all the steps till here. But generally, when this sort of problem arises, new Magento developers realize what cache is all about.
Right now our module structure should look like this:
1 2 3 4 5 6 7 8 9 10 11 | app – code – local – Codingace – LogProductUpdate – etc – config.xml – etc – modules – Codingace_LogProductUpdate.xml |
Let’s Define an Event Observer Now!
In Magento or in its modules, event observers are exceptionally powerful and are considered as one of the cleanest and easiest ways to enhance Magento’s functionality without rewriting or overriding any core methods or classes. Here, we want to observe the event that Magento triggers just after a product is saved. Therefore, the code for the event we need to pay attention to is catalog_product_save_after. To determine which event code should be used while defining a new observer requires a fundamental understanding of Magento’s model layer, which is pretty far away from the scope of this short tutorial. However, we will try to cover that in another tutorial in the future.
Apart from that, we now have to modify our config.xml so that we can include the event observer definition code.
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<Codingace_LogProductUpdate>
<version>0.0.1</version>
</Codingace_LogProductUpdate>
</modules>
<!-- Configure our module's behavior in the global scope -->
<global>
<!-- Defining an event observer -->
<events>
<!-- The code of the event we want to observe -->
<catalog_product_save_after>
<!-- Defining an observer for this event -->
<observers>
<!--
Unique identifier within the
catalog_product_save_after node.
By convention, we write the module's
name in lowercase.
-->
<Codingace_logproductupdate>
<!-- The model to be instantiated -->
<class>codingace_logproductupdate/observer</class>
<!-- The method of the class to be called -->
<method>logUpdate</method>
<!-- The type of class to instantiate -->
<type>singleton</type>
</seoSemanticxhtml_logproductupdate >
</observers>
</catalog_product_save_after>
</events>
</global>
</config>
Configuring Our Model’s Directory
In the code mentioned above, we have defined an event observer and made a reference to a particular model that hasn’t been created as of now. But now we have to tell Magento where to look for these models in our module by updatingconfig.xml with the code mentioned below.
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<Codingace_LogProductUpdate>
<version>0.0.1</version>
</Codingace_LogProductUpdate>
</modules>
<!-- Configure our module's behavior in the global scope -->
<global>
<!-- Defining models -->
<models>
<!--
Unique identifier in the model's node.
By convention, we put the module's name in lowercase.
-->
<codingace_logproductupdate>
<!--
The path to our models directory, with directory
separators replaced by underscores
-->
<class>codingace_LogProductUpdate_Model</class>
</codingace_logproductupdate>
</models>
<events>
<catalog_product_save_after>
<observers>
<codingace_logproductupdate>
<class>codingace_logproductupdate/observer</class>
<method>logUpdate</method>
<type>singleton</type>
</codingace_logproductupdate >
</observers>
</catalog_product_save_after>
</events>
</global>
</config>
Create An Observer Model
Now we have to create the model to be instantiated when the event is triggered. So create a new PHP file in app/code/local/codingace/LogProductUpdate/Model/Observer.php with the specific code given below.
<?php
/**
* Our class name should follow the directory structure of
* our Observer.php model, starting from the namespace,
* replacing directory separators with underscores.
* i.e. app/code/local/Codingace/
* LogProductUpdate/Model/Observer.php
*/
class Codingace_LogProductUpdate_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’re done! Try it out.
Now we are done with our newly created module, and its overall directory structure should look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | app – code – local – Codingace – LogProductUpdate – Model – Observer.php – etc – config.xml – etc – modules – Codingace_LogProductUpdate.xml |
As of now, our module is complete, so you should try it out. Therefore, log into your Magento admin panel, and create or update any listed product in your catalog, and then check the var/log folder to see if the yourproduct-updates.log file gets populated or not. And if nothing comes out or you find that the directory does not exist, then please ensure that the correct permissions are set to allow Magento to write to this particular directory, and that logging is enabled. In order to check this, go to Admin Panel >> System >> Configuration >> Developer >> Log Settings >> Enabled.
This is just a basic tutorial that has been made to tell you how Magento modules work. However, if you want to dig deeper and understand more, then we advise you to explore the Magento modules located inside the app/code/core directory and see if you now have a better idea about how the module functions.