Magento sales transactional email – highlight if billing address equals shipping address

Insert this code on the desired place in the .html transactional email (deepter in the locale folder):

{{block type='core/template' area='frontend' template='email/shippingcheck.phtml' order=$order}}

Then create the file in the template you’re using (app/design/frontend/default/default/template/email/shippingcheck.phtml) for example. Insert the following content:

<?php if($this->getData('order')->getShippingAddress()->format('html') != $this->getData('order')->getBillingAddress()->format('html')) { echo $this->getData('order')->getShippingAddress()->format('html'); } else { echo 'The billing address equals the shipping address.'; } ?>


Magento remove images of deleted products

Clean up not used Magento images

Magento unfortunately does not remove images of a product unfortunately if the product is removed. The following script checks all the images and checks if it’s still present in the database of Magento. If not, it deletes the image. Use the following code:

<?php

$mageFilename = 'app/Mage.php';
require_once $mageFilename;

Mage::setIsDeveloperMode(true);
ini_set('display_errors', 1);
umask(0);

Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);

set_time_limit(0);
ini_set('memory_limit','1024M');

$media = Mage::getBaseDir('media').'/catalog/product';

echo "Query database for images …\n";
$query = "SELECT value FROM catalog_product_entity_media_gallery";
$data = Mage::getSingleton('core/resource')->getConnection('core_read')->fetchAll($query);

$dbData=array();
foreach($data as $item){
  $dbData[$item['value']]=$item['value'];
}

echo "Images found in database:".count($dbData)."\n";

echo "Search images in media directory …\n";
$images = findFiles($media, array('jpg'));
echo "Images found under directory ($media):".count($images['jpg'])."\n";

echo "Start removing images …\n";
$removedCount=0;
$skippedCount=0;
foreach($images['jpg'] as $image) {
  if(strpos($image,'cache')!==false)
  {
    //echo "Skip cached image : $image\n";
    continue;
  }

  $imageCleanup = str_replace($media,"",$image);
  if(isset($dbData[$imageCleanup]))
  {
    echo "Skip image is in database : $image\n";
    $skippedCount++;
    continue;
  }
  else
  {
    echo "Remove image : $image\n";
    //if($testrun==false) unlink($image);
    $removedCount++;
  }
}

echo "Done, removed $removedCount images and skipped $skippedCount images.\n";

function findFiles($directory, $extensions = array()) {
  function glob_recursive($directory, &$directories = array()) {
    foreach(glob($directory, GLOB_ONLYDIR | GLOB_NOSORT) as $folder) {
      $directories[] = $folder;
      glob_recursive("{$folder}/*", $directories);
    }
  }
  glob_recursive($directory, $directories);
  $files = array ();
  foreach($directories as $directory) {
  foreach($extensions as $extension) {
  foreach(glob("{$directory}/*.{$extension}") as $file) {
  $files[$extension][] = $file;
}
}
}
return $files;
}

?>

Clean up Magento space: could save a lot of GBs

In my case, I tried the script for a store with 40K images of which 10K were not used. This is a disk space reduction of a few Gigabytes.

Final word

This script is thanks to a comment on RapidCommerce. If you use the script, that’s on your own responsibility. Try it out on a staging server and make a backup in advance. Cheers!



Load normal product price instead of indexed product price

Would you like to ignore the indexed product price in the templates (for example in catalog/product/list.phtml where the indexed price is used)?

Then go to: catalog/product/list.phtml

Change:

<?php echo $this->getPriceHtml($product) ?>

With:

<?php $product = Mage::getModel( 'catalog/product' )->load($_product->getId()); ?>
<?php echo $this->getPriceHtml($product) ?>

There are two occurrences in list.phtml, so don’t forget to replace it twice. Only do this when it’s the only solution of displaying right prices, since loading the product takes extra time, compared to loading the indexed product price.



Magento Contact Form Attachment Functionality

Would you like to have attachments in your contact form in Magento?

