Limit login attempts locks every day or so from 127.0.0.1

I use the WordPress Limit Login Attempts plugin a little bit across various WordPress sites that I run and support. Lately i’ve toyed with fine tuning some of these sites by using Limit login attempts in conjunction with Nginx and Varnish.

Varnish happens to be a reverse proxy (more on varnish here varnish) which means all traffic is routed through it first.

Every other day I would get a message telling me that limit login attempts has exceeded total amount of failed attempts from IP 127.0.0.1 – after a little brain racking and a bit of confusion I had an aha moment! Varnish was causing all failed login attempts to be from the same IP I.E the local one!

Once I realised this was the cause of the problem it was pretty simple to fix. Limit login attempts has an under reverse proxy setting which is as simple as just flicking on to prevent this problem.

Simple as that, quite frustrating until you realise this though. So i’m hoping it helps someone else out sometime in the future.

If – a poem written in 1895 by British Nobel laureate Rudyard Kipling

If you can keep your head when all about you are losing theirs and blaming it on you, if you can trust yourself when all men doubt you, but make allowance for their doubting too; if you can wait and not be tired by waiting,or being lied about, don’t deal in lies, or being hated, don’t give way to hating, and yet don’t look too good, nor talk too wise: if you can dream – and not make dreams your master; if you can think – and not make thoughts your aim; if you can meet with Triumph and Disaster and treat those two impostors just the same.

If you can bear to hear the truth you’ve spoken twisted by knaves to make a trap for fools, or watch the things you gave your life to broken, and stoop and build ‘em up with wornout tools: if you can make one heap of all your winnings and risk it on one turn of pitch-and-toss, and lose, and start again at your beginnings and never breathe a word about your loss.

If you can force your heart and nerve and sinew to serve your turn long after they are gone, and so hold on when there is nothing in you except the will which says to them: ‘Hold on!’

If you can talk with crowds and keep your virtue, or walk with kings – nor lose the common touch.

If neither foes nor loving friends can hurt you, if all men count with you, but none too much; if you can fill the unforgiving minute with sixty seconds’ worth of distance run -yours is the Earth and everything that’s in it, and – which is more – you’ll be a man my son!

Laravel .htaccess localhost MAMP and Mac OS X

I was, like anyone, excited about the release of Laravel 4 and quickly set about following the initial installation instructions on a vanilla vhost locally to have a play around with. I quickly found that the default suggested .htaccess file was causing a server error in MAMP on OS X.

I got around it with a little trial and error and can confirm the below contents in your .htaccess file – works great for me.

Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /index.php [L]

The offending line from the suggested .htaccess contents was

RewriteRule ^ index.php [L]

Vim delete all lines in currently open file

It’s been a while since I blogged anything so I thought i’d stick this up which I found useful from time to time.

Deleting all lines in a currently open file when opening from vim in mac terminal.

Type gg to move the cursor to the first line of the file, if it is not already there.
Type dG to delete all the lines.

Then press “i” to insert new lines or copy from clipboard.

How to get the ID of Facebook Page loading application as a page tab

Sometimes you might be required to build a Facebook Application which might go live on several different Facebook page tabs. Often as a subset of being installed in several locations you may find you want to make subtle tweaks to the Application itself. Many Facebook app developers will hard code some of the URLS which they use for redirection in their code base, this is not good practise and tends to lead to these such problems. With the following example you will be able to install the same Application across many different Facebook Pages with the ability to record and adapt the Facebook page currently loading the application by the page ID.

I’ve had to consider this problem at length for work this weekend and found that there was really not much decent documentation on it (least not anything particularly coherent). Needless to say I did still manage to find some documentation and with a bit of googling pieced together how to do this.

Facebooks documentation states the following:

When a user navigates to the Facebook Page, they will see your Page Tab added in the next available tab position. Broadly, a Page Tab is loaded in exactly the same way as a Canvas Page. When a user selects your Page Tab, you will received the signed_request parameter with one additional parameter, page. This parameter contains a JSON object with an id (the page id of the current page), admin (if the user is a admin of the page), and liked (if the user has liked the page). As with a Canvas Page, you will not receive all the user information accessible to your app in the signed_request until the user authorizes your app.

One way to achieve this using the Facebook SDK would be to grab the signedRequest using the Official PHP SDK. Here’s an example:

// PATH TO FB-PHP-SDK
require '../../src/facebook.php';
$facebook = new Facebook(array(
  'appId'  => 'APP_ID',
  'secret' => 'APP_SECRET',
  'cookie' => true,
));
$signed_request = $facebook->getSignedRequest();
if( $page = $signed_request['page'] ) {
    echo $page['id'];
}

I also learned that Facebook via the signed_request method would make user_id, other basic information (such as age) a locale and a country so that you can serve age related or locale related content. Right on the money for me who needs to serve content in different languages using it icon smile How to get the ID of Facebook Page loading application as a page tab

Or you could roll your own and grab it without the Facebook SDK like so:

if(!empty($_REQUEST["signed_request"])) {
    $app_secret = "APP_SECRET";
    $data = parse_signed_request($_REQUEST["signed_request"], $app_secret);
    if (isset($data["page"])) {
        echo $data["page"]["id"];
    } else {
        echo "Not in a page";
    }
}
function parse_signed_request($signed_request, $secret) {
    list($encoded_sig, $payload) = explode('.', $signed_request, 2);
    // decode the data
    $sig = base64_url_decode($encoded_sig);
    $data = json_decode(base64_url_decode($payload), true);
    if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
        error_log('Unknown algorithm. Expected HMAC-SHA256');
        return null;
    }
    // check sig
    $expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
    if ($sig !== $expected_sig) {
        error_log('Bad Signed JSON signature!');
        return null;
    }
    return $data;
}
function base64_url_decode($input) {
    return base64_decode(strtr($input, '-_', '+/'));
}

Both of these methods will return the page ID of the Facebook Page loading your application. You could then save to session and store against the user when they authenticate or all manner of other quirky things and start tailoring your App for each page if needs be.

Serving static assets from AWS S3 & CloudFront

This is the first in a two part blog about configuring a WordPress install to successfully serve both static assets (your themes static assets such as css, javascript, images etc) via Amazons Web Services (AWS) S3 and CloudFront.

This blog will cover how to serve your static assets from an Amazon S3 bucket & configuring that bucket to be served by Amazons Cloudfront Content Delivery Network (CDN) service for optimised delivery of assets across the world. if you are unfamiliar with what a CDN can do for you then I recommend reading the following article Jack Whitey – CDN

Throughout this article I assume that you already have an Amazon AWS account. If you do not, then please visit Amazon AWS and register an account before continuing.

Login to your Amazon Account and then visit the ‘My Console’ tab. Once you have located this visit the S3 tab and create a bucket.

Give the bucket a relevant name and just choose Region ‘Us Standard’.

You’ve now created your amazon S3 bucket. Nice. But, it’s not much use, so let’s upload an image file to it. Click the upload button and upload a random image file on your machine to it. Hit start upload and then watch. Once it’s uploaded it should appear in the left hand side bucket. If it does, click it and change the tab on the top left to ‘Properties’ here you’ll find a link to the item. Click it and you should be faced with a permission denied XML output alot like the image below.

Screen Shot 2013 03 25 at 13.42.16 Serving static assets from AWS S3 & CloudFront

This is good as I want to expose you to an important part of S3, permissions. Permissions in terms of Amazon S3 mean whether or not something is public or privately viewable. Complicated rules can be created to determine the visibility of any item in any S3 bucket.

In our case we just want this file to be publicly viewable. So, we’ll just click properties on the image and then permissions and add a new rule for ‘Everyone’ to Open/Download and save. Now if you click the same link once the save has been successful you should see the image served.

Well done! This is your first image being served from the Amazon S3 bucket service. Although this is now being served by Amazon S3 you can go better. Serving that same image via Amazons own CloudFront service will perhaps give your site a bit more global oomph! CloudFront syncs your bucket across all Amazons data centres around the world and routes requests to the nearest (most local) data centre. This should ensure that all static assets are served from a geographically closer location than if you just hosted it from the US only region.

To enable CloudFront for your application you need to head back to your Amazon Console and open the CloudFront Service. Once you have it open follow the steps below:

  • Click ‘Create Distribution’
  • Choose the ‘Download’ option
  • Set Origin name to yourbucketname.s3.amazonaws.com
  • Leave all the other settings at their default settings
  • If you would like to map a CNAME to your distribution then you can add the CNAMES in the box ‘Alternate Domain Names(CNAMEs)’ perhaps something like cdn.yourdomain.com
  • You can then update your DNS records to reflect this CNAME record.
  • Click create distribution

