James Carr | Rants and Musings of an Agile Developer

Mar/13

17

Dynamic Vagrant Nodes

I use vagrant a lot and at Zapier I use a setup where one Vagrantfile can be used to launch any instance in our infrastructure locally for testing. This is really quite useful as I can boot up a two node rabbitmq cluster with haproxy by simply typing vagrant up rabbitproxy01 rabbit01 rabbit02.

In the beginning this was a little messy as I just kept adding new node definitions and incrementing the ip address. But today I’ll share my refactored vagrant file for your own dynamic virtualizing goodness.

Essentially you just add your node names to nodes and when vagrant runs it will calculate a range of 10 host only ip addresses and node definitions for that node. So if you add “redis” to the list you can boot up redis01, redis02 … redis10.

Caveat: don’t just type vagrant up by itself or you’re going to have a bad time. This will essentially start bootstrapping many many vagrant boxes until your computer screams and falls over. Enjoy!

No tags

Sep/12

16

Zend Framework 2: Select Optgroups

On my project I’m currently working on I needed to use optgroups. After looking high and low through the documentation and the code I discovered the feature kind of worked, but kind of didn’t. I issued a pull request that fixed the code for the next release (2.0.1) but here’s the skinny on how to set it up.

When setting the valueOptions attribute of a SelectElement specify an array as follows for optgroup support.

No tags

Sep/12

16

Using Select In Zend Framework 2

I’ve been using Zend Framework 2 on a recent project as a way to asses it’s features and one of the early blockers I had was trying to figure out how the heck to use the Select form element. As of this writing there is no good documentation on how to use it, so I’ll instead introduce how to use it in this blog post.

Album Manager, Revisited

For this demonstration I’ll be using the zend-skeleton application I originally worked on following through the zend framework 2 tutorial. I’ve left off from my previous post where we DRY’d up our code by using form annotations. You can follow me in this post by checking out my zend-skeleton project on github and checking out the “select-beginning” tag.

To start with, we have our annotated Album model object with just the title and artist:

So we’ve written our application and our customer is pleased, however he’d like to be able to tag the albums with a genre. When adding or editing a new album, there should be a genre drop down populated with options like Rap, Jazz, Alternative, Rock and Country.

Turns out this is a breeze, we just need to add a new field to our model and a Select form element:

Now comes the boilerplate part, adding it to your views and AlbumTable (soon I’ll blog about replacing TableGateways). I’ll leave this as an exercise for the reader. See the tag select-annotated to see the completed work here. You’ll also need to add the genre column to the album table yourself (boo… no migrations).

Getting Values From an External Source

Commonly we’ll be getting genres from a database table or some other external source, not hard coded as a list of values in an annotation. To understand how to do this better, let’s first extract the value population out of the form annotation and do it elsewhere. The obvious place to manipulate the form after the fact is obviously not within the controller so let’s extract form creation out to something that can encapsulate it. With the lack of any kind of convention our guidance from the framework here, let’s just call it AlbumFormBuilder and go strong. :)

First we create a new class called FormBuilder under module/Album/src/Album/Form/FormBuilder. Previously (as in during the last tutorial) we applied extract method to extract a common method out of the addAction and editAction to handle the form building logic.

Now we simply need to move this method over to our new FormBuilder class and name it something meaningful, like “newForm”.

Now we could simply drop this object into the existing method in the AlbumController and see it still work (and I normally do this while refactoring). But to really harness the power we should create this new builder through ZF2′s factory mechanism. So we open up module/Album/Module.php and the following to the factories section:

And modify the AlbumController to use it via the service locator.

Now with the logic better encapsulated away from the controller, let’s simply set the value options directly within the builder class.

Now if we save this and check out the app, we’ll notice that our new addition completely overrides what was in the annotation. Since we don’t need those anymore, we can remove the value_options attribute from our form annotation. Go ahead and edit or add a new album, select a genre and save it. Notice something? If you use an array of string literals the values will all be the index number of the item while the actual values will be the labels.

We have two options here… either specify keys that represent option values or explicitly define the label and the value (yes this is a bit strange). See the examples below for a quick reference.

This actually didn’t give me what I originally expected… I expected to see the array keys as labels and the values as, well, values. However using a keyed array will basically match the same left to right layout an actual select elements option items will have. If you want to be more explicit you can also do the following:

