Zend_Tool and ZF 1.8

By now, you are sure to have heard the news, Zend Framework 1.8 has landed. With ZF 1.8 comes several new features such as Zend_Application, Zend_Navigation, Zend_Tag_Cloud, and, my favorite Zend_Tool. Zend_Tool is not a component in the typical sense. Most components have a class at its top level namespace, Zend_Tool does not. Most components are generally consumed inside your application code to simplify runtime tasks, Zend_Tool does not. Zend_Tool is more akin to a framework than a component – a framework within a framework.

So what is Zend_Tool?

The initiative began by exploring what it would take to create a next generation framework for RAD, or Rapid Application Development. RAD as you can imagine, is a term with a pretty wide definition. In its most general sense, its a term that describes the speed at which you can build the resources that form your application's backlog of requirements. In the most ideal of situations, the initial development, or loading phase of a project, should be kept to an absolute minimum such that the developers can get on with the more interesting development. After all, the more "interesting development" is more than likely the reason the application was born.

So if there is interesting development, what is the uninteresting development? For Zend Framework, and most MVC based frameworks for that matter, it's the process of creating the initial project resources common to all projects: the primary project structure, initial configuration files, initial bootstrapping and autoloading code, etc. It also includes the tasks of error handling, controller creation, and view creation to name a few more. For someone just getting involved with ZF, some of these tasks would require hours of reading though tutorials, manuals, and quickstarts. Not exactly "rapid".

Zend_Tool As A Framework

Instead of whipping together a system that was targeted specifically for creating ZF based applications, specifically on the command line, and strictly generating code and not modifying existing code, we set out to build a system extensible in every regard that should concern a developer. Zend_Tool was designed to facilitate abstraction at all the necessary points where we felt that developers would want to extend the system. For example, while we have a primary CLI client, the tooling framework was developed as a generic RPC (remote procedure call) system to enable developing other non-CLI clients. While we have the stock providers (the capabilities of the system), the interfaces to build future providers has remained simple and easy to extend and understand.

Zend_CodeGenerator & Zend_Reflection

During development, we discovered a couple of problem areas that had no solid solution. Code generation is one of those areas. Generally speaking, when you talk about generating code, it's typically a template-based approach; the generated code comes from template files which are usually written without regard as to whether or not they are well-formed (by the target language's standard). Having an templated approach also introduces the risk of developers going outside the suggested coding standard and generating generally bad code (bad code in this sense is both code that will not run as well as poorly formatted code). So, we immediately realized that there was an opportunity to create a component that would provide an object-oriented interface, similar to that of PHP's Reflection API, with the sole purpose of generating well-formed and well-formatted object oriented code. It should be said that the Zend_CodeGenerator component can be used without the rest of the Zend_Tool stack. This means that if you ever find yourself in a position where you need to repeatedly generate code, the first place you should look is Zend_CodeGenerator.

Zend_CodeGenerator doesn't simply write code from scratch; it has the capability of reading existing code, modifying it, and producing new code. This is primarily due to the other component born out of Zend_Tool, Zend_Reflection. Zend_Reflection is not, and I repeat, not a reinvention of the wheel. In fact, it extends PHP's Reflection API to add support for user-based extensions (i.e., extending the Reflection API), docblock reflection (and annotation tags within docblocks), and file-based reflection. The semantics of the component are true to its origins, and can be used as a drop in replacement when the additional feature-set is needed.

Zend_CodeGenerator and Zend_Reflection have similar API's, with Zend_Reflection targetting reading code structure, and Zend_CodeGenerator targetting writing code structure. Together these two components make it easy to reflect and write code during the development process of an application.

Zend_Tool Command Line Client et. al.

It goes without saying that CLI based RAD is a very highly desired for ZF developers. As mentioned previously, the task of setting up the initial resources of a project can be tedious. Many developers prefer to interact with their development environment through the terminal, or command line, so naturally, this is the place we decided would make the most sense to build a client into Zend_Tool. This does not mean it will be the only client; as mentioned previously, the client functionality of Zend_Tool has been abstracted in such a way that additional clients can be built to interact with Zend_Tool. IDEs and text editors have an opportunity to hook into the client framework and dispatch commands from their native interface. Two potential extension points include to of my favorite tools, Zend Studio and Textmate -- but the possibilities are almost limitless. Any client that can execute PHP can effectively build on top of Zend_Tool for tooling needs.

Zend_Tool_Project

Since project development is an iterative process, the tooling side of the equation also needs to keep track of history, so to speak. What we mean by history is keeping track of the actions you have performed: what have you created, where is it located in the project structure, and what is its context in the project? As an example, after creating a project, you might want to create a controller. For all intents and purposes, a controller is simply a file with a class in it; how can the tooling environment know the difference between a regular file and a controller file?

Zend_Tool_Project sets out to solve this problem. Zend_Tool_Project is the bundle of functionality built to work with Zend_Tool_Framework to deliver a solution to the project management problem. Zend_Tool_Project keeps track of the resources inside your application, where they are in relation to each other, and the name by which you refer to them; this is the key to allowing "iterative development". As an example, if you had created that project, with a controller named "foo"; you might want to add actions to that controller later on down the line. To make development as seamless as possible, it should be as simple to modify as it was to create resources. To do this, Zend_Tool_Project keeps track of everything you've done inside your project.

In addition to being an application resource tracker, Zend_Tool_Project is the key part of Zend_Tool that delivers the "build a Zend Framework based project" solution. Zend_Tool_Project knows specifically what a project, controller, view, bootstrap class, index.php file, and so on, should look like, and aids you in creating them. If you were to take Zend_Tool_Project out of the Zend_Tool runtime, you'd be left with just the framework or platform to build a tooling system with. That said, any project can use Zend_Tool_Framework to build tools fulfilling their needs.

What It Can Currently Do

So, with all that in mind. What can it do right now? Instead of talking about it, lets walk through a few screenshots.

Help

Error

Create Project

create controller

create action

What's Next

In addition to what it can already do in the 1.8 release, several additional features are already in the pipeline. Some of these features are considered beta (which is why they are not in the distribution), or are still in the design phase. For example, with Zend_Application, we are finally deciding what a "model" should look like, even if we are only talking about what the name should be. Also, with 1.8 we are finally publishing the default project structure. For a project that has a very firm footing in the "component library" space, these are tremendous steps for Zend Framework.

In addition to model support, we also have plans to add "module" support (for building componentized applications), database connectivity, and Zend_Db_Table file generation. Look for these feature in the upcoming releases. Additionally, since Zend_Tool is so extensible, new (more beta) features can be distributed by outside projects that plug directly into Zend_Tool.