The distribution will take about 10 minutes to spin up. Once it’s done the important thing to note is your domain name for example – d3pmoderwnmasf.cloudfront.net/. This is the base URL for your buckets contents when served over CDN (you can also use the CNAME you registered).

Depending on how quickly your CNAME resolves you will be able to access your file via d3pmoderwnmasf.cloudfront.net
or your CNAME.

In a small test against serving from an S3 bucket from the US region versus calling the bucket via the CDN I was serving an image asset at an average of 130 ms from the bucket and 30 ms from the CDN. The biggest part of which was probably that being in the UK my requests from the CDN we’re probably being routed to the EU Ireland data centre accounting for a dramatically quicker geographical serving.

You can now link to these assets very easily in your code by using your CDN URL.

So thats serving assets from an S3 bucket, but, where does WordPress come in I here you ask? Continue reading as this is where it all gets interesting.

WordPress, Scaling and asset serving/uploading to S3

If you are looking to scale a WordPress site and serve all assets via an S3 bucket fronted by the AWS CloudFront CDN then this is where things get interesting.

In part II – Serving WordPress assets from AWS S3 and AWS CloudFront »

I deal with how to configure WordPress to upload all uploaded content to the Amazon S3 bucket automatically and how to use a third party service such as beanstalkapp.com to automatically push static assets to S3 when a new deployment is ready at the source code level (it’s very neat).

Install Laravel with symlink through terminal shell function/command mamp

I’ve been throwing together a few useful mac terminal os x shell scripts lately and this was another one of those cases today. It’s not completely finished just yet but it will do a job the first time round. I’m not sure just yet how best to have lots of different symlinks to different Library bases and how to code that so that it happens.

The below code and it’s paths are relevant to me and my setup with MAMP. You can easily edit this function to include different paths as you require.

Open up your ~/.bash_profile

sym-install-laravel () {
    echo “Installing Laravel as symlink to $1″
    mkdir -p ~/Develop && cd ~/Develop
    DIR=”/Users/davidheward/Develop/Laravel”
    if [ ! -d "$DIR" ]
    then
        git clone https://github.com/laravel/laravel.git Laravel
    else
        echo “Directory already exists”
    fi
    cd /Applications/MAMP/htdocs
    ln -s ~/Develop/Laravel/public/ /Applications/MAMP/htdocs/$1
    cd /Applications/MAMP/htdocs/$1
    echo “Install complete”
}

Save it close and open a new terminal session or reload profile ./profile

Then you can simply cd into your desired directory for me it’s /Applications/MAMP/htdocs/ because i’m running MAMP on my Mac OS X machine and run the following at the terminal.

$ sym-install-laravel symlara

Visit this by just hitting http://localhost/symlara/ in your browser (if you have localhost configured in this way of course).

Git diff only show file names with changes

If you just want to see a list of files with changes in the .git repository you are in then just fire terminal up and run the following command.

git diff --name-only

For a more detailed view of all changed files:

git diff

For a detailed view of just one file:

git diff application/routes.php

Show all un-committed / un-tracked files

git ls-files --other --exclude-standard

Undo the last commit

git reset --hard HEAD^1

All pretty useful git diff commands.

Install WordPress From Mac Os X terminal bash/shell/terminal profile function

Sometimes staying on top of the latest version of WordPress can be quite annoying when your testing things locally or rolling out regular wordpress sites. I normally install with .svn but this is a neat little bash script function I threw together to grab the latest version of WordPress and unzip into the current directory through Mac OS X Terminal command.

Open up your

vim ~/.bash_profile

and paste the following code into it.

