Google Analytics Testing Script

Developing against the Google Analytics Tracking API is a pain. Not only is it a bit of a black box, but the actual statistical output only updates every so often. It isn’t easy, but I love the power it enables.

Long have I wished that someone would create some sort of testing library, either to replace the Analytics script itself, or to sit alongside it and output any interactions with the Analytics server. Until now it hasn’t existed – until now.

I present the Google Analytics Testing script. This bad boy utilises the Firebug script console to output most information you care about going to Google Analytics. Great for AJAXy trackEvent projects or anything else doing more than the rudimentary Analytics set and forget stuff. It works as a Greasemonkey script or you can include it in a script tag anywhere in your HTML. It doesn’t prevent the data itself being sent through to the data, but that is something that may change in a future version of the script.

This script currently relies on the existence of the Google Analytics script, but in the future will exist as a standalone script.

I would love any feedback, bug reports or ideas as to how to make this better and more useful.

Install it now with Greasemonkey or include it in a script tag.

ShootQ WordPress Contact Form 7 Integration

Recently I’ve been doing a heap of work improving the lovely Lizzy C’s business website. She is a melbourne photographer specialising in portraits, commercial and wedding photography. A lot of the improvements have been focused on restructuring the website to improve the user experience but also to improve the ability for us to see what visitors are looking at and what their intentions were.

The other thing I’ve done for her is a integrating her ShootQ CRM with her website. This takes the form of a WordPress plugin which you can download at

PHP5 Date Iterator

I’ve recently had cause to iterate through ranges of dates, either Weekly, Monthly or Daily and for some reason there isn’t really a good default way to do this. So I wrote my own. This is a pretty basic implementation of an iterator but it serves its without too much fuss.

