All posts by Rob

Homestead per-project crib sheet

I wanted a drop-dead simple way to try and replicate a problem someone was having on the Slim forums. I couldn't reproduce with php -S which is my go-to for this sort of thing, so I thought I'd try Homestead.

I had recently listend to a Voices of the Elephpant episode with Taylor Otwell & Joe Ferguson where Joe mentioned that Homestead worked on a per-project basis too. I didn't know this, so tried it out. The docs are fine, but there's a lot there that covers the global installation option when I just want to get up and running on a per-project basis.This is my crib sheet:

1. Create project

We just need a project that uses Composer. You probably have one already. If not, Slim Framework is a good choice!

2. Add Homestead to the project

The make command creates VagrantFile and a Homestead.yaml for configuration.

3. Deal with IP address and hostname

By default, the Homestead vagrant box is set up on 192.168.10.10 with the hostname homestead.app. You can change this in Homestead.yaml.

Add the IP address to /etc/hosts. This only needs to be done once if you don't change the defaults.

All done

We're all done, so we can use vagrant up to run our new website Go to homestead.app in a browser to see it. To shut down, use vagrant halt or vagrant destroy.

Slim home page

Automatic OCR with Hazel and PDFPen

I have a useful scanner as part of my networked HP printer that will scan directly to a shared directory on my computer. Once there, I want the file to be renamed to the current date and the document OCR'd so that I can search it.

To do this, I use Hazel and PDFPen and this is a note to ensure that I can remember to do it again if I ever need to!

Firstly, rename the file. My scanner names each file with the prefix scan, so the Hazel rule is quite simple:

If all the following conditions are met:
	Name starts with scan

Do the following to the matched file or folder:
	Rename with pattern: [date created][extension]

This is the screenshot:

Hazel1

Having renamed the file, we can use PDFPen's AppleScript support to perform an OCR of the document:

If all the following conditions are met:
	Extension is pdf
	Date Last Modified is after Date Last Matched

Do the following to the matched file or folder:
	Run AppleScript embedded script

The embedded AppleScript is:

tell application "PDFpen"
	open theFile as alias
	tell document 1
		ocr
		repeat while performing ocr
			delay 1
		end repeat
		delay 1
		close with saving
	end tell
	quit
end tell

This is the screenshot of it in Hazel:

Hazel2

That's it. Scanning a document now results in a dated, OCR'd PDF file in my Scans folder.

Using Phive to manage PHPUnit

I recently came across the Phive project and have had a play with it. Phive is part of phar.io and is intended to manage development tools such as PHPUnit in preference to using Composer's dev dependencies. The main advantages of Phive are that it uses the phar file of the tool and only keeps one copy of each version rather than downloading a new copy into each project.

How it works

Phive stores one copy of each phar file within ~/.phive/ and then for each project, it creates a symlink. For example, to install PHPUnit into a project, you simply change directory to the root of your project and type:

$ phive install phpunit

