Magento impotent tips

0
271
Magento: Clear all caches from command line
Create a file in your Magento root and name it clearCache.php with the below code: 
<?php
echo "Start Cleaning all caches at ... " . date("Y-m-d H:i:s") . "\n\n";
ini_set("display_errors", 1);

require 'app/Mage.php';
Mage::app('admin')->setUseSessionInUrl(false);
Mage::getConfig()->init();

$types = Mage::app()->getCacheInstance()->getTypes();

try {
    echo "Cleaning data cache... \n";
    flush();
    foreach ($types as $type => $data) {
        echo "Removing $type ... ";
        echo Mage::app()->getCacheInstance()->clean($data["tags"]) ? "Cache cleared!" : "There is some error!";
        echo "\n";
    }
} catch (exception $e) {
    die("[ERROR:" . $e->getMessage() . "]");
}

echo "\n";

try {
    echo "Cleaning stored cache... ";
    flush();
    echo Mage::app()->getCacheInstance()->clean() ? "Cache cleared!" : "There is some error!";
    echo "\n\n";
} catch (exception $e) {
    die("[ERROR:" . $e->getMessage() . "]");
}
?>

Magento continue shopping link to last added product’s category page

Put below code at the start of the checkout/cart.phtml file

$lastProductIdAddedToCart = Mage::getSingleton('checkout/session')->getLastAddedProductId();
if($lastProductIdAddedToCart) {
    $productCategoryIdsArray = Mage::getModel('catalog/product')->load($lastProductIdAddedToCart)->getCategoryIds();
    //print_r($productCategoryIdsArray);    
    $continueShoppingCategoryUrl = Mage::getModel('catalog/category')->load(end($productCategoryIdsArray))->getUrl();
}

Replace continue shopping button with below code, in the checkout/cart.phtml file

<?php if($this->getContinueShoppingUrl()): ?>
    <button type="button" title="<?php echo $this->__('Continue Shopping') ?>" class="button btn-continue" onclick="setLocation('<?php echo (isset($continueShoppingCategoryUrl)) ? $continueShoppingCategoryUrl : $this->getContinueShoppingUrl(); ?>')"><span><span><?php echo $this->__('Continue Shopping') ?></span></span></button>
<?php endif; ?>

Magento display categories and sub-categories

agento display categories and sub-categories. Below code will show all the parent and child categories along with show/hide functionalities by jQuery.


<div class=”block block-layered-nav”>

    <div class="block-title">
        <strong><span><?php echo $this->__('Shop By Category') ?></span></strong>
    </div>

        <div class="block-content">
        <?php $productid = Mage::registry('current_product')->getId();
        $product = Mage::getSingleton('catalog/product')->load($productid);
        $parentIds = $product->getCategoryIds();
        $parentId = $parentIds[0];
        $_categories = Mage::getBlockSingleton('catalog/navigation');
        foreach ($_categories->getStoreCategories() as $_category) {
                $category = Mage::getModel('catalog/category');
                $category->load($_category->getId());
                $subcategories = explode(',', $category->getChildren());
                if(!in_array($_category->getId(),$parentIds)) { $hide="display:none"; $inactive="inactive"; } else { $hide=""; $inactive="active"; }
                ?>
                <div style="padding:5px 5px 0px 10px">
                        <div class="cat parent <?php echo $inactive;?>" style="font-size:15px"><?php echo $_category->getName() ?></div>
                        <div class="child" style="<?php echo $hide;?>">
                         <?php foreach ($subcategories as $subcategoryId) {
                                $category->load($subcategoryId);
                                if($category->getChildren() == '') {
                                        if(in_array($subcategoryId,$parentIds)) { $bold = "font-weight:bold"; } else { $bold = ""; }
                                      echo '<div class="subcat" style="'.$bold.'"><a href="' . $category->getURL() . '">' . $category->getName() . '</a></div>';
                                 } else {?>
                                <div class="subcat">
                                        <div class="parent active"><?php echo $category->getName() ?></div>
                                        <div class="child">
                                        <?php $subsubcategories = explode(',', $category->getChildren());
                                        foreach($subsubcategories as $subsubcatid) {
                                                if(in_array($subsubcatid, $parentIds)) { $bold = "font-weight:bold"; } else { $bold = ""; }
                                                $category->load($subsubcatid);
                                                echo '<div style="padding-left:10px;'.$bold.'"><a href="' . $category->getURL() . '">' . $category->getName() . '</a></div>';
                                        } ?>
                                        </div>
                                </div>
                        <?php }
                        }
                        ?>
                        </div>
                </div>
                <?php

        } ?>
    </div>
</div>

<script type="text/javascript">
        jQuery('.block-content .cat').click(function(){
        var t = jQuery(this);
        if(jQuery(this).next().css('display')=='none') {
                jQuery('.col-left .block-content .child').hide();
                t.next().show(); t.next().find('div.child').show("slow");
        } else {
                t.next().hide(); t.next().find('div.child').hide("slow");
        }
        });
</script>

 

Magento enterprise: show top mini cart when product is added to cart

Magento Enterprise comes with a top header mini-cart, which displays all the items with their custom options added to cart, when you click on My Cart in the header. This is a good feature, but what if you want to show this mini-cart each time a product is added, without clicking on that link? I will show you here how to display your mini cart automatically when a product is added to cart.

Open your cartheader.php file, which is located at:
app/design/frontend/enterprise/YOUR_DESIGN/template/checkout/cart/cartheader.phtml

In the last few lines of this file, you should find the below line in javascript:

1
2
3
Enterprise.TopCart.initialize('topCartContent');
// Below can be used to show minicart after item added
// Enterprise.TopCart.showCart(7);

Replace the last line, //Enterprise.TopCart.showCart(7); with the below lines:

1
2
3
4
5
6
7
8
9
jQuery( document ).ready(function() {
    if( jQuery('#messages_product_view').children().length ){ 
        if(jQuery('#messages_product_view').children().children().attr('class') == 'success-msg') {
            if(jQuery('.success-msg ul li span').text().indexOf('was added to your shopping cart') > -1) {
                Enterprise.TopCart.showCart(7);
            }
        }
    }
});

So whenever in the page, there will be an element with ID “#messages_product_view” and it has a children with class “success-msg” and it has a ul/li/span with text containing “was added to your shopping cart”, we will show the top mini-cart. This is only true when an product is added to shopping cart.

Magento remove session id from URL

Magento displays session ID in url, something like:

1
http://loca.lho.st?__SID=2wewesfdgfsdm

You can remove this in two ways:

1. Go to your Magento admin panel > System > Configuration > Web.
Under Session Validation Settings, set “No” against label “Use SID on the Frontend”.
If this doesn’t work, then move to option two below.

2. Edit the file at app/code/core/Mage/Core/Model/App.php (somewhere around line 222),

1
protected $_useSessionInUrl = true;

Change that value to “false”. That should now prevent session IDs appearing in URL.

