IP geolocation is something that’s needed more and more as people publish & trade internationally. Stores want to offer different pricing, currencies, shipping rules to different countries, or provide content in different languages.
Many systems have something already baked in, but working on a project recently I needed to do some simple country-level IP geolocation. My previous iteration had used a third party service, but that slowed things down, and had a tendency to be unreliable – recently going AWOL for a couple of weeks!
There are some free GeoLocation databases provided by MaxMind, but I doubt I’m telling you anything new there, it seems to be fairly well known about. However I’ve never actually used them myself directly, so in I dived.
Firstly I used their public PHP wrapper:
I was able to pull it into my project using Composer really easily, download the database and hook it up simply. Running a geolocation really was as simple as their documentation suggested, I ended up with this in my code:
When you find a piece of software to fill a specific need on a project, do you:
Add it in straight away while proclaiming “Open source is awesome, on to the next feature everybody!”
Proceed cautiously, taking a good look at the project’s health before adding it in
If you picked option 1, then congratulations; this blog post is firmly for you. If you picked option 2 then you’re already ahead of the game, but hopefully this will give you some thoughts about how you assess project health.
A lot of the agencies (and freelancers) that I’ve worked for, or with, have got some way of assessing project health when considering software to add to their project. For larger agencies that might be formal, written-down rules. In smaller agencies its often unwritten “best-practice”. For freelancers, it’s commonly just a mental checklist / gut-feel that gets worked through.
As I’ve moved into working more heavily with new frameworks over the past 6 months, I’ve had to do my fair share of searching for new (to-me) software to plug missing holes. I’ve posted about a lot of the solutions I’ve found in my Stuff I’ve Used series.
There were a couple that I had on my shortlist to cover, but I’ve since decided need to be covered differently. The main reason is that while they solve my problem today, I’m not confident with the health of the projects to view them as long term / maintainable solutions. So – I’ll be talking about them in a blog post soon, but I wanted to write down my thoughts on project health first to give that post some context.
So, how do I assess project health?
I work with different technologies, and the exact measures vary depending on the ecosystem I’m working in. For example a module on drupal.org, a free WordPress plugin, or a repo or package on GitHub have different indicators which you can use. The general principles are the same though. I look at each of the following areas before making my decision.
For each one you can just weigh things up to get to your gut feel. You can use a fancy scoring matrix if that floats your boat, or if you need to set rules / guidelines for a team. You might also have specific “red flags” in each area that would block you from using a project.
Here’s the things I look for.
What does it mean to be “stable”? In some eco-systems it might be that there is a release that’s marked as “stable”. Drupal.org for example lets module maintainers tag releases as stable / dev etc. Packagist packages generally follow semantic versioning allowing you to infer stability from the version number. However, as a concept it means that there have been a couple of releases, there is basic usage / installation documentation, and there has been some feedback in the form of issues / feature requests.
Some projects don’t even have a release (common with GitHub repos), or have only an initial release. This generally makes me uncomfortable, particularly because it makes it really hard to assess some of the other areas.
There’s nothing to say that new software is bad. However, new software is often subject to change, which can make extra work for you as integration / usage changes – or worse make you stick with an old version to avoid the pain.
I don’t think I’d ever red-flag a project based on “age” – after all newer projects haven’t always acquired “feature-bloat” either. However, it’s certainly easier to feel confident about an established project than a new one.
This covers a few things, and as ever there are a few different ways to measure it. If the commit history is available, I’d look at how recent the latest commits are, and how sporadic they are. Of course – no recent commits isn’t always a bad thing – stable software doesn’t necessarily need changing regularly. I’d also look at issues raised against the project (if that’s available), to see if issues are responded to, and/or worked on. For GitHub repos, I’d look at outstanding pull-requests to see if they are merged and/or responded to.
If there are issues / pull-requests backing up, and no sign of those being worked on / merged it would definitely count against the project.
This looks at whether there are releases firstly – I’d hesitate to depend on a project from which you alway just had to go with an arbitrary commit as the version you’re using.
Where there are releases, it’s important to check that they are “usable”. This means a few different things:
that the version numbering is sensible (semver preferably)
that each release has clear, plain-english release notes – a list of commits since the last release does not count
releases are made with a relevant frequency, not too often, not too rarely
that releases aren’t regularly superceded by bugfix releases to the release
A package that you’re going to pick up and use in your project should have some level of documentation.
Important note to developers: If your software has no releases, and no documentation you don’t have an “open-source” project, you’re just hosting your version control in public.
I’m not going to suggest that you only use software that has pages, and pages of documentation. At the bare minimum though I’d expect a project to have a short document that explains:
what the software should do
what the software isn’t expected to do
how it should used
basic ‘getting started’ instructions
As a developer, I’m fortunate enough that I can generally look at the code and see how well I think it’s written.
I generally check for basic security precautions being taken (proper escaping of SQL to avoid injection, use of tokens to prevent CSRF, and output escaping to avoid XSS). I also check that the software fits the general approaches taken by the eco-system in which it fits. I’ve found that adherence to eco-system best practice is usually a good barometer for whether its been developed by someone who has taken care with their code.
If you’re non technical, or perhaps don’t have experience in the technology you’re pulling in, then if you know someone who is skilled – it’s worth asking them to give it a quick review.
Hopefully this has given you a feel for some of the things I look at when deciding whether to use a new module / plugin / package. If you’re not doing any evaluation right now – I’d encourage you to start. It saves time in the long run.
The last couple of Laravel projects I’ve worked on have all included important emails being delivered. It was important that the triggering of these emails could be tested. I also needed to make sure that the correct email was being sent, as some processes would trigger different emails based on the data input.
In the first project, I relied on Mockery to test that Mail functions were called, e.g.
This allowed testing that the correct email was being triggered. However if you want to test in more detail that that, for example testing that data from input has been inserted correctly into the email content then it gets a lot less straightforward. On the next project I tried to evolve how I was testing emails. I needed to do some more detailed testing on email contents, so I turned to the MailThief package.
This allowed me to easily test not only that emails were being triggered, but specific tests against the email content. Here’s some examples from my tests:
I find it much more consistent to keep assertions after the actions in my test rather than having them as expectations before my actions. The package has proved so flexible that I’ll be using it for all email-related tests in future.
If you’ve done much with PHP you’ve probably come across its image handling libraries. Normally this involves using either the GD, or ImageMagick.
These work reasonably well, but there are a number of disadvantages:
The APIs are thin wrappers around the relevant image libraries. Neither of them offer particularly developer-friendly APIs, and the two APIs aren’t equal enough to make switching between them simple.
You have to know which library your server has in order to start developing, or make extra work, and support both.
On a recent project I needed to do image manipulation (thumbnail generation etc.), and came across the Intervention Image library. This is a PHP library that can be used in any PHP project, and offers a much improved API for working with images. The API is agnostic to whether you’re using ImageMagick, or GD, so you can swap between them at will without having to re-code your application.
I’ve been working on a new service for the last month or so that enables people to log, track and share walks in the UK’s hills and mountains. The service is based on Laravel, and one of the things I wanted to include on the site was an “activity feed”.
There are two types of feed I wanted to create. The first was for my own benefit. I wanted to see a simple timeline of activity on the site as usage builds up. Secondly, I wanted to be able to log data so that I can create public timelines in the future.
This is all pretty simple to build from scratch, but it turns out that the team at Spatie have already got this covered with a general package for logging activity on a Laravel application.
You can easily log custom activity events wherever you like, it’s as easy as:
activity()->log('My custom message here');
Even better though is that you can get it to log changes to Eloquent models automatically using the handy LogsActivity trait. If you add the trait to your model, then creating, updating or deleting a model will automatically create a log entry. The log entries include the item affected, and the “causer” (normally a user).
Going beyond the basics, you can also define custom messages, choose what data to store along with log events.
The activities are logged as normal Eloquent models, so once you have your data logged it’s easy to pull out the information you need using standard Laravel querying, and views.
On a recent project, I needed to add some Google Maps functionality to a number of pages. The functionality I was looking for included:
adding KML layers
adding markers onto the maps with custom info windows
layering photo thumbnails onto the maps.
With the library in place, I didn’t have to worry about the basics. Instead, I spent my time on custom elements I wanted to add. I logged an issue early on with a bug that came up with my use case, and Brad was really helpful getting it resolved and into a release. Brad is actively working on the library, and a few features I was planning as custom ended up being covered by updates to the library mid-project.
With a couple of Laravel developments out in the wild, I needed to make sure that they were integrated with my existing backup solution, which includes archived / off-server storage of backups. Pulling down the backups once I had them is pretty straightforward – everything is already set up to do that from the servers I use.
For Laravel though, I was starting afresh. I found what looked like a good solution in the form of the Laravel Backup package from the team at Spatie. There were a couple of things I liked about the package:
It’s simple, straightforward, and does one thing (create backups) well.
From a look through the issue queue, it’s well maintained and open to pull requests from users.
While I’m using it to back up to the local filesystem initially (backups are then transferred offsite separately by an existing system), the package allows you to put your backups onto any supported filesystem, so having it backup to S3, Dropbox, FTP, Rackspace cloud files or similar is just as straightforward.
I love the team’s concept of “Postcardware“, it’s nice as an open source author to know that your work is being appreciated, and used, and I hope they get plenty of postcards!
I have to say though, the real highlight in finding this package was finding Spatie and their broad range of Laravel packages – there’s at least one more that features in this series, and I can easily see myself using more of their packages in the future – thanks Spatie!
I’ve worked with Drupal & WordPress for the majority of my projects for many years. For a lot of projects that are content-centric they can make a good starting point, and minimize the amount of custom work that needs to be done.
Starting with WordPress or Drupal gives you a user framework, permissions, content management, easy content display, and a wealth of prebuilt modules / plugins to get your project off to a quick start.
However, they do have their limitations, and they’re not for every project. More recently I’ve been working with Laravel as a development framework on a number of projects that made sense to build from the ground-up. Established Laravel agencies / developers probably already have a set of add-ons that they regularly use to build out common features, but for someone relatively new to the framework, a lot of my time has been spent finding the building blocks to fill in missing bits of the puzzle.
I’m going to cover a number of these in future articles (backups / WYSIWYG editing / content filtering) in future articles of the series, but today I’m going to talk about user registration.
Laravel has scaffolding built out for user management, including registration, and password management. However – the default setup doesn’t do anything to enforce password rules / guidelines on users. One of my recent projects includes users registering for a service, and I wanted to make sure that they weren’t using too simple passwords. WordPress does this out of the box, and Drupal has plenty of modules to choose from, but for Laravel I had to look for something to plug in.
The library I settled on was zxcvbn-php :
Wiring it up to Laravel was a small job (If there’s any interest I can write that up separately), essentially just extending Laravel’s validation framework, and setting the validation control on the RegisterController.
I maintain a number of WordPress plugins, and they get used on all manner of WordPress sites. One of my more popular plugins is the WooCommerce Google Product Feed extension. This queries all products, applies some logic, and user-definable mappings and outputs an XML feed that Google will import into their product ad system.
On small stores, this is pretty straightforward, but on larger stores, the effort to query all products (including all individual variations of products) can be significant.
I’ve recently been doing some work on performance-tuning the plugin. I started out with some really simple performance tracking outputting total time and memory usage at the end of the XML document. There were some quick wins as a result of that, but it didn’t really give me a feel for what was going on, or any big gains.
I’m normally a big fan of the Query Monitor plugin for reviewing what queries are run to generate a page, however in this instance it doesn’t help since there is no HTML output to the page for Query Monitor to add its results to. I needed something that wasn’t tied to logging its output to the generated page. I finally settled on Time-Stack by Joe Hoyle.
There are actually two things you need to get up and running – the timestack “app” (repo linked above), and the WordPress plugin that logs the data. Once you’ve got the app installed, and the WordPress plugin activated, then every request will be tracked, and visible in the app:
You get to see the total runtime, and memory usage, but more importantly you can drill into sections of the page request to see further information. You can right down to the actual queries being run and see exactly what’s going on. You can even instrument your code to markup useful sections for your profiling.
How did I get on? I’ll let the evidence speak for itself …