Note to self: PHP classes are case insensitive

Class names in PHP are case insensitive. The following two are equivalent:

class Something extends BaseClass {}

and

class someThing extends baseClass {}

However…

If you are using an autoloader that searches for a class file when the class is required, the autoloader will match the file based on the filesystem’s case-sensitivity. This caught me out because I develop on a Mac which is case-aware but not case sensitive. When I deployed some code to a Linux server I discovered I had a class which … extends view rather than … extends View. The autoloader found the file (View.php) on my dev machine but the remote server was looking for view.php, couldn’t find it and erorred out.

Open House Route Planner – an experiment with Silex, Twig, Eloquent and Backbone

London Open House is an annual event where buildings across the capital that are normally inaccessible are opened up for the public to explore. This year’s event runs from 20th – 21st September and I usually try to get to see a few different things over the two days to make the most of the opportunity.

The Open House website lists all the buildings and information and has a search facility, but frustratingly doesn’t offer a simple way to collect together a list of the buildings you might want to see and plot some kind of itinerary for the day. That being the case I thought I would use it as an opportunity to build a tiny web app to help me plan my weekend and learn some new technologies along the way.

You can see the current version here: Open House Route Planner
I won’t go into all the ins and outs of the build but here a few thoughts on the various technologies I used:

Silex

Silex is a PHP micro-framework based on the Symfony set of components. I really like the simplicity of the Silex approach. It gives just enough structure to get things going but it doesn’t tie you down to a particular way of working. Here’s the canonical example from their site to give you an idea:

$app = new Silex\Application();

$app->get('/hello/{name}', function($name) use($app) {
return 'Hello '.$app->escape($name);
});

It makes for very readable code and allowed me to prototype things quickly. Naturally, as the app gets more complex there are better ways to structure things, but I like being able to get a quick result without having to dig into a whole load of examples and documentation.

Silex Skeleton

A quick nod to Silex Skeleton which sets up a nicely-organised Composer-based project for Silex apps. You can simply type composer create-project fabpot/silex-skeleton new-app and you’re almost ready to go.

I had to tweak a couple of things (like adding an .htaccess file to push everything to the front controller) but otherwise it was a very useful base on which to build

Twig

Twig is a templating engine made by the same people as Silex and integrates nicely with it. I hadn’t used it directly before, although I had looked at using it in some WordPress projects. If uses the double braces (eg. {{ thing }}) convention familiar to anyone who has used Moustache, but unlike that engine, it allows for some logic with the templates and comes with quite a few built in filters and helpers to format data correctly.

My templates were fairly simple so I didn’t get to explore the full potential but it might make an appearance in future projects if it seems suitable.

Eloquent ORM

Now this is one area of the backend that took most of the time to set up. Naturally, I needed a basic database to store my buildings and routes in and I started looking at connecting Silex to a database of some kind. To make things a bit more interesting I thought instead of using a simple access layer I would make use of an ORM solution to abstract away the persistence layer making it more flexible in the future. Also it would give me another bit of technology to learn.

Doctrine seems to be the biggest player in the PHP ORM arena an and whilst it is certainly powerful, the learning curve looked like it would sap my limited time. Instead I opted for Eloquent ORM which is part of the Laravel PHP framework. It has a nice fluent interface and there is an adapter to connect it to Silex as a service.

That said, it still took me some time to get my head around setting up the database schema and establishing the relations between my tables so that I could use the ORM correctly. The documentation is ok and although it is a fairly popular project, a lot of the examples I found were (understandably) using the Laravel framework so I had to disentangle the nuggets of information that I needed to get things working.

In the end it would probably have been quicker to use a simple DBAL and write the SQL by hand for what I needed. Still, it was good to get a sense of what Eloquent is capable of for more complex projects.

Goutte

One last thing I needed for the backend was a way to get the information about each building so that I could build my list. Goutte is a nice little web-scraping library that wraps a few other things (such as Guzzle) to make it easier to grab the page from the Open House site and extract the basic info I needed.

