Like a “review” in Magento

Today I’ve created a “review” liking module in Magento so customers can read the reviews of a product and like (or dislike) any which they find useful. I based it on some code I found here:

http://sapnandu-magento.blogspot.co.uk/2012/06/create-review-like-module-in-magento.html#comment-form

I found the code a great place to start from, but found some problems with the login links, and I’m not sure how the data was being stored because it seemed to not have a 1 to 1 relationship between the review_like table and a particular review, but we’re interested in the total number of likes or dislikes. So I adapted things somewhat and seems to work great now.

I particularly like it because I’ve got the sorting on the review to show the most useful one first, and then it goes by most recent which I think will be very helpful for customers.

Creating Magento Free Post Promotion Coupons through code

I’ve getting increasing numbers of promotions to set-up in Magento, so I decided it was time to write a script so I can get them added more quickly.

I found some good code here, and decided to adapt it to suit my needs.

This script will generate a free postage code, with start and expiry date but could be easily adapted to offer discounts. It turned a 30 min job into a 5 min one. I’ll eventually write something in VBA so I can generate the data in excel and then just push the button to update the website with new promotions.


#Free Post Coupon Generation
#2013-05-29
#David Boyce

define('MAGENTO', realpath('/srv/www/htdocs/Catalogue'));
ini_set('memory_limit', '128M');

require_once MAGENTO . '/app/Mage.php';

Mage::app();

#Free Post
$code = "[PROMOTIONCOUPONCODE]";
$label = "[PROMOTIONLABEL]";
$amount = 0;
$freeShipping = 1;
$from_date = "2013-05-29";
$to_date = "2013-07-01";

generateRule( $code, $amount, $label, $from_date, $to_date, $name, $freeShipping);

function generateRule($code, $amount, $label, $from_date, $to_date, $name = '', $freeShipping){

  $name = (empty($name))? $label : $name;
  $labels[0] = $label;//default store label

  $coupon = Mage::getModel('salesrule/rule');
  $coupon->setName($name)
  ->setDescription($name)
  ->setFromDate($from_date)
  ->setToDate($to_date)
  ->setCouponCode($code)
  ->setUsesPerCoupon('')
  ->setUsesPerCustomer('')
  ->setCustomerGroupIds(getAllCustomerGroups()) //an array of customer group ids
  ->setIsActive(1)

  //serialized conditions.  the following examples are empty
  ->setConditionsSerialized('a:6:{s:4:"type";s:32:"salesrule/rule_condition_combine";s:9:"attribute";N;s:8:"operator";N;s:5:"value";s:1:"1";s:18:"is_value_processed";N;s:10:"aggregator";s:3:"all";}')
  ->setActionsSerialized('a:6:{s:4:"type";s:40:"salesrule/rule_condition_product_combine";s:9:"attribute";N;s:8:"operator";N;s:5:"value";s:1:"1";s:18:"is_value_processed";N;s:10:"aggregator";s:3:"all";}')

  ->setStopRulesProcessing(0)
  ->setIsAdvanced(1)
  ->setProductIds('')
  ->setSortOrder(0)
  ->setSimpleAction('cart_fixed')
  ->setDiscountAmount($amount)
  ->setDiscountQty(null)
  ->setDiscountStep('0')
  ->setSimpleFreeShipping($freeShipping)
  ->setApplyToShipping('0')
  ->setIsRss(0)
  ->setWebsiteIds(getAllWbsites())
  ->setCouponType(2)
  ->setStoreLabels($labels)
  ;

  $coupon->save();

}


function getAllCustomerGroups(){
  //get all customer groups
  $customerGroupsCollection = Mage::getModel('customer/group')->getCollection();
  $customerGroupsCollection->addFieldToFilter('customer_group_code',array('nlike'=>'%auto%'));
  $groups = array();
  foreach ($customerGroupsCollection as $group){
    $groups[] = $group->getId();
  }
  return $groups;
}

function getAllWbsites(){
  //get all wabsites
  $websites = Mage::getModel('core/website')->getCollection();
  $websiteIds = array();
  foreach ($websites as $website){
    $websiteIds[] = $website->getId();
  }
  return $websiteIds;
}

Updating Magento Order Status through an API call

I’ve written an integration between our backoffice system and magento – to update the status of orders in Magento.

I used the Microsoft MSXML2.ServerXMLHTTP object to send a post to the website – it’s basically requesting a URL and passing some parameters on the query string (ie order number, status etc).

The url might be something like:
http://www.mywebsite.co.uk/updateOrderStatus.php?orderId=[orderid]&orderStatus=[orderstatus]

