-
Notifications
You must be signed in to change notification settings - Fork 0
A lightweight, flexible web application framework in PHP 5
License
mailmojo/kolibri
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
*************** ABOUT KOLIBRI *************** Kolibri is a lightweight, flexible web application framework written in PHP 5. Kolibri's focus is on providing you with the tools to customize the framework to your liking -- from its custom URI mapper and plug-in-based core architecture, to the view technology of your choice. Kolibri flies either way. Kolibri is under active development and is not feature complete, nor is the API stable. It is however fully functional and is already used in several production applications. ************** INSTALLATION ************** Requirements: * Apache with mod_rewrite support PHP 5.2 with: (PHP 5.1 should work but is * currently untested) - XSL extension - PostgreSQL or SQLite extensions for database applications Check out our bazaar branch if not already done: $ bzr branch lp:kolibri The src/ directory within the checked out directory contains the framework itself, and can be installed where ever you want where Apache has read access (it doesn't need to be in your Apache document root). Copy kolibri.php and .htaccess (which resides in the src/ directory as well) into an Apache document root, and edit kolibri.php to set the install path and application directories. ***************** GETTING STARTED ***************** As documentation is yet a major TODO, this is a [somewhat] small guide to help you get started. A sample application you should look at when following this guide is provided in the examples/wishlist directory. 1. Setup and directory structure -------------------------------- Copy the contents of examples/wishlist to an Apache document root along with kolibri.php and .htaccess as mentioned in the general installation instructions above. Modify the permissions on the db/ directory (which will hold the SQLite database required for this application) to give Apache write access (i.e. "chmod 777 db/" in a shell). As with Kolibri itself, the application files don't have to reside in the document root, but for simplicity's sake we'll keep it there for this example. With the exception of the db/ directory, the other directories are default Kolibri application directories (although again, most can be changed). Their names should be pretty self-evident. To complete the installation of the example application, go to http://localhost/setup (or whatever hostname you're using) to create the database tables. 2. Configuration (or lack thereof) ---------------------------------- You don't have to edit any configuration if you followed the defaults above, but let's take a quick look. As mentioned above, kolibri.php defines Kolibri's and the application's installation directories, while conf/config.php defines application-specific configuration. You can change the web root, URI of static resources (.htaccess may also have to be updated if this is changed), database settings among others. More interesting is the sections related to action mappers and interceptor mappings. Action mappers are PHP classes that defines how URIs (and/or other request data) are mapped to actions, while the interceptor mappings specifies which interceptors (you could also call this "plug-ins" or "filters") are invoked. We discuss both of these in more detail below. 3. Actions and action mappers ----------------------------- In Kolibri, when using the default action mapper (appropriately named DefaultActionMapper, as can be seen in config.php), an URI maps to exactly one action class and vice versa. This mapper tries to find matching action classes by mapping the URI to directory and file names within the actions directory, with a fallback to an Index.php action if no exact match is found. What this means is that a request to the web root will be mapped to Index.php directly within the actions/ directory, while /items maps to items/Index.php if an items/ directory exists, else Items.php directly within the actions/ directory. After adding some wishlist items in the example application, take a look at the URI for the links to delete entries. It links to /items/del/<itemname>, which corresponds to the actions/items/Del.php file. As you can see, no action maps to the item name. Instead, if the last URI-part is not matched to an action, it is put into a request parameter named "id". As for the action classes themselves, their names must exactly match their file names. They implement either one, or both, of doGet() and doPost() methods, which will be executed on HTTP GET or POST calls respectively. Action classes can be plain old objects and need not extend ActionSupport as our example actions does, but more often than not they do simply because it provides some functionality commonly needed by most actions (specifically access to the session and status message facility). How you write your own action mappers are beyond the scope of this introduction, but generally you simply extend DefaultActionMapper, override mapAction(), mapMethod() and/or mapParams() and put it in a directory named mappers/ in your application. Writing your own mappers gives you complete freedom to lay out the actions however you want (i.e. you can have action methods instead of action classes). 4. Interceptors and the wings of Kolibri ---------------------------------------- Kolibri makes use of interceptors for much of it's core functionality. Interceptors are like filters or plug-ins, but we like their names because they, well, intercept requests and can change the outcome of the execution. Everything from session support through authentication to validation is implemented through interceptors. This makes it easy to customize the framework however you like, by disabling interceptors you don't need or writing your own. Interceptors are enabled per URI similar to action mappers. See the documentation in config.php for information how they are setup, and conf/interceptors.php in Kolibri for a list of the currently supported interceptors. The most interesting use of interceptors in our example application can be seen in the Add action. It implements ModelAware and ValidationAware and defines a couple of fields that are used by the ModelInterceptor and ValidatorInterceptor respectively. When the ModelInterceptor is invoked (which it is, as it's part of the defaultStack interceptor stack we have configured), it checks to see if the target action is ModelAware. If it is (as is the case with the Add action), a model instance of the class named in the $model property of the action (in this case Item) is created. Request parameters are traversed and the model instance is populated with their values before being put back into the action. For the ValidatorInterceptor to have any meaning it must be invoked after the ModelInterceptor, which it is as dictated by their order in the defaultStack. If the target action is ValidationAware, it grabs the model object from the action (which was prepared by the ModelInterceptor) and validates the model according to its own rules. Any errors are put into the $errors field in the action, which the action can look at to determine what to do during its execution. While the interceptors just described are among the most complex, more simple functionality such as session support and status messages are also implemented by interceptors. The session for instance can be access in SessionAware actions through $this->session['key'], while the messages we set by $this->msg->setMessage(...) is a facility provided to MessageAware actions by the MessageInterceptor. 5. Models and data access objects --------------------------------- Models in Kolibri applications can, and will most often be, plain objects. You don't have to extend any specific class, in fact, there is no provided "super-model" class to extend. Instead Kolibri makes use of the object-oriented proxy pattern to transparently wrap model objects in a proxy, which among other things provides access to the model's corresponding data access object. Contrary to many other frameworks, Kolibri doesn't include an Object-Relational Mapper (ORM). Instead we prefer to write more complex SQL queries ourselves (as ORMs rarely manage), and provide a SQL-to-Object-Framework (acronyms are fun, let's call it SOFA) which automatically maps the result of SQL to a nested structure of model objects according to their relationships (if joins were involved). Clean separation of PHP logic and SQL queries are of course important, which is why the SQL should be put in a data access object (DAO). They must be put in a dao/ directory within the models/ directory, and each model (which cares about the database) should have it's own DAO. As an example, our Item model has a corresponding ItemDao class for its database access. Taking a step back, let's look at a model class and how it defines its validation rules which is used by the validation framework provided by the ValidatorInterceptor. Our Item model implements Validateable and a rules() method which defines its validation criteria. See the Item class to see how it's defined, and conf/validation.php in Kolibri for a list of all available validators. If the validation is successful, you might want to save the model during the action execution. This is done by simply calling save() on the model. The model proxy will try to figure out if the model actually need saving (i.e. do we know if it was changed since it was retrieved from the database?), and if so calls the appropriate method in the DAO (either insert() or update()). Similarly you call delete() to, well, delete. Direct access to the DAO is provided through the objects property, as demonstrated in the sample actions. 6. Results and views -------------------- One of the cornerstones of Kolibri is the fact that it is not tied to any specific view technology. While we prefer XSL for our views, we realize that not all do (although we urge you to take a look, not least due to the simplified form handling in XSL). This is why Kolibri does not tie actions to views directly. Instead actions return a Result object, of which there could be many kinds. Kolibri already has XsltResult for XSL views, SmartyResult for Smarty templates, PhpResult for regular PHP files, RedirectResult for HTTP redirects, JsonResult for JSON, and more. This makes it easy to support other view technologies and response data simply by providing other Result implementations. As XSL is the view technology with most widespread use in current Kolibri applications, it has got some extra love to offer you. Most importantly it provides simplified syntax to define HTML forms, which will automatically output validation errors and model data. Take a look at the form in views/index.xsl which targets the Add action (which, again, is ModelAware and ValidationAware). If validation fails, XSL and thus the form receives and presents the errors and model data from the action without any extra code on your part. X. The end ---------- While this guide has only scratched the surface, it has hopefully got you going. Any questions, feedback and last but not least contributions are most welcome: https://launchpad.net/kolibri
About
A lightweight, flexible web application framework in PHP 5
Resources
License
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published