Use GEOIP2 for PHP Geo IP data in WordPress, Magento, HTML

The above iFrame makes an ajax request to a PHP class querying GeoLite2 data created by MaxMind, available from
This example displays the location of a single visitor i.e. YOU. Click here to see the logging data for this WordPress blog which demonstrates a PHP memcache data logging solution with geo ip visitor data displayed dynamically on a google map.

Magento SEPA Migration Check List

The Single Euro Payments Area (SEPA) is a payment-integration initiative of the European Union for simplification of bank transfers denominated in euro.

If you make or accept payments via direct bank transfers then you will know all about SEPA. As a customer online payment method direct bank transfers are popular in some countries (i.e. Germany) and not so popular in others (i.e the UK).

The deadline for SEPA payments was 1st February 2014 but (as of the time of writing) has been extended 6 months to 1st August 2014.

SEPA standardises bank transfers in Europe, replacing bank specific account and sort code numbers with an IBAN (International Bank Account Number) and BIC (Business Identifier Code).

For most businesses the migration to SEPA involves communicating the new changes to customers and migrating bank account numbers and sort codes to IBAN and BIC.

For Magento stores if you have a payment method that allows customers to pay via a direct bank transfer then you need to ensure that you can capture IBAN and BIC numbers at checkout. Until 1st August 2014 you can decide to give the customer the option of entering either bank account number and sort code or IBAN and BIC. From August 1st you *should* only be accepting IBAN and BIC.

Here is what you need to do to get your Magento Store ready for SEPA payments

  • Make sure you are capturing bank account information in the SEPA format – IBAN and BIC at checkout.
  • Check that your validation rules work for the IBAN and BIC formats.
  • Make a note to remove input fields and validation rules for old account formats, bank account number and sort code.
  • Upgrade your existing debit payment methods to make sure they support SEPA.
  • Implement a validation system for IBAN and BIC

This debit module is perfect for German Magento shops implengint Direc Debit (Lastschrift) payment methods and supports SEPA :

To validate IBAN account numbers with PHP take a look at



Javascript only EU Law Cookie Notification Message for WordPress and Magento

You know sometimes you just want a quick solution to a problem and wherever you look there are just complex, overpriced scripts that make your simple problem sound like something that needs a lot of code and money to get to work.

I needed to display a cookie notification message on a wordpress and magento site, to avoid compatibility problems I wanted to avoid using jQuery and just do it as simply as possible in javascript.

After looking around at a lot of $10 jQuery solutions I found a free javascript only solution, modified it for Magento and WordPress and implemented it.

Download the code from Github here

Whatever your opinion of the EU Cookie Law which came into effect in 2012, sooner or later if you are in Europe you may need to show that you are doing something about it. Err actually it’s 2014, so I guess we are already a teeny weeny bit late.

From what I understand the law may differ in various countries (certainly outside Europe), so depending on where your website is, and who visits your site the law may or may not apply to you.

This script will let  you quickly implement a cookie notification banner with a link to your privacy policy. The notification itself uses cookies and will not be show again when closed.

You can implement this solution on any website by copying the install files to your web server and adding the following code to the footer of your site.

<script type=”text/javascript”>

var cookieNotificationURL='/cookies/';
var cookieNotificationLifetime=180;
var cookieNotificationMessage='This website uses cookies. For more information please ';
var cookieNotificationClickMessage='click here';
var cookieNotificationMessageFade=true;
var cookieNotificationPath='/path-to-install-folder/

<script type="text/javascript" src="/js/cookienotification/cookie.notification.min.js"></script>

This sets up some variables used by the script, the URL of the privacy info page, the lifetime of the cookie used by the script in days, messages displayed, the option to fade the message automatically and the path to the install folder – used to display the close image.

For wordpress simply paste this into the footer php file of your theme.

For Magento paste this into the footer.phtml template file of your Magento theme. You can translate the messages, and perhaps a good idea, choose to display the message only on non SSL pages – we don’t want this javascript to somehow screw up a sale!

