Using get_defined_vars() for debugging local scope variables

May 8, 2013  |  2 Comments  |  by Raj (MagePsycho)  |  Latest, Magento

Suppose say, you want to debug variables in some observer method.
You can either log the each variable or simply dump it. But when you have many variables, debugging each variables can be an overhead task. For this purpose we can use PHP’s inbuilt function: get_defined_vars()
How to use it?
CODE:

//put this line at the top of your variable declarations
$vars = get_defined_vars();

// Now your regular stuffs goes here...
$foo = 'foo';
$bar = 'bar';
$data = $model->getData();

// Only stores all the variables defined in current scope
$vars = array_diff(get_defined_vars(), $vars);

//Now you can either dump
Zend_Debug::dump($vars);
//or keep in log
Mage::log($vars, null, 'var-debug.log', true)

This approach can be very handy in debugging any local scope variables. At least it provides an easier approach with clean code.

How to filter shipping method in onepage checkout?

April 21, 2013  |  2 Comments  |  by Raj (MagePsycho)  |  Latest, Magento

Introduction

You may want to filter shipping method in onepage checkout for one of the following cases:
– Filter shipping method based on Customer Group
– Filter Shipping method based on Country, State, Zipcode etc
– Filter Shipping method based on products
– etc.

Unlike event: ‘payment_method_is_active’ for payment method filtration, we don’t have similar event: ‘shipping_method_is_active’ available for shipping method. May be Magento team forgot to implement it or it was too hard to implement due to the structure.
Whatever may be the reason we still can filter by overriding: Mage_Shipping_Model_Shipping::collectCarrierRates()

Solution

Suppose a skeleton module(MagePsycho_Shipmentfilter) has already been created. And for example purpose we will be hiding flat rate shipping for non-logged in customer.
1> Rewrite the shipping model class: ‘Mage_Shipping_Model_Shipping’
File: app/code/local/MagePsycho/Shipmentfilter/etc/config.xml
Code:

...
<global>
	...
	<models>
		<shipping>
			<rewrite>
				<shipping>MagePsycho_Shipmentfilter_Model_Shipping</shipping>
			</rewrite>
		</shipping>
	</models>
	...
</global>

2> Override the method: collectCarrierRates()
File: app/code/local/MagePsycho/Shipmentfilter/Model/Shipping.php
Code:

<?php
/**
 * @category   MagePsycho
 * @package    MagePsycho_Shipmentfilter
 * @author     magepsycho@gmail.com
 * @website    http://www.magepsycho.com
 * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 	*/
class MagePsycho_Shipmentfilter_Model_Shipping extends Mage_Shipping_Model_Shipping
{
    public function collectCarrierRates($carrierCode, $request)
    {
        if (!$this->_checkCarrierAvailability($carrierCode, $request)) {
            return $this;
        }
        return parent::collectCarrierRates($carrierCode, $request);
    }

	protected function _checkCarrierAvailability($carrierCode, $request = null)
	{
		$isLoggedIn	 = Mage::getSingleton('customer/session')->isLoggedIn();
		if(!$isLoggedIn){
			if($carrierCode == 'flatrate'){ #Hide Flat Rate for non logged in customers
				return false;
			}
		}
		return true;
	}
}

3> That’s all.

Please share any other ideas you have.

Hide other shipping methods when free shipping is enabled

March 19, 2013  |  1 Comments  |  by Raj (MagePsycho)  |  Latest, Magento

When free shipping method is enabled, it is shown along with other available shipping methods unlike free payment method ‘Zero Subtotal Checkout’.
There is no harm in showing other payment methods along with free shipping method. Nevertheless some merchants wants to hide rest of the methods when it is enabled.

There are many ways to do it. One of the way is to override the method:
Mage_Checkout_Block_Onepage_Shipping_Method_Available::getShippingRates()

1. Rewrite the block class

File: app/code/local/MagePsycho/Shipmentfilter/etc/config.xml:
Code:

...
<blocks>
	...
	<checkout>
		<rewrite>
			<onepage_shipping_method_available>MagePsycho_Shipmentfilter_Block_Onepage_Shipping_Method_Available</onepage_shipping_method_available>
		</rewrite>
	</checkout>
	...
</blocks>
...

2. Override the getShippingRates() method

File: app/code/local/MagePsycho/Shipmentfilter/Block/Onepage/Shipping/Method/Available.php:
Code:

<?php
/**
 * @category   MagePsycho
 * @package    MagePsycho_Shipmentfilter
 * @author     magepsycho@gmail.com
 * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */
class MagePsycho_Shipmentfilter_Block_Onepage_Shipping_Method_Available extends Mage_Checkout_Block_Onepage_Shipping_Method_Available
{
	public function getShippingRates()
	{
		$rates = parent::getShippingRates();
		if (array_key_exists('freeshipping', $rates)) {
			$rates = array('freeshipping' => $rates['freeshipping']);
		}

		return $rates;
	}
}

3. Refresh the cache. Bingo!

How to find the size / rows of Magento database & tables?

February 17, 2013  |  1 Comments  |  by Raj (MagePsycho)  |  Latest, Magento, Mysql