Final Step: Extract Values Out

There was a reason I used ZF2′s dependency management to fetch the new FormBuilder instance and that was to easily extract the value options out to be provided by something else, perhaps another table gateway. So let’s go ahead and move that array to be returned by a new GenreTable.

Now we modify FormBuilder to take the GenreTable as a constructor argument and use it to populate the value options.

Finally, we update module/Album/Module.php to inject an instance of the new GenreTable.

Now we’re free to change the object injected into FormBuilder to fetch genres from the database rather than use an in-memory array when we’re ready but I’m tired of writing TableGateways. In my next post I’ll make my code a bit DRY’er by ripping those table gateways out in favor of doctrine. :)

You can see my completed work for this post on github.

No tags

Sep/12

10

Fixing PHP Code Standard Issues

It’s been one busy day, cranking out features like no tomorrow (even issuing pull requests on github to fix Zend Framework 2 issues) and still finding time to improve my PHP toolbelt.

Today while issuing pull requests I came across PHP-CS-Fixer which was referenced as a way to fix some minor code formatting issues in my pull request. Basically run it on a project directory and it fixes “most” issues to make your code better adhere to PHP coding standards as defined in the PSR-1 and PSR-2 documents.

Just run it against the root of your project and it fixes all the formatting issues caused by python/java/javascript developers like myself. :)

As an added check, I’m now using this script as a git pre-commit hook on my PHP projects to tell me of any issues.

No tags

Sep/12

9

Using Guard + PHPUnit for Great Good!

Another day, another post about the tooling I’ve been using to make PHP development bearable. Today I’ll share guard-phpunit, which I discovered thanks to a tip by @ctshryock.

I’ve been using this as a replacement for watchr which I use to autorun tests whenever I make code changes. I’ve switched to guard for a number of reasons, chief amongst them being the awesome notification support. You can use growl, libnotify and rb-notifu to notify test pass/fail.

Here’s the Guardfile I’ve been using. This is tailored for Zend Framework 2 so that whenever I modify a php class under a module directory it will run the tests for that particular class. Rapid feedback for the win!

No tags

I’ve been using Zend Framework 2 on a recent project due to it being the department’s framework choice and off the bat one of the things that really irked me was the “Struts-ness” of how models are handled. If you walk through the ZF2 quickstart tutorial you’ll find the section on forms incredibly verbose, requiring an extra Form object and about 30 lines of boilerplate for the form’s input filter.

Luckily after digging into the documentation and source code I was able to uncover how to avoid that nonsense by using annotations. All you need as a pre-requisite is to add doctrine/common to your project (for reference, here’s my composer.json file).

Building off the tutorial’s example, I simply delete the Form class and modify the Album model to the following.

Still looks pretty hideous but at least we’ve removed “some” of the boilerplate involved. The final step is to modify the AlbumController to use the AnnotationBuilder instead of the old AlbumForm.

The only downside to this setup is that the submit button now feels a bit out of place. For this example I just leave it alone but I’d most likely encapsulate it somewhere. One option I’ve been playing with is to encapsulate the form generation in some kind of prototype builder but have omitted going that route for this simple example.

The changes I’ve made for this post can be found in my zend-skeleton project on github.

No tags

Sep/12

6

My PHP Development Environment

I’ve been working in PHP at my new day job and despite the usual exclamation that comes with stating that (yeah, I hear you screaming “PHP!? Yech!!!”) I’m actually quite happy with a change in pace and the development environment I use. I like it enough I thought I’d share it. :)

Vagrant

Vagrant is a godsend for virtualizing server environments that often have different configurations. Since a lot of servers I work on can often have different and conflicting setups I’ve been setting up vagrant boxes for each of my projects with puppet manifests that tailor the specific settings those projects require. An added bonus is that I can also populate the virtual machine’s database on boot.

I also setup a host-only ip address in the Vagrantfile and edit my /etc/hosts file to resolve against it, usually some domain like local.example.com or the like. The benefit of all this? I can checkout a project, type vagrant up and BOOM! I can navigate to http://local.example.com and see a perfectly usable, runnable instance. And with /var/www/ mapped back to the project directory on the machine I can make changes and see them on the vm. It also creates a nice local environment to test out my capistrano deployment scripts.

Capistrano