<?php if (empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] = ‘off’): ?>

<!-- Cookie Notification -->
<script type="text/javascript">
var cookieNotificationURL='/datenschutzerklaerung/';
var cookieNotificationLifetime=180;

<?php if (Mage::app()->getStore()->getId()==2): ?>
var cookieNotificationMessage='This website uses cookies. For more information please ';
var cookieNotificationClickMessage='click here';
<?php else: ?>
var cookieNotificationMessage='Diese Website verwendet Cookies. ';
var cookieNotificationClickMessage='Klicken Sie hier für weitere Informationen.';
<?php endif ?>

<script type="text/javascript" src="/js/cookienotification/cookie.notification.js"></script>
<?php endif ?>

Here I am manually checking the store id and translating the text to German. Remember to refresh your Magento cache after editing and saving the footer template file.

You can see the code working on this WordPress blog below, and also with Magento on my Magento development site.

Tested with Magento 1.8.x, WordPress 3.blah, Chrome, Firefox, IE11. Detects mobile devices and modifies banner size accordingly.

IOS 7.x Jailbreak SSH Access / SSH Tunnel

There are 3 reasons why I always “Jailbreak” my iPad.

  1. The Apple iPad is a (bloody expensive) computer. When I buy a (bloody expensive) computer I expect to have 100% usability from it. The restrictions imposed by Apple on their i device operating system (IOS) inhibit it’s practical usability considerably, and I really don’t like that.
  2. When I am travelling I use the excellent MyWi app to turn my iPad into a wireless hotspot.
  3. For privacy and security I like to be able to tunnel my iPad traffic through a secure SSH connection to my server.

“Jailbreaking” exploits vulnerabilities in IOS to achieve root access to the operating system thus “liberating” IOS and allowing ad hoc software to be installed and executed. If you come from a Unix background this is great, because your (bloody expensive) computer now becomes really useful in accessing other Unix based systems and doing geeky Unix type stuff.

I have been Jailbreaking my iPad since IOS v.5 – I find little point in Jailbreaking my iPhone as the screen size limits use.

The Jailbreak process itself is always seamless:

  • Backup with iTunes
  • Install update from iTunes (not via OTA update)
  • Restore from iTunes
  • Jailbreak
  • Restore Cydia software and purchases, i.e. MyWi.

The IOS 7.x Jailbreak was released recently and I finally decided to upgrade my iPad from IOS 6.x to IOS 7.x and apply the Jailbreak, as usual this worked pretty well, but some changes in IOS 7 caused problems:

  • IOS 7 stops applications from connecting to localhost SSH on port 22
  • IOS 7 multi tasking affects SSH background connections

IOS 7 Stops Applications from Connecting to localhost SSH on Port 22

This was a devious software change by Apple. Normally after Jailbreaking the first task is to install Open SSH via Cydia – this gives you normal SSH terminal access to the device, and then use a terminal application such as iSSH to login to the device (localhost) as root.

With IOS 7 Apple have hardcoded a restriction into the operating system that stops (App Store) Apps from making an SSH connection to localhost on the default SSH port 22. When you try and connect with iSSH you will get a connection cancelled error. You can still SSH from an external device, but not locally.

The workaround for this is to change the listening TCP/UDP ports used by the SSH daemon to something other than 22.

To do this you need to edit a couple of system files. An easy way to edit the files is with the Cydia app iFile.

Take a look at /etc/services this file defines network services including SSH. Find the entries for SSH:

ssh    22/udp    # SSH Remote Login Protocol
ssh    22/tcp      # SSH Remote Login Protocol

and duplicate them creating a new service called ssh2

ssh2    52222/udp    # SSH Server
ssh2   52222/tcp      # SSH Server

Save the file.

Here I am using 52222 for the UDP/TCP ports, you can use other port numbers but stay clear of well known ports from 0 – 1023 (dynamic/private ports 49152 to 655535 are preferable).