wp-install(){
	wget http://wordpress.org/latest.tar.gz;
 	tar xfz latest.tar.gz;
	mv wordpress/* ./;
	rmdir ./wordpress/;
	rm -f latest.tar.gz;
}

Now quit and re-open terminal or type ./profile for the changes to take effect.

CD into the desired directory and type wp-install and let magic behold you, you’ll shortly have the latest version of WordPress downloaded and installed.

Translating PHP application using gettext & msgfmt with .po / .mo files

Firstly install the gettext cmd line tools.

brew install gettext
brew link gettext

If your not a big fan of homebrew you can do the same using macports. Personally I really like homebrew and if you’d like to give it a try go to Homebrew. This will install useful cmds such as xgettext, msgfmt, msginit & msgmerge.

Fire up a fresh terminal and cd into your PHP apps working directory /Applications/MAMP/htdocs/my_app/ in my case.

I’d suggest getting yourself a local environment to test this on. I’m using MAMP and have created a new folder in the htdocs called localetest. Call it whatever you like and create a few PHP files with strings of echo gettext("This is translatable string"); or echo _("This is translatable string");

Once you’ve done this open up a terminal and cd into your cd /Applications/MAMP/htdocs/yourfoldername/

Once in it your going to run a command which will recursively search through the PHP files in this entire directory looking for translatable strings.

find . -name "*.php" | xargs xgettext -a --from-code=utf-8

or more simply

find . -iname "*.php" | xargs xgettext

The first part of this command will search recursively starting from the current level of directory structure for .php files. xargs builds and executes from standard input and executes the xgettext command for each file. This command searches the input from the found files for strings of gettext() or _() in a .php file and outputs them into a messages.po file.

Run the command and you’ll end up with a file a little like this one.

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSIONn"
"Report-Msgid-Bugs-To: n"
"POT-Creation-Date: 2013-01-17 10:13+0000n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONEn"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>n"
"Language-Team: LANGUAGE <LL@li.org>n"
"Language: pt_PTn"
"MIME-Version: 1.0n"
"Content-Type: text/plain; charset=UTF-8n"
"Content-Transfer-Encoding: 8bitn"
#: another.php:3
msgid "Another string in file 2"
msgstr "mumbo jumbo"
#: index.php:3
msgid "Lets make this a translatable string"
msgstr "oh mumbo jumbo la la la"
#: index.php:4
msgid "Another translatable string"
msgstr "Otra cadena traducible"
#: index.php:5
msgid "Something here"
msgstr "Algo aquí"

If you look toward the bottom of this file you’ll notice it’s picked up our translatable strings. Also, notice, I have manually filled in the language this is going to correspond to under “Language: pt_PTn” and also set the character under the content type: “Content-Type: text/plain; charset=UTF-8n”. You’ll also notice I made some mumbo jumbo translations (which are not portuguese) to illustrate the translation.

Create a directory structure in your app which is going to help you organise your translations for instance mine is something like this.

Screen Shot 2013 01 17 at 11.29.56 Translating PHP application using gettext & msgfmt with .po / .mo files

Example folder structure for gettext

Once you have created th

Once you create this you will need to fire off a few more cmd line cmds. So fire up your terminal boys…

The next cmd you will run will create a .mo file which is a machine readable binary file used by gettext in PHP to quickly provide the translations.

msgfmt -cv -o locale/pt/LC_MESSAGES/messages.mo locale/messages_pt.po

After you run this cmd you should get a response finishing in 4 translated messages. This is actually the last step in the creation of files. Next we need to configure our app to detect the locale and forcibly translate our gettext snippets on the fly for us.

This can be achieved in a multitude of different ways and my solution below will not suit all. It is mainly here for demonstration purposes only. In the top of any of your .PHP files in your local directory add the following code.

$locale = "pt_PT";
putenv("LC_ALL=$locale");
setlocale(LC_ALL, $locale);
bindtextdomain("messages", dirname(__FILE__).'/locale');
textdomain("messages");

This will force your app to use the locale pt_PT and in doing so use the translations provided by you in the .po file.

Important: Each time you provide more translations you must re-build the .mo files with the following command.

msgfmt -cv -o locale/pt/LC_MESSAGES/messages.mo locale/messages_pt.po

Edit:

I recently found that when receiving translations from Windows users (as is the case quite often) the .po files need to be re-saved with UTF-8 encoding. I also found sometimes Windows users might get .BOM extension added to the files as well. This will not be interpreted by msgfmt correctly and will result in a fatal error on compilation. A save in the correct encoding will fix this.

Also another handy tip when installing gettext for translating:

Since I wrote this post the brew formula for gettext has changed and now is ‘keg-only’ you will find it is not symlinked and symlinking it may cause issues when installing and compiling other applications.

Even though it is not symlinked you can still find the binary like so:?
/usr/local/Cellar/gettext/0.18.2/bin/msgfmt -cv -o locale/fr_FR/LC_MESSAGES/messages.mo translations/messages_fr.po