Friday, March 23, 2012

A list of some useful code snippets for Magento developers


1. Check if customer is logged in:
if(!Mage::getSingleton('customer/session')->isLoggedIn())
{
 $this->_redirect('customer/account/login/');
}
2. Get current site url:
Mage::getUrl();
3. Get Category URL:
$categoryUrl = Mage::getModel('catalog/category')->load($categoryId)->getUrl();
4. Get product URL:
$productId = 1;
$product = Mage::getModel('catalog/product')->load($productId);
$path = Mage::getUrl().$product->getUrlPath();
5. Get Product image path:
$productId = 1;
$product = Mage::getModel('catalog/product')->load($productId);
$path = Mage::helper('catalog/image')->init($product, 'image')->resize(75, 75);
6. Format a number as price:
$this->formatPrice(10);
7. Call a .phtml explicitly:
echo $this->getLayout()->createBlock('sales/order_recent')->setTemplate('sales/order/recent.phtml')->toHtml();
8. Get Currency Code:
Mage::app()->getStore()->getCurrentCurrencyCode();
9. Get Currency Symbol:
Mage::app()->getLocale()->currency(Mage::app()->getStore()->getCurrentCurrencyCode())->getSymbol();
10. Get Customer Shipping/Billing Address:
$customerAddressId = Mage::getSingleton('customer/session')->getCustomer()->getDefaultShipping();
if ($customerAddressId){
       $address = Mage::getModel('customer/address')->load($customerAddressId);
}
11. Get all products in the cart:
$mageFilename = 'app/Mage.php';
require_once $mageFilename;
umask(0);
Mage::app();

// Secret Sauce - Initializes the Session for the FRONTEND
// Magento uses different sessions for 'frontend' and 'adminhtml'
Mage::getSingleton('core/session', array('name'=>'frontend'));

$session = Mage::getSingleton('checkout/session');
foreach ($session->getQuote()->getAllItems() as $item)
{
 $productid      = $item->getProductId();
 $name       = $item->getName();
 $qty       = $item->getQty();

 echo "Product Id-".$productid.', Name-'.$name. ', Quantity-'.$qty;
}
12. Find which class is loaded in current template:
<?php
    print_r(get_class_methods(get_class($this)));
?>
or
<?php
    print_r($this->debug());
?>
or
<?php
    echo Zend_Debug::dump($this);
?>
13. Get Current theme folder:
<?php echo $this->getSkinUrl('') ?>
14. Get total price of items in the cart:
<?php echo $this->helper('checkout')->formatPrice(Mage::getSingleton('checkout/cart')->getQuote()->getGrandTotal()); ?>
15. Get the current category:
<?php
    $currentCategory = Mage::registry('current_category');
?>
16. Add product to cart through querystring:
http://www.mydomain.com/checkout/cart/add?product=[id]&qty=[qty]
http://www.mydomain.com/checkout/cart/add?product=[id]&qty=[qty]&options[id]=[val

Improving PHP performance

I want to share these tips with my readers.

1. 'echo' is much faster than print. So always try echo something rather than printing it.

/*This is faster*/
echo 'This is echoed text';

/*This is slower*/
print 'This is printed text';

2. Always use the stacked form of echo instead of using concatenation. e.g

/*Faster form of echo*/
echo 'This is stacked form of ', $variable;

/*Slower form of echo*/
echo 'This is regular form of ' . $variable;

3. Use of single quotes rather than double quotes with echo can improve the performance of your code because compiler will not search for the variables inside the single quotes but in double quotes it will perform a search for possible variables.

/*Faster form of echo*/
echo 'This is single quoted string.';

/*Slower form of echo*/
echo "This is double quoted $string.";

4. Use pre-increments where possible instead of post-increments. Pre-incrementing is faster than post-increments.

/*Slower form of iteration*/
for ( $i=0; $i < 1000; $i++ ) {
echo 'Loop ',$i;
}

/*Faster form of iteration*/
for ( $i=0; $i < 1000; ++$i ) {
echo 'Loop ',$i;
}

5. Never use calculations as counters in an iteration.

/*Slower form of iteration*/
for ( $i=0; $i < count($arr); $i++ ) {
echo 'Loop ',$i;
}

/*Faster form of iteration*/
$counter = count($arr);

for ( $i=0; $i < $counter; $i++ ) {
echo 'Loop ',$i;
}

6. Always unset the variable after using those. It may save some of your resources on the server.