Magento debug XML (layout, config) files

In Magento if there is any error in XML file, Magento silently ignores it and continues further parsing. So you never get to know where is the actual error and makes it difficult to debug. You can’t even do any logging in XML file and also Magento don’t tell that error is in XML. It makes debugging almost impossible and ends up wasting in hours to find some silly mistake.

But we can know if there is any error in XML (layout.xml or config.xml or any xml file) if you use below code in the controller action which is being called. The browser will display WHOLE XML code and if it encounters any error in it, simply gives where is the error in the XML tree.

If you are trying to load let’s say Product View page, then put this code in Mage/Catalog/controllers/ProductController.php file’s viewAction() method temporarily to display whole XML tree to find out error(s) if any. As we are saying to display the page as XML, the page will break if it finds any mal-formed XML code and will show where is the mistake.

1
2
header("Content-Type: text/xml");
echo Mage::app()->getConfig()->getNode()->asXml();exit;

If you want to debug Layout Handles only, you can just check by this code:

1
2
header("Content-Type: text/xml");
echo Mage::app()->getLayout()->getUpdate()->getHandles();exit;

Magento delete empty categories and sub-categories

Remove all empty categories and sub-categories in Magento. When there are empty categories, the website shows empty page in those categories in frontend. Create a file in the magento root, I will name it rmvEmptyCats.php, with following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
require "app/Mage.php";
umask(0);
Mage::app();

$categoryCollection = Mage::getModel('catalog/category')->getCollection()
    ->addFieldToFilter('level', array('gteq' => 2)); //greater than root category id

foreach($categoryCollection as $category) {
    if ($category->getProductCount() === 0) {
        $category->delete();
    }
}

echo 'Empty Categories Deleted!';

Now you can easily run it by navigating to http://loca.lho.st/rmvEmptyCats.php and wait for the message Empty Categories Deleted!

Note that this is going to DELETE those categories with zero product count.

Magento convert attribute type from TEXT to DROPDOWN

Magento convert attribute type from TEXT (varchar) to DROPDOWN / SELECT (int) in Backend.
Magento doesn’t have this in-built so we will have to do it in our own way. We will convert our existing attribute which is in TEXT type, to DROPDOWN (select). Let’s say our attribute code is “vendor”, you will need to replace it with your own attribute code in all the code below.

WARNING: All the coupon codes that uses this attribute for discounts/promotions will GO AWAY! Please note down all the coupon code Conditions and Actions (which uses this attribute) before converting the attribute.

Step 1.) Backup your database.

1
mysqldump -u mysqluser -p mysqldbname > mysqldbname_backup.sql

Step 2.) Export all the values of the attribute you want to convert in a CSV file. For that, create a file vendor.php (your_attribute.php) in your magento root with following code inside it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
require "app/Mage.php";
umask(0);
Mage::app();

$collection = Mage::getModel('catalog/product')
                        ->getCollection()
                        ->addAttributeToSelect('sku')
                        ->addAttributeToSelect('vendor'); //replace vendor with your attribute code

$data = $collection->getData();

foreach ($data as $product) { 
    echo $product['entity_id'] . "," . $product['vendor']."\n";
}

After saving the above code, run it from command line:

1
php vendor.php > vendor.csv

You should now have all the attribute’s data with product ID in the vendor.csv (your_attribute.csv) file.

Step 3.) Now get all the unique values you have in the attribute’s data, which we will be filling them as options of select dropdown.
Run following mysql command to get all the unique values and copy them in a new file:

1
select distinct value from catalog_product_entity_varchar where attribute_id in (select attribute_id from eav_attribute where attribute_code='vendor'); //replace vendor with your own attribute code

After this step, we have all the attribute’s data in CSV file, and all the UNIQUE attribute values.

Magento how to remove order

First of all, removing live orders is not recommended. But if you are sure you want to remove orders (test orders?) then you can do so by custom script below. Get the order increment id(s) of the order you wish to delete from Magento. Remember, once order is deleted you can’t get any related information of that order.

Create a test PHP file in your Magento project root with below code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
require 'app/Mage.php';
Mage::app('admin')->setUseSessionInUrl(false);                                                                                      

$orderIncrementIDs = array('100000001','100000002'); //your order increment ids to delete, beware!
$rmvd = array();

foreach($orderIncrementIDs as $ordID){
    try{
        Mage::getModel('sales/order')->loadByIncrementId($ordID)->delete();
        $rmvd[] = $ordID;
    } catch(Exception $e){
        echo 'Error: '.$e->getMessage().'<br />';
    }
}
echo "Following Orders Removed!<br />" . implode(", ",$rmvd);

and run the file to delete the order(s).

Magento get current url with and without parameters

You can get the current page URL and it’s parameters (if any) by using getCurrentUrl() method in Magento. Below code will show you how to use it. Consider for example you have this url:

http://loca.lho.st/review/product/list/id/27/name/sony

To get this (current) URL in your module:

1
2
$currentUrl = $this->helper('core/url')->getCurrentUrl();
//Gives: http://loca.lho.st/review/product/list/id/27/name/sony

To get current URL parameters:

1
2
3
4
$params = $this->getRequest()->getParams(); //all the parameters
//Gives: Array ( [id] => 27 [name] => sony )
$param = $this->getRequest()->getParam('name'); //parameter "name"
//Gives: sony

To get only URL without parameters:

1
2
3
$request = $this->getRequest();
$urlWithoutParameters = $this->getBaseUrl() . $request->getRouteName() .DS. $request->getControllerName() .DS. $request->getActionName();
//Gives: http://loca.lho.st/review/product/list

Magento get all categories of a product

Get all the categories a product belongs to in Magento. Below code will get you all the categories with details the product is attached to. Product can be shown under more than one category, so you may get more than one category ID. Either get the category collection from product, or get all the category IDs and then load them using catalog category collection model.

1
//$_product = Mage::getModel('catalog/product')->load($productID);

First way,

1
2
3
4
5
6
$catCollection = $_product->getCategoryCollection();
foreach($catCollection as $cat){
  print_r($cat->getData());
  //echo $cat->getName();
  //echo $cat->getUrl();
}

Another way,

1
2
3
4
5
6
7
8
9
10
11
12
13
$catIds = $_product->getCategoryIds();
$catCollection = Mage::getResourceModel('catalog/category_collection')
                     //->addAttributeToSelect('name')
                     //->addAttributeToSelect('url')
                     ->addAttributeToSelect('*')
                     ->addAttributeToFilter('entity_id', $catIds)
                     ->addIsActiveFilter();

foreach($catCollection as $cat){
  print_r($cat->getData());
  //echo $cat->getName();
  //echo $cat->getUrl();
}

Magento tweak .htaccess for performance optimization

MAGENTOPERFORMANCE

Jul 19, 2013

kalpesh

No Comments

Magento tweak .htaccess for performance optimization

Share1

