Monthly Archives: June 2009

Can u imagine !! how much data Magento load to show an order ?

I stuck-ed at office today just going to print_r an object !!

Today at 11.00AM, i entered in office and check mail. Than started my schedule work. I open a file and just wrote 2 lines code

print_r($this->getOrders());

and hit the browser url. Oh my god !! browser is loading and loading data. After 10 minutes i see browser is hanged !! Then i closed the browser. Again start browser and run the same url but no luck got the same result.

Now what can i do ? then i update code like this

 $orders = Mage::getResourceModel('sales/order_collection')
            //->addAttributeToSelect('*')
            ->joinAttribute('shipping_firstname', 'order_address/firstname', 'shipping_address_id', null, 'left')
            ->joinAttribute('shipping_lastname', 'order_address/lastname', 'shipping_address_id', null, 'left')
            ->addAttributeToFilter('customer_id', Mage::getSingleton('customer/session')->getCustomer()->getId())
            ->addAttributeToFilter('state', array('in' => Mage::getSingleton('sales/order_config')->getVisibleOnFrontStates()))
            ->addAttributeToSort('created_at', 'desc')
        ;

        $this->setOrders($orders);
        print_r($this->getOrders());

wowwwwww… now i got the data after 2 minutes !!

Here i see magento loaded around 10 thousands line data just to show a single order of a customer.

Then i again run below modified code

 $orders = Mage::getResourceModel('sales/order_collection')
            ->addAttributeToSelect('*')
            //->joinAttribute('shipping_firstname', 'order_address/firstname', 'shipping_address_id', null, 'left')
            //->joinAttribute('shipping_lastname', 'order_address/lastname', 'shipping_address_id', null, 'left')
            ->addAttributeToFilter('customer_id', Mage::getSingleton('customer/session')->getCustomer()->getId())
            //->addAttributeToFilter('state', array('in' => Mage::getSingleton('sales/order_config')->getVisibleOnFrontStates()))
            //->addAttributeToSort('created_at', 'desc')
        ;

        $this->setOrders($orders);
        print_r($this->getOrders());

Now i got result and copy that data from browser and paste in MS word file. To keep all data MS word take 2499 !! pages and file size is 12.8 MB !!

You believe it or not , i have just discovered the largest array of the world !! :)
If any guys know about larger array then you can challenge me. I am ready for your bouncer.

Download Doc

Create new module “HelloWorld” – in Magento

Do you want to create a new page in Magento ? or Do you want to create a new module in Magento ? If yes, Then ok, just spend 10 minutes and follow below steps.

Objectives: I will create a new page in Magento whose output will be “Hello World ! I am a Magento Guy..”.

Target: Create a new module called “HelloWorld”

Step 1: Module Declaration

Create app/etc/modules/M4U_HelloWorld.xml and write below code

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

Step 2: Module Configuration

a. Create a controller class app/code/local/M4U/HelloWorld/controllers/IndexController.php

class M4U_HelloWorld_IndexController extends Mage_Core_Controller_Front_Action
{
    public function indexAction()
    {
     $this->loadLayout(array('default'));
     $this->renderLayout();
    }
}

b. Create a Block class app/code/local/M4U/HelloWorld/Block/HelloWorld.php

class M4U_HelloWorld_Block_HelloWorld extends Mage_Core_Block_Template
{
  // necessary methods
}

c. create configuration xml in app/code/local/M4U/HelloWorld/etc/config.xml

<?xml version="1.0"?>
<config>
	<global>
		<modules>
                <m4u_helloworld>
                        <version>0.1.0</version>
                </m4u_helloworld>
        </modules>
	<blocks>
            <helloworld>
                <rewrite>
		 <helloworld>M4U_HelloWorld_Block_HelloWorld</helloworld>
		</rewrite>
            </helloworld>
	 </blocks>

        </global>
	   <frontend>
                <routers>
                        <helloworld>
                                <use>standard</use>
                                <args>
                                      <module>M4U_HelloWorld</module>
                                      <frontName>helloworld</frontName>
                                </args>
                        </helloworld>
                </routers>
		<layout>
			<updates>
				<helloworld>
		   		      <file>helloworld.xml</file>
				</helloworld>
			</updates>
       		</layout>
        </frontend>
