CSRF Protection in PHP

All the libraries I found via $ composer search required coding to work. But csrf-magic only requires that you include the project file and everything else happens magically. (Behind the scenes it adds a hidden __csrf_magic form element to all forms). This does mean that error handling is by default kind of ugly, but there’s a hook to change that should you wish.

History (Third Time)

[zarquon ~] history | awk '{a[$2]++}END{for(i in a){print a[i] " " i}}' | sort -rn | head
1772 vi
1727 c
1496 php
1458 git
1394 ssh
1303 cd
887 ls
711 pass
380 sudo
379 ruby

Compare to nearly four years ago. New: c, ruby [but was there in 2008], pass, sudo. Climbers: vi, php, ssh. Fallers: git, cd, ls. Old: mate, rsync, cat, make.

Run MacVim Inside a Terminal

MacVim is the de facto standard vim for OS X now. But you don’t necessarily want to run it as a separate GUI application. If you’re making a quick edit in a terminal you want to stay in the terminal environment.

You can achieve this with mvim -v {filename} where mvim is this shell script.

Use System Clipboard in vim

  • Install a version with vim with +clipboard. You can check your current setting with :echo has('clipboard'). “1” is good, “0” is bad. This lets you access the system clipboard with (for example) “+p to paste.
  • Add clipboard=unnamed to .vimrc and restart vim. You are now using the system clipboard by default for all cut/copy/paste operations.

Mustache Templates in PHP

I’ve always admired the simplicity of Mustache templates but the complication of internationalization support has always prevented me using them until a recent project. I used them in my Magic: the Gathering tournament software.

Mustache templates look like this:

<h2>Create Event</h2>

<form action="{{formAction}}" method="post">
  <label for="format">Format</label> <input type="text" name="format">
  <label for="cost">Cost</label> <input type="text" name="cost">
  <input class="btn btn-primary btn-block" type="submit">
</form>

You can see a bunch from the project at https://github.com/bakert/tournament/tree/master/views.

As long as you have { "require": { "mustache/mustache": "~2.5" } } in your composer.json using them is as simple as:

$loader = new Mustache_Loader_FilesystemLoader('path/to/templates');
$engine = new Mustache_Engine(['loader' => $loader]);
echo $engine->render('template_name', $arguments);

I wrapped this up in a class (Template) and a global (T()) so I could make calls like this:

echo T()->signin($args);

Treat cURL as a Stream in PHP

class HttpStream {

    public class go($url) {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_WRITEFUNCTION, array($this, 'streamHandler'));
        curl_exec($ch);
        curl_close($ch);
    }

    protected function streamHandler($ch, $data) {
        // Handle the stream here
        // ...
        return strlen($data); // strlen($data) to continue streaming or return another value to end the stream.
    }
}

CSS Sprite for Magic: the Gathering Mana Symbols

Image:

Mana symbols sprite

CSS:

.mana {
    display: inline-block;
    background: url('/img/mana/mana.png') no-repeat;
    color: transparent;
    width: 15px;
    height: 15px;
}

.mana-2b { background-position: -0px -0px }
.mana-br { background-position: -15px -0px }
.mana-r { background-position: -30px -0px }
.mana-gw { background-position: -45px -0px }
.mana-2r { background-position: -60px -0px }
.mana-2w { background-position: -75px -0px }
.mana-rb { background-position: -90px -0px }
.mana-rg { background-position: -0px -15px }
.mana-wb { background-position: -15px -15px }
.mana-6 { background-position: -30px -15px }
.mana-gr { background-position: -45px -15px }
.mana-bu { background-position: -60px -15px }
.mana-s { background-position: -75px -15px }
.mana-2 { background-position: -90px -15px }
.mana-8 { background-position: -0px -30px }
.mana-wu { background-position: -15px -30px }
.mana-ru { background-position: -30px -30px }
.mana-cp { background-position: -45px -30px }
.mana-uw { background-position: -60px -30px }
.mana-3 { background-position: -75px -30px }
.mana-gb { background-position: -90px -30px }
.mana-2g { background-position: -0px -45px }
.mana-5 { background-position: -15px -45px }
.mana-16 { background-position: -30px -45px }
.mana-bp { background-position: -45px -45px }
.mana-y { background-position: -60px -45px }
.mana-17 { background-position: -75px -45px }
.mana-11 { background-position: -90px -45px }
.mana-2u { background-position: -0px -60px }
.mana-ug { background-position: -15px -60px }
.mana-wg { background-position: -30px -60px }
.mana-b { background-position: -45px -60px }
.mana-up { background-position: -60px -60px }
.mana-gu { background-position: -75px -60px }
.mana-ub { background-position: -90px -60px }
.mana-u { background-position: -0px -75px }
.mana-rp { background-position: -15px -75px }
.mana-19 { background-position: -30px -75px }
.mana-13 { background-position: -45px -75px }
.mana-g { background-position: -60px -75px }
.mana-12 { background-position: -75px -75px }
.mana-wr { background-position: -90px -75px }
.mana-w { background-position: -0px -90px }
.mana-gp { background-position: -15px -90px }
.mana-bw { background-position: -30px -90px }
.mana-bg { background-position: -45px -90px }
.mana-ur { background-position: -60px -90px }
.mana-7 { background-position: -75px -90px }
.mana-x { background-position: -90px -90px }
.mana-rw { background-position: -0px -105px }
.mana-9 { background-position: -15px -105px }
.mana-10 { background-position: -30px -105px }
.mana-20 { background-position: -45px -105px }
.mana-14 { background-position: -60px -105px }
.mana-0 { background-position: -75px -105px }
.mana-wp { background-position: -90px -105px }
.mana-18 { background-position: -0px -120px }
.mana-1 { background-position: -15px -120px }
.mana-15 { background-position: -30px -120px }
.mana-4 { background-position: -45px -120px }

Usage:

    <span class="mana mana-2">2</span>
    <span class="mana mana-b">B</span>

Dead Simple Google Maps API Geolocation

Google turned off the v2 Google Maps API on September 9th which means my 2008 PHP Wrapper for Google Maps API Geocoding has ceased to function.

I’ve put a replacement dead simple PHP wrapper of the v3 Google Maps Geolocation API on github. It has the same API as before.

v2 of the API now gives "We're sorry... ... but your computer or network may be sending automated queries. To protect our users, we can't process your request right now. See Google Help for more information." which isn’t a super useful message.