Tweak .htaccess for performance optimization in Magento. It will not sky rocket your website, but will show notable improvement. The default Magento .htaccess comes with performance optimization, but commented by default. I will show you here which lines to uncomment and improve the performance.

Compressing web pages with mod_deflate

The mod_deflate module allows the Apache2 web service to compress files and deliver them to browser that can handle them. With mod_deflate you can compress HTML, text or XML files by upto 70% of their original sizes! Thus, saving you server traffic and speeding up page loads.

Check your .htaccess file for below code, I have removed hashes before few lines to uncomment them for performance.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<IfModule mod_deflate.c>

############################################
## enable apache served files compression
## http://developer.yahoo.com/performance/rules.html#gzip

    # Insert filter on all content
    SetOutputFilter DEFLATE
    # Insert filter on selected content types only
    AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript

    # Netscape 4.x has some problems...
    BrowserMatch ^Mozilla/4 gzip-only-text/html

    # Netscape 4.06-4.08 have some more problems
    BrowserMatch ^Mozilla/4\.0[678] no-gzip

    # MSIE masquerades as Netscape, but it is fine
    BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

    # Don't compress images
    SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary

    # Make sure proxies don't deliver the wrong content
    Header append Vary User-Agent env=!dont-vary

</IfModule>

Enabling expires header with mod_expires

Make browser cache static files with Apache2’s mod_expires module.

1
2
3
4
5
6
7
8
9
10
<IfModule mod_expires.c>

############################################
## Add default Expires header
## http://developer.yahoo.com/performance/rules.html#expires

        ExpiresActive On
    ExpiresDefault "access plus 1 year"

</IfModule>

Magento get attribute options

Get attribute options list i.e. label and value, if the attribute type is dropdown.

This post will show you how to get all the options of attribute with dropdown type in Magento. If your attribute has options, below code will give all the attribute options labels and values in an array format.

1
2
3
4
5
6
7
$attribute = Mage::getSingleton('eav/config')->getAttribute('catalog_product', 'shirt_size'); //change shirt_size to your attribute code
if ($attribute->usesSource()) {
    $options = $attribute->getSource()->getAllOptions(false);
    foreach($options as $option) {
        print_r($option);
    }
}

In the above code, first line will initialize the attribute. Then we are checking if the attribute is using source model or not, if using then get all the options of that attribute.

It will output this for attribute shirt_size:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Array
(
    [value] => 100
    [label] => Small
)
Array
(
    [value] => 99
    [label] => Medium
)
Array
(
    [value] => 98
    [label] => Large
)

If you are here to get attribute option’s label from value OR get attribute option’s value from label

Magento get attribute value

To get product attribute value in Magento is very common. You will need it everytime when dealing with catalog products in your development. Attributes have different types, which can be any of Text Field, Text Area, Date, Yes/No, Multiple Select, Dropdown, Price, Gallery, Media Image, Fixed Product Tax (as you can see in backend Manage Attributes > New Attribute > Catalog Input Type for Store Owner). To get the value for these different types of attributes there is no one straight line of code, you will need to use different code for getting values from plain attributes, while different code to get values from select and multiselect attributes.

Get attribute value for PLAIN TEXT, TEXTAREA or DATE type attribute:

1
$attribute_value = $product->getShirtSize(); //for shirt_size attribute

Get value from SELECT, MULTISELECT, DROPDOWN or YES/NO attributes:

1
$attribute_value = $product->getAttributeText($attribute_code);

OR

1
$attribute_value = $product->getResource()->getAttribute($attribute_code)->getFrontend()->getValue($product);

Get value from PRICE attributes:

1
$attribute_value = $product->getNew_price(); //for attribute code "new_price"

and in product list page,

1
$attribute_value = $product->getNewPrice();

Get attribute value by attribute code and productID WITHOUT loading whole product

1
$attribute_value = Mage::getResourceModel('catalog/product')->getAttributeRawValue($product_id, $attribute_code, $store_id);

Magento get attribute label

To get attribute label for the product in Magento is not that straight-forward as we do for getting attribute value. You will need attribute code and product object to get the attribute label as shown below.

If you have the product object, you can use it to get the attribute’s label..

1
$label = $product->getResource()->getAttribute($attribute_code)->getFrontend()->getLabel($product);

For the current/selected store view..

1
$label = $product->getResource()->getAttribute($attribute_code)->getStoreLabel();

This will output you the label of the attribute associated with the attribute code you passed for that product. E.g. Shirt Size, Color, etc..

To get select/dropdown attribute label by value OR to get select/dropdown attribute value by label

Magento get list of all product attributes

Get list of all the product attributes defined in Magento. This will fetch you an array with all the attribute codes as a key AND all the attribute details including attribute code as a value. You can limit this array by just attribute code and attribute label as per your need. I will show you all the possible attribute information you can fetch defined for the product.

1
2
3
4
5
6
7
$attrib_data = array(); $allAttributeCodes = array();
$attributes = Mage::getResourceModel('catalog/product_attribute_collection')->getItems();

foreach ($attributes as $attribute){
    $attrib_data[$attribute->getAttributeCode()] = $attribute->getData();
    //$allAttributeCodes[] = $attribute->getAttributeCode();

Magento filter products by status

Get all the products with status equal to enabled/disabled.

If you are using Flat Catalog in Magento, you will not get disabled products by this filter as in flat table all the products are only enabled one. You can check if your Magento website uses flat catalog or not by going here:
Admin > System > Configuration > Catalog section > Catalog > Frontend

Check Use Flat Catalog Category and Use Flat Catalog Product, if they are Yes it means you are using flat catalog, if they are No it means you are NOT using flat catalog.

So, if you don’t have flat catalog enabled and you want to filter all the products with status equal to disabled, you can use below code:

1
2
3
4
5
6
7
8
$products = Mage::getModel('catalog/category')->load($category_id)
->getProductCollection()
->addAttributeToSelect('*') //whatever attributes you want to get here
->addAttributeToFilter(
    'status',
    array('eq' => Mage_Catalog_Model_Product_Status::STATUS_DISABLED) 
        //replace DISABLED to ENABLED for products with status enabled
);

Magento disable guest checkout / enable guest checkout

 

By default the guest checkout in Magento is enabled and visitors can place an order without registering to the website. Some websites require mandatory login for placing orders, and this default feature should be turned off to disallow guest checkout.

To disable guest checkout, navigate to:

System > Configuration > Sales section > Checkout > Checkout Options
Set 
Allow Guest Checkout to No

This will now disable any guest checkout in your site.
To enable guest checkout, simply set the above dropdown option to 
Yes.

Magento get subcategories of a category by category ID

Get all the subcategories of any category in Magento.

If you have a category ID (current category OR any category) then you can easily get all the subcategories of that particular category.

Below code will load all the subcategories of the current category. You can even get all the subcategories of any specific category by assigning category ID to $catID.

1
2
3
4
5
6
7
8
$catID = $current_category->getId(); //or any specific category id, e.g. 5
$children = Mage::getModel('catalog/category')->getCategories($catID);
foreach ($children as $category) {
        echo $category->getId();
        echo $category->getName();
        echo $category->getRequestPath();
        print_r($category->getData());
}

Magento add attribute to category

Adding category attribute in Magento is same as we add for product and customer. Here in this post I will create a custom module which will add your new custom category attribute in Magento. So let’s start with the module:

1.) As usual, create an XML file in app/etc/modules/ directory, I will name it Namespace_Module.xml
Paste below code in it changing the Namespace and Module as you want.