</config>

Define Frontend Template :

1. Define page layout in app/design/frontend/M4U/default/layout/helloworld.xml

N.B: Use default instead of M4U as template location if you use default design packages. Means create file in app/design/frontend/default/default/layout/helloworld.xml

<?xml version="1.0"?>

	<layout version="0.1.0">

		<helloworld_index_index>
			<reference name="root">
				<action method="setTemplate"><template>page/1column.phtml</template></action>
       	 	</reference>
			<reference name="content">
            	<block type="helloworld/helloworld" name="hello" template="helloworld/helloworld.phtml"/>
        	</reference>
		</helloworld_index_index>

	</layout>

2. Create template file app/design/frontend/M4U/default/template/helloworld/helloworld.phtml and write down

N.B: Use default instead of M4U as template location if you use default design packages. Means create file in app/design/frontend/default/default/template/helloworld/helloworld.phtml

Hello World ! I am a Magento Guy..

Hey, new module is ready to run and hit browser with url http://127.0.0.1/projectname/index.php/helloworld/

and see result.

That’s it……..

Is it easy or not ? what you think ?

Coder, Please at first try yourself.

Ohh.., Still are you facing problem ? Lets download full module source code from left panel “BOX” section or let me know.

Note: I have upgraded HelloWorld module source code of BOX widget. So it will resolve the problem which was faced by some guys.

Create a new module in magento

When you need to add new functionality or want to edit existing magento class in both case you should create a new module. Suppose, you want to add “User Credit” system then you need to create a new UserCredit module in magento. And if you want to edit/update customer functionality  then you should follow magento override rules. To override existing Customer module you should create another new customer  module name M4U_Customer in local pool. In this case you need to use magento rewrite rules. When you go to add or edit something in magento,  each time you can be done as separate module or few methods can be combined in same module if they share functionality or could be used together.

Let’s create a module :

Module Declaration:
Create app/etc/modules/M4U_NewModule.xml and write below code

<?xml version="1.0"?>
<config>
         <modules>
<!-- declare CompanyName_NewModule module -->
           <M4U_NewModule>
<!-- this is an active module -->
                  <active>true</active>
<!-- this module will be located in app/code/local code pool -->
                  <codePool>local</codePool>
<!-- specify dependencies for correct module loading order -->
                  <depends>
                             <Mage_ExistingModule />
                  </depends>
<!-- declare module's version information for database updates -->
                  <version>0.1.0</version>
           </M4U_NewModule>
	</modules>
</config>

Here is example of create new M4U_customer module to override existing Mage_Customer module and M4U_Credit module to create new credit module.

<config>
    <modules>
        <M4U_Customer>
           <active>true</active>
           <codePool>local</codePool>
        </M4U_Customer>
        <M4U_Credit>
           <active>true</active>
           <codePool>local</codePool>
        </M4U_Credit>
    </modules>
</config>

Our new module will be called NewModule.

Replace all instances of ‘NewModule’ with name of your module and ‘newmodule’ with simplified code, that contains only alphanumeric characters and underscore.

To make this tutorial most concise, it’s implied that mentioned folders will be created when needed.

Module Configuration:

Create Model, Helper, coltrollers, Block, sql and etc folder under  app/code/local/M4U/NewModule/ and configure app/code/local/M4U/NewModule/etc/config.xml like below:

<?xml version="1.0"?>
   <config>
       <modules>
           <M4U_NewModule>
                 <version>0.1.0</version>
           </M4U_NewModule>
       </modules>

<!-- define Front end controller and template  -->
       <frontend>
<!-- define Front end controller  -->
           <routers>
               <newmodule>
                   <use>standard</use>
                   <args>
                          <module>M4U_NewModule</module>
                          <frontName>newmodule</frontName>
                   </args>
               </newmodule>
           </routers>
<!-- define Front end template xml -->
           <layout>
               <updates>
                    <newmodule>
                         <file>newmodule.xml</file>
                    </newmodule>
                </updates>
              </layout>
           </frontend>   

