Index: manual.xml =================================================================== --- manual.xml (revision 1865) +++ manual.xml (working copy) @@ -63,13 +63,7 @@ be compatible with the framework and it's components, such as the routing. - If you want to install Agavi via PEAR, you do, obviously, need - PEAR installed. If you'd like to grab it straight from the SVN - repository, you'll need a Subversion client installed, of course. Either - way, we recommend you have Phing installed, because creating a project, - actions, view and all these things by hand becomes utterly annoying over - time, and the command line utility uses Phing to relieve you of that - burden. + If you want to install Agavi via PEAR, you do, obviously, need PEAR installed. If you'd like to grab it straight from the SVN repository, you'll need a Subversion client installed, too. You will also need Phing, which Agavi uses for its build system. You should also install PHPDocumentor, so that you too can generate your own documentation if you don't do it already. Subversion, PHPDocumentor and Phing are obvious tools of a serious PHP developer.
@@ -447,22 +441,38 @@
System Architecture - - + Describing an architecture of a free software project essentially means answering the toughest question: what do you get? With Agavi, you get two things: + + A clear and sound way to describe and code up your application logic and to work with your source code, tests and documentation, a set of libraries to solve your common problems and an engine which runs your application + A meta-application based on the aforementioned engine suited for the Web, which has placeholders for your logic. + + + Agavi is a PHP application framework. The essence of an Agavi application corresponds to that of the HTTP protocol: whenever a web request arrives, Agavi application and framework code gets executed by the web server, and the resulting output is returned to the user's browser. In other words, an Agavi application receives an asyncronous request and syncronously returns a response. However, Agavi is perfectly suitable for other types of applications and might be an answer for any kind of large PHP project. + Before we explain the architecture of Agavi, we need to make it clear what Agavi is, exactly. First of all, Agavi is an user-space PHP 5 application framework. This author strongly advises the reader to look at the layout of the Agavi source tree. Every subdirectory of src/ stores classes that correspond to a a particular PHP application pattern. At its core, Agavi is a family of classes that implement various necessary functionality of your application as if you were to write it in raw PHP from scratch. All this code is unified by the developers' single and conservative perspective, resulting in a big, orderly and cooperative library. There are again two distinct families of these classes: those that solve common problems for any general PHP application (I/O, logging, caching, and other support infrastructure), and those that solve problems specifically related to Web applications (such as routing and templating). These classes are glued together by configuration into a runtime environment for your application logic to execute in. This is possible and comfortable because of Agavi's powerful configuration mechanism, allowing you to extend and replace components of your application. For instance, you can replace Agavi's default Security Filter to implement an exotic authentication scheme. Agavi is designed to be extended, and you will find that as you work more with Agavi you reuse the Agavi extensions you wrote for previous projects. + Being a developer, you define your application logic. The framework provides you with a skeleton Web application and a build engine that you can use to create initial source files for your application logic. Your application skeleton consists of some default code and the recommended starter configuration which consists of several XML files that define the shape of entire Agavi environment. + All execution of Agavi application code is given in a certain Context. A Context defines the general conditions in which the application is executed. The Context object is the end product of gluing Agavi components together via configuration; it is literally constructed from components as configuration prescribes for any particular execution conditions. Configuration is an inseparable part of an Agavi application. For example, you may define in the configuration that logging is enabled for a particular Context, performed with alternative logging classes (or databases, or format) in another, and totally disabled in yet another. During execution, the Context is an object that encapsulates access to different parts of Agavi's runtime API. For instance, your web application's requests may execute in a "web" Context when an user is using a browser. However, your XMLRPC web service requests may execute in a Context called "xmlrpc". Interaction with your application via command line console would occur in the "console" Context. Configuration brings life into Context, and it is very important to comprehend that configuration is also a way to achieve your goals. + Pieces of your Agavi application logic are organized as Actions. An Action is a PHP class that Agavi loads and uses when a relevant request arrives (whether it's an external request or a result of another Action). You create an action by running Agavi's build tool, which writes the necessary code skeleton for you. An Action is executed by an Execution Container object, which isolates it from outside world and provides it with the environment it needs, thus making it unaware of outside world. An Action has no idea whether it was called by a console command, a XMLRPC request or an user submitting an HTML form. When you construct your application logic in such fashion, it becomes reusable, and clear borders between actions prevent nasty logic leaks and other long term problems. You can, for instance, write an Action that adds an order once, and then have it instantly available over XMLRPC. You then can write another Action that uses the previous one for batch order processing! When you need to process an Excel file you receive from your affiliate describing your orders, you write a simple script that executes the batch ordering Action in Agavi environment (which means all the nuisance of loading vendor libraries, starting database engines, ensuring integrity of data and notifying all observers etc would be already taken from you by Agavi), passing it orders as parameters from your custom Excel parsing script. Actions may respond with error conditions and pass data to the outside world, but they do not really know what they are communicating with. + Many things happen before an Action gets executed. Agavi initializes the environment, reads configuration, loads necessary classes, and starts the Controller which then works its way towards executing the action. The high-level flow of an Agavi application is implemented using filter chains. A filter chain is a way to chain pieces of logic to one another and pipe some input data through them, resulting in something happening and some output data being returned. All major waypoints of execution are wrapped in filter chains, which are constructed out of configuration. + In the "web" Context, an Action's input is gathered from the HTTP request, and the output must be translated into an appropriate HTTP response. Agavi helps on both counts: first, it preprocesses and organizes the request data into an object that your Action is expecting; then, after your Action is finished, its result is supplied to Views. Depending on the result of your action (most commonly "success" or "error"), a View is selected that can translate its particular response into a Web response. A View does not implement any application logic; it merely selects a template, loads data into it and uses an object called a Renderer to produce output. + However, Agavi's involvement with your application does not end here. Agavi provides you with everything you need on every step of your application's life: tools to perform authorization, maintain sessions, enforce security constraints, format output, log internal software messages, validate data, retain rich and extensible configuration and much more.
Elements of an Application - modules + Agavi applications are made of Modules. A Module encompasses a part of your application logic: typically, it consists of Actions with their associated Views and templates, Models, Validators and module specific configuration. Despite having some peculiar technical properties, Modules exist for the sole purpose of helping you to keep your code organized. A Module is simply a directory that holds other directories containing the components of a module. - actions + Actions are the application logic you develop. An Action is a PHP class which wraps the desired application functionality in its execute(). Agavi Actions may have more than one execute(), and it is recommended that you understand Agavi's division to executeRead() and executeWrite(); see more below. - views and templates + Views are Agavi's idea of presentation logic. A View's main purpose is to interpret the result of an Action and transform it into desired output. Views are distinctly separate from templates; selecting the template and the mechanism that renders the template is a View's +responsibility. A View's output consists of one or more Layers. A Layer is a simple canvas. Views draw their output on Layers. A Layer may also contain Slots, which are gateways to output of other Actions. - models and global models + An unique feature of Agavi is Layouts. To better explain Layouts, a real life example must be given. Let's say you have a web application with a bunch of reports implemented as Actions, as well as some database maintenance tools used by system administrator. Your web +application has navigation, status, messaging and a bunch of other stuff which all needs to be drawn every time a web response is generated. However, your Actions and Views do not deal with top level organization of visual elements across the entire application or some of its part. This is achieved by using Layouts. A Layout is a configuration item that describes how Layers are assigned to Views. Let's imagine that you want your application to compare two reports from different periods; the complete output of such page would be the main decorator template HTML, two HTML blocks containing output of the same report Action for different periods and some controls to control the dates. You don't want the main navigation displayed on this page because the controls are complicated as it is. How do you achieve this without creating a copy of the decorator template or polluting the sole decorator with if/switch statement? Clearly this approarch would not be appropriate for Agavi applications. The Agavi way would be to write some XML to describe the layout you need in high level terms, placing the output of the two actions in Slots, and associating this layout with the particular action that you want to compare the two reports. - config files + Models encapsulate the data access logic. Agavi has the necessary facilities (configuration and factory, connection management, exception management, logging, drivers for some third party database libraries) that you can use but does not have its own ORM mechanism or anything of the sort. Since your Actions intimately depend on how you design your Models, Agavi does not intervene. It is important to emphasize that Agavi's notion of a model is exactly that - a model - not a particular design pattern such as Active Row as it would be the case with many other frameworks. A model begins its life as an empty class and it is up to you to fill it up. + + Configuration files are Agavi's secret sauce. Agavi configuration is described using full power of XML and available PHP 5 tools, which makes it really comfortable to work with. The configuration facility includes a mechanism that uses well defined schemas to compile XML into executable PHP code, which is cached by Agavi internally. In other words, Agavi application does not read its whole configuration from XML files during startup. Configuration describes many aspects of your application that you do not describe in your application logic. For example, you define Agavi routes via the configuration. You can use XML magic such as XPointer to formalize and reuse elements of your configuration, which comes in really handy when you start spotting patterns in your application. For instance, when you realize that you have three distinguishable type of reports, you use the configuration to summarize their high level properties so that you do not have to do the same setup in your code. Agavi configuration is an essential glue that describes how every Agavi object is spawned, making it possible to move static but reusable information about your application from code into XML.
@@ -553,14 +563,17 @@
How a Request is Processed - If you call an URL that is handled by pub/index.php, Agavi will + If you call an URL that is handled by pub/index.php, Agavi will bootstrap the specified (or default) Environment and then create an instance of the specified (or default) Context (this instantiation sets up all of the core components of the framework). Finally, the request is - dispatched from the Context's Controller instance. + dispatched from the Context's Controller instance. For example, the sample Agavi + application would bootstrap the development environment, + load the web context and call it's controller's + dispatch() method. - The dispatch method first executes the routing (if enabled) to - determine the Module/Action that are to be executed. The routing returns + The dispatch method first executes the routing + (if enabled) to determine the Module/Action that are to be executed. The routing returns an Execution Container for the first action. Then, a filter chain containing all Global Filters is created, and the DispatchFilter is added to that chain as the last element. Each filter will be called in