1
2
3
4
5
6
7
8
9
< ?xml version="1.0"?>
<config>
    <modules>
        <namespace_module>
            <active>true</active>
            <codepool>local</codepool>
        </namespace_module>
    </modules>
</config>

2.) Second step would be to create a file config.xml in app/code/local/Namespace/Module/etc/ directory. Create all the directories required get there. Paste the below code in it making sure you have changed Namespace and Module with your naming.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
< ?xml version="1.0"?>
<config>
    <modules>
        <namespace_module>
            <version>0.0.1</version>
        </namespace_module>
    </modules>
 
    <global>
        <resources>
            <module>
                <setup>
                    <module>Namespace_Module</module>
                    <class>Mage_Catalog_Model_Resource_Eav_Mysql4_Setup</class>
                </setup>
                <connection>
                    <use>core_setup</use>
                </connection>
            </module>
            <module_write>
                <connection>
                    <use>core_write</use>
                </connection>
            </module_write>
            <module_read>
                <connection>
                    <use>core_read</use>
                </connection>
            </module_read>
        </resources>
    </global>
</config>

I have only included setup class and connections as those are the only things we will need to execute our script which will insert the custom attribute to category in our Magento project.

Magento add attribute to customer

In Magento to add an attribute to customer is not an option in the admin panel like it does have for Product attribute. So you have to end up writing the script that will add your custom attribute in customer’s EAV tables.

Below code will insert your custom customer attribute in Magento system. You can even specify whil creating the attribute whether that attribute should appear in the forms (like register/signup) or not.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$installer = $this;
$installer->startSetup();

$setup = new Mage_Eav_Model_Entity_Setup('core_setup');

$entityTypeId     = $setup->getEntityTypeId('customer');
$attributeSetId   = $setup->getDefaultAttributeSetId($entityTypeId);
$attributeGroupId = $setup->getDefaultAttributeGroupId($entityTypeId, $attributeSetId);

$setup->addAttribute('customer', 'your_attribute_code_here', array(
    'input'         => 'text', //or select or whatever you like
    'type'          => 'int', //or varchar or anything you want it
    'label'         => 'Attribute description goes here',
    'visible'       => 1,
    'required'      => 0, //mandatory? then 1
    'user_defined' => 1,
));

$setup->addAttributeToGroup(
 $entityTypeId,
 $attributeSetId,
 $attributeGroupId,
 'your_attribute_code_here',
 '100'
);

$oAttribute = Mage::getSingleton('eav/config')->getAttribute('customer', 'your_attribute_code_here');
$oAttribute->setData('used_in_forms', array('adminhtml_customer')); 
$oAttribute->save();

$setup->endSetup();

Here we have used our custom attribute’s:
– 
input type as text, but you can have it anything you like to appear in the form. It can be textarea, date, select or anything you want.
– data 
type as int, but you can have it anything from text, datetime, varchar or decimal. Remember customer is EAV in Magento, so it needs this information to store all the future values of this attribute in customer_entity_int (customer_entity_*) table.

Magento get products by attribute set id or name

In Magento get all the products by specific attribute set ID or Name with below code snippet. If you want to get products by attribute set Name, then first get the attribute set ID from name as shown in the first 4 lines of code. If you already have attribute set ID, ignore first 4 lines of code as it is only used if you have attribute set Name and not it’s ID.

The resultant array will give you all the products with all the attributes and values. You can narrow the attributes that you only need by specifying them when you call $products->addAttributeToSelect(*) or when you get all data from product $prod->getData().

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//If planning to get all products by attribute set NAME
$attrSetName = 'your_attribute_set_name_here';
$attributeSetId = Mage::getModel('eav/entity_attribute_set')
    ->load($attrSetName, 'attribute_set_name')
    ->getAttributeSetId();

//If planning to get all products by attribute set ID
$attributeSetId = 'your_attribute_set_id_here';

$products = Mage::getModel('catalog/product')->getCollection();
$products->addAttributeToFilter('attribute_set_id',$attributeSetId);

$products->addAttributeToSelect('*');

$products->load();
foreach($products as $prod) {
        $productsArray[] = $prod->getData(); //get all data or specify any attribute
}

Mage::log($productsArray());

Magento get all invoices and shipments of an order

$order = Mage::getModel('sales/order')->load($orderID);
if ($order->hasInvoices()) {
    $invIncrementIDs = array();
    foreach ($order->getInvoiceCollection() as $inv) {
        $invIncrementIDs[] = $inv->getIncrementId();
    //other invoice details...
    } Mage::log($invIncrementIDs);
}

Getting all the shipments of an order:

1
2
3
4
5
$order = Mage::getModel('sales/order')->load($orderID);
foreach($order->getShipmentsCollection() as $shipment)
{
    Mage::log($shipment->getData()); //get each shipment data here...
}

Magento join EAV collection with Flat table

Joining tables in Magento when it comes to EAV with Flat table is quite complicated. Consider you want to join sales_flat_order table with customer EAV tables to get Customer’s firstname and lastname, it becomes difficult as customer’s name comes from customer_entity_varchar table.

Below code will join sales order flat table with customer EAV to get customer’s full name in the collection along with all the order details.

1
2
3
4
5
6
7
8
9
10
11
12
13
$coll = Mage::getModel('sales/order')->getCollection();

$fn = Mage::getModel('eav/entity_attribute')->loadByCode('1', 'firstname');
$ln = Mage::getModel('eav/entity_attribute')->loadByCode('1', 'lastname');

$coll->getSelect()
    ->join(array('ce1' => 'customer_entity_varchar'), 'ce1.entity_id=main_table.customer_id', array('firstname' => 'value'))
    ->where('ce1.attribute_id='.$fn->getAttributeId()) 
    ->join(array('ce2' => 'customer_entity_varchar'), 'ce2.entity_id=main_table.customer_id', array('lastname' => 'value'))
    ->where('ce2.attribute_id='.$ln->getAttributeId()) 
    ->columns(new Zend_Db_Expr("CONCAT(`ce1`.`value`, ' ',`ce2`.`value`) AS fullname"));

print_r($coll->getData());

Magento: Check if any particular customer is currently logged in

Let’s say you want to check if any particular customer is currently logged in to your site or not. Or let’s check how many customers with their customer IDs and other activities are online on your store.