Now edit /Library/LaunchDaemons/com.openssh.sshd.plist  and change the SockServiceName string to ssh2.


Save the file and reboot.

We are basically telling the operating system to continue using port 22 for SSH connections but to listen for SSH connections on a different port.

You can now connect using SSH on the port you specified i.e.

ssh root@my.ipad.address:52222

Remember to change the root and mobile default passwords of your i device when you login.

IOS 7 multi tasking affects SSH background CONNECTIONS

So now I have root access to my IOS 7.0 device I can run SSH to create a secure tunnel to my Ubuntu server:

ssh -N -g -D XXXX

This creates a SOCKS proxy tunnel on port XXXX over SSH to my server, the i device can be configured to send all traffic via this proxy with a proxy auto config (PAC) file.

On IOS 7.0 this worked as expected, hurrah! I ran the shh tunnel changed my Wifi proxy settings to auto using my PAC file URL, switched apps to Chrome, checked my IP address to confirm I was proxying via the SOCKS tunnel and was happy that my iPad data was going through the “secure” tunnel –  until a few minutes later when it stopped working, doh!

The tunnel stops working because shortly after switching apps the SSH connection to the iPad is terminated, also terminating the SSH tunnel. This is because Apple has changed the way App multitasking works in IOS 7.x

When you switch apps in IOS 7 some apps continue to run for a short while and are then set to a suspended state to reduce system resources. They will “instantly” launch when you return to them. Of course when an app like iSSH switches to the background and is suspended by the operating system any active SSH connections will quickly timeout and terminate. This means our session running the SSH tunnel will be terminated, closing the tunnel.

Some apps are allowed to update in the background, and this is controlled via the background refresh options in settings, but as of the time of writing iSSH (and Prompt) do not appear in this list. (in IOS 6 apps were allowed to run for 10 minutes in the background and iSSH used to prompt you to return to the app to keep connections alive).

Fortunately there is a simple work around to this problem, install the mobile terminal app via Cydia and reboot. The mobile terminal app has been around for a while and gives you direct command line access as the mobile user. Although Cydia says it only supports IOS v4 to v6 it installs and runs perfectly on IOS v7.x too.

The great thing about mobile terminal is that it creates a direct local login session. When you switch the app to the background this session will keep running even when the mobile terminal app is suspended and reset. In fact if you install adv-cmds via Cydia you can login via SSH and see this login session running as a process with the ps command.

So we execute our SOCKS proxy ssh command in mobile terminal and setup the tunnel, when the mobile terminal app switches to the background the tunnel will stay open in the login session indefinitely, or until you kill the session manually from another command line using the kill process command.

If you don’t want to use mobile terminal have a look at the cydia implementations of screen and autossh.

Now I have full SSH functionality from my (bloody expensive) IOS 7.x computer again!

Here is the pac file I use for my proxy auto config:

function FindProxyForURL(url, host) {
return “SOCKS localhost:XXXX”;


HTTP Live Streaming using Quicktime Broadcaster and FFMPEG

It’s 2014 and I am still using the Apple Darwin Media server, but after years of being neglected by Apple it is starting to show it’s age. One of the main problems is that for Apple i devices there is no native RTSP support so streaming content from the Darwin server to portable devices is not so easy.

Apple have largely replaced RTSP with HTTP Live Streaming (HLS). HLS basically just cuts up video files into small MPEG video segments that can be downloaded/streamed via a normal website using the HTTP protocol.

This works pretty well for video content that you want to convert from say MP4 to HLS, you run a conversion process that transcodes the video into multiple 10 second segments that you serve up to clients via an .m3u8 reference file on your web server.

If you want to do this with live content then the process is similar but you will also need a client to transmit the live video to your server to transcode it into segments on the fly.

When I am streaming live RTSP content to my Darwin media server I use the Apple Quicktime Broadcaster (on my MAC) as its free and kinda works well. So lets use Quicktime Broadcaster (QTB) to stream live video to a server running FFMPEG which will transcode the video into HLS segments which can be served up by Apache (or your web seriver of choice) to HLS clients.

You can download the Quicktime Broadcaster for Mac here. It hasn’t been updated since 2009, so obviously isn’t high on Apples list of supported software anymore, but hey ho, it is free.

Fire up QTB and configure your video and audio settings.

We will be creating a manual unicast connection and the screen shots below show the settings I used.

Set transmission to Manual Unicast. The address is the TCP/IP address of the server that will run FFMPEG. Note the port numbers used for audio and video, this info is saved in the .SDP file.



For this demo I am using my webcam as the source video. If you have an external device select it as the video source. Choose your compression options depending on the bandwidth available to you. Enable and configure audio compression in the same way.



Click broadcast and the client will attempt to unicast the video data to the server (even though nothing is listening yet).

Export these settings to a .sdp file by clicking File -> Export -> SDP save the SDP file and then upload it to your server.

Now we want to run FFMPEG so that it listens on the ports we specified, captures the unicast video and audio data, transcodes it into HLS segments and stores the HLS data to a publicly accesible area of your web server.

We do this by running FFMPEG with all the options we need, Here is an example command line :


ffmpeg -i  /Dropbox/stream/hls.sdp -acodec libfaac -ac 2 -b:a 128k -vcodec libx264 -vpre libx264-ipod640 -b:v 500k -threads 0 -g 75 -level 3.1 -map 0 -vbsf h264_mp4toannexb -flags -global_header -f segment -segment_time 10 -segment_list hls.m3u8 -segment_list_flags +live -segment_list_entry_prefix -segment_format mpegts stream%05d.ts


Here we are telling FFMPEG to use the SDP file we exported from QTB as the input, I saved it to my Dropbox. Then we are specifying the compression parameters for the transcoded MPEG transport stream (TS) files. You can easily find other examples of various FFMPEG compression options and use them depending on your requirements.

The segmenter options define how big the segments will be and where the .m3u8 file will be created – in this case I specified 10 second segments and the m3u8 file is being created in the folder where I ran FFMPEG from. The .m3u8 file and TS segments should be created in, or later moved to a folder accessible from the internet.

The segment_list_entry_prefix defines the prefix to the TS files in the m3u8 file, this is the configured url of your web server including the uri to your HLS files.

Finally the name used for the segment files is defined. Note the +Live segment_list_flags option, this tells ffmpeg that we will be transcoding live content. The official documentation for all these options can be found here.

Configure your ffmpeg options, start the QTB broadcast and run FFMPEG. If all is working you will see FFMPEG starting to receive and transcode the unicast video (and audio) data.

Now point your i-Phone/Pad/Pod or HLS client (i.e. VLC, Safari) to the m3u8 file on your webserver, i.e. from the options I used above the url would be :

You should see your live video stream.

My video stream had about a 60 second lag time. Disconnect and reconnect and you will see you are receiving live content – with the 60 second lag. Note that FFMPEG doesn’t automatically remove the old TS segments, you need to handle that yourself.

If it doesn’t work check FFMPEG for errors, note that some of the segment options need a relatively new version of FFMPEG to function. I downloaded and compiled the latest version of FFMPEG and it’s dependencies on my Ubuntu server using the guide found here.

Make sure the m3u8 file and MPEG TS segments are accessible from the web, open the m3u8 file in a text editor to check the url being used for each segment.

If FFMPEG starts dropping files it means your live data is coming in too fast for FFMPEG to process, you need to look at your compression settings. Try reducing the length of the TS segments from 10 seconds to 2 seconds, Remember your server must be able to transcode and save the live data within these times otherwise the stream will start to stutter.





Amazon iFrame X-Frame-Options SAMEORIGIN error

I didn’t realize that Amazon restricted access to product content in iframes with an X-Frame-Options header until yesterday (16.02.2014) when they applied the same iFrame restrictions to their admin backend Amazon Seller Central.

This made me very grumpy.

I created an eBay and Amazon admin website to allow us to consolidate order info from both merchants. It was useful to go directly from this site to the Amazon order in seller central by clicking on a button, even more useful was showing this in a fancybox iframe so the user didn’t have to leave the admin page. This worked, up until yesterday, when the iframe request is cancelled due to a :

Refused to display …. in a frame because it set ‘X-Frame-Options’ to ‘SAMEORIGIN’.

X-Frame-Options is an HTTP response header to prevent framing of pages. If the header is present the browser will refuse to render (cancel) the page in a frame depending on the values:

DENY – stops all framing
SAMEORIGIN – stops framing except for requests from the website itself.

So it looks like Amazon changed the security policy on their customer admin pages (Seller Central) yesterday to match the front end product pages and block frame request to content using the SAMEORIGIN header. There is no way around this so it is no longer possible to frame any amazon content. Boo!

The workaround is to load the content into a new _blank page and not use iframes – Hurrah!

Upgrading Magento 1.7 to

A few notes after upgrading to Magento from

Make sure you backup your Database and Magento source directory first! My first upgrade attempt using Magento connect (via SSH) failed, The following error appeared when trying to load the site

“Call to a member function rewrite() on a non-object”

After googling the error and trying a few suggestions the install was still broken so I restored from backup and tried again. This time I followed the following steps

1. Remove cached files from /var/cache and /var/session

2. Restart memcached (if being used)

3. Sync mage


./mage sync

4, Run upgrade (with force switch)

./mage upgrade-all –force

5. Reset ownership and permissions on all files and folders.

Magento loaded without error.

There are no major database changes between and so you can restore your 1.7 installation and switch between the two versions quite easily if you need to do any debugging etc.


Ajaxx Tweet – send direct messages via Twitter from web apps using Ajax


I wanted to be alerted when something changed in a Magento admin web application (new customer registration). I guess notifications by email are a little bit old fashioned and I thought a Twitter DM notification would be a more up to date solution.

The PHP classes allow you to create Tweets or DM’s via an Ajax request as demonstrated here.

It uses a simple JavaScript function to make an ajax call containing the data for the tweet. Can be used for any type of notification, app warnings, customer messages, contact forms, etc. etc. etc.

Source code coming to GitHub soon.

PHP Application & Ajax Request Security / Authentication

I have been using Ajax a lot recently in my PHP applications, especially in my Magento interfaces to retrieve order and customer information. Working with Magento in PHP you need to be careful you do not completely bypass Magento application security by creating open access to the Magento back end code via your PHP scripts, this is especially the case when using Ajax.

For a previous web site I looked at implementing best practice methods for implementing PHP session security and persistent login security for application logins. I revisited this code to create a PHP security class that I could quickly implement to add application login / persistent login security to a PHP app and additional authentication checks for Ajax requests.

The demo below shows the code in action, for login and Ajax authentication. Login using the demo username and password, then check the links out to read about the best practices implemented by the PHP class.

Source code on request.


Magento HTML Invoices, Print, Save, PDF

A Magento invoice display and printing system using PHP that can run externally to Magento.

The application displays Magento orders based on a time range in days and lets you display or print them with one click.

You can select a range of orders and preview the invoices, or print them by clicking on each order to select it. and clicking the print button.

Acknowledged orders (printed orders) are recorded and shown with a print symbol next to the order. (requires a configured cache folder writeable by www user.)

Click the time range to change the order time range in days. Some customer data can be edited directly in the app and exported to a text file which can be useful for automatic imports to shipping software etc.

Invoices can be displayed in the language they were placed in – simply create a translation file for your language and configure the application store id’s and languages.

Tested with
Chrome and Firefox – IE9/10 has some issues with printing.
Magento 1.3x – 1.7x (Community Edition)

Source code

Copy the source files to a web accessible folder and configure settings in the configuration files. Point your browser at the installation folder to view orders.

BETA Demo below NOTE - no application security has been included, you should secure the application folder with Apache or implement a PHP login system. Installing the app in a public folder will give public read/write access to your Magento data!