Extending Symnfony by Sébastien Armand is a tutorial-style introduction to a variety of the ways that you can extend a Symfony 2 full stack installation. I’m a big fan of Symfony 2 and I’ve done a fair amount of app building with it, so I was interested in Armand’s book and seeing what new things I could discover about hooking into sf2.
The book is filled with code samples, far more than you’ll find in most other technical books. Most of these code samples are also complete, which anyone who has traversed the official Symfony 2 cookbooks will greatly appreciate. Unfortunately, these code samples sometimes cross pages in inconvenient ways, and none of them include syntax highlighting which can make it hard to read at times.
Armand tackles six (sort of eight) areas of Symfony 2 development where developers can tap in and extend existing functionality of Symfony 2. First and foremost he kicks off his tutorials with covering service definitions and listeners. These topics seem like they could have been separate chapters to me, but nonetheless he does a good job of giving real world examples of how to tie these things in. He especially does well with event listeners - the secret weapon of the Symfony 2 stack (in my opinion anyhow).
Armand’s approach to extending symfony is project-based, meaning that through the book you’re working on building an app that handles some details for meet ups between users. You can think of it like the old Symfony 1 Askeet tutorial. This is a huge advantage of Armand’s book over other Symfony 2 texts you’ll find in the wild. Actual applications create context and drive home the concepts. As an added bonus, in this book you are NOT building yet another task manager!
The Security chapter covers some of the more difficult areas of Symfony 2. Anyone who has dealt with Security in sf2 knows that, while extremely powerful, it can also be extremely challenging. Armand’s examples are helpful, especially as he tackles an OAuth implementation. Armand uses the Friends of Symfony UserBundle to get going, but unfortunately didn’t cover with too much depth getting started with this super handy bundle. The examples in the book are priceless, but I look forward to future revisions that cover the new SimpleAuth implementation in Symfony 2. The only other thing I wished Armand would have covered was securing an api with tokens and a custom user provider for doing this. He shows how a cookie can be used with an event listener, but truthfully there are better ways of tackling this problem in Symfony 2 that are more consistent with its security model.
One of the most valuable chapters in this book is the Doctrine chapter. Doctrine 2’s official documentation lacks a lot of context. By being a project-based tutorial, Armand actually shows you how to write a custom data type, custom DQL function, and a custom filter, rather than stumble through the Doctrine 2 docs and hope you got close. This chapter in and of itself is a valuable resource for those times when you need to do these things.
The final chapter discusses bundles briefly. This is one area of the book I felt could have been fleshed out a bit more. Armand covers the basics, but part of me felt like this chapter almost belonged at the beginning of the book instead of the tail end. The other thing that was missing from this chapter was bundle inheritance which, while a tricky subject, is a huge part of extending a Symfony 2 application.
All in all I think this is a solid book on tapping into some of the more powerful features of Symfony 2 and it’s counterpart Doctrine 2. The book is at times a little oddly organized, but the code samples and tip are worthy any web developers time. If you’re looking to dive into some of the things in the book’s table of contents get yourself a copy and profit from Armand’s tutorials and extensive code samples.
I recently decided to signup for Pley, a service that supplies lego sets by mail for a monthly membership price. They advertise that you're safe to lose a piece or two and that the kits are always sanitary using their special FDA grade process. Unfortunately I found both of these claims to be false.
First off let's set the record straight, I'm an adult Lego geek. That's a technical term, you can check me on it. As a kid I had a vast array of sets and spent countless hours constructing my dreams. Then I went to High School, College and got married and had mostly forgotten about Legos. Until I took a job where I was working on the hosting infrastructure used by the Official Lego Podcasts, like this one. Suddenly I had an excuse to play with Legos again, it was work related after all...
I've collected a few sets as an adult, and I fully admit to playing with them from time to time. I'm not ashamed. When I saw Pley I thought it could be the perfect life-as-a-service for my late night hobby.
I went through the trial and the first set I got was a total bust. The Desert Skiff came in the mail and I started piecing it together. Normally I try to avoid the directions as much as possible, as that adds to the general fun of the puzzle. But on this one though I had to pull out the book. This probably sounds a little crazy since it's only a 213 piece set, but hear me out. As it turns out the set was missing pieces, to the tune of at least 10! I finally couldn't finish the set because there were so many missing. I logged online an reported the missing pieces and sent the set back in. I admit that out of frustration I didn't pull everything apart. I hadn't heard back from Pley until this week when they sent this email to me.
We hope you are enjoying Pley. We have received your set today. Thank you!
To keep kids happy, we ask all users to disassemble the sets to individual pieces so that each child has the same building experience with no sets arriving partially built.
Here is a note we received from on of our Pleyers:
We appreciate you taking a few extra minutes to separate each piece so that other children can enjoy the set equally.
Thanks for Pleying!
The Pley Team
I'm a little more than flabbergasted. I didn't get any replies when I filed a missing-part list! On their website they say, "Lost a piece? No worries. We won't charge." What they don't say is, "The next guy might be out of luck though!" Furthermore, if their process is so clean how did this kid Tal get the set still stuck together? How do they know I didn't stick a booger between those blocks? And really what are they doing sending this kid's letter to me? Surely this is some kind of privacy violation!
The thing I really miscalculated though was thinking that renting one set at a time would somehow pacify my burning desire as a Lego-master to mix and match multiple sets. There simply is nothing better than owning your sets, period.
Unfortunately I just can't recommend this service. Yeah, it's partially out of bitterness, but I also feel like I've been lied to. So keep buying on Amazon, or Target or wherever it is you get your Lego-fix and steer clear of Pley!
About a week ago I released v1.3 of jGrowl. This is for all intents and purposes a maintenance release, containing primarily packing info for npm and bower, as well as a Grunt config for future development. More importantly is that the 'develop' branch is underway and this contains some significant changes to the plugin.
The 1.4 release intends to address the following things:
These things are currently available for testing, simply pull 'develop' and give it a spin.
Additionally I am very happy to share that the jGrowl package on Bower now points at the correct repository, meaning you can easily add jGrowl to your project using this excellent package manager.
Lastly, while most of the development on 1.4 is complete I am hoping at some point to work on automating some tests of the plugin. If you have experience doing this with jQuery plugins I would welcome advice, insight or better yet - pull requests. If you have any feedback on either 1.3 or 1.4 please don't hesitate to drop me a line.
I'm pretty excited about a contribution I recently made to Aura.Sql. For those not familiar with Aura, it's the brain child of Paul M Jones (a decent dude despite his hate for design patterns starting with the letter F) and strives to be a set of standalone components with no outside dependencies and 100% test coverage. Aura.Sql v2 is also known as ExtendedPdo, and it's a drop in replacement for PDO. The idea is it gives you some extra giddy up in your database tooling, via lazy connections, short hand helpers and a basic profiler. I've found this especially helpful on a couple of projects where I have a bunch of technical debt and an antiquated ORM. The problem is database connections are expensive and opening up a new one via ExtendedPdo is not always feasible. My contribution to this project was the ability to decorate or wrap an existing PDO instance so that you could pull the raw connection from another system and use it without reconnecting to the database. This is an idea I got from Doctrine 2, which offers similar support by passing in an existing instance object. This is a particularly handy feature when refactoring a legacy code base.
If you're getting off the ORM band wagon, or dealing with some poorly performing legacy code you're trying to refactor take a look at Aura.Sql, it's right tool for the job.
My love affair with Symfony 2 has hit a rocky spot. I have an atomic deployment system for a Symfony 2 app that I've been working on. Basically it works like this... The app gets built on my CI server, Bamboo. That build results in an artifact, a tarball of the entire application. This tarball is intended to represent the final product, meaning tests have all been run - they passed - and any compilation steps have been executed. But I've got a problem. It comes when I try to warm the cache or more generally if I run any Symfony console command on the build system before the artifact is made. This includes things like installing Assetic dependencies. To work around my problem I've been making sure my 'cache' folder is empty before I build the tarball. I wind up crossing my fingers on the deploy step and trusting that things will work themselves out when the cache is warmed and the container is compiled on the application server. This is a horrible solute. It's one I'm forced to deal with because of the way Symfony 2 dumps it's dependency injection container. The container dump compiles references to %kernel.root_dir% which is an absolute path to the application root. That path is different on my CI server than it is on my production application server. If I compile the container on the CI server I wind up with a dump file that has the wrong absolute paths, resulting in a non-function app.
Some may want to question not doing the build on the application server if this is a problem. That may work for some people, but I think it's wrong to assume it's going to be possible in every deployment scenario. There are simply a lot of regulated industries where building on the application server simply is not going to pass an audit. In my experience both in the PCI and Hippa worlds this simply wouldn't have worked. You may disagree, but the reality is when you get into sorts of regulated environments you are playing by someone else's rules, even if they're silly rules. Furthermore, this solution does not scale. It works for small clusters, but there's a point at which it simply is too long to roll that sort of deployment process out across a datacenter. I've spent a fair amount of time solving software problems in these sort of regulated environments, so now I am admittedly wired to consider such things even when they're not being mandated by a regulatory body. My build system involves Bamboo and Ansible. Out of this system a singular artifact of the application is produced for deployment. It's a clean system and I can pull the artifact down from the CI server at any point and work with the exact distribution that will hit my application server at any time. Well, identical so long as the cache is not built. Here lies my beef with the way Symfony works.
As I mentioned, this has been a bit of a pain with Assetic. Until recently I was able to avoid it for the most part. Assetic can be a great tool, especially during development, but much of it can be circumvented with more front end centric tools like Grunt. Recently though I started playing around with the SpBowerBundle to manage front end assets and hit this problem again. In principle I really like what SpBowerBundle brings to the table. It's an awesome union of front end and back end dependency management into a nice clean integrated system. However, this time I just couldn't make it work. This is no fault of the Bundle's, as I eluded to earlier, I consider this a flaw in the way the container is compiled.
In general I am a huge fan of Symfony 2. I love the design and architecture of the system, and the flexibility to build a truly componetized app is unique in the PHP-stratosphere right now. This doesn't seem to me like it should be an issue, yet it is. It also seems to me like more people should be wrestling with this, but I'm not finding the blog articles on it or any workarounds for that matter. Truthfully I suspect the problem could be resolved by delegating the string replacement of %kernel.root_dir% to a method call, like getRootDir() which could then return the magic constant __DIR__ and we could use absolutely paths without having to hardcode them.