class Date_Iterator implements Iterator {
	private $increment;
	private $startDate;
	private $endDate;
	private $currentDate;
	private $iterations = 0;
	 * @param string $increment Anything that strtotime can understand. eg. day, week, month, year
	 * @param int|string $startDate
	 * @param int|string $endDate
	 * @return 
	function __construct($increment, $startDate, $endDate) {
		$this->increment = $increment;
		if(is_int($startDate)) {
			$this->startDate = $startDate;
		} else {
			$this->startDate = strtotime($startDate);
		if(is_int($endDate)) {
			$this->endDate = $endDate;
		} else {
			$this->endDate = strtotime($endDate);	
		$this->currentDate = $this->startDate;
	function current() {
		return date("d-M-Y", $this->currentDate);
	function next() {
		$current = date("d-M-Y", $this->currentDate);
		$this->currentDate = strtotime($current." + 1 ".$this->increment);
		$this->iterations ++;
	function valid() {
		return $this->currentDate < = $this->endDate;
	function rewind() {
		$this->currentDate = $this->startDate;
	function key() {
		return $this->iterations;

5 Excuses Bad Programmers Make

It’s a common problem, there’s a young kid on your team who thinks he is a great architect. He wants to replace the simplest include with a new whizbang inherited menu system or add 3 layers of abstraction to the database access layer, or replace the beautifully crafted error reporting system with exceptions. When quizzing this “architect” he has a reason for every possible change, these are those classic excuses and reason.

  1. Security. “This will stop any possible security breaches in the future,” he says. Little does he realise that including one extra file into your system isn’t a security risk and probably never will be.
  2. Performance. “We will do this and this and this, and then cache it all in memory. It will be faster than the existing system,” he says. Sure this might be faster, but the difference between 5ms execution and 8ms execution is irrelevant. Chances of him actually having done the profiling and being able to improve the performance gains are minimal.
  3. Future proofing. “This will put us in a great position to make changes in the future.” Which changes? You know those unspecified, unrealised and unkown changes that we may or may make sometime in the future.
  4. Outdated. “There’s a new better way to do that exact thing.” There is a new way to do it, there is a new way to do anything and everything, but is it better? Is it worth holding the project back a week to modernise the codebase? Probably not.
  5. That’s ugly. “But this code is ugly”, he pleads. Is a 3 line hack better or worse than a leaky abstraction?

I’m sure you know of more, what are they?

Update: This comes across as very bitter. Perhaps “bad programmer” isn’t the right word. Try “inexperienced”.  Working on systems, refactoring them and improving them is obviously our job as programmers, yet sometimes you need to take a step back and think. The first design or system we think of is very rarely the right one, it doesn’t matter how much experience you have.

Lessons learnt from Tiger’s Cancellation Procedure

Tiger Airways has an unenviable reputation of a lack of leg space, strict check-in restrictions, late flights and worst of all cancellations. Although each of these is a risk you take when booking the cut-price flights flying with Tiger is still a test of even the most patient man. It seems like each of these problems should be avoidable by the airline, but even if they aren’t there is one thing they could do to make it the whole process far less painful. Improve their cancellation procedures. This is a valuable lesson on how to handle letting down customers in any industry.

I’m sure each flight is handled on a case-by-case basis but our recent 9:15pm flight from Hobart to Melbourne was initially delayed 1 hour. This was never announced and the only way we were made aware of this was an update on the airport monitors. At the time of scheduled departure a loudspeaker announcement was made that informed us the flight was to be delayed by 3 hours, there would be $5 refreshment vouchers made available and if anyone would like to cancel or rebook on Tiger to contact the gate desk. Immediately a large queue of people formed seeking their vouchers and most people were trying to ascertain wether or not they should rebook or cancel their flight, very little information was given and while most people were quite well tempered there was a growing atmosphere of, “We aren’t getting home tonight”

Tiger Airways Approximately 1 hour later a loudspeaker announcement was made that the flight was cancelled and refunds and rebooking would be handled at the gate. No further information regarding the necessary procedures, the availability of future flights or overnight accommodation options was made available and customer dissatisfaction was now at an all-time high. A huge queue was then formed at the desk, with no-one in the line having any idea what to do or what their options were. Immediately people started booking flights on alternate airlines without waiting an hour in line to speak with the 2 Tiger ground crew. There was another Tiger employee available seemingly wandering around behind the gate desk doing very little.

It turns out there are a few gotchas that weren’t announced which people may not know.

  1. Tiger will not provide overnight accommodation
  2. You must fill out the refund form at the time of the cancellation, not tomorrow.

This is information that could and should have been announced, and a lot more communication provided. Had the extra employee been answering people’s questions in the line, handing out forms and showing a human face to the company the mood of all of these disgruntled customers may have been far better. This would have also made the line move faster, less disputes at the counter and could have improved what was already a bad experience.

This is a perfect case of letting a customer down gently rather than kicking them off the flight and letting them fend for themselves. I understand that flights are cancelled and don’t have a huge problem with it, yet I won’t be booking Tiger again in the near future. This is due more to their apparent lack of care rather than the flight cancellation itself.

Remember, failing a customer sometimes is unavoidable, but you have to let them know you care about the problem. This leaves them with a good feeling in a bad situation and hopefully they will come back next time.

On Engagement and Authority

Since it’s early beginnings, there has been much talk about Twitter’s place in the online media landscape. Questions have been raised over whether it will take over from blogging or if it will become just another messaging service. I think it is important to look at what they both provide to give us a brief glimpse into the future.

Twitter’s beauty lies in it’s simplicity. Friends are easy to come by, do a quick search on a topic you are interested in, find some people that are talking about that topic, follow them and then start the conversation. As time passes and the conversation continues these relationships which started as very tenuous “follows” can blossom in to something more. That is so long as you spend the time actually conversing, rather than spamming them with “Get 200 followers easily” or “I’ve just started playing this cool spy game”.

The barrier to entry to this style of interaction is so low, it is conceivable that you can maintain 200-500 of this style of relationship and as time goes on your followers will grow and the attention each tweet you send will grow. This power to influence a number of people through weight of conversation is engagement. You can engage a huge number of followers in conversation and they will click on your links and retweet you, so long as what you are saying is good.

On the other hand building relationships with blogs is hard. Promoting your finely crafted blogpost to like minded people (presumably bloggers) requires sourcing email addresses and then sending a friendly pointer, or leaving a comment on a number of similar blog posts suggesting they read your post. Neither of these options is particularly good, it makes you feel a bit like a spammer and I’m yet to believe that this method really ends up in an ongoing readership. Basically, blogging lacks what Twitter has in spades. Engagement.

Where it lacks this ability to quickly reach and build a large readership it makes up with being able to say something worthwhile. 140 characters is an extremely short space to write 2 sentences, let alone pose a question and make a compelling argument. This is core of any long form writing, but doesn’t have any sort of comparison in the shorter form of microblogging.

The ability to develop and produce a convincing argument is what writers (and bloggers) apart. This then draws inbound links, that post will then rise up the Google rankings becoming the definitive article for that topic. Much like Wikipedia holds the top spot for so many search term. This propensity to become the definitive resource for a topic is authority.

Authority is something that the temporary nature of Twitter doesn’t allow. The search doesn’t find the most important tweet on the topic, just the most recent. In fact it is very difficult to find something someone tweeted in the past let alone use it as reference.

Each medium has its own benefits and down falls and as someone trying to build a “brand” or “presence” in this world of new media would ignore either at their own peril. Robert Scoble is a perfect example, over the past 6 months he has hardly touched his blog let alone written anything of note while other blogs who haven’t over commited to microblogging have maintained their place in the mindspace of the blogosphere.

Dave Winer’s suggestion of posting every week is a move in the right direction, but perhaps for the wrong reasons. He advocates it primarily because a blog is under your control, it is your place and should be forever. Yet he doesn’t raise the point that you can actually say something worthwhile in a blog post. It is hard to do that in a tweet.

So every Friday, or whenever you have something worth saying post an authoritative blog post, and engage your audience by tweeting about it. They go hand in hand.

SEO Google Analytics Greasemonkey Script – Search for Keywords

I’ve been doing a fair bit of keyword analysis and so forth here at Easy Weddings and have found that I regularly need to do a search directly from Google Analytics. So I’ve written a quick and dirty greasmonkey script that does just that. This adds a search link to each line of the keywords report. At the moment it is just for one search engine, but using a dropdown would also work.


Grab Greasemonkey and then download Search for Keywords Greasemonkey script.

Rules of the Road Trip

In no particular order (this is all for comedy’s sake, I don’t condone urinating on people):

  • No fucking U-turns.
  • If you try and open the door as the driver is unlocking the car and you can’t get in, you’ve either got to walk, or get in another door before he drives off.
  • If you’ve got to piss, you have to wait till someone else has to piss. Unless it’s just you and the driver, then you can piss on him, or there’s alcohol involved and he has to stop. But everyone has to piss all at once so he doesn’t stop every 2 minutes, cause that’s shit.
  • You are not allowed to open a beer in a car unless it is travelling at more than 100km/h.