$counter = count($arr);

for ( $i=0; $i < $counter; $i++ ) {
$value = $arr[$i];

foo( $value );//call any function

unset($value);//unset the variable after using it.
}

7. Always initialize your variables before using those. It can sometimes prove beneficial in terms of performance.

$counter = count($arr);

$value = '';//initialize the variable before using it

for ( $i=0; $i < $counter; $i++ ) {
$value = $arr[$i];

foo( $value );//call any function

unset($value);//unset the variable after using it.
}

8. Always close the database connections after you are done with the queries.

mysql_connect('localhost', 'root', 'secret123');

mysql_select_db('test_db');

//write database queries here

mysql_close();//close the connection at the end

9. Avoid strlen() to check the length of a string. Checking the desired index in the string can also work.

/*Slower form*/
if ( strlen($str) > 100 ) {
echo 'You have crossed the limits';
}

/*Faster form*/
if ( $str[100] ) {
echo 'You have crossed the limits';
}

10. Use include() and require() instead of include_once() and require_once(). There's a lot of work involved in checking to see if a file has already been included. Sometimes it's necessary, but you should default to include() and require() in most situations.

11. Use full file paths on include/require statements. Normalizing a relative file path can be expensive; giving PHP the absolute path (or even "./file.inc") avoids the extra step.

12. Don't copy variables for no reason. Sometimes PHP novices attempt to make their code "cleaner" by copying predefined variables to variables with shorter names before working with them. What this actually results in is doubled memory consumption (when the variable is altered), and therefore, slow scripts. In the following example, if a user had inserted 512KB worth of characters into a textarea field. This implementation would result in nearly 1MB of memory being used.

/*Slower form*/
$description = strip_tags($_POST['description']);
echo $description;

/*Faster form*/
echo strip_tags($_POST['description']);

13. Avoid doing SQL queries within a loop. A common mistake is placing a SQL query inside of a loop. This results in multiple round trips to the database, and significantly slower scripts. In the example below, you can change the loop to build a single SQL query and insert all of your users at once.

foreach ($userList as $user) {
$query = 'INSERT INTO users (first_name,last_name) VALUES("' . $user['first_name'] . '", "' . $user['last_name'] . '")';
mysql_query($query);
}

Produces:

INSERT INTO users (first_name,last_name) VALUES("John", "Doe")

Instead of using a loop, you can combine the data into a single database query.

$userData = array();
foreach ($userList as $user) {
$userData[] = '("' . $user['first_name'] . '", "' . $user['last_name'] . '")';
}
$query = 'INSERT INTO users (first_name,last_name) VALUES' . implode(',', $userData);
mysql_query($query);

Produces:
INSERT INTO users (first_name,last_name) VALUES("John", "Doe"),("Jane", "Doe")...

14. Avoid OOP whenever you can. You should use OOP concepts only when these are really required. Study the situation you are working in. If you can do the things without OOP concepts, do it without hesitation. Using OOP for smaller tasks will always increase overhead rather than improving the performance. So the core concepts can help in most of the situations.'

15. Always strive for caching. Each time your request is processed by the server, the server has to reproduce the similar content repetitively. This wastes a lot of server resources just for nothing useful. So try to implement templating systems like 'Smarty'. It will always fasten your web application.

16. Using in built functions of PHP is many times faster than using custom build functions. So search the PHP manual thoroughly before writing your own function. Nearly every type of function is available in PHP.

Implementing alphabetical search in Magento

Create below mentioned files in the app/core/code/local directory with complete directory structure as in Magento core.

app\code\local\Mage\Catalog\Block\Product\List\Toolbar.php
In this file replace the setCollection function with following:

public function setCollection($collection)
    {
        $this->_collection = $collection;

        $this->_collection->setCurPage($this->getCurrentPage());

        // we need to set pagination only if passed value integer and more that 0
        $limit = (int)$this->getLimit();
  $postData = '';
        if ($limit) {
            $this->_collection->setPageSize($limit);
        }
        if ($this->getCurrentOrder()) 
  {
   /**********Alphabetic search Code Start From here**********/
   $postData = Mage::app()->getRequest()->getParam('alpha').'%';
   if(isset($postData['alpha']) && $postData['alpha']!= '' && trim($postData) !='ALL')
   {
    $this->_collection->setOrder($this->getCurrentOrder(), $this->getCurrentDirection())->addAttributeToFilter(array(
                    array('attribute'=>'name', 'like'=>$postData)
                ));
   }
   else
   {
      $this->_collection->setOrder($this->getCurrentOrder(), $this->getCurrentDirection());
   }
   /**********Alphabetic search Code ends here**********/
        }
        return $this;
    }