This little script will help you in finding all the currently active OR any particular customer(s) active in your store.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
require "app/Mage.php";
umask(0);
Mage::app();

$collection = Mage::getModel('log/visitor_online')->prepare()->getCollection();

//Get all the customers that are logged in......
foreach($collection->getData() as $cust) {
        echo 'Customer ID: '.$cust['customer_id'] . '<br/>';
        echo 'Last URL visited: '.$cust['last_url'] . '<br/>';
        echo 'First visit: '.$cust['first_visit_at'] . '<br/>';
        echo 'Last visit: '.$cust['last_visit_at'] . '<br/>';
        echo '======================<br/>';
}

//Get any particular customer, if he's currently logged in or not.....
$collection->addFieldToFilter('customer_id', 5)->addCustomerData(); //5 is customer ID of customer you want to check
if($collection->count()) {
    echo 'Customer is logged in';
} else {
    echo 'Customer is NOT logged in';
}

Magento Special price products page

Magento special price products page. We will be creating a new CMS page that will display all the Special or Sale products. We can make a product as a Special by filling it’s “Special From” and “Special To” price in “Prices” tab in Manage Products individual screen.

So let’s first create CMS Page, by going to CMS > Pages, which we will name it as “Specials”. In the Content tab of that Page, paste the below line of code:

1
{{block type="catalog/product_special" template="catalog/product/list.phtml" column_count="3" num_products="0"}}

and save the page.

Here we are saying Magento to display Product List template by looking at our new block type file, Catalog/Product/Block/Special.php. So let’s create this file, Special.php in local/Mage/Catalog/Product/Block/ directory. You will have to create this directory path if it’s not already there.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php
class Mage_Catalog_Block_Product_Special extends Mage_Catalog_Block_Product_List
{
    protected function _getProductCollection()
    {
        if (is_null($this->_productCollection)) {
            $categoryID = $this->getCategoryId();
            if($categoryID)
            {
              $category = new Mage_Catalog_Model_Category();
              $category->load($categoryID); // this is category id
              $collection = $category->getProductCollection();
            } else
            {
              $collection = Mage::getResourceModel('catalog/product_collection');
            }
             
            $todayDate = date('m/d/y');
            $tomorrow = mktime(0, 0, 0, date('m'), date('d')+1, date('y'));
            $tomorrowDate = date('m/d/y', $tomorrow);
             
            Mage::getModel('catalog/layer')->prepareProductCollection($collection);
            $collection->addAttributeToSort('created_at', 'desc');
            $collection->addStoreFilter();
             
            $collection->addAttributeToFilter('special_from_date', array('date' => true, 'to' => $todayDate))
                ->addAttributeToFilter('special_to_date', array('or'=> array(
                0 => array('date' => true, 'from' => $tomorrowDate),
                1 => array('is' => new Zend_Db_Expr('null')))
                ), 'left');
             
             
            $numProducts = $this->getNumProducts() ? $this->getNumProducts() : 0;
            $collection->setPage(1, $numProducts)->load();
  
            $this->_productCollection = $collection;
        }
        return $this->_productCollection;
    }
}

Change default length of Increment ID for orders, invoices, shipments, creditmemos

By default in Magento CE 1.6, the default Increment ID of orders, invoices, shipments and creditmemos is 9 characters. If you want to make it short or long due to some other application dependency or whatever you will have to change the value of increment_pad_length in eav_entity_type table.

For changing it with some setup script installer, this code will do the trick:

1
2
$entityType = Mage::getModel('eav/entity_type')->loadByCode('order'); //invoice, shipment, creditmemo
$entityType->setIncrementPadLength(12)->save(); //changing length to 12

For changing it directly in database table, execute this queries:

1
2
3
4
UPDATE `eav_entity_type` SET `increment_pad_length`= 12 WHERE entity_type_code = 'order';
UPDATE `eav_entity_type` SET `increment_pad_length`= 12 WHERE entity_type_code = 'invoice';
UPDATE `eav_entity_type` SET `increment_pad_length`= 12 WHERE entity_type_code = 'shipment';
UPDATE `eav_entity_type` SET `increment_pad_length`= 12 WHERE entity_type_code = 'creditmemo';

Magento: Design Patterns

Factory:

It implement the concept of factories and deals with the problem of creating objects without specifying the exact class of object that will be created.

1
$product = Mage::getModel('catalog/product');

Singleton:

It restricts the instantiation of a class to one object. It will refer to same object each time called.

1
$category = Mage::getSingleton('catalog/session');

Registry:

It is a way to store information throughout your application.

1
2
Mage::register('key',$value); //stores
$currentCategory = Mage::registry('key'); //retrives

Prototype:

It determines the type of object to create. In Magento it can be Simple, Configurable, Grouped, Bundle, Downloadable or Virtual types.

1
Mage:getModel('catalog/product')->getTypeInstance();

Observer:

It is mainly used to implement distributed event handling systems. Here the subject maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.

1
Mage::dispatchEvent('event_name', array('key'=>$value));

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<config>
    <global>
        <events>
            <event_name>
                <observers>
                    <unique_name>
                        <class>Class_Name</class>
                        <method>methodName</method>
                    </unique_name>
                </observers>
            </event_name>
        </events>
    </global>
</config>


Object Pool:

It is used to reuse and share objects that are expensive to create.

1
2
$id = Mage::objects()->save($object);
$object = Mage::objects($id);

Iterator:

It is used to traverse a collection and access the collection’s items.

1
Mage::getModel('catalog/product')->getCollection();

Lazy Loading:

It is used to defer initialization of an object until the point at which it is needed.

1
2
$collection_of_products = Mage::getModel('catalog/product')
->getCollection();

Decorator:

It is used to extend or modify the behaviour of an object at runtime.

1
<script type="text/javascript">decorateTable('product_comparison');</script>

Helper:

Multiple methods are available for use by other objects. Here you can use core’s helper methods from anywhere in the application.

1
Mage::helper('core');

Service Locator:

Allows overrides or renamed physical resources (e.g. Classes, DB tables, etc)

1
Mage::getModel('catalog/product') and $installer->getTable('customer/address_entity');

Magento: Add product custom attribute options dynamically

Once you have the product attributes in place, and you want to add lot of options to these attributes it becomes time consuming and hectic task. If you have only few attribute options to add, it’s easy to go to backend and add manually. But if you have many attribute options, more than 10 options for many attributes, it’s very tiresome and feels like data entry job. Magento is not built to do stuff manually, so here I will provide you the code snippet which will push all the attribute options to their respective attribute.

Create a file in the root of your Magento installation and copy this code there. I generally name it test.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
require_once 'app/Mage.php';
umask(0);
Mage::app('default');

$installer = new Mage_Eav_Model_Entity_Setup('core_setup');
$installer->startSetup();

//Change this....
$aColors = array('PINK','BLACK','BLUE','BROWN','GOLD','GRAY','GREEN','MULTI','NEUTRALS/CREAM/WHITE','ORANGE','PURPLE','RED','RUST','TAUPE','YELLOW');
$attrCode = 'color'; //this should be there already
//........

