How to create a Module in Magento 2

Here I’m going to explain step-by-step how you can create a module in Magento 2 (A module is called component in Magento 2). In Magento 1 we used to write business logic, layout, template and module enabling code in different places but Magento 2, gives us flexibility to create everything in one folder i.e app/code.

I’ve uploaded a simple Magento 2 module on github which will be taken as a reference in this tutorial. If you have any question, leave in the comments section and I will be happy to answer.

Magento 2 has introduced the concept of composer which is helpful to manage components details, components installation, and helps with managing component dependency.

Let’s start creating a new component. Create a folder app/code/Amit/Helloworld/ in root Magento directory, where Amit is the vendor name and Helloworld is the component/module name.
Now inside Helloworld folder create file composer.json with following code.

  "name": "amit/helloworld-module",
  "description": "Simple Magento 2 module that shows uses of Controller, Block & Template.",
  "type": "magento2-module",
  "version": "1.0.0",
  "license": [
  "require": {
    "php": "~5.5.0|~5.6.0|~7.0.0",
    "magento/framework": "~100.0"
  "autoload": {
    "files": [ "registration.php" ],
    "psr-4": {
      "Amit\\Helloworld\\": ""

Explanation of the tags defined in composer.json
1. name is the unique name of your component.
2. description describes about your component.
3. type is the type of component.
There are 3 component types:
Module (defined as magento2-module)
Theme (defined as magento2-theme)
Language (defined as magento2-language)
4. version defines version of the component.
5. license defines license type of the component.
6. require defines dependency modules. All modules on which this component will be dependent will be listed here.
7. autoload defines which files should be auto-loaded when this component is installed.

Next, create a file registration.php php with following code


Using Magento’s ComponentRegistrar’s register function we are registering our component.
create a file etc/module.xml. It is used to enable our component.

<?xml version="1.0"?>
<config xmlns:xsi="" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Amit_Helloworld" setup_version="2.0.0"/>

Controllers in Magento 2
A frontend controller should be created at app/etc/frontend/routes.xml with following code.

 <?xml version="1.0"?>
<config xmlns:xsi="" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="standard">
        <route id="helloworld" frontName="helloworld">
            <module name="Amit_Helloworld" />

Where router id is standard which means this controller should be applied on storefront, route id should be a unique id and front name is defined in frontName keyword which is used to access your controller like http://example.cpm/helloworld/ .

Now create your controller file at app/code/Controller/Index/Index.php with following content:

namespace Amit\Helloworld\Controller\Index;
class Index extends \Magento\Framework\App\Action\Action
    protected $resultPageFactory;
    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Framework\View\Result\PageFactory $resultPageFactory
    ) {
        $this->resultPageFactory = $resultPageFactory;
    public function execute()
       echo "Hello World!";

Now clear var/cache, var/page_cache and var/generation folders and in your browser run your controller like http://example.cpm/helloworld/ and you should see output Hello World! .

Leave a comment if you’re having issue making it work. In next tutorial I’ll be explaining how to create and use layout, block and template.


Handful git commands

I’m going to list out few helpful git commands here which might be very handy specially when you’re a noob like me with a thurst to learn a lot 😛

Few golden rules while you’re working with git.

#1. Always pull from remote repository before you push your files to remote.
#2. Use git status to see status of your local repo after/before pull/push.
#3. Generally we work on development branch rather than master branch. TL/PM should merge the files from development to master branch after reviewing them.
#3. You can create a branch if you’re working on a new module from scratch.
#4. You can draft (called stash) your changes in your local repo using git stash commands if you don’t want to push the changes now.


Register your identity in your local system using:

git config --global "user_name"
git config --global "user_email"

Git initialization

If you have created a new directory and want to initiate git in it

cd /path/to/my/directory
git init

Git Add and commit

If you’ve modified some files in your local repo, you need to add it to git before pushing to remote repo. Add a file to git using

git add <file_name>

Add all modifiled files to git using

git add . 
git add -A

Commit files using

git commit -m “commit message”

Note: Check the status using git status.

Git pull

git pull origin <branch_name>
Ex: git pull origin development

Git push

git push origin <branch_name>
Ex: git push origin development

Fixing git conflicts:

Check logs

If you see there are pull/push/merge conflicts and want to revert back to previus commits, use command git log to see log history and get commit id from it and afterwards reset it using

git reset <commit_id> 

It will update your repo with the code to the version when commit_id was commited.


When you initiate git in new directory using git init, automatically master branch will get created.Though if you want to create new branch you can use git checkout -b to create new branch and switch to newly created branch.

Use following commands to show list of branches

git branch 
git branch -a

If there is a branch with name branch_name on remote repo but not in your local repo. Use this command to update your local repo and switch to new branch:

git fetch && checkout <branch_name>

Merging branches

git checkout <base_branch>
git merge <branch_to_merge>

Stashing/Drafting your changes

Use following command to stash/draft your changes in local repo.

git stash

Use following command if you don’t want to keep changes or delete them:

git stash drop 

If you’ve modifed any local file, then added that file to gitignore, still you’ll see that file will be present in index (git status). You can clear your screen using below command

git update-index --assume-unchanged <file_name>

I’ll keep extending this list based on your suggestions and my experiences.

Magento: Export product attributes with category name and product URL

You can use following code to export product attributes, categories, and complete product URL link. Customize it according to your need.

require_once 'app/Mage.php';
// output headers so that the file is downloaded rather than displayed
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=data.csv');
// create a file pointer connected to the output stream
$output = fopen('php://output', 'w');
$userModel = Mage::getModel('admin/user');
$collection = Mage::getModel('catalog/product')
->addAttributeToSelect('*') //Select everything from the table
->addUrlRewrite(); //Generate nice URLs

fputcsv($output, array(
'sku', 'Category ', 'Color', 'url_key'

foreach($collection as $product) {
$_cat = array();
$categoryName = array();

foreach ($product->getCategoryIds() as $Id) {
$_cat = Mage::getModel('catalog/category')->setStoreId(Mage::app()->getStore()->getId())->load($Id);
$categoryName[] = $_cat->getName();
$color = array();
$color = implode(',', $product->getAttributeText('color'));
$comma_separated = implode(",", $categoryName);
fputcsv($output, array(

Prestashop – Customer data Export

In the previous tutorial Customer Password Migration – Prestashop to Magento, we were discussing about customer data migration from Prestashop to Magento. Through Prestashop admin panel, it’s not possible to export all customers data, so you need to write custom sql query to select all customer data in PHPMYADMIN and export CSV sheet.

Using following query you can select all customers who are having addresses.

select ps_customer.id_customer,, ps_customer.firstname,
ps_customer.lastname, ps_customer.passwd,,
ps_customer.birthday, ps_customer.newsletter,
ps_address.id_country, ps_address.id_state, ps_address.address1, ps_address.address2,
ps_address.postcode,,, ps_address.vat_number
from ps_customer INNER JOIN ps_address
ON ps_customer.id_customer=ps_address.id_customer;


Using following query you can select all customers who are not having addresses.

SELECT id_customer, email, firstname, lastname, passwd, company, birthday, newsletter
FROM ps_customer WHERE id_customer NOT IN (SELECT id_customer FROM ps_address);

Customize your query based on your need of customer attributes.

Customer Password Migration – Prestashop to Magento

To get the migrated passwords from Prestashop to Magento working, we need go through these 2 steps:

Step 1

Export customers from Prestashop.
In Prestashop, there is no straight forward method to export customers password, but you can always write your custom query to get the reuired information from database. Login to Prestashop admin section go to Advanced Parameters->SQL Manager and write a new sql query “select email, firstname, lastname, passwd from ps_customer; “ which will be used to select customers email id, firstname, lastname and password from customer table. If you want to select more fields, write your sql query accordingly. Afterwars export the information in csv file.

Step 2

The process through which Prestashop and Magento creates customer password is slightly different. Prestashop uses ‘Cookie Key’ prefix to the customer password, which is then MD5 encrypted. Magento uses MD5 and salt at the end. It’s not possible to convert passwords to plain text once it is encrypted using MD5 , so we need to rewrite customer authentication model to extend default validation process and validate passwords imported from Prestashop by adding prefix Cookie Key value to the passwords which was used to generate passwords in Prestashop.

Rewriting Mage_Customer_Model_Customer Model

1. Create a module with namespace Retailon and modulename Customerimport
2. Enable your Module in app/etc/modules/Retailon_Customerimport.xml

<?xml version="1.0"?>

3. Create config.xml file app/code/local/Retailon/Customerimport/etc/config.xml with following content:

<?xml version="1.0"?>

4. Create model file app/code/local/Retailon/Customerimport/Model/Customer.php with following content:

class Retailon_Customerimport_Model_Customer extends Mage_Customer_Model_Customer {

public function authenticate($login, $password)

if ($this->getConfirmation() && $this->isConfirmationRequired()) {
throw Mage::exception('Mage_Core', Mage::helper('customer')->__('This account is not confirmed.'),
if (!$this->validatePassword($password) && !$this->validatePassword('u4qrHpFiADz3peo8rS5tBkWARaa2WqN3qa7XqCI8iddIo7gdbj3KPNzGyK0'.$password)) {
throw Mage::exception('Mage_Core', Mage::helper('customer')->__('Invalid login or password.'),
Mage::dispatchEvent('customer_customer_authenticated', array(
'model' => $this,
'password' => $password,
return true;

5. You will see a long string prepended to the password variable in authenticate method, which is the cookie string used to generate passwords in Prestashop. Go to config/
file of your Prestashop project’s directory and you will see a line like

define('_COOKIE_KEY_', 'u4qrHpFiADz3peo8rS5tBkWARaa2WqN3qa7XqCI8iddIo7gdbj3KPNzGyK0'); 

Copy this string and replace the cookie sting of your Magento’s authenticate function.

That’s all you need to do. Now you should be able to login to Magento store using your Prestashop credentials.

In the next article Prestashop – Customer data Export, I’m going to write about How you can export customer data from Prestashop. Stay tuned.

Magento – Export last 3 months shipment information

Recently I was supposed to export shipping carrier, order number, shipment number and associated customer info of an order. Here goes the code:

SELECT orders.increment_id, grid.increment_id, grid.created_at, address.firstname, address.lastname,, track.track_number, title-- prior to 1.6 `track_number` should be `number`
FROM sales_flat_order AS orders
JOIN sales_flat_order_address AS address ON address.parent_id = orders.entity_id
JOIN sales_flat_shipment_grid AS grid ON grid.order_increment_id = orders.increment_id
JOIN sales_flat_shipment_track AS track ON track.order_id = orders.entity_id
WHERE address.address_type =  'shipping' and grid.created_at >= '2015-04-10'

Modify it according to your need and export the sheet.

Magento product list collection modification

According to Marius, events are always the best approach to modify and apply filter on product listing page. This way, your changes are independent of the presentation layer (theme). If you have 2 websites with different themes you will have all modifications in one place. Changing the template file may result in pagination problems.

I had a requirement to customize product listing (category) page such that if a configurable product is present, and even a single associated product for that configurable product is out of stock, configurable product should not appear in product listing (category) page.

I’ve created my own module and observer and customized it. Here goes the code:




<?xml version="1.0"?>



class Retailon_Configurable_Model_Observer {
* Observes the catalog_block_product_list_collection event
public function addInStockOnlyFilter($observer){
$productCollection = $observer->getEvent()->getCollection();

foreach ($productCollection as $product) {
if ($product->getTypeId() == "configurable"){
$product->getTypeInstance(true)->getUsedProducts ( null, $product);
foreach ($product->getTypeInstance(true)->getUsedProducts ( null, $product) as $simple) {
//all associated pro
if($simple->getStockItem()->getQty() < 1 ){
$proArray[] = $product->getId();
$stock = Mage::getModel('cataloginventory/stock_item')->loadByProduct($simple)->getQty();
echo $simple->getName()." with size ".$simple->getSize()." have a stock of ".$stock. " have sku "
.$simple->getSku()."Qty of ".$simple->getStockItem()->getQty();
echo '<br/>';

foreach ($proArray as $key) {