<!-- define blocks, models, helpers in global area -->
            <global>
               <models>
                  <newmodule>
                         <class>M4U_NewModule_Model</class>
                  </newmodule>
               </models>
               <blocks>
                  <newmodule>
                          <class>M4U_NewModule_Block</class>
                  </newmodule>
               </blocks>
               <helpers>
                  <newmodule>
                          <class>M4U_NewModule_Helper</class>
                  </newmodule>
               </helpers>

<!-- declare resource setup for new module -->
               <resources>
                    <newmodule_setup>
<!-- specify that this resource is a setup resource and used for upgrades -->
                       <setup>
<!-- which module to look for install/upgrade files in -->
                           <module>M4U_NewModule</module>
                       </setup>
<!-- specify database connection for this resource -->
                       <connection>
<!-- do not create new connection, use predefined core setup connection -->
                           <use>core_setup</use>
                       </connection>
                    </newmodule_setup>
                    <newmodule_write>
                         <connection>
                              <use>core_write</use>
                         </connection>
                    </newmodule_write>
                    <newmodule_read>
                         <connection>
                               <use>core_read</use>
                         </connection>
                    </newmodule_read>
                </resources>
           </global>
      </config>

Adapter Class:
To obtain module functionality you can write necessary method in various classes as magento convention.
1. Create necessary model class in app/code/local/M4U/NewModule/Model/
2. Create Block in app/code/local/M4U/NewModule/Block/
3. Create Helper in app/code/local/M4U/NewModule/Helper/
4. Place necessary updated database sql file in app/code/local/M4U/NewModule/sql/

Frontend Template Define:

1. Define page layout in app/design/frontend/M4U/default/layout/NewModule.xml

<?xml version="1.0"?>
   <layout version="0.1.0">
     <newmodule_index_usercredit>
        <reference name="root">
            <action method="setTemplate"><template>page/1column.phtml</template></action>
        </reference>
        <update handle="customer_account"/>
        <reference name="content">
            <block type="newmodule/blockClassName" name="usercredit" template="newmodule/usercredit.phtml"/>
        </reference>
     </newmodule_index_usercredit>
</layout>

2. Create template file app/design/frontend/M4U/default/template/newmodule/usercredit.phtml

Troubleshooting

  • Dont put your module in /Mage. It belongs in app/code/community/ or app/code/local/
  • Make sure your module’s first letter is capitlized. newmodule apparently will not work, it must start with a capital letter Newmodule.
  • If your module is not showing in configuration>advanced then check your config.xml
  • Make sure you clear the cache.

In this post i described general module customization theory of Magento. For more clarification you can see next post  “write HelloWord module” in this blog.

Magento Helper override rules

Sometimes Magento uses helper class to retrieve some of the help info such url, name, group etc. So you have to override helper class when you want to change any url or something else. Helper class override  is similar to block and model override. Here i described details about helper override with example.  Here i show how to override helper class Mage_Customer_Helper_Data.

1. At first create new module to process override work and write below code in app/etc/modules/M4U_Customer.xml

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

2. Do configuration in app/code/local/M4U/Customer/etc/config.xml

<?xml version="1.0"?>
    <config>
        <modules>
            <M4U_Customer>
                <version>0.1.0</version>
            </M4U_Customer>
        </modules>

        <global>
           <helpers>
              <customer>
                  <rewrite>
                      <data>M4U_Customer_Model_Customer</data>
                 </rewrite>
              </customer>
           </helpers>
        </global>
  </config>

3. Now write your new helper class M4U_Customer_Helper_Data and define all other override methods

class M4U_Customer_Helper_Data extends Mage_Customer_Helper_Data
{
   // override existing method
  * Retrieve customer register form post url
  public function getRegisterPostUrl()
    {
        return $this->_getUrl('customer/account/create2');
    }

    //write new function
    public function getRegisterPostUrl2()
    {
        return $this->_getUrl('customer/account/createpost');
    }
}