Note: naturally I cached the scraped pages heavily so that I wouldn’t end up hitting the Open House site itself more that was necessary – they are a charity after all.

Once all that was wired together I ended up with a very simple REST API that I could query to add and retrieve collections of buildings and render them to the front end. Talking of which…

Frontend: Bower, Backbone, HTML5 Sortable, Map Icons

Having built the backend I could then use a very small Backbone-based app on the front end to pull the data and render it as a list with accompanying map. I used this lightweight HTML5 Sortable jQuery Plugin to allow users to drag and drop buildings into whatever order they wanted.

I looked at a few options for rendering maps but in the end I went with the simple solution – Google Maps. The API is reasonably easy to use and had most of the features I needed. One wrinkle was that I needed to display numbered markers to show the sequence of building that the user was planning to visit. Unfortunately the Google Maps markers don’t have a simple way of achieving this, but luckily I came across these (map icons)[http://map-icons.com/] which extend the standard marker and allow arbitrary text to overlay the icon.

Summary

So I’m pretty pleased with the outcome – it does what I wanted it to do and allows me to share a simple URL with friends to suggest a possible route for the weekend. There’s not much in the way of styling and I didn’t really bother to test it beyond the devices I am planning to use it on, but as a proof of concept I think it stands up.

One of the great things about modern web development is the availability of a huge range of well-written, open source libraries and frameworks that allows for exactly this kind of experiment at relatively short order.

Finally, it was nice to step outside of the WordPress development bubble for a while and expand and test my knowledge of the wider PHP landscape. PHP gets a lot of bad press, but frankly you can write good and bad software in any language and the main thing for me is to keep learning from all the great code that is out there and to use it to improve my own work.

Killing a LiveReload server

LiveReload is super useful, especially in combination with grunt-contrib-watch as it enables me to quickly see my code reflected in the browser.

However, I am often working on more than one project and that can mean constantly having to shut down the running LiveReload server so that I can run grunt watch in another project’s directory.

To save the hassle of finding the process ID so that I can kill the server, I wrote a quick bash function to find whatever is running on the standard LR port of 35729 and kill it.

Thus… lrkill

I simply put this in my ~/.bash_profile and ran source ~/.bash_profile to update the current shell.

lrkill() {
    LRPID=`lsof -n -i4TCP:35729 | grep LISTEN | awk '{print $2}'`

    if [ $LRPID ]
        then
        echo 'Killing LiveReload server (PID: '$LRPID')'
        kill $LRPID
    fi
}

Now all I need to do is call lrkill and then grunt watch and my new LiveReload server is up an running.

This works in OSX, but other OS users may need to find an equivalent of lsof to achieve the same thing.

Flexbox, clear fix and pseudo elements in Safari and Chrome

If you are progressively enhancing a layout with flexbox, remember that when you apply display: flex to an element, the flex layout applies to all its children including any pseudo elements.

This can occasionally cause issues in some browsers if you already have a clear fix in place to ensure the height of the element respects any floated children. One of the most common ways of doing this is to set the pseudo elements ::before and ::after to force the parent element to wrap:

.clear-fix:before,
.clear-fix:after {
    content: "";
    display: table;
}

.clear-fix:after {
    clear: both;
}

But applying flexbox can cause these elements to obtain small width of 1px in some browsers which looks ugly and probably isn’t what you want. Here’s a pen to test it out for yourself.

The fix

To hide the pseudo element, we need to tell the flexbox algorithm that they should definitely have zero width by using the flex-basis property which sets the initial size of the flexitem.

However, for some reason (I think to do with the fact the pseudo-elements are display: table) that isn’t enough. The ::after element shrinks away to nothing, but the ::before remains. The only way I have found to fix this is by explicitly setting the order property to something other than the default 0. The seems to give flexbox the kick it needs to force apply the flex-basis to both pseudo-elements:

.clear-fix:before,
.clear-fix:after {
  flex-basis: 0;
  order: 1;
}

Because these properties are only available in browsers which support flexbox, they shouldn’t interfere with the styles in older browsers, so you don’t need to test with Modernizr before using it.

The culprits

I haven’t tested extensively but this is what I’ve found so far:

Browser Chrome Safari Firefox
Version 33 6.1.1 27.0.1
Display Incorrect Incorrect Correct

The flexbox spec is still settling down so this kind of anomaly is to be expected. Still it’s good to know there is a fix for it.

Tracking internal WordPress events with Google Analytics

Recently I have been trying to use more of the features of Google Analytics beyond the basic stats. In particular, I wanted to keep track of when I publish a new blog post so that I can look for any changes in traffic.

Now, for a tiny site like mine there’s not going a huge rush on the web to see what pearls of wisdom (or ignorance) I have unleashed on the world, nevertheless I thought it would be interesting and could certainly be useful to my clients who have more traffic to analyse.

Annotations – a feature in search of an API

Screenshot of an annotation on Google AnalyticsMy first thought was to use annotations to keep track of things. Annotations allow you to add a note to a certain point on your timeline to record when external events happened that might have had an impact on the data. For example it could be a new post, new code deployment or a change in hosting setup.

Seems perfect right? One problem: there is not external API for adding annotations. There is a feature request currently open for it but, given that it goes back to 2010, it seems unlikely that Google consider it a priority for future developments.

So, what next? Events to the rescue!

Events are commonly used for interactions that occur on a site, but which do not trigger a page view and therefore don’t send the tracking beacon. A good example is the opening of a modal overlay which contains some content or goal that you want to track. By triggering an event using the analytics JavaScrip code, you can record what happened and include it in your reports.

But what if we want to record an event that doesn’t include any direct user interaction with the site – for instance, publishing a post? Well it turns out we can use the rather grand sounding Measurement Protocol. To quote Google:

The Google Analytics Measurement Protocol allows developers to make HTTP requests to send raw user interaction data directly to Google Analytics servers.

How does it work? essentially, we make a POST request with the event information and a bit of configuration and Analytics will record the event as if we had clicked on something on the site.

curl --data "v=1&tid=UA-XXXXXXX-Y&cid=123-456&t=event&ec=WordPress&ea=Publish%20Post&el=The%20Post%20Title" https://ssl.google-analytics.com/collect

A full reference for the parameters can be found here, but essentially we set the UA string (tid), a reference to the user (cid) and then the details for the event.

Using it in WordPress

If we put all of these things together, we can tell WordPress to trigger an Analytics event when we publish a post. All we need to do is hook into the publish_post action and send a remote request using wp_remote_post and we have automatic tracking of our events.

add_action( 'publish_post', 'dbisso_trigger_ga_post_event', 10, 1 );

function dbisso_trigger_ga_post_event( $post_id ) {
    $title = get_the_title( (int) $post_id );

    $data = array(
        'v' => 1,
        'tid' => 'UA-XXXXXXXX-Y', // Replace with a real UA string
        'cid' => get_current_user_id(),
        't'   => 'event',
        'ec'  => 'WordPress',
        'ea'  => 'Publish Post',
        'el'  => $title,
    );

    wp_remote_post(
        'https://ssl.google-analytics.com/collect',
        array( 'body' => $data )
    );
}

To make things easier, I have rolled a small plugin that does the job of triggering the request at the right time with the correct parameters. I’ve called it Google Analytics Internal. Why the generic name? Well there are numerous other internal WordPress events that you might want to track in addition to publishing posts, so I left the door open to extending the plugin in the future.

Screenshot of event report in Google Analytics

Anyway, if you think this technique might be useful just download the plugin from your dashboard or from the WordPress plugin directory and give it a try.

The source code is available on GitHub so any issues or pull requests can be posted there.

Splitting old IE styles with Grunt

The need

I was looking for a quick way to extract my Internet Explorer styles into their own CSS file so it could be conditionally loaded for older versions of the browser and not clutter up my main stylesheet, so I took the opportunity to create my first Grunt plugin to achieve the task.

I tend to use old Paul Irish trick of using conditional comments to add extra classes such .ie8 to the HTML element depending on which version of Explorer is being used1. This means I can prefix any workarounds for those browsers with a class and not have them interfere with the rest of the styles.

Presenting… grunt-split-styles

The plugin grunt-split-styles allows you to extract rulesets from a CSS file based on the selector and move them over to a new file. It uses the excellent PostCSS post-processing library to do all the hard work of manipulating the CSS.

You can install via npm:

npm install grunt-split-styles --save-dev

The plugin allows me to add this to my Gruntfile

grunt.initConfig({
  split_styles: {
    ie: {
      options: {
        pattern: /\.ie[6|7|8]/,
        output: 'style-ie.css'
      },
      files: {
        'style.css': 'style.css'
      }
    },
  },
});

load in the plugin with…

grunt.loadNpmTasks('grunt-split-styles');

and then run

grunt split_styles:ie

Which should give me a separate file (style-ie.css) with just those selectors with the .ie[n] prefix included and a styles.css file without any extra IE-ness in the way.

Why? Why not!

Now, I have to admit, this was partly an excuse to play with making a Grunt plugin and using PostCSS rather than an meeting an urgent need. The case for having a separate stylesheet for old IE users along with its extra HTTP request (and probably parsing / paint issues) is not so strong that I will need this on every project I do.

That said, I hope by making it flexible (you can extract any selector or media query that you can build a regular expression for) that I may find more uses for it in larger projects beyond its original scope. Some possibilities include:

  • Use Modernizr’s feature-detect classes to only load CSS with data URIs when they are available in the browser.
  • Collect particularly heavy styles relating to a lesser-used section of a site (assuming something like <body class="section-heavything">).
  • Extract styles for a particular widget or script and load them in with the Javascript when needed.
  • Use the mediaPattern option to create a widescreen specific stylesheet.

Perhaps the most important lesson was that Grunt plugins are pretty simple and enjoyable to get started with so I hope to make some more in the future to improve my workflow.

Yours for the taking

The plugin, along with instructions is up on GitHub so do try it out and do reach out to me if you find it useful.


  1. I am aware that this technique has been removed from the HTML5 boilerplate, but some of us often still have to support older versions of IE in some form and the extra classes are a simple way of targeting them. 

Note to self: Firefox handles inherited height differently

Unlike Chrome and Safari, elements in Firefox don’t automatically inherit their heights from the containing element. So elements with implicit height (eg. images) will stretch the containing element to to their full height.

To prevent this happening, each descendant element of a container with a height must have either and explicit heigh (probably height: 100% or height: inherit. Note that IE7 doesn’t support inherit as a value for height.

See this pen for a test case.

I’m not clear which browser is out of spec on this.

Note to self: user_has_cap doesn’t do what you think it does.

The WordPress filter user_has_cap is a bit misleading. It doesn’t (as the name suggested to me) return a boolean indicating whether the user has a given capability. Instead it allows last minute filtering of the capabilities that a user has, allowing you to add and remove caps just before they are checked against those required for the particular action.

The arguments are:

  • $allcaps
    • The array of caps that the given user has assigned to them
  • $caps
    • The array of caps required for the current action
    • Has already been filtered through map_meta_caps
  • $args
    • Additional arguments passed to the has_cap() method of the user object
    • May contain post ID or other info needed for cap check

A user_has_cap filter might make additional checks against the user and then set or unset the relevant capability in the $allcaps array before returning it.

Note to self: the map_meta_cap conversation

The WordPress function current_user_can() calls $user->has_cap() which calls the map_meta_cap filter.

The purpose of map_meta_cap is to filter and return the list of capabilities that a user needs to complete a task. Essentially, the conversation goes something like this:

has_cap: “Hey, user ‘Dan’ would like to read_post 342. What caps will he need?”

map_meta_cap: “He’ll need read, read_post and read_published_posts

has_cap: “Cool. Let me see if he has all of those. … Looks like he does! I’ll let current_user_can() know.”

The other thing to remember is that capabilities are cumulative. Each additional cap that map_meta_cap returns makes the permission more restrictive: has_cap() will check each one in turn against the capabilities that the user has and bail out immediately if any are not present.