app\design\frontend\default\default\template\catalog\product\list\toolbar_bottom.phtml

Open this file an replace the code with given below:
<?php 
$search_array = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','ALL');

/*Find if the URL already contains any querystring variable or not */
if (strstr( $this->helper('core/url')->getCurrentUrl(), "&" ))
{
 $separator = '&'; 
}
else
{
    $separator = '?';
}
?>
    <div>
        <p class="view-mode-list-bot">
            <?php 
   $postData = Mage::app()->getRequest()->getParam('alpha');
   foreach ($search_array  as $search_array_value):
   
   /*Clean the URL*/
   if (strstr( $this->helper('core/url')->getCurrentUrl(), "?" ) )
   {
    $new_Url =  $this->str_replace_once('&','?',str_replace("?alpha=".trim($postData['alpha']),'',str_replace($separator."alpha=".trim($postData['alpha']),'',$this->helper('core/url')->getCurrentUrl())));
   }
   else
   {
    $new_Url = str_replace("?alpha=".trim($postData['alpha']),'',str_replace($separator."alpha=".trim($postData['alpha']),'',$this->helper('core/url')->getCurrentUrl()));
   }

   $alphaURL = $new_Url.$separator.'alpha='.$search_array_value;
?>
                
                    <a href="<?php echo $alphaURL; ?>" title="<?php echo $_label ?>" class="<?php echo strtolower($_code); ?> <?php if($search_array_value == $postData){ echo 'remove_under'; } ?>"><?php echo $search_array_value; ?></a>   
                
            <?php endforeach; ?>
           
        </p>
       
    </div>

Thursday, March 22, 2012

Magento : Add category attribute

There are following step
1.Create a new module under your local folder, in our case under /app/local/Bd/Customcategoryattribute.
2.Register the module in etc/modules directory Bd_Customcategoryattribute by using the following code

<?xml version="1.0"?>
<config>
  <modules>
    <Bd_Customcategoryattribute>
      <active>true</active>
      <codePool>local</codePool>
      <version>0.1.0</version>
    </Bd_Customcategoryattribute>
  </modules>
</config>
3.Create config.xml under etc directory of your module /app/local/Bd/Customcategoryattribute/etc/config.xml by using the following code

<?xml version="1.0"?>
<config>
  <modules>
    <Bd_Customcategoryattribute>
      <version>0.1.0</version>
    </Bd_Customcategoryattribute>
  </modules>
  <global>
    <helpers>
      <customcategoryattribute>
        <class>Bd_Customcategoryattribute_Helper</class>
      </customcategoryattribute>
    </helpers>
<models>
 <customcategoryattribute>
<class>Bd_Customcategoryattribute_Model</class>
<resourceModel>customcategoryattribute_mysql4</resourceModel>
 </customcategoryattribute>
</models>
<resources>
 <customcategoryattribute_setup>
<setup>
 <module>Bd_Customcategoryattribute</module>
 <class>Mage_Catalog_Model_Resource_Eav_Mysql4_Setup</class>
</setup>
<connection>
 <use>core_setup</use>
</connection>
 </customcategoryattribute_setup>
 <customcategoryattribute_write>
<connection>
 <use>core_write</use>
</connection>
 </customcategoryattribute_write>
 <customcategoryattribute_read>
<connection>
 <use>core_read</use>
</connection>
 </customcategoryattribute_read>
</resources>
  </global>
</config>
4.Create setup file mysql4-install-0.1.0 under sql directory of your module /app/local/Bd/Customcategoryattribute/sql/customcategoryattribute_setup/mysql4-install-0.1.0.php by using the following code

<?php
$installer = $this;
$installer->startSetup();
$installer->addAttribute("catalog_category", "custom_attribute",  array(
    "type"     => "varchar",
    "backend"  => "",
    "frontend" => "",
    "label"    => "Custom Attribute",
    "input"    => "text",
    "class"    => "",
    "source"   => "",
    "global"   => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
    "visible"  => true,
    "required" => false,
    "user_defined"  => false,
    "default" => "",
    "searchable" => false,
    "filterable" => false,
    "comparable" => false,
    "visible_on_front"  => false,
    "unique"     => false,
    "note"       => "Extra Attribute"
));
$installer->endSetup();
5. At last create helper Data.php under helper directory of your module /app/local/Bd/Customcategoryattribute/Helper/Data.php by using the following code
<?php class Bd_Customcategoryattribute_Helper_Data extends Mage_Core_Helper_Abstract { }  