Introduction

Magento is a giant e-commerce application having more than 300 tables. It uses an eav model concept and provides different complex features which makes the database huge.

Sometimes you may wonder what’s the database size of your Magento database or individual tables so that you can work on some optimization task or freeing some of your server space.
Here we are going to discuss some SQL queries which seems to be helpful.

SQL Snippets

1. Find size & rows of Magento database

SELECT 
  TABLE_SCHEMA AS "Database",
  SUM(TABLE_ROWS) AS "Rows #",
  ROUND(
    SUM(DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024,
    2
  ) AS "Size (MB)" 
FROM
  information_schema.TABLES 
WHERE information_schema.TABLES.TABLE_SCHEMA = 'database-name' 
 GROUP BY TABLE_SCHEMA;

2. Find size & rows of Magento database tables

SELECT 
  TABLE_NAME AS "Table",
  TABLE_ROWS AS "Rows #",
  ROUND(
    (DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024,
    2
  ) AS "Size (MB)" 
FROM
  information_schema.TABLES 
WHERE information_schema.TABLES.TABLE_SCHEMA = 'database-name' 

3. Find size & rows of Magento log tables

SELECT 
  TABLE_NAME AS "Table",
  TABLE_ROWS AS "Rows #",
  ROUND(
    (DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024,
    2
  ) AS "Size (MB)" 
FROM
  information_schema.TABLES 
WHERE information_schema.TABLES.TABLE_SCHEMA = 'database-name' 
  AND (
    TABLE_NAME LIKE 'log_%' 
    OR TABLE_NAME LIKE 'report_%' 
    OR TABLE_NAME LIKE 'dataflow_%' 
    OR TABLE_NAME = 'catalog_compare_item'
  ) 
ORDER BY TABLE_ROWS DESC 

Magento log tables info

These queries can be useful for optimizing your database. Suppose say if log tables are huge with large no of data then you can optimize the log tables by truncating them using following SQL:

TRUNCATE dataflow_batch_export;
TRUNCATE dataflow_batch_import;
TRUNCATE log_customer;
TRUNCATE log_quote;
TRUNCATE log_summary;
TRUNCATE log_summary_type;
TRUNCATE log_url;
TRUNCATE log_url_info;
TRUNCATE log_visitor;
TRUNCATE log_visitor_info;
TRUNCATE log_visitor_online;
TRUNCATE report_viewed_product_index;
TRUNCATE report_compared_product_index;
TRUNCATE report_event;
TRUNCATE index_event;
TRUNCATE catalog_compare_item;

Caution: Always take a DB backup before performing truncate operation.

Hope you found this article useful.
Thanks for reading!

How to filter payment method in onepage checkout

January 9, 2013  |  10 Comments  |  by Raj (MagePsycho)  |  Latest, Magento

Introduction

Q: How will you filter the payment method in onepage checkout based on some conditions?
A: There are different ways to do so. Some of them are:
#1 By overriding template: app/design/frontend/[interface]/[theme]/template/checkout/onepage/payment/methods.phtml
#2 By overriding method: Mage_Checkout_Block_Onepage_Payment_Methods::_canUseMethod()
#3 By overriding method: Mage_Payment_Model_Method_Abstract::isAvailable()
#4 By overriding method: Mage_Checkout_Block_Onepage_Payment_Methods::getMethods()
#5 By observing event: payment_method_is_active
#6 etc.

Among above methods obviously using event-observer technique is the best way to go (#5).
And here I will be discussing about how to enable the PayPal (Website Standard) method only when current currency is USD.

Steps

Suppose a skeleton module(MagePsycho_Paymentfilter) has already been created.
1> Register the event: ‘payment_method_is_active’ in config.xml.
Add the following xml code in app/code/local/MagePsycho/Paymentfilter/etc/config.xml:

...
<frontend>
	...
	<events>
		<payment_method_is_active>
			<observers>
				<paymentfilter_payment_method_is_active>
					<type>singleton</type>
					<class>paymentfilter/observer</class>
					<method>paymentMethodIsActive</method>
				</paymentfilter_payment_method_is_active>
			</observers>
		</payment_method_is_active>
	</events>
	...
</frontend>
...

2> Implement the observer model
Create observer file: app/code/local/MagePsycho/Paymentfilter/Model/Observer.php and paste the following code:

<?php
/**
 * @category   MagePsycho
 * @package    MagePsycho_Paymentfilter
 * @author     magepsycho@gmail.com
 * @website    http://www.magepsycho.com
 * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 	*/
class MagePsycho_Paymentfilter_Model_Observer {

	public function paymentMethodIsActive(Varien_Event_Observer $observer) {
		$event			 = $observer->getEvent();
		$method			 = $event->getMethodInstance();
		$result			 = $event->getResult();
		$currencyCode	 = Mage::app()->getStore()->getCurrentCurrencyCode();
		
		if( $currencyCode == 'USD'){
			if($method->getCode() == 'paypal_standard' ){
				$result->isAvailable = true;
			}else{
				$result->isAvailable = false;
			}
		}
	}

}

3> Go ahead for testing.

Happy E-Commerce!