It’s not much of a secret that I’m a big fan of capistrano and amusingly have never used it to deploy a rails application. I just find it to be the most easiest to use tool to painlessly deploy projects to remote servers and be able to rollback when I screw up. All with one command. In fact, I’ve even performed production rollbacks from my mobile phone while on a trip.

The big gain here is that capistrano checks the project out to a timestamped directory, does any softlinking that needs to be done (for example uploaded files and content not stored in version control) then finally updates a link for a current directory to the newly deployed application. This allows for a pretty seamless switchover with practically zero impact to end users.

Of course, capistrano by itself isn’t enough to make my deployment toolbelt complete. Since we’re working with a non-rails app, we need to remove the “railsness” of capistrano. railsless-deploy works well here by stripping out the more rails related tasks. I also use multi-stage deployments are used to deploy to staging and production. Finally, after the app is deployed (but not yet live as the symlink hasn’t been updated) my capistrano script runs composer on the app to gather dependencies.

Composer

When I last worked in the PHP world (2006!) PEAR was pretty much the de facto dependency management system, and it was “meh”. Not bad, but not as good as rubygems, pip, or npm. Imagine my joy last week when I discovered composer, which is heavily based off of ideas in npm. With composer I can define a composer.json file that defines all the dependencies my application has, whether they’re composer enabled or not. I’ve used this with composer based packages, pear, github projects, etc. Here’s a sample of one from a current project:

Basically I just run “composer install” from the project directory and all the dependencies are downloaded and placed under ./vendor. A nice addition is that it also handles psr-0 autoloading as well, which is a separate topic in its own right. :)

Jenkins

FInally, I tie all this together with Jenkins by using it to automatically check out projects on commit, run PHPUnit and php lint on the project, then ship it to staging if all goes well. I usually leave the production deployment to be manually kicked off but I can also automated that as well if I wanted to. If you’re not already using jenkins, why aren’t you?

That’s about all for now. In a nutshell I guess I could say PHP development isn’t great due to being very verbose but it’s tolerable. Knowing tools from other stacks goes a long way in making it fun. :)

No tags

Sep/12

6

Capistrano Deployment from Jenkins

Recently I had a challenge of getting capistrano deployments working from jenkins installed on a RHEL box. The problem seemed to be down to the fact that ssh-agent isn’t running for the daemon process that jenkins runs as for whatever reason and it is needed to do ssh agent forwarding (which is what I do so I can use the ssh key on the jenkins server to check code out from github on remote servers).

After banging my head against the head for a couple hours, I came up with a simple solution: execute a shell script through ssh-agent. I simply created a deploy.sh script in the root of my project with the following contents:

Then execute it through ssh agent.

exec /usr/bin/ssh-agent "${WORSKPACE}/deploy.sh" "production"

Works perfectly. Hopefully this helps someone else, took me a lot of grief to figure this out.

Oh yeah, in case you didn’t know, I’m back in PHP development again for awhile so there should be some interesting posts ahead. :)

No tags

Aug/12

13

Don’t Be the Bearer of Bad News

Nobody likes hearing bad news. Whether someone passed away, another dismal economic report or a project failure within your company, bad news does nothing but breed negativity in the person who hears it and brings their morale down.

Instead of rebroadcasting negativity that brings people’s hopes down, why not share something to bring their hopes up? Rather than focusing on dreadful economic reports, why not share stories of people toughing it out and making a profit despite all the odds against them?

Seek to inspire people, not demotivate them.

No tags

Jun/12

18

The First Thing When You Wake Up

What’s the first thing you do when you wake up in the morning? Check facebook? Check twitter? Your email? Watch some morning news when you get ready?

All of these things are easy for us to do when we wake up but in my opinion they’re the worst possible activities we can engage in when waking up. Why? All of the activities listed above are a form of procrastination of some type and by doing them first thing in the morning we set our day up to be a day of procrastination.

My challenge this month is to start my mornings by doing something productive. It might be a blog post, reviewing a chapter from one of the books I’m tech editing, or getting some early morning yard work done. Whatever it may be, I’m going to start the day off with an achievement (however small) rather than idle procrastination.

As Dogen Zenji once said,

“Life and death are of supreme importance. Time swiftly passes by and opportunity is lost. Each of us should strive to awaken. Awaken. Take heed, do not squander your life.”

No tags

Older posts >>

Theme Design by devolux.nh2.me