Here, 
type:(realted to db)  varchar, text, datetime, int, etc.
input:(reated to frontend filed) text, textarea, date, select, multiselect, select, image

Please comment if u need about other properties. Thanks.


Remove Head Block From Page


You can either unset head block entirely, or just remove the script files. What you need to do is to create an observer on

controller_action_layout_render_before
event, and create this observer function:
public function removeHead()
{
 if (Mage::app()->getRequest()->getModuleName() == "lazyload") { //put your module/controller/action name here so you don't remove head for every single page
  $layout = Mage::getSingleton('core/layout');
  $layout->unsetBlock('head');

  /* second level of destruction - because this block has two lives .. like a final queen in an arcade */

  $head = $layout->getBlock('root')->getChild('head');
  if (is_object($head)) {
   $head->setData('items',array());
   $layout->getBlock('root')->setChild('head',$head);
  }

  /* third level of destruction - if the bitch respawns */
  //$layout->getBlock('root')->setChild('head', new Mage_Core_Block_Template);
 }
}

Friday, March 16, 2012

Useful code in Magento


Magento Home URL
- Mage::getBaseUrl();
 
Magento Home Directory
- Mage::getBaseDir();
 
URL of a file in the skin directory
- $this->getSkinUrl(‘images/myfile.png’); // in a template or Block
- Mage::getDesign()->getSkinUrl(‘images/myfile.png’); // from anywhere
 
Format a price value
- Mage::helper(‘core’)->formatPrice($amount);
 
Get the display value of a (multi-)select product attribute
- echo $product->getAttributeText(‘manufacturer’);
 
Create an object instance in magento
- Mage::getModel(‘module/class’);  // for models
- Mage::helper(‘module/class’); // for helpers
- Mage::app()->getLayout()->createBlock(‘module/class’, ‘name_in_layout’); // for blocks
 
GET/POST parameters
- Mage::app()->getRequest()->getParam(‘param_name’); // single parameter
- Mage::app()->getRequest()->getParams(); // all parameters
 
Get the Id of the curent store view
- Mage::app()->getStore()->getId();
 
Get all Store Views
- Mage::app()->getStores(); // pass true to include the admin store view, too
 
Get the configurable/grouped/bundled product a simple product belongs to
- $simpleProduct->loadParentProductIds();
- $parentProductIds = $simpleProduct->getParentProductIds();
 
Get the simple products assigned to a configurable product
$configProduct->getTypeInstance()->getUsedProductCollection($configProduct);
 
Get an instance of an attribute
Mage::getSingleton(‘eav/config’)->getAttribute($entityType, $attributeCode);

Online Visitors Magneto

You might have seen in Magento we have a section for seeing the online visitors at a given time.

<?php
//this code can be written directly in the template file
            $visitor_count = Mage::getModel('log/visitor_online')
            ->prepare()
            ->getCollection()->count();
 
        if(!empty($visitor_count) && $visitor_count > 0)
        {
            $cnt $visitor_count;
                echo 'Visitors online :'.$cnt;
        }
?>