This will download the phpunit phar file (if it's not already downloaded) to your ~/.phive directory, It will then create a tools directory in your project with the symlink to phpunit.phar.

$ ls -l tools
total 8
lrwxrwxr-x  1 rob  staff  42  3 Jan 07:34 phpunit -> /Users/rob/.phive/phars/phpunit-5.7.5.phar

You can now run PHPUnit using ./tools/phpunit, however if you would rather install to a different directory, e.g. bin, then use the --target switch:

$ phive install --target bin/ phpunit

The phive.xml file

Phive also creates a phive.xml file to keep track of what it has installed. You should add this file to your git repository and ignore the installed files in tools.

$ echo -e "phpunit" >> tools/.gitignore
$ git add phive.xml tools/.gitignore
$ git commit -m "Add phpunit via Phive"

Other users of the project can now install all the Phive tools using:

$ phive install

Installing for global use

Phive also supports global installation with the -g switch:

$ phive install -g phpunit
Phive 0.6.2 - Copyright (C) 2015-2017 by Arne Blankerts, Sebastian Heuer and Contributors
Downloading https://phar.phpunit.de/phive.xml
Copying phpunit-5.7.5.phar to /usr/local/Cellar/php71/7.1.0_11/bin/phpunit

You may need sudo privileges, but for my HomeBrew installation, this wasn't necessary.

GPG signatures required

Note that Phive only works with projects that also release a GPG signature for their tools. This is good security, but currently a significant limitation if you use anything else other than the few tools listed on phar.io.

The most significant missing tool for me is PHP_CodeSniffer. There's an open issue on their bug tracker but as it's been open for 6 months now, I assume that it isn't important for that project which is frustrating.

As such, this limits the usefulness of Phive for me today, but it's certainly a project to watch.

2016 in pictures

Another year has passed which gives me an excuse to to reflect on what's happened. As usual, I look at the photos that I've taken and frame my thoughts around them.

January

At the very end of January I visited Phoenix, Arizona to see Evan, Priscilla & other friends. I also attended FOSDEM again and spent a tourist day in Brussels.

The Europeans insisted on seeing the sun!Atomium


February

I was fortunate enough to speak at PHPUK again in February.

The conference is about to startStart of the second day

March

The highlight of March was visiting the NYMR to see Flying Scotsman.

Flying Scotsman from the linesideUp close

April

In April, my eldest drove a Lamborghini and now intends to buy one! It's important to be able to dream when you're 14. I also visited the NRM.

Eldest drove a Lamborghini!Mallard

May

May is the month of birthdays in our household. I also attended the StatusCode event in Nottingham

Happy Birthday!Andrew


June

Two conferences in June. I spoke at PHP South Coast and took my favourite photo of Andrew Smith ever! I also attended Lead Developer.

Best pose everMichael Lopp

July

July was the inaugural UK edition of REST Fest in Edinburgh. We also went on holiday where I attempted sunrise photos and ate lots of ice cream.

Mike talks about Conway's four lawsSunrise

August

Worcester Comic Con happened in August where we got to meet "our" Doctor! Unfortunately this was also the month when my dad was taken ill.

Georgina with her DoctorLearning table top gaming

September

September was about family and friends with an extended family gathering and a trip to Leeds to see friends. Dad was transferred to a closer hospital too and started to get better. September was also the start of conference madness that lastest to November, with a trip to Dublin for DrupalCon.

Dad & meA group of amazing people

October

October was the month of conferences when I spoke at PHPNW in Manchester, attended OSCON Europe and spoke at the Software Architecture conference, both in London! The other welcome news this month was that Dad came out of hospital.

Coffee breakAttendies to my talk!

November

November is Fireworks Night in the UK which we celebrated with friends. This year, we contributed wood for the bonfire as we've been tiding our garden. I also spoke at Velocity in Amsterdam as did my friend Kevin.

Bonfire nightKevin discussing how to survive the Grand National

December

As usual, the final month of the year found me in a pub with some of my oldest Internet friend from our MMORPG gaming group that I've been part of since 1999. I visited Northern Ireland for the first time. Family from America also visited; I haven't seen my cousin Leigh in 28 years and so had not met her husband or children, so this was very much a highlight.

BL Cronxmas meetupFamilies



All in all a good year, though I will try and space out my conferences a little better in 2017!

SSH keys in macOS Sierra

Now that I've upgraded to macOS 10.12 Sierra, I noticed that SSH required me to enter my passphrase to keys every time I used them. This was a surprise as it's not how 10.11 El Capitan worked.

This is how to fix it.

Firstly, add your SSH key's passphrase to the keychain using ssh-add -K ~/.ssh/id_rsa (or any other key file). You can now use your SSH key without re-typing the password all the time which is very handy for use with GitHub/GitLab/Bitbucket/etc.

You can add as many keys as you like and ssh-add -l will show you which keys are registered.

When you reboot, you'll notice that ssh-add -l is empty which is different from how it works on macOS 10.11 and earlier which automatically re-added the keys it knew about. In Sierra, Apple has changed it so that you now need to explicitly add the known identities to the ssh agent. This is done using ssh-add -A which you need to run every time you reboot.

To save having to do this, you can either add ssh-add -A to your ~/.bash_profile file or update your SSH config by editing ~/.ssh/config and adding:

SSH will now work as expected and you'll never need to reenter your passphrase once it has been added to the system keychain.

Handling JSON data errors in Slim 3

When you send JSON data into a Slim Framework application with a content-type of application/json, then Slim will decode it for you if you use getParsedBody():

Using curl to test:

If there's an error however, you get this:

If you care about this, you can use json_last_error_msg() and return an error:

(note – in real code, you should check that the Accept header was a JSON one…)

Don't forget the JSON_PRETTY_PRINT as a human is going to be reading this error, so make it easier for them.

Use jsonlint for more information

If you really want to provide great diagnostics, then use jsonlint:

Update your handler like this:

(lint() will return NULL or a ParsingException, so we don't need to test for anything else.)

The result looks like this:

This is much more informative!

Use curl to create a CouchDB admin user

This too me longer to find than it should have done, so I'm writing it here for future me.

When you install CouchDB, it is in a mode where anyone can do anything with the database including creating and deleting databases. This is called "Admin Party" mode which is a pretty cool name, but not what I want.

Creating admin users

To create a user in 1.6 (I've not used 2.0 yet, but assuming it's the same) you simply click on the "Fix This" link in Futon which is available at http://localhost:5984/_utils/ by default.

As CouchDB's entire API is essentially a RESTFul API, to do this via the command line, you simply PUT a new user to into the _configs/admins collection like this:

This creates an admin user called rob with a password of 123456. Note that the password within the body of the PUT request must be a quoted string. This caught me out for a while!

From this point on, we can then use basic authentication to do admin-y things, such as create a bookshelf_api database:

Other users

You can also set up per-database users which is handy for limiting what your application can do when connected to CouchDB. This is done creating users in the /_users/ collection and then assigning them to a class in the _security collection of the database. There are two default classes: "members" and "admins" where members can modify data, but not design documents and admins can modify all documents including user roles on that database.

On respect in the workplace

I recently came across Don’t be that dude: Handy tips for the male academic, an article covering 20 actions that the author identified as things that men do everyday to perpetuate inequality. A number seem specific to the academic world, but the majority are relevant everywhere.

Now, 20 items is a lot to remember, so I want to call out a few that I see regularly when I'm in offices and at conferences. They are all about respect for the individual and while they aren't necessarily gender specific, I personally have seen many more men doing these things to women than vice-versa and cringe every time I notice.

Don't talk about someone's appearance

Don’t comment on a woman’s appearance in a professional context. It doesn’t matter what your intentions are; it’s irrelevant. Similarly, don’t tell someone they don’t look like a scientist/professor/academic, that they look too young, or they should smile.

Complimenting someone on they way that they look rather than what they have achieved or do is demeaning and disrespectful. Nobody tells me that they like the way that I've ironed my shirt, but I've been in meetings with potential clients where a man has introduced his colleague to me by saying that she must have dressed up today because of the meeting. He didn't comment on the dress sense of any of his male colleagues when introducing them and left me feeling uncomfortable. I have no idea how the woman felt; different and unwelcome I expect.

Be aware of what you say about people, especially women. If you find that you do seem to mention your colleague's clothing or (lack of) makeup, then train yourself to stop talking about it. If you feel like you must make small talk, then find a different topic: something in the news, the travel situation, anything else!

Don't interrupt

Don’t talk over your female colleagues. There is a lot of social conditioning that goes into how men and women communicate differently. You may not realize that you’re doing it, but if you find yourself interrupting women, or speaking over them, stop.

The general case here is don't interrupt. However, it's much more common to see a man who listens intently when his male colleagues are talking, but interrupts and talks over a woman in the meeting. I think this happens because the man doesn't even hear the woman. This is especially frustrating for me as when if you're paying for my time at a meeting, then everyone's input is important.

Pay attention to your own behaviour in meetings. In particular, check that someone else isn't talking the you want to make your point. If you notice that you are interrupting someone else talking, then start consciously waiting for a pause before talking. Your point won't be less important because you waited a few minutes before speaking.

Make tea for and minute your own meetings

Volunteer when someone asks for a note-taker, coffee-run gopher, or lunch order-taker at your next meeting. Don’t let this task fall to women, even if they tend to volunteer (we’re socially conditioned to do so). Make sure that women aren’t being asked to do this more than men.

I see this all the time in client meetings where there is a mix of gender in the room and I now get a bit embarrassed as I used to be that man.

At a previous job, I didn't initially even realise that I was letting a woman team member do much more than her fair share of the tea making rounds. Once I did realise, I told myself that as the senior lead, it was a better use of resources to let the junior members do tea making. That was rubbish. At some point I was educated on this phenomenon and worked on changing the culture by explicitly asking different team members to make the tea.

I have one client where the rule is that the host of the meeting is the note taker and lunch handler which works really well too as it's clear that if you want this meeting to take place, then you get to do some of the leg work. I don't know why they introduced this system: I suspect that it was to promote fewer meetings, but the end result is fairer too.

To sum up

You should read the full list of 20 points as all are worthy of consideration and behaviour change. I've called out the three that I've had to personally work on and improve at and are the ones that I most want to see change on.

In this day and age, be a professional; show some respect.

Hide the ST3 sidebar automatically

As a mostly keyboard user, I take advantage of the keyboard shortcuts in Sublime Text. However, the sidebar is quite a lot of effort to manage, especially as I mostly leave it closed.

Firstly, you need cmd+k,cmd+b to open it. Then you type ctrl+k,ctrl+0 to focus it as opening it doesn't automatically set focus. Then you can navigate to the file you want and open it via pressing return. Finally, you type cmd+k,cmd+b to close it again.

That's a lot of keyboard combinations! Note also that you swap from cmd to ctrl too.

Revealing the current file

I find that I often want to open the side bar with the currently open file highlighted. There's a command for this: reveal_in_side_bar which you assign to a keyboard shortcut like this:

    { "keys": ["super+shift+1"], "command": "reveal_in_side_bar"},

Now, pressing cmd+shift+1 will open the sidebar with the current file highlighted. You still need to press ctrl+k,ctrl+0 to focus though.

Automating with plugins

There's a plugin called FocusFileOnSidebar that solves this problem, so if you have this workflow, then install it now.

Again, you need to set a keyboard binding:

    { "keys": ["super+shift+1"], "command": "focus_file_on_sidebar"},

It doesn't automatically close the sidebar for you though, so I created HideSidebarWhenNotFocussed that does just that.

Done

With the combination of FocusFileOnSidebar and HideSidebarWhenNotFocussed, the sidebar works the way I want it to!

It's closed most of the time, I press shift+cmd+1 to open it with focus set on the currently highlight file. If I open another file by pressing return or go back to what I was doing by pressing Esc, then the sidebar automatically closes as it should.