$aColors = array_map('utf8_encode',$aColors); //If you're using special characters
$iProductEntityTypeId = Mage::getModel('catalog/product')->getResource()->getTypeId();
$aOption = array();
$aOption['attribute_id'] = $installer->getAttributeId($iProductEntityTypeId, $attrCode);

for($iCount=0;$iCount<sizeof($aColors);$iCount++){
   $aOption['value']['option'.$iCount][0] = $aColors[$iCount];
}
$installer->addAttributeOption($aOption);

$installer->endSetup();

Now you just need to give the existing product attribute name AND future attribute options to this script. Run it and rest all script will do for you! ?

Magento: Create database backups daily programatically by cron

It’s a good practice to create your database backup every day/week. But to manually go to Magento admin and create backup daily is a cumbersome process. You can’t guarantee that your database will be secure especially if you are on a cloud storage. Backups are MUST and if it’s automated, life becomes very easier.

This code will create backup of your Magento DB and place it to var/backups directory.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public function backup()
{
    try {

        $backupDb = Mage::getModel('backup/db');
        $backup   = Mage::getModel('backup/backup')
            ->setTime(time())
            ->setType('db')
            ->setPath(Mage::getBaseDir("var") . DS . "backups");

        $backupDb->createBackup($backup);

        return Mage::helper('core')->__('Backup successfully created');

    } catch (Exception  $e) {
        Mage::logException($e);
    }

    return $this;
}


Now, you can set the cron to run every midnight and call this above method to automatically create your DB backups. Sounds good? But there is a problem. As Magento DB size is huge, running daily/weekly backups will soon fill up your hardrives like hell.

So, we will now first create new DB database backup through our above method, and after it’s created we will delete the older backups just to free up the disk space.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public function endsWith($haystack, $needle)
{
    $length = strlen($needle);
    if ($length == 0) {
        return true;
    }

    return (substr($haystack, -$length) === $needle);
}

public function backup()
{

    //get all the older db backup files in an array
    $filelist = array();
    if ($handle = opendir(Mage::getBaseDir('var') . DS . "backups" . DS)) {
        while ($entry = readdir($handle)) {
            if ($this->endsWith($entry, "_db.gz")) {
                $filelist[] = $entry;
            }
        }
        closedir($handle);
    }

    try {
        //create the db backup
        $backupDb = Mage::getModel('backup/db');
        $backup   = Mage::getModel('backup/backup')
            ->setTime(time())
            ->setType('db')
            ->setPath(Mage::getBaseDir("var") . DS . "backups");

        $backupDb->createBackup($backup);

        //delete all older db backup files we found
        foreach((array)$filelist as $fileToDelete) {
                unlink(Mage::getBaseDir("var") . DS . "backups" . DS . $fileToDelete);
        }

        return Mage::helper('core')->__('Backup successfully created');

    } catch (Exception  $e) {
        Mage::logException($e);
    }

    return $this;
}

Now you can set the CRON to run the file every midnight, which calls the above backup() method. You will now get daily fresh backups replacing the old ones ?

If you are not sure how to create a cron, check this link: http://www.magentocommerce.com/wiki/1_-_installation_and_configuration/how_to_setup_a_cron_job

Magento: Add additional product/item attributes in order and invoice emails

Recently I was working with a German client, who wanted to show additional product attribute options in the order and invoice emails due to stricter law for e-commerce in their country. Magento provides basic information in the default email templates, but each store has their unique requirement to show additional information.

I will show you how to add extra product attribute values, along with order item options and custom options in order emails and invoice emails.

Here is the code that should work for order and invoice emails to get additional PRODUCT ATTRIBUTES displayed:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$productId = $_item->getProduct()->getId(); //for order emails
//$productId = $_item->getProductId(); //for invoice emails
$product = Mage::getModel('catalog/product')->load($productId);
$attributes = $product->getAttributes();

//Get a list of all PRODUCT ATTRIBUTES you want to show in this array...
$dispAttribs = array('hardrive', 'memory', 'processor'); 

foreach ($attributes as $attribute) {    
        $attributeCode = $attribute->getAttributeCode();
        if(!in_array($attributeCode, $dispAttribs)) continue;
        $label = $attribute->getFrontend()->getLabel($product);
        $value = $attribute->getFrontend()->getValue($product); 
        echo "<br /><strong>" . $label . ":</strong> " . $value;
}


For displaying CUSTOM OPTIONS and/or ITEM OPTIONS from the item, use this:

1
2
3
4
5
6
7
foreach($this->getItemOptions() as $opt) {
    if(isset($opt['option_id'])) { //for CUSTOM OPTIONS
            echo "<strong>" . $opt['label'] . ":</strong> ". $opt['option_value'] . "<br />";
    } else { //for ITEM OPTIONS
            echo "<strong>" . $opt['label'] . ":</strong> ". $opt['value'] . "<br />";
    }
}

For adding code to ORDER emails, the file where the code should go is:
app/design/frontend/base/default/template/email/order/items/order/default.phtml

For adding code to INVOICE emails, the file where the code should go is:
app/design/frontend/base/default/template/email/order/items/invoice/default.phtml

Instead of base/default, you can put it in your custom theme location which is obvious.

Magento: Add products to placed order programatically

Ever wondered how to attach products to order programatically? It may require if you want to surprise your customer by giving them some special items along with their ordered products. Magento doesn’t allow you to do this, you need to write it through calling observer for event sales_order_place_after.

Copy this in the observer file which observes order place after event.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$product = Mage::getModel('catalog/product')->loadByAttribute('sku', $skuToAdd); //your product SKU to add 
$qty = 1;
$rowTotal = $product->getPrice();
$orderItem = Mage::getModel('sales/order_item')
        ->setStoreId($order->getStore()->getStoreId())
        ->setQuoteItemId(NULL)
        ->setQuoteParentItemId(NULL)
        ->setProductId($product->getId())
        ->setProductType($product->getTypeId())
        ->setQtyBackordered(NULL)
        ->setTotalQtyOrdered($qty)
        ->setQtyOrdered($qty)
        ->setName($product->getName())
        ->setSku($product->getSku())
        ->setPrice($product->getPrice())
        ->setBasePrice($product->getPrice())
        ->setOriginalPrice($product->getPrice())
        ->setRowTotal($rowTotal)
        ->setBaseRowTotal($rowTotal)
        ->setOrder($order);
$orderItem->save();

Please note that you may also need to add the entry in sales_flat_quote_item table to be 100% sure it’s going to work for reorder also. If you’re not worried about reordering, the above code is fine.

Magento Get most popular products in a category

Magento get most popular products in any specified category using below code, you can show them in the sidebar of product detail page to let your visitors know the popularity of the products for that category.