I think who is familiar with Magento override theory, helper override is easy for them. Just try your self. If you face any problem then just make a post. I will try to help you.

Magento Block override rules

Magento Block override rule is similar as helper and model override. Magento follows MVC pattern but Block is the extra layer in Magento. Block class render data for a particular template block. Magento introduces great blocking system in template design system.

Blocks are a way by which Magento distinguishes the array of functionalities in the system and creates a modular way to manage it from both visual and functional stand point. There are two types of blocks and they work together to create the visual output.

* Structural Blocks
These are blocks created for the sole purpose of assigning visual structure to a store page such as header, left column, main column and footer.
* Content Blocks
These are blocks that produce the actual content inside each structural block. They are representations of each feature functionality in a page and employs template files to generate (X)HTML to be inserted into its parent structural block. Category list, mini cart, product tags and product listing…etc are each its own content block.

Instead of including template after template as a typical eCommerce application would in order to gather the whole (X)HTML output, Magento gathers and arranges page content through blocks.

How to override a block ?:
Here i used Customer module as example. And here i describe various customer block class override system as example.
a) Customer register form block (Mage_Customer_Block_Form_Register)
b) Customer view form block (Mage_Customer_Block_Form_View)
c) Customer address edit block (Mage_Customer_Block_Address_Edit)
d) Customer account dashboard info block (Mage_Customer_Block_Account_Dashboard_Info)
e) Customer account dashboard address block (Mage_Customer_Block_Account_Dashboard_Address)
f) Customer widget name block (Mage_Customer_Block_Widget_Name)

Lets start step by step…………

1. At first create new module to process override work and write below code in app/etc/modules/M4U_Customer.xml

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

2. Configure in app/code/local/M4U/Customer/etc/config.xml. Here, I mention 5/6 block override syntax as example. Keep only those classes whose classes you want to override.

<?xml version="1.0"?>
    <config>
        <modules>
            <M4U_Customer>
                <version>0.1.0</version>
            </M4U_Customer>
        </modules>

        <global>
           <blocks>
              <customer>
                  <rewrite>
                      <form_register>M4U_Customer_Block_Form_Register</form_register>
                      <form_view>M4U_Customer_Block_Form_View</form_view>
                      <address_edit>M4U_Customer_Block_Address_Edit</address_edit>
                      <account_dashboard_address>M4U_Customer_Block_Account_Dashboard_Address</account_dashboard_address>
                      <account_dashboard_info>M4U_Customer_Block_Account_Dashboard_Info</account_dashboard_info>
                      <widget_addressname>M4U_Customer_Block_Widget_Name</widget_addressname>
                 </rewrite>
              </customer>
           </blocks>
        </global>
  </config>

3. Now write your new block class and define all override methods

a) Customer register form block override

class M4U_Customer_Block_Form_Register extends Mage_Customer_Block_Form_Register
{
   // override existing method
  //write new function
    public function newmethod()
    {
        return true;
    }
}

b) Customer view form block (Mage_Customer_Block_Form_View)

class M4U_Customer_Block_Form_View extends Mage_Customer_Block_Account_Dashboard
{
   // override existing method
  //write new function
    public function newmethod()
    {
        return true;
    }
}

c) Customer address edit block (Mage_Customer_Block_Address_Edit)

class M4U_Customer_Block_Address_Edit extends Mage_Customer_Block_Address_Edit
{
   // override existing method
  public function getAddressStatus()
   {
      return $this->getRequest()->getParam('address');
   }

  //write new function
    public function newmethod()
    {
        return true;
    }
}


d) Customer account dashboard info block (Mage_Customer_Block_Account_Dashboard_Info)

class M4U_Customer_Block_Account_Dashboard_Info extends Mage_Customer_Block_Account_Dashboard_Info
{
   // override existing method
  //write new function
    public function newmethod()
    {
        return true;
    }
}

e) Customer account dashboard address block (Mage_Customer_Block_Account_Dashboard_Address)

class M4U_Customer_Block_Account_Dashboard_Address extends Mage_Customer_Block_Account_Dashboard_Address
{
   // override existing method
  //write new function
    public function newmethod()
    {
        return true;
    }
}

