Working with qooxdoo and PHP


Since the birth of my daughter, I have not been spending much time coding in PHP, let along writing about it.  Recently, however, the professional necessity of developing a new website for the Chiara Quartet that would allow better workflow pushed me back into the coding arena.  Basically, we realized that we were maintaining several separate calendars, separate contact lists, and having great difficulty sharing any of these things.

I looked into a couple of possibilties for pre-existing solutions, and decided that no existing framework or CMS fully satisfied my tech needs:

  1. luddite-friendly.  We are musicians, not programmers
  2. full google calendar API-aware
  3. full constant contact API-aware
  4. federated login through OpenID – no more shared easy-to-remember-insecure logins/passwords
  5. fully separated admin interface from website
  6. both code and data managed through version control
  7. easy installation in both a test location and a live location

Although many components satisfy one or more of these requirements, I decided to handle them all through a combination of existing technologies and cobble them together to make a perfect frankenstein monster.

Choosing my stuff

First, I decided to make a fully RIA application for the administrative backend, so I began to investigate javascript frameworks.  The riches out there are impressive.  Although many people are using the jQuery and Zend Framework has hung its hat on Dojo, I was most impressed by the rigor and flexibility of qooxdoo.  Not, mind you, by the visual appeal of the website, which is by any standard fugly, but by the clever use of an external tool written in Python to make it possible to easily create a debuggable source version, lightning-fast optimized build version, API documentation, and tests all from a single codebase.  In addition, its design from the ground up to be a javascript application rather than a fancy webpage with javascript stuff on it appealed to me.  The choice turned out to be fantastic, I was able to go from zero knowledge of qooxdoo to a fully-functioning administrative backend written with qooxdoo’s stuff in just 1 month.  It’s taken another 7 to tweak the application to make it more luddite-friendly, but the first iteration was pretty dang good.

Implementing the google calendar stuff, I decided to use Zend Framework’s code, which worked great.  Constant Contact’s API was easily implemented using the docs on their website, and I used PEAR’s OpenID code because it is really easily installable using Pyrus.  It turned out to be a bit of a pain because the implementation is not fully maintained, and thus supports neither Google apps OpenID (which is admittedly very complicated and obtuse) or AOL’s OpenID implementation, which uses a redirect.  A bit of hackery had that fixed in no time thanks to the OO design of the package.

To enable storing both the code and data in version control, I decided to store all of the data in sqlite3 databases and use PHP’s sqlite3 extension to manage it.  This works amazingly well because unlike the old sqlite 2 database (PHP’s sqlite extension), an sqlite3 database will work on any operating system.  I chose git to manage the codebase because of its easy cloning and ability to work offline with full revision history and then push to a repository.  Using, I have a private repository accessible via ssh using GPG public keys, so no password problems.  In addition, using Pyrus’s excellent and simple facilities for creating a package.xml, I can publish the codebase to the live site directly from the test site on the server, and easily roll back to a previous version in a pinch.

To facilitate the communication between qooxdoo and PHP, I wrote a new, very small and very fast RPC server based on qooxdoo’s internal standard for the things instead of the large and (in my opinion) poorly constructed one that comes by default.  I saw a very large performance increase after this, and the online app responds at nearly the speed of a normal desktop app.

The frontend of the website is handled simply by rendering templates in the format defined by PEAR2_Template_Savant, which is to say PHP-based templates that use closures to reduce overhead and to simplify rendering by mapping objects to templates much like Zend Framework‘s Views, but with a much simpler codebase or dependency chain.

In addition, I decided to use Yahoo’s media player for our audio files, which is a wonderful, free, remotely hosted javascript player that intelligently chooses a flash player, java player, or direct-to-device player based on the browser’s capabilities.

Putting it all together

The best thing about all of this was the process of combining these disparate technologies.  None of them were designed to work together, but all of them were designed with some basic principles of extensibility that made it possible.  By publishing a REST-based standard, Constant Contact made it really easy to utilize their lists to add a contact form to our website.  Google’s REST-based standards are second-to-none for anything GData-based.  The software I used was also all written with interoperability in mind.  When I first began writing PHP code in the days before PEAR even worked on Windows-based machines, when PHP 4.0.6 was new, there was nothing like this.  XML-RPC was all the rage, and nobody was doing anything that made it easy to use their code remotely in a completely different language.  I love how far we’ve come, and I’m excited to unveil the new site, stay tuned towards the beginning of February!

I’ve attached some screenshots of the administrative backend that uses qooxdoo to show its spartan but fantastic functionality.

Tagged with: , ,
Posted in Computers
5 comments on “Working with qooxdoo and PHP
  1. Kelvin Jones says:

    Can you give more details on how you use Pyrus for managing your code?I’m looking into replacing PEAR with Pyrus, but currently trying to understand the differences.

  2. Gregory Beaver says:

    Kelvin, the biggest difference is that Pyrus is self-contained in pyrus.phar. As a consumer of packages, it is almost the same as PEAR. You still do:php pyrus.phar upgrade PackageNameand so on.The largest difference is as creator of packages, which pyrus makes far easier to do. Pyrus also uses some more robust features under the hood, such as redundant registries, so if one gets corrupted, you can reconstruct it from the others.Is there something specific you do that you are wondering how it would translate into pyurs?

  3. Kelvin Jones says:

    Hi Greg,The issue I’ve had with PEAR, historically, is managing the dependencies that a project has, it seems that the general design was to have 1 PEAR repo on a server, whereas most developers probably have multiple sites on a machine all depending on a different configuration of PEAR.Unless I’m mistaken (highly possible) the only real way to manage this with PEAR was just to extract the PEAR files needed for each project, which makes managing the PEAR code more difficult.

  4. Gregory Beaver says:

    Hi Kevin,Sorry I missed your comment earlier, just approved it. Historically, PEAR was designed with having 2 repositories, a system and a user configuration. This was, as you noted, extremely inflexible. Pyrus is designed to support many PEAR installs all with their own configurations.However, Pyrus also has the ability to upgrade a PEAR package that has been extracted, which makes managing a bundled package inside a larger application that much easier. Check it out, you’ll see what you’re missing.

  5. Sourabh says:

    Hi Professor Greg! I met you at the New Media Center today when you stopped by to check out a camera. Were you able to find one at Henzlik or Love library? Sorry we didn’t have any to check out :(Btw, Todd was telling me about your programming ninja skills so I googled you and found your blog. Just wanted to say, this php stuff is super cool :)Let us know if we can be of any other help ! Have a great rest of the semester !

Leave a Reply

Your email address will not be published. Required fields are marked *


HTML tags are not allowed.