1
2
3
4
5
6
$category = Mage::getModel('catalog/category')->load($categoryId); 
$products = Mage::getResourceModel('reports/product_collection') 
    ->addOrderedQty() //total number of quantities ordered
    ->addAttributeToSelect('*') //get all attributes
    ->setOrder('ordered_qty', 'desc') //most ordered quantity products first
    ->addCategoryFilter($category);

Magento: Get details of all Admin users

As we can get details of all the customers of the Magento store, we can also get details of all the Admin users. It may be necessary sometimes when you want to display all the admin uses either in dropdown for filtering something or just as a text or something based on requirement.

The following code will get you all the Admin users with their details:

1
2
3
$adminUserModel = Mage::getModel('admin/user');
$userCollection = $adminUserModel->getCollection()->load(); 
Mage::log($userCollection->getData());

Magento: Get product attribute’s select option id/label/value

If you have a select dropdown for any product attribute, to get the value from label or vice versa is always needed in order to display or get value for further processing, etc. Every now and then you will require this values while working on product attributes. There aer many ways you can achieve it but the best, in terms of performance and simplicity is what I will tell you here. Get product attribute’s value from label, label from value easily in Magento.

Suppose, you have an product attribute called “color” in Magento. You have the label (e.g. Red), and you want to find it’s value. The below code will help you get the value for it.

1
2
3
4
5
$productModel = Mage::getModel('catalog/product');
$attr = $productModel->getResource()->getAttribute("color");
if ($attr->usesSource()) {
    echo $color_id = $attr->getSource()->getOptionId("Red");
}


Now suppose, you have the value (let’s say 8, for Red) for your attribute, but want to get the label for it. Below code will help you to achive it.

1
2
3
4
5
$productModel = Mage::getModel('catalog/product');
$attr = $productModel->getResource()->getAttribute("color");
if ($attr->usesSource()) {
    echo $color_label = $attr->getSource()->getOptionText("8");
}

Note that the only thing changed in both is, getOptionId() and getOptionText. getOptionId() will accept label and give you value, while getOptionText() will accept value and give you label.

Magento: Get route name, module name, controller and action name from URL

Mage::app()->getRequest()->getControllerName();

Mage::app()->getRequest()->getActionName();

Mage::app()->getRequest()->getRouteName();

Mage::app()->getRequest()->getModuleName();

Magento: How to delete/remove all products from all categories

When you are using some script to automatically add products to categories from XLS file to your Magento system, you may need to delete all products frequently for testing purpose. It’s not as easy to mark all products and press delete button in admin. No, it’s not like that, you need to delete all products, remove them from their linked categories, reset the inventory, etc. so many things to do.

Below is the MySQL queries that will make your task easier. By running all the queries, it will delete all the products in your Magento system. Use it carefully, it’s going to delete everything without an option to rollback.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
SET FOREIGN_KEY_CHECKS = 0;
TRUNCATE TABLE `catalog_product_bundle_option`;
TRUNCATE TABLE `catalog_product_bundle_option_value`;
TRUNCATE TABLE `catalog_product_bundle_selection`;
TRUNCATE TABLE `catalog_product_entity_datetime`;
TRUNCATE TABLE `catalog_product_entity_decimal`;
TRUNCATE TABLE `catalog_product_entity_gallery`;
TRUNCATE TABLE `catalog_product_entity_int`;
TRUNCATE TABLE `catalog_product_entity_media_gallery`;
TRUNCATE TABLE `catalog_product_entity_media_gallery_value`;
TRUNCATE TABLE `catalog_product_entity_text`;
TRUNCATE TABLE `catalog_product_entity_tier_price`;
TRUNCATE TABLE `catalog_product_entity_varchar`;
TRUNCATE TABLE `catalog_product_link`;
TRUNCATE TABLE `catalog_product_link_attribute`;
TRUNCATE TABLE `catalog_product_link_attribute_decimal`;
TRUNCATE TABLE `catalog_product_link_attribute_int`;
TRUNCATE TABLE `catalog_product_link_attribute_varchar`;
TRUNCATE TABLE `catalog_product_link_type`;
TRUNCATE TABLE `catalog_product_option`;
TRUNCATE TABLE `catalog_product_option_price`;
TRUNCATE TABLE `catalog_product_option_title`;
TRUNCATE TABLE `catalog_product_option_type_price`;
TRUNCATE TABLE `catalog_product_option_type_title`;
TRUNCATE TABLE `catalog_product_option_type_value`;
TRUNCATE TABLE `catalog_product_super_attribute`;
TRUNCATE TABLE `catalog_product_super_attribute_label`;
TRUNCATE TABLE `catalog_product_super_attribute_pricing`;
TRUNCATE TABLE `catalog_product_super_link`;
TRUNCATE TABLE `catalog_product_enabled_index`;
TRUNCATE TABLE `catalog_product_website`;
TRUNCATE TABLE `catalog_product_entity`;
TRUNCATE TABLE `cataloginventory_stock`;
TRUNCATE TABLE `cataloginventory_stock_item`;
TRUNCATE TABLE `cataloginventory_stock_status`;
TRUNCATE TABLE `catalog_product_link`;
TRUNCATE TABLE `catalog_product_link_type`;
TRUNCATE TABLE `catalog_product_option`;
TRUNCATE TABLE `catalog_product_option_type_value`;
TRUNCATE TABLE `catalog_product_super_attribute`;
TRUNCATE TABLE `catalog_product_entity`;
TRUNCATE TABLE `cataloginventory_stock`;
DELETE FROM catalog_product_flat_1;
DELETE FROM catalog_product_flat_10;
DELETE FROM catalog_product_flat_11;
DELETE FROM catalog_product_flat_12;
DELETE FROM catalog_product_flat_13;
DELETE FROM catalog_product_flat_14;
DELETE FROM catalog_product_flat_15;
DELETE FROM catalog_product_flat_16;
DELETE FROM catalog_product_flat_17;
DELETE FROM catalog_product_flat_18;
DELETE FROM catalog_product_flat_19;
DELETE FROM catalog_product_flat_2;
DELETE FROM catalog_product_flat_20;
DELETE FROM catalog_product_flat_21;
DELETE FROM catalog_product_flat_22;
DELETE FROM catalog_product_flat_23;
DELETE FROM catalog_product_flat_24;
DELETE FROM catalog_product_flat_25;
DELETE FROM catalog_product_flat_26;
DELETE FROM catalog_product_flat_27;
DELETE FROM catalog_product_flat_28;
DELETE FROM catalog_product_flat_29;
DELETE FROM catalog_product_flat_3;
DELETE FROM catalog_product_flat_30;
DELETE FROM catalog_product_flat_31;
DELETE FROM catalog_product_flat_32;
DELETE FROM catalog_product_flat_33;
DELETE FROM catalog_product_flat_34;
DELETE FROM catalog_product_flat_35;
DELETE FROM catalog_product_flat_36;
DELETE FROM catalog_product_flat_37;
DELETE FROM catalog_product_flat_4;
DELETE FROM catalog_product_flat_5;
DELETE FROM catalog_product_flat_6;
DELETE FROM catalog_product_flat_7;
DELETE FROM catalog_product_flat_8;
DELETE FROM catalog_product_flat_9;
SET FOREIGN_KEY_CHECKS = 1;