f) Customer widget name block (Mage_Customer_Block_Widget_Name)

class M4U_Customer_Block_Widget_Name extends Mage_Customer_Block_Widget_Abstract
{
   // override existing method
  public function showMiddlename()
    {
        return $this->_showConfig('middlename_show');
    }

  //write new function
    public function newmethod()
    {
        return true;
    }
}

Magento Model override rules

I worked on various e-commerce open-source such x-cart, zen-cart but Magento is the special one for his great convention and high thought system. Override system was the great thinking of Magento team. Using Magento override rules you can can easily extends any Magento feature or can add new modules. Magento follows MVC pattern. Model is one of the main pattern of MVC. Usually model is used for database connectivity and for various logical coding. Mogento also use model for same purpose. Every module of Magento have his own model class. But you can extend or modify any existing model class by following Magento override rules.

Suppose, to fulfill your project requirements you need to change or enhance customer model class. You can change code in Mage_CUstomer_Model_Customer class. But it’s not a good practice of Magento customization and when upgrade your Magento version then there have a chance of remove your customized code. Means you will lost your changes. Really it will be pathetic for you !!!!! So we should follow magento override rules. Here i tried to clear how you can easily override your various model classes.

Override Customer Model class:

At first create new module to do override work and write below code in app/etc/modules/M4U_Customer.xml

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

Do configuration in app/code/local/M4U/Customer/etc/config.xml

<?xml version="1.0"?>
    <config>
        <modules>
            <M4U_Customer>
                <version>0.1.0</version>
            </M4U_Customer>
        </modules>

        <global>
           <models>
              <customer>
                  <rewrite>
                      <customer>M4U_Customer_Model_Customer</customer>
                 </rewrite>
              </customer>
           </models>
        </global>
  </config>

Now write your new model class M4U_Customer_Model_Cutomer and define all override method
class M4U_Customer_Model_Customer extends Mage_Customer_Model_Customer
{
   // override existing method
   public function validate()
    {
       // Define new validate rules. From now magento call this validate method instead of existing method
        //return $errors;
        return true;
    }

    // You can create new method as you needed.
    public function newMethod()
    {
       // function logic
    }
}

Override Address Model class :

Every thing is same as customer model override system. Just put a line in etc/config.xml.

<?xml version="1.0"?>
    <config>
        <modules>
            <M4U_Customer>
                <version>0.1.0</version>
            </M4U_Customer>
        </modules>

        <global>
           <models>
              <customer>
                  <rewrite>
                      <customer>M4U_Customer_Model_Customer</customer>
                      <address>M4U_Customer_Model_Address</address>
                  </rewrite>
              </customer>
           </models>
        </global>
  </config>

Now write your new model class M4U_Customer_Model_Address and define all override method
class M4U_Customer_Model_Address extends Mage_Customer_Model_Address
{
   // override existing method
   public function validate()
    {
       // Define new validate rules. From now magento call this validate method instead of existing method
        //return $errors;
        return true;
    }

    // You can create new method as you needed.
    public function newMethod()
    {
       // function logic
    }
}

Override Customer Entity Model class :

Define app/code/M4U/Customer/etc/config.xml like below. Here you will get clear concept how to override various model class in same xml.

<?xml version="1.0"?>
    <config>
        <modules>
            <M4U_Customer>
                <version>0.1.0</version>
            </M4U_Customer>
        </modules>

        <global>
           <models>
              <customer>
                  <rewrite>
                      <customer>M4U_Customer_Model_Customer</customer>
                      <address>M4U_Customer_Model_Address</address>
                  </rewrite>
              </customer>
              <customer_entity>
                  <rewrite>
                      <address>M4U_Customer_Model_Entity_Address</address>
                  </rewrite>
              </customer_entity>
           </models>
        </global>
  </config>

class M4U_Customer_Model_Entity_Address extends Mage_Customer_Model_Entity_Address
{
    protected function _afterSave(Varien_Object $address)
    {
        // Write your code
    }
}

Now just try your self. If you face any problem then make a post. I will try to help you.