Do the following:

  1. Clone the zip of this github: https://github.com/yogisfunda/magento-contact-form-attachment
  2. Upload (merge) the files into the public_html directory
  3. Recompile/flush cache
  4. Go to your-site.com/contacts
  5. If the form does not changes or there’s a blank page, move the contents of the frontend/default part to frontend/base.

You can insert the form as a widget on a cms page by adding the following code:

{{block type="core/template" name="contactForm" form_action="/contacts/index/post" template="eurowsport/customform/customform.phtml"}}


One Step Checkout – show shipping methods after postcode entered

Would you like to show shipping methods of a one step checkout plugin after that a postcode is entered?

Go to the file app/design/frontend/base/default/template/checkout/onepage/shipping_method/available.phtml and replicate this file in your default interface/theme. Within the file, after (about line 31):

<p><?php echo $this->__('Sorry, no quotes are available for this order at this time.') ?></p>
<?php else: ?>

Add:

<?php
	$checkout = Mage::getSingleton('checkout/session')->getQuote();
	$billAddress = $checkout->getShippingAddress();
	$postcode = $billAddress->getPostcode();

	/* 13-10-2014 Added requirement to enter postcode before shipping */
	if (isset($postcode) && $postcode == "")
	{
	?>
	<p><?php echo "First enter your postcode before the shipping costs are calculated."; ?></p>
	<?php
	}
	else
	{
	?>

And close the else tag at the end. You can do this with countries, cities, etc. as well by changing the $postcode = $billAddress->getPostcode(); variable to:
$postcode = $billAddress->getCountry();

Good luck!



Magento 1.8 add to url via url query

Would like to add a product via an url like (as described in this Mage article):

<?
echo "
<form action='/checkout/cart/add/product/" . $id . "/form_key/'>
<input type='submit' value='In Cart' />
</form>";
?>

This doesn’t work in Magento 1.8 unfortunately, because of the new form_key system. You can provide an hidden form_key field. Unfortunately this didn’t work in my case. Best way is to omit the form_key security for add to cart querystrings. This can be solved with this rewrite plugin:

https://github.com/deivisonarthur/Inovarti_FixAddToCartMage18/

Good luck!



Magento Direct SQL Queries

Queries for fetching in an array


    /**
     * Get the resource model
     */
    $resource = Mage::getSingleton('core/resource');
     
    /**
     * Retrieve the read connection
     */
    $readConnection = $resource->getConnection('core_read');
     
    $query = 'SELECT * FROM ' . $resource->getTableName('catalog/product');
     
    /**
     * Execute the query and store the results in $results
     */
    $results = $readConnection->fetchAll($query);
     
    /**
     * Print out the results
     */
     var_dump($results);

Fetching one query

Therefore use the method fetchCol() instead of fetchAll, so like:

$sku = $readConnection->fetchCol('SELECT sku FROM ' . $table . ');

Read more at FishPig.

Queries for wrtiting

$resource = Mage::getSingleton('core/resource');
	$writeConnection = $resource->getConnection('core_write');
	
	$query = "INSERT INTO abc_hit SET
			  visitor_id = :visitor_id,
			  hit_date = :hit_date,
			  ";
	$binds = array(
    'visitor_id' => $_SESSION['visitor_id'],
    'hit_date' => date("Y-m-d H:i:s"),
	);
	
	$writeConnection->query($query, $binds);

Get Last Inserted ID

$write = Mage::getSingleton('core/resource')->getConnection('core_write');
$sql = "INSERT INTO .......";
$write->query($sql);
$lastInsertId = $write->lastInsertId();

Thanks to sbditto85.



Magento A/B testing or Multivariate testing – Php script

Split test A/B PHP Script

Magento is quite limited in tools like conversion optimalisation like A/B testing or multivariate testing. That is why I created a very simple php script that you can put directly into a phtml file. It’s a bit hacky, that it’s not via the core, but it works though and is fast. This script has its limitation, see the note on the bottom.

If you want to variate the text of a button on the product page and go to a file like /app/design/frontend/default/default/catalog/product/view.phtml and insert this into the header (in the php-code):

srand((double)microtime()*1000000);

$var = array();
$var[1]['name'] = 'direct';
$var[1]['value'] = 'Buy direct';
$var[2]['name'] = 'purchase';
$var[2]['value'] = 'Purchase product';
$var[3]['name'] = 'invest';
$var[3]['value'] = 'Invest in product';

$choice = cookieCheck($var);

function cookieCheck($var)
{
	$cookie = Mage::getSingleton('core/cookie');
	$cookievalue = $cookie->get('variation_test');
	if (isset($cookievalue) && ($cookievalue > 0))
	{
		$choice = $cookievalue;
	}
	else
	{
		$choice = rand(1,count($var));
		$cookie->set('variation_test', $choice ,time()+30*86400,'/');
	}
	return $choice;
}

Then create a piece of text like a link or a button. That is where the variation takes place:

<a class="varbutton" href="&lt;? echo $this-&gt;getUrl('bedankt'); ?&gt;">&lt;? echo $var[$choice]['value']; ?&gt;</a>

If you want to track the variable in Google Analytics, you can edit the template file /app/design/frontend/default/default/googleanalytics/ga.phtml , so it gets like:

 srand((double)microtime()*1000000);

$var = array();
$var[1]['name'] = 'direct';
$var[1]['value'] = 'Buy direct';
$var[2]['name'] = 'purchase';
$var[2]['value'] = 'Purchase product';
$var[3]['name'] = 'invest';
$var[3]['value'] = 'Invest in product';

$choice = cookieCheck();

function cookieCheck()
{
	$cookie = Mage::getSingleton('core/cookie');
	$cookievalue = $cookie->get('variation_test');
	if (isset($cookievalue) && ($cookievalue > 0))
	{
		$choice = $cookievalue;
	}
	else
	{
		$choice = rand(1,count($var));
		$cookie->set('variation_test', $choice ,time()+30*86400,'/');
	}
	return $choice;
}
 
 
?>
<?php if (!Mage::helper('core/cookie')->isUserNotAllowSaveCookie()): ?>
<?php $accountId = Mage::getStoreConfig(Mage_GoogleAnalytics_Helper_Data::XML_PATH_ACCOUNT) ?>
<!-- BEGIN GOOGLE ANALYTICS CODEs -->
<script type="text/javascript">
//<![CDATA[
    var _gaq = _gaq || [];
    _gaq.push(["_setCustomVar", 1, "variation_test", "<?php echo $choice; ?>"]);
    <?php echo $this->_getPageTrackingCode($accountId) ?>
    <?php echo $this->_getOrdersTrackingCode() ?>

    (function() {
        var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
    })();

//]]>
</script>
<!-- END GOOGLE ANALYTICS CODE -->
<?php endif; ?>

Note: This script could not work properly if you’re using Full Page Cache. Also it could not work with the page block html cache. So, work in progress …



Lesti::Fpc and layered navigation (Vinagento and Amasty)

How to let Lesti::FPC Full page caching work with Vinagento Layered Navigation in Ajax mode?

I just tried some random settings and this seemed to work:

In System->Configuration->Sytem->Lesti FPC add the following to Session Params:
catalogsearch_advanced_result_ajax,
catalog_category_ajax_view,
catalog_category_layered_ajax,
catalogsearch_result_ajax

In System->Configuration->Sytem->Lesti FPC add the following to Uri Params:
id,
category,
page_id,
p,
limit,
dir,
order,
mode,
price,
cat,
manufacturer,
no_cache,
color,
ajax,
your_attribute_code1,
your_attribute_code2,

How to let Lesti::FPC Full page caching work with Amasty Layered Navigation in Ajax mode?

The parameters for Amasty will follow shortly.