insert  into `catalog_product_link_type`(`link_type_id`,`code`) values (1,'relation'),(2,'bundle'),(3,'super'),(4,'up_sell'),(5,'cross_sell');
insert  into `catalog_product_link_attribute`(`product_link_attribute_id`,`link_type_id`,`product_link_attribute_code`,`data_type`) values (1,2,'qty','decimal'),(2,1,'position','int'),(3,4,'position','int'),(4,5,'position','int'),(6,1,'qty','decimal'),(7,3,'position','int'),(8,3,'qty','decimal');
insert  into `cataloginventory_stock`(`stock_id`,`stock_name`) values (1,'Default');

Now go to System > Index Management, and re-index all indexes.

Magento, PHP: Merging/Joining two objects collections

MAGENTOPHP

Jul 29, 2012

kalpesh

1 Comment

Magento, PHP: Merging/Joining two objects collections

Share

It’s easy to merge two arrays with array_merge, but have you came across to merge two objects? It’s not that easy in Magento. You need to convert it to array first, merge them, and convert it to the object again to make it work. If you have two objects of different class, then it’s really difficult job to merge as both will not be compatible. If they are from similar classes or share same elements inside, then it’s not that tricky.

If you want to add collection2 in collection1 (in Magento), where collection1 will be a merged form of both, you can do so by:

1
2
3
foreach($collection2 as $coll) {
    $collection1->addItem($coll);
}


In core PHP, it’s quite easy in this way:

1
$merged_obj = (object) array_merge( (array) $collection1, (array) $collection2 );

In Magento, converting collection to array is easy:

1
$arr = $collection->toArray();

while vice versa is difficult as Magento doesn’t have any built-in method to do so.

Magento add radio / checkbox button to admin grid

Add custom column in admin Grid which will show radio/checkbox button. I know this is weird, but some people need this as a requirement. Here I will show you how you can have radio button or checkbox button that you can have directly in your grids.

For radio button,

1
2
3
4
5
6
7
8
$this->addColumn('some_id', array(
            'header_css_class' => 'a-center',
            'header'    => Mage::helper('adminhtml')->__('Some Header'),
            'type'      => 'radio',
            'html_name' => 'items[]',
            'align'     => 'center',
            'value'    => array('1')
        ));


For checkbox button,

1
2
3
4
5
6
7
8
$this->addColumn('some_id', array(
            'header_css_class' => 'a-center',
            'header'    => Mage::helper('adminhtml')->__('Some Header'),
            'type'      => 'radio',
            'field_name' => 'items[]',
            'align'     => 'center',
            'values'    => array('1','2')
        ));

Further, in Form.php you can add this below code to have by default behavior and onclick behaviour:

1
2
3
4
$fieldset->addField('some_id', 'checkbox', array(
          'checked'    => $this->getSomeId()==1 ? 'true' : 'false',
          'onclick'    => 'this.value = this.checked ? 1 : 0;'
));

Magento: Image resize/compression reduces quality of JPEG

In Magento, image quality is distorted when it’s resized in Category page as well as Product page. This is very bad if you are running an eCommerce website because image is the only thing which gives best impression to your customers. There are several complains regarding this in Magento forums with different answers. Some even suggest to use ImageMagick over the default Gd2 library.

If you don’t want to switch to ImageMagick and also don’t want to do much changes, here is a simple solution.

1.) Copy app/code/core/Mage/Catalog/Helper/Image.php
2.) Paste it in local (app/code/local/ , create directories Mage/Catalog/Helper if it’s not there)
So the final structure will be app/code/local/Mage/Catalog/Helper/Image.php
3.) Edit newly pasted Image.php’s init() method, just after it sets “watermark size”, add a line:

1
$this->setQuality(100);

4.) Save, flush image cache, run any category or product page and see the difference!

Magento: Difference between source_model, frontend_model, backend_model

When dealing with Magento Admin’s system configuration, you may have encountered with these models. If you don’t know, these models are used when you add custom fields through your system.xml file at Magento’s backend configuration (Admin -> System -> Configuration).

Okay, so the difference between these 3 models are:

source_model:
It specifies a Model class, where you will be returned with options that can populate in the current field.

Example,

1
<source_model>adminhtml/system_config_source_yesno</source_model>

this will populate select dropdown with values Yes/No

frontend_model:
It specifies a Block class to add custom render to use as a frontend field type instead of/along with default frontend_type field value (text, textarea, select, etc.).

Example,

1
2
<frontend_type>button</frontend_type>
<frontend_model>MyCustomModule/button</frontend_model>

this will keep frontend type as button, but the customized one taken from Block class Button.php of MyCustomModule module

Code at Button.php can be anything like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php 
class MyNamespace_MyCustomModule_Block_Button extends Mage_Adminhtml_Block_System_Config_Form_Field
{

    protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
    {
        $this->setElement($element);
        $url = $this->getUrl('catalog/product'); 

        $html = $this->getLayout()->createBlock('adminhtml/widget_button')
                    ->setType('button')
                    ->setClass('scalable')
                    ->setLabel('Run Now !')
                    ->setOnClick("setLocation('$url')")
                    ->toHtml();

        return $html;
    }
}
?>

backend_model:
Generally, when you save any form at System Configuration, the data is stored in the table core_config_data. But if your requirement is to do something prior/after the save is performed, you can do it by having _beforeSave() & _afterSave() methods defined in this custom/defined class.

Example,

1
<backend_model>adminhtml/system_config_backend_shipping_tablerate</backend_model>

Magento add admin user in MySQL

In Magento, if you want to create a new user directly in Mysql, it’s not that easy to insert one record in admin_user table.
You need to also update the privileges and inserting new admin’s roles.
So here is a Mysql script which will create a new admin user with all privileges.

Replace FIRSTNAME, LASTNAME, EMAIL, USERNAME, PASSWORD with your desired values.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
insert into admin_user
select
(select max(user_id) + 1 from admin_user) user_id,
'FIRSTNAME' first_name,
'LASTNAME' last_name,
'TEST@EMAIL.COM' email,
'USERNAME' username,
MD5('PASSWORD') password,
now() created,
NULL modified,
NULL logdate,
0 lognum,
0 reload_acl_flag,
1 is_active,
(select max(extra) from admin_user where extra is not null) extra,
NULL,
NULL;

insert into admin_role
select
(select max(role_id) + 1 from admin_role) role_id,
(select role_id from admin_role where role_name = 'Administrators') parent_id,
2 tree_level,
0 sort_order,
'U' role_type,
(select user_id from admin_user where username = 'USERNAME') user_id,
'USERNAME' role_name