# Lithium Architecture Though most of this manual covers how to create your own classes in Lithium (controllers, models, and the like), you may want to familiarize yourself with some of the basic architectural ideas and philosophies behind the framework. As you come to know the code—and start to build plugins and extensions—keeping additions in style with Lithium's architecture becomes important. This guide explains some of the ideas and practices behind how Lithium is put together, at a fundamental level. Inspecting the core libraries will make much more sense after understanding the principles outlined here. # Constructors and Initialization The base class in Lithium's hierarchy, `lithium\core\Object`, forms the basic logic for all of the concrete classes in the framework. This class defines several conventions for how classes in Lithium should be structured: * Universal constructor * Object configuration * Object initialization * Filtering * Testing utilities ## Universal Constructor The `Object` class features a unified constructor, which all classes share. The function takes a single argument, `$config` which is an array of properties that is automatically saved to the `$_config` property of the current object. This approach allows for short constructor signatures and creates a unified way to override object configuration, or set object defaults when subclassing. ## Object Configuration & Initialization Constructor logic should be kept to a minimum. One of the last steps in the unified constructor is to call the objects `init()` method. Here's where you do your heavy lifting. If you need to manipulate an object in its un-initialized state, pass `false` as the value to the `init` key to the constructor. This prevents `init()` from running, and is especially handy when building test cases. {{{ <?php namespace app/extensions; use lithium\net\http\Service; class Foo extends \lithium\core\Object { public $service; public function __construct(array $config = array()) { $defaults = array( 'foo' => 'bar' ); parent::__construct($config + $defaults); } public function _init() { parent::_init(); $this->service = new Service(); } public function baz() { echo $this->_config['foo']; } } ?> }}} {{{ <?php use app\extensions\Foo; $foo = new Foo(); $foo->baz(); // 'bar' $foo2 = new Foo(array( 'foo' => '123' )); $foo2->baz(); // '123' $foo3 = new Foo(array( 'init' => 'false' )); get_class($foo3->service); // PHP Warning... get_class($foo->service); // 'lithium\net\http\Service' ?> }}} ## Filtering The `Object` class also allows subclasses to filter their methods. An entire guide has been dedicated to filters, and you'll find examples and explanations later in this chapter. Long story short, a filterable method is created by encapsulating the main logic for a method inside a closure. That closure is then passed to `Object::_filter()` (or `StaticObject::_filter()` for static objects) to allow for chain management. Subclasses of `Object` use the filter methods to allow other developers to wrap logic around their own without cluttering the object's API. ## Testing and State One challenge with testing is creating and initializing your objects. The `__set_state()` function allows test writers to quickly create objects with their pre-existing properties and values intact. This method can be called statically on any class that extends `Object` to return an instance of itself. {{{ <?php class MockObject extends \lithium\core\Object { protected $_protected = null; public function getProtected() { echo $this->$_protected; } } $object = MockObject::__set_state(array( '_protected' => 'testing' )); $object->getProtected(); // 'testing' ?> }}} # Managing Dependencies Objects that subclass Lithium's core `Object` class can also manage dependencies at runtime using a simple dependency injection mechanism. # Package Organization # Exception Handling # Lithium File Structure Before you get started with Lithium, it's important to know how your application's main folder is structured, and where everything should go. Clone yourself a copy of the main repo, and you'll find an app folder structure that contains: * `config` * `controllers` * `extensions` * `libraries` * `models` * `resources` * `tests` * `views` * `webroot` Let's tackle each of these folders one-by-one, covering what each is used for, and how you can best organize your application. ## Config The `config` folder contains three main pieces: bootstrap files, your connections information, and your routes definitions. ### Bootstrapping Lithium The main bootstrap file in the config folder is `bootstrap.php`. This file is second file PHP will execute in any request cycle, and it loads up the Lithium framework along with any other extras that you define there. As such, it's a great place to place initial application configuration. The best practice for bootstrapping parts of your application is by writing specific bootstrap files and placing them in `config/bootstrap/filename.php`. Once written, include the configuration into the main bootstrap file: {{{ // Adding my custom configuration or initialization... require __DIR__ . '/bootstrap/myconfig.php'; }}} ### Connections The `connections.php` file in config lists the connections you have to external data resources, most often some type of database. Connections should be listed in this file, as calls to `Connections::add()`, like so: {{{ Connections::add('default', array( 'type' => 'database', 'adapter' => 'MySql', 'host' => 'localhost', 'login' => 'root', 'password' => '', 'database' => 'my_blog' )); Connections::add('couch', array( 'type' => 'http', 'adapter' => 'CouchDb', 'host' => '127.0.0.1', 'port' => 5984 )); Connections::add('mongo', array('type' => 'MongoDb', 'database' => 'my_app')); }}} The particulars on the adapter will shape how the connection definition is put together, but this list should constitute what you've got in `connections.php`. ### Routes Routes definitions is how you inform the framework how URLs and bits of code match up. At the most basic level, it's how you tell Lithium which controller should respond to a request to a given URL. For example, I could specify that any request to `/login` is handled by `UsersController::login()` like this: {{{ Router::connect('/login', array('controller' => 'users', 'action' => 'login')); }}} More on routes later, but this file should house all such configuration information. ## Controllers Application controllers are housed here. Each controller is named in CamelCased, plural format (i.e. `PostsController.php`), and placed here. ## Extensions The extensions folder is meant to store extension classes that you've created for your application. Custom helpers, adapters, console commands and data classes. ### Adapter A number of Lithium classes extend the `lithium\core\Adaptable` static class. This class allows you to take a number of different approaches and easily switch out implementations for an application task. Authentication, session handling, and caching are a few examples of Lithium functionality that have been made adaptable. Custom application adapters should be placed in this folder, organized by subfolder. For example, if I created a custom adapter for the `Auth` class, based on my LDAP setup, I'd create the implementation in `/extensions/adapter/auth/Ldap.php`. ### Command Custom console applications are placed in `command`. Commands you create should be built similar to those you see in `/lithium/console/command`. As an example, say I created a custom mailer queue, and I need to create a command to fill up the queue with announcement emails and trigger the send process. I'd create a new class called `QueueFiller` that extends `lithium\console\Command`, and place it in `app/extensions/command/QueueFiller.php`. Once there, running `li3 queue-filler` from the command line will trigger the logic I've written. ### Data Occasionally a new application will require custom data classes to work with a storage engine not already accommodated for by core classes. If you've got some proprietary database, and it's result objects or query structures are very customized, you'll extend the classes in the `lithium\data` namespace (i.e. `Source`, `source\Database` or `source\Http`) and place them here for use in your application. ### Helper Custom view helpers are common need. These classes should extend `lithium\template\Helper` and be placed in this folder. ## Libraries The `libraries` folder is meant to house entire Lithium applications—or plugins—that your main application makes use of. Any plugins you download from the [ Laboratory](http://lab.lithify.me/), or pull down via the Library `li3` command should end up here. Third-party, non-Lithium libraries should be placed here as well. If you're integrating with Facebook, or using part of the Zend Framework in your application, place those files here as well. ## Models Application models are stored here, in CamelCased, plural naming format (i.e. `Posts.php`). ## Resources The resources folder is used by a Lithium application as a non-web viewable storage place for application data. By default globalization files (such as `.po` string files) and temporary application files are stored there. As you build your application, the `resources` folder is a great place for other application data like custom cache files, SQLite databases, or a temporary spot for uploaded files. The `resources` is a place where the web server has write access, so make sure to keep that in mind when securing your application. ## Tests The `tests` folder is where the unit testing framework files for your application reside. The testing setup for Lithium is covered elsewhere, but let's cover what ends up in each of the testing subfolders here. ### Cases All of the actual unit testing logic for the main MVC classes in the application go in the `cases` folder. Subfolders should already exist inside of `cases` to prompt you where each sort of test case should go. ### Integration Unit tests in the `integration` folder test the interaction between two or more classes, or abstract class implementations. ### Mocks Classes in `mocks` are used to facilitate certain unit tests. For example, if I'm testing a custom model I've created, I can create a new class in `mocks/data/MockSource.php` and use it in my model unit testing logic. It is recommend that you use subfolder organization that mimics your application's and Lithium's namespacing and folder structure. ## Views The `views` folder contains any pieces of view-level code in your application. The two main core folders here to note are `elements` and `layouts`. Other view folders here contain views organized by controller name. ### Elements Elements are small bits of view code that are used in multiple views. A common navigational element, menu, or form might end up as an element in this folder. Element files are suffixed with a compound extension: the first showing the type of view code, and the last as `.php`. Example element filenames might include `nav.html.php`, `animateLink.js.php`, or `header.xml.php`. ### Layouts Views (and the elements they may contain) are rendered inside of view layouts. The layouts for your application reside in this folder, named similar to elements. A layout named `default` will be used to render a view if none other has been specified by the controller. ### Controller View Folders Along with the `elements` and `layouts` folders, many other controller-specific view folders will reside here. One default example is the `pages` folder here that holds all the views for the core `PagesController`. As you create new controllers and views for your application, create new folders here, named after your controllers. ## Webroot The `webroot` folder of your application is (ideally) the only place in your application that is web-visible. The `index.php` file takes care of bootstrapping Lithium, and the rest of the folders and files here are used for static content delivery. Things like JavaScript files, images, Flash objects, and movies should end up here for easy access for your web server to deliver to the client.