Here is another way for doing this
<?php
//this code can be written directly in the template file
            $visitor_collection = Mage::getResourceModel('log/visitor_collection')->useOnlineFilter();
        $visitor_count = count($visitor_collection);
        if(!empty($visitor_count) && $visitor_count > 0)
        {
            $cnt $visitor_count;
                echo 'Visitors online :'.$cnt;
        
 
?>

Tuesday, March 13, 2012

How to Add Google Analytics on Magento from Admin


When your Magento Store is ready to sales then you should add Google Analytics to monitor your web site’s traffic and conversion ratio. Google Analytics is a free service of Google. Installing Google Analytics in Magento is so simple. If you want to add Google Analytics to your website, there is a nice way in Magento admin panel.
You can easily add Google Analytics from magento backend by some steps which are given below:
Step -1. First you need to sign up for your Google Analytics account here:
http://www.google.com/analytics/sign_up.html.
Step -2. Write down your Google Analytics account number since you will need it for the Magento configuration. e.g. – UA-xxxxxx-x
Step -3. Then Go: System -> Configuration Then selact Google API from under SALES of Left panel to configure the Google Analytics tracking.
Step -4. Now expand the “Google Analytics” section then select “Yes” form dropdown in Enable field and enter your Account Number in the Account Number field.

Step -5. Now Save the configuration by click on the “Save Config” Button and you’re done.
Note: It may take a few times to track and verify your web-store. To confirm about Receiving Data from your website, you can check the Tracking Status from your Google Analytics profile page.

How to activate iPhone Theme For Mobile Browsers on Magento


If you run your web store by using Magento e-commerce platform, you may know by default there is an iPhone theme in your web directory. This theme provides your web store to browse with full functionality on all modern mobile platforms.
You can configure this theme to display automatically when your customers browse your web store by using an iPhone, iPod or an Android browser. Otherwise they will see the default theme of your web store.
To enable iPhone theme for mobile browsers, you can follow some step which are given below:
Step 1. Go: System -> Configuration from Admin panel of your web store.
Step 2. Click on the Design tab from left panel.
Step 3.Expand the Themes options by click on the Themes tab

Step 4.Click on the Add Exception button from under Templates.  Then two new boxes will appear.
Step 5.  Enter iPhone|iPod|Android In the Matched Expression field.
Note:  In this step you can enter more mobile user agents such as Opera, Blackberry etc.
Step 6.  Enter iphone In the Value field.
Step 7.  Now repeat steps 4-6 for Skin (Images/CSS) and Layout field.

Step 8.  Then click the Save Config button from the right top. After that you should change the logos of your iPhone theme.
Now you are done. When any customer browse your web store by using an iPhone, iPod or an Android browser then he will see the iPhone theme.


How to get Previous & Next Product Buttons on Product view Page in Magento


To implement Previous & Next product button you have to edit view.phtml file which is located in:
app/design/frontend/your-instance-name/your-theme/template/catalog/product/view.phtml
If you not found view.phtml there then go:
app/design/frontend/base/default/template/catalog/product/view.phtml
Now open the view.phtml with any code editor. If you want to insert Previous & Next product button after the Product Name as me, then find the following code (line no:49 in version-1.5):
<div class="product-name">
    <h1><?php echo $_helper->productAttribute($_product, $_product->getName(), 'name') ?></h1>
</div>


<?php // Previous and Next product links in product page
$_product = $this->getProduct();
if(!$_product->getCategoryIds())
return; // Don't show Previous and Next if product is not in any category
$cat_ids = $_product->getCategoryIds(); // get all categories where the product is located
$cat = Mage::getModel('catalog/category')->load( $cat_ids[0] ); // load first category, you should enhance this, it works for me
$order = Mage::getStoreConfig('catalog/frontend/default_sort_by');
$direction = 'asc'; // asc or desc
$category_products = $cat->getProductCollection()->addAttributeToSort($order, $direction);
$category_products->addAttributeToFilter('status',1); // 1 or 2
$category_products->addAttributeToFilter('visibility',4); // 1.2.3.4
 $cat_prod_ids = $category_products->getAllIds(); // get all products from the category
$_product_id = $_product->getId();
$_pos = array_search($_product_id, $cat_prod_ids); // get position of current product
$_next_pos = $_pos+1;
$_prev_pos = $_pos-1;
 // get the next product url
if( isset($cat_prod_ids[$_next_pos]) ) {
$_next_prod = Mage::getModel('catalog/product')->load( $cat_prod_ids[$_next_pos] );
} else {
$_next_prod = Mage::getModel('catalog/product')->load( reset($cat_prod_ids) );
}
// get the previous product url
if( isset($cat_prod_ids[$_prev_pos]) ) {
$_prev_prod = Mage::getModel('catalog/product')->load( $cat_prod_ids[$_prev_pos] );
} else {
$_prev_prod = Mage::getModel('catalog/product')->load( end($cat_prod_ids) );
}
?>
 <div>
<?php if($_prev_prod != NULL): ?>
<a href="<?php print $_prev_prod->getUrlPath(); if($search_parameter):?>?search=1<?php endif;?>"><span><?php echo $this->__('PREVIOUS PRODUCT') ?></span></a>
<?php endif; ?>
<?php if($_next_prod != NULL): ?>
<a href="<?php print $_next_prod->getUrlPath(); if($search_parameter):?>?search=1<?php endif;?>"><span><?php echo $this->__('NEXT PRODUCT') ?></span></a>
<?php endif; ?>
</div>