On the server a php script at the URL requested handles the request and updates the order status – a very simple solution with no checks might be…
updateOrderStatus.php:

$mage_url = 'http://www.mywebsite.co.uk/api?wsdl';
$mage_user = 'apiuser';
$mage_api_key = 'apipassword';

// Initialize the SOAP client
$proxy = new SoapClient( $mage_url );

// Login to Magento
$session_id = $proxy->login( $mage_user, $mage_api_key );

//Get Parameters
$thisOrderId = $_GET['orderId'];
$thisStatus = $_GET['orderStatus'];

//Update Status
$proxy->call($session_id, 'sales_order.addComment', array($thisOrderId,$thisOrderStatus,'Updated through API', false));

Amazing Colour Video of London, 1927

This video from London in 1927 is well worth a look, the problem I always find with black and white pictures and videos is that they never seem quite real.  Colour pictures and video has so much more life – it’s amazing  to see horse-drawn vehicles passing slowly over Tower Bridge, and how differently people dressed back  then.  It’s poignant to see people laying flowers at the Cenotaph, just 9 years after the end of the 1st World War.

Screen-Shot-2013-05-16-at-3.16.16-PM

Greenfingers II

The vegetables in the garden are coming along quite nicely.  The weather hasn’t done them too many favours, but we seem to have managed to keep the marauding slugs at bay, so far.  The lettuces, onions and beans are doing best – hopefully a bit of sunshine and the tomatoes will perk up.

imageimageimageimage

 

Magento Category Caching

The website I administer has lots of configurable products, with many colour/size variations.  The category page load speed had been very slow, and I’d been looking to work on the caching for some time.  I put block caching in using the tutorial here on the product list and it’s made a remarkable difference, with categories loading in 1-2 seconds from a time of 10-12 seconds (worse categories).  I added the block cache to this code:

/app/code/core/Mage/Catalog/Block/Product/List.php

protected function _construct() {
  $this->addData(array('cache_lifetime' => 99999999, ));
}

public function getCacheTags()
{
  return array(Mage_Catalog_Model_Product::CACHE_TAG);
}

public function getCacheKey()
{
  $category = Mage::getModel('catalog/category')->load($this->getCategoryId());
  return $this->getRequest()->getRequestUri();
}

I hope it helps others to speed up their sites too – ps you probably shouldn’t follow my bad example and update the core file, but the one in the local directory.

Deduping part II

I am back working on data selections, and improving the health of the mailing list again today. I’m finding relatively few duplicates, and the ones that I do find are broadly down to one of four reasons:

  • Two or more people who genuinely share the same address (can be either home or place of work)
  • Spelling mistakes in the name and/or address
  • Differences in the name provided eg using different initals, giving a middle name in one record and not the other.
  • Differences in the address provided (or it’s layout) – for example giving a house name in one record, and a house number in another.

It’s a tricky one because we want to send two mailing pieces, where we have two different customers at the same workplace, but on the otherhand we want to save money by not sending more than one piece to two family members at the same address. Using other data, like phone numbers and email addresses does give some clues as to whether two records are the same customer, or members of the same family group, and I’m using this to help supress records, and choosing just the best record to mail.

I will hand over an output of data to our customer services team to manually check some of the records and correct where possible – particularly where it’s likely to be spelling mistakes, or the same customer but with the data in a different format.

Not the most exciting work, but if it saves money off the bottom line 🙂 and the coding and logic is a bit of a challenge.

Greenfingers

This year I’m having a go at growing some vegetables in the garden. It’s something I’ve got no prior experience of at all, and having started reading some books, I can see that I’ve been doing lots of things wrong – but so far I haven’t completely killed anything so we may just have something to eat this summer. I don’t think the supermarkets need to be getting too worried yet 🙂

IMG_0238IMG_0233

London Marathon 2013

Last year I ran in the Brighton Marathon, but I decided this year I would head up to London and run in the big one. The training was tough over the winter, as yet again the UK weather was unseasonably bad, with one of the coldest winters on record. The week before the marathon the race was hit by the sad news from Boston, but I think it gave most runners all the more conviction to run. I was two minutes down on my performance last year, finishing in a time of 2:48:46 but sneaking into the top 500. I was pretty pleased with the time, as I missed several weeks training with the flu, and really enjoyed the experience of running in a big city race again. I was raising money for Scope this year, and collected just over £400 in donations for the charity. My Virgin Money Giving page is: http://uk.virginmoneygiving.com/boycey

554218_10151389937042197_696598772_n