Commit: c58f2b89725669ca0820b477ad6e2ca23e5ee927
Author: gwoo | Date: 2010-11-18 16:08:54 -0800
diff --git a/.gitignore b/.gitignore
index e69de29..496ee2c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+.DS_Store
\ No newline at end of file
diff --git a/.htaccess b/.htaccess
new file mode 100644
index 0000000..3b75463
--- /dev/null
+++ b/.htaccess
@@ -0,0 +1,5 @@
+<IfModule mod_rewrite.c>
+ RewriteEngine on
+ RewriteRule ^$ webroot/ [L]
+ RewriteRule (.*) webroot/$1 [L]
+</IfModule>
\ No newline at end of file
diff --git a/config/bootstrap.php b/config/bootstrap.php
new file mode 100644
index 0000000..eaca28f
--- /dev/null
+++ b/config/bootstrap.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2010, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+/**
+ * This is the primary bootstrap file of your application, and is loaded immediately after the front
+ * controller (`index.php`) is invoked. The code below allows you to tell Lithium where to find
+ * your application and support libraries (including the framework itself). It also includes
+ * references to other feature-specific bootstrap files that you can turn on and off to configure
+ * the services needed for your application.
+ */
+
+/**
+ * This is the path to the class libraries used by your application, and must contain a copy of the
+ * Lithium core. By default, this directory is named `libraries`, and resides in the same
+ * directory as your application. If you use the same libraries in multiple applications, you can
+ * set this to a shared path on your server.
+ */
+define('LITHIUM_LIBRARY_PATH', dirname(dirname(__DIR__)) . '/libraries');
+
+/**
+ * This is the path to your application's directory. It contains all the sub-folders for your
+ * application's classes and files. You don't need to change this unless your webroot folder is
+ * stored outside of your app folder.
+ */
+define('LITHIUM_APP_PATH', dirname(__DIR__));
+
+/**
+ * Locate and load Lithium core library files. Throws a fatal error if the core can't be found.
+ * If your Lithium core directory is named something other than 'lithium', change the string below.
+ */
+if (!include LITHIUM_LIBRARY_PATH . '/lithium/core/Libraries.php') {
+ $message = "Lithium core could not be found. Check the value of LITHIUM_LIBRARY_PATH in ";
+ $message .= __FILE__ . ". It should point to the directory containing your ";
+ $message .= "/libraries directory.";
+ throw new ErrorException($message);
+}
+
+/**
+ * This file contains the loading instructions for all class libraries used in the application,
+ * including the Lithium core, and the application itself. These instructions include library names,
+ * paths to files, and any applicable class-loading rules. Also includes any statically-loaded
+ * classes to improve bootstrap performance.
+ */
+require __DIR__ . '/bootstrap/libraries.php';
+
+/**
+ * This file contains configurations for connecting to external caching resources, as well as
+ * default caching rules for various systems within your application
+ */
+require __DIR__ . '/bootstrap/cache.php';
+
+/**
+ * Include this file if your application uses one or more database connections.
+ */
+require __DIR__ . '/bootstrap/connections.php';
+
+/**
+ * This file defines bindings between classes which are triggered during the request cycle, and
+ * allow the framework to automatically configure its environmental settings. You can add your own
+ * behavior and modify the dispatch cycle to suit your needs.
+ */
+require __DIR__ . '/bootstrap/action.php';
+
+/**
+ * This file contains configuration for session (and/or cookie) storage, and user or web service
+ * authentication.
+ */
+// require __DIR__ . '/bootstrap/session.php';
+
+/**
+ * This file contains your application's globalization rules, including inflections,
+ * transliterations, localized validation, and how localized text should be loaded. Uncomment this
+ * line if you plan to globalize your site.
+ */
+// require __DIR__ . '/bootstrap/g11n.php';
+
+/**
+ * This file contains configurations for handling different content types within the framework,
+ * including converting data to and from different formats, and handling static media assets.
+ */
+// require __DIR__ . '/bootstrap/media.php';
+
+/**
+ * This file configures console filters and settings, specifically output behavior and coloring.
+ */
+// require __DIR__ . '/bootstrap/console.php';
+
+
+?>
\ No newline at end of file
diff --git a/config/bootstrap/action.php b/config/bootstrap/action.php
new file mode 100644
index 0000000..41b4d5e
--- /dev/null
+++ b/config/bootstrap/action.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2010, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+
+/**
+ * This file contains a series of method filters that allow you to intercept different parts of
+ * Lithium's dispatch cycle. The filters below are used for on-demand loading of routing
+ * configuration, and automatically configuring the correct environment in which the application
+ * runs.
+ *
+ * For more information on in the filters system, see `lithium\util\collection\Filters`.
+ *
+ * @see lithium\util\collection\Filters
+ */
+
+use lithium\core\Libraries;
+use lithium\net\http\Router;
+use lithium\core\Environment;
+use lithium\action\Dispatcher;
+
+/**
+ * This filter intercepts the `run()` method of the `Dispatcher`, and first passes the `'request'`
+ * parameter (an instance of the `Request` object) to the `Environment` class to detect which
+ * environment the application is running in. Then, loads all application routes in all plugins,
+ * loading the default application routes last.
+ *
+ * Change this code if plugin routes must be loaded in a specific order (i.e. not the same order as
+ * the plugins are added in your bootstrap configuration), or if application routes must be loaded
+ * first (in which case the default catch-all routes should be removed).
+ *
+ * If `Dispatcher::run()` is called multiple times in the course of a single request, change the
+ * `include`s to `include_once`.
+ *
+ * @see lithium\action\Request
+ * @see lithium\core\Environment
+ * @see lithium\net\http\Router
+ */
+Dispatcher::applyFilter('run', function($self, $params, $chain) {
+ Environment::set($params['request']);
+
+ foreach (array_reverse(Libraries::get()) as $name => $config) {
+ if ($name === 'lithium') {
+ continue;
+ }
+ $file = "{$config['path']}/config/routes.php";
+ file_exists($file) ? include $file : null;
+ }
+ return $chain->next($self, $params, $chain);
+});
+
+?>
\ No newline at end of file
diff --git a/config/bootstrap/cache.php b/config/bootstrap/cache.php
new file mode 100644
index 0000000..3e124be
--- /dev/null
+++ b/config/bootstrap/cache.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2010, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+
+/**
+ * This file creates a default cache configuration using the most optimized adapter available, and
+ * uses it to provide default caching for high-overhead operations.
+ */
+use lithium\storage\Cache;
+use lithium\core\Libraries;
+use lithium\action\Dispatcher;
+use lithium\storage\cache\adapter\Apc;
+
+if (PHP_SAPI === 'cli') {
+ return;
+}
+
+/**
+ * If APC is not available and the cache directory is not writeable, bail out. This block should be
+ * removed post-install, and the cache should be configured with the adapter you plan to use.
+ */
+if (!($apcEnabled = Apc::enabled()) && !is_writable(LITHIUM_APP_PATH . '/resources/tmp/cache')) {
+ return;
+}
+
+if ($apcEnabled) {
+ $default = array(
+ 'adapter' => 'lithium\storage\cache\adapter\Apc',
+ );
+} else {
+ $default = array(
+ 'adapter' => 'lithium\storage\cache\adapter\File',
+ 'strategies' => array('Serializer')
+ );
+}
+Cache::config(compact('default'));
+
+Dispatcher::applyFilter('run', function($self, $params, $chain) {
+ if ($cache = Cache::read('default', 'core.libraries')) {
+ $cache = (array) $cache + Libraries::cache();
+ Libraries::cache($cache);
+ }
+ $result = $chain->next($self, $params, $chain);
+
+ if ($cache != Libraries::cache()) {
+ Cache::write('default', 'core.libraries', Libraries::cache(), '+1 day');
+ }
+ return $result;
+});
+
+?>
\ No newline at end of file
diff --git a/config/bootstrap/connections.php b/config/bootstrap/connections.php
new file mode 100644
index 0000000..edad5a9
--- /dev/null
+++ b/config/bootstrap/connections.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2010, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+
+/**
+ * ### Configuring backend database connections
+ *
+ * Lithium supports a wide variety relational and non-relational databases, and is designed to allow
+ * and encourage you to take advantage of multiple database technologies, choosing the most optimal
+ * one for each task.
+ *
+ * As with other `Adaptable`-based configurations, each database configuration is defined by a name,
+ * and an array of information detailing what database adapter to use, and how to connect to the
+ * database server. Unlike when configuring other classes, `Connections` uses two keys to determine
+ * which class to select. First is the `'type'` key, which specifies the type of backend to
+ * connect to. For relational databases, the type is set to `'database'`. For HTTP-based backends,
+ * like CouchDB, the type is `'http'`. Some backends have no type grouping, like MongoDB, which is
+ * unique and connects via a custom PECL extension. In this case, the type is set to `'MongoDb'`,
+ * and no `'adapter'` key is specified. In other cases, the `'adapter'` key identifies the unique
+ * adapter of the given type, i.e. `'MySql'` for the `'database'` type, or `'CouchDb'` for the
+ * `'http'` type. Note that while adapters are always specified in CamelCase form, types are
+ * specified either in CamelCase form, or in underscored form, depending on whether an `'adapter'`
+ * key is specified. See the examples below for more details.
+ *
+ * ### Multiple environments
+ *
+ * As with other `Adaptable` classes, `Connections` supports optionally specifying different
+ * configurations per named connection, depending on the current environment. For information on
+ * specifying environment-based configurations, see the `Environment` class.
+ *
+ * @see lithium\core\Adaptable
+ * @see lithium\core\Environment
+ */
+use lithium\data\Connections;
+
+/**
+ * Uncomment this configuration to use MongoDB as your default database.
+ */
+// Connections::add('default', array(
+// 'type' => 'MongoDb',
+// 'host' => 'localhost',
+// 'database' => 'lithium_blog'
+// ));
+
+/**
+ * Uncomment this configuration to use CouchDB as your default database.
+ */
+// Connections::add('default', array(
+// 'type' => 'http',
+// 'adapter' => 'CouchDb',
+// 'host' => 'localhost',
+// 'database' => 'my_app'
+// ));
+
+/**
+ * Uncomment this configuration to use MySQL as your default database.
+ */
+// Connections::add('default', array(
+// 'type' => 'database',
+// 'adapter' => 'MySql',
+// 'host' => 'localhost',
+// 'login' => 'root',
+// 'password' => '',
+// 'database' => 'lithium_blog'
+// ));
+
+?>
\ No newline at end of file
diff --git a/config/bootstrap/console.php b/config/bootstrap/console.php
new file mode 100644
index 0000000..e47e2c0
--- /dev/null
+++ b/config/bootstrap/console.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2010, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+
+use lithium\console\Dispatcher;
+
+Dispatcher::applyFilter('_call', function($self, $params, $chain) {
+ $params['callable']->response->styles(array(
+ 'heading' => '\033[1;30;46m'
+ ));
+ return $chain->next($self, $params, $chain);
+});
+
+
+?>
\ No newline at end of file
diff --git a/config/bootstrap/g11n.php b/config/bootstrap/g11n.php
new file mode 100644
index 0000000..ab9581f
--- /dev/null
+++ b/config/bootstrap/g11n.php
@@ -0,0 +1,142 @@
+<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2010, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+
+namespace lithium;
+
+use lithium\core\Environment;
+use lithium\g11n\Locale;
+use lithium\g11n\Catalog;
+use lithium\g11n\Message;
+use lithium\util\Inflector;
+use lithium\util\Validator;
+use lithium\net\http\Media;
+use lithium\action\Dispatcher as ActionDispatcher;
+use lithium\console\Dispatcher as ConsoleDispatcher;
+
+/**
+ * Sets the default timezone used by all date/time functions.
+ */
+date_default_timezone_set('UTC');
+
+/**
+ * Adds globalization specific settings to the environment.
+ *
+ * The settings for the current locale, time zone and currency are kept as environment
+ * settings. This allows for _centrally_ switching, _transparently_ setting and retrieving
+ * globalization related settings.
+ *
+ * The environment settings are:
+ * - `'locale'` The effective locale.
+ * - `'locales'` Application locales available mapped to names. The available locales are used
+ * to negotiate he effective locale, the names can be used i.e. when displaying
+ * a menu for choosing the locale to users.
+ */
+$locale = 'en';
+$locales = array('en' => 'English');
+Environment::set('production', compact('locale', 'locales'));
+Environment::set('development', compact('locale', 'locales'));
+Environment::set('test', array('locale' => 'en', 'locales' => array('en' => 'English')));
+
+/**
+ * Globalization (g11n) catalog configuration. The catalog allows for obtaining and
+ * writing globalized data. Each configuration can be adjusted through the following settings:
+ *
+ * - `'adapter' The name of a supported adapter. The builtin adapters are _memory_ (a
+ * simple adapter good for runtime data and testing), _gettext_, _cldr_ (for
+ * interfacing with Unicode's common locale data repository) and _code_ (used mainly for
+ * extracting message templates from source code).
+ *
+ * - `'path'` All adapters with the exception of the _memory_ adapter require a directory
+ * which holds the data.
+ *
+ * - `'scope'` If you plan on using scoping i.e. for accessing plugin data separately you
+ * need to specify a scope for each configuration, except for those using the _memory_,
+ * _php_ or _gettext_ adapter which handle this internally.
+ */
+Catalog::config(array(
+ 'runtime' => array(
+ 'adapter' => 'Memory'
+ ),
+// 'app' => array(
+// 'adapter' => 'Gettext',
+// 'path' => LITHIUM_APP_PATH . '/resources/g11n'
+// ),
+ 'lithium' => array(
+ 'adapter' => 'Php',
+ 'path' => LITHIUM_LIBRARY_PATH . '/lithium/g11n/resources/php'
+ )
+) + Catalog::config());
+
+/**
+ * Integration with `Inflector`.
+ */
+// Inflector::rules('transliteration', Catalog::read(true, 'inflection.transliteration', 'en'));
+
+/*
+ * Inflector configuration examples. If your application has custom singular or plural rules, or
+ * extra non-ASCII characters to transliterate, you can configure that by uncommenting the lines
+ * below.
+ */
+// Inflector::rules('singular', array('rules' => array('/rata/' => '\1ratus')));
+// Inflector::rules('singular', array('irregular' => array('foo' => 'bar')));
+//
+// Inflector::rules('plural', array('rules' => array('/rata/' => '\1ratum')));
+// Inflector::rules('plural', array('irregular' => array('bar' => 'foo')));
+//
+// Inflector::rules('transliteration', array('/É|Ê/' => 'E'));
+//
+// Inflector::rules('uninflected', 'bord');
+// Inflector::rules('uninflected', array('bord', 'baird'));
+
+
+/**
+ * Integration with `View`. Embeds message translation aliases into the `View`
+ * class (or other content handler, if specified) when content is rendered. This
+ * enables translation functions, i.e. `<?=$t("Translated content"); ?>`.
+ */
+Media::applyFilter('_handle', function($self, $params, $chain) {
+ $params['handler'] += array('outputFilters' => array());
+ $params['handler']['outputFilters'] += Message::aliases();
+ return $chain->next($self, $params, $chain);
+});
+
+/**
+ * Integration with `Validator`. You can load locale dependent rules into the `Validator`
+ * by specifying them manually or retrieving them with the `Catalog` class.
+ */
+foreach (array('phone', 'postalCode', 'ssn') as $name) {
+ Validator::add($name, Catalog::read(true, "validation.{$name}", 'en_US'));
+}
+
+/**
+ * Intercepts dispatching processes in order to set the effective locale by using
+ * the locale of the request or if that is not available retrieving a locale preferred
+ * by the client.
+ */
+ActionDispatcher::applyFilter('_callable', function($self, $params, $chain) {
+ $request = $params['request'];
+ $controller = $chain->next($self, $params, $chain);
+
+ if (!$request->locale) {
+ $request->params['locale'] = Locale::preferred($request);
+ }
+ Environment::set(Environment::get(), array('locale' => $request->locale));
+ return $controller;
+});
+ConsoleDispatcher::applyFilter('_callable', function($self, $params, $chain) {
+ $request = $params['request'];
+ $command = $chain->next($self, $params, $chain);
+
+ if (!$request->locale) {
+ $request->params['locale'] = Locale::preferred($request);
+ }
+ Environment::set(Environment::get(), array('locale' => $request->locale));
+ return $command;
+});
+
+?>
\ No newline at end of file
diff --git a/config/bootstrap/libraries.php b/config/bootstrap/libraries.php
new file mode 100644
index 0000000..cdb3b3f
--- /dev/null
+++ b/config/bootstrap/libraries.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2010, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+
+use lithium\core\Libraries;
+
+/**
+ * Optimize default request cycle by loading common classes. If you're implementing custom
+ * request/response or dispatch classes, you can safely remove these. Actually, you can safely
+ * remove them anyway, they're just there to give slightly you better out-of-the-box performance.
+ */
+require LITHIUM_LIBRARY_PATH . '/lithium/core/Object.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/core/StaticObject.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/util/Collection.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/util/collection/Filters.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/util/Inflector.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/util/String.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/core/Adaptable.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/core/Environment.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/net/Message.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/net/http/Message.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/net/http/Media.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/net/http/Request.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/net/http/Response.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/net/http/Route.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/net/http/Router.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/action/Controller.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/action/Dispatcher.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/action/Request.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/action/Response.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/template/View.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/template/view/Renderer.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/template/view/Compiler.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/template/view/adapter/File.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/storage/Cache.php';
+require LITHIUM_LIBRARY_PATH . '/lithium/storage/cache/adapter/Apc.php';
+
+/**
+ * Add the Lithium core library. This sets default paths and initializes the autoloader. You
+ * generally should not need to override any settings.
+ */
+Libraries::add('lithium');
+
+/**
+ * Add the application. You can pass a `'path'` key here if this bootstrap file is outside of
+ * your main application, but generally you should not need to change any settings.
+ */
+Libraries::add('app', array('default' => true));
+
+/**
+ * Add some plugins
+ */
+// Libraries::add('li3_docs');
+
+?>
\ No newline at end of file
diff --git a/config/bootstrap/media.php b/config/bootstrap/media.php
new file mode 100644
index 0000000..c4a42c6
--- /dev/null
+++ b/config/bootstrap/media.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2010, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+
+/**
+ * The `Collection` class, which serves as the base class for some of Lithium's data objects
+ * (`RecordSet` and `Document`) provides a way to manage data collections in a very flexible and
+ * intuitive way, using closures and SPL interfaces. The `to()` method allows a `Collection` (or
+ * subclass) to be converted to another format, such as an array. The `Collection` class also allows
+ * other classes to be connected as handlers to convert `Collection` objects to other formats.
+ *
+ * The following connects the `Media` class as a format handler, which allows `Collection`s to be
+ * exported to any format with a handler provided by `Media`, i.e. JSON. This enables things like
+ * the following:
+ * {{{
+ * $posts = Post::find('all');
+ * return $posts->to('json');
+ * }}}
+ */
+use lithium\util\Collection;
+
+Collection::formats('lithium\net\http\Media');
+
+/**
+ * This filter is a convenience method which allows you to automatically route requests for static
+ * assets stored within active plugins. For example, given a JavaScript file `bar.js` inside the
+ * `li3_foo` plugin installed in an application, requests to `http://app/path/li3_foo/js/bar.js`
+ * will be routed to `/path/to/app/libraries/plugins/li3_foo/webroot/js/bar.js` on the filesystem.
+ * In production, it is recommended that you disable this filter in favor of symlinking each
+ * plugin's `webroot` directory into your main application's `webroot` directory, or adding routing
+ * rules in your web server's configuration.
+ */
+use lithium\action\Dispatcher;
+use lithium\action\Response;
+use lithium\net\http\Media;
+
+Dispatcher::applyFilter('_callable', function($self, $params, $chain) {
+ list($library, $asset) = explode('/', $params['request']->url, 2) + array("", "");
+
+ if ($asset && ($path = Media::webroot($library)) && file_exists($file = "{$path}/{$asset}")) {
+ return function() use ($file) {
+ $info = pathinfo($file);
+ $media = Media::type($info['extension']);
+ $content = (array) $media['content'];
+
+ return new Response(array(
+ 'headers' => array('Content-type' => reset($content)),
+ 'body' => file_get_contents($file)
+ ));
+ };
+ }
+ return $chain->next($self, $params, $chain);
+});
+
+?>
\ No newline at end of file
diff --git a/config/bootstrap/session.php b/config/bootstrap/session.php
new file mode 100644
index 0000000..b57d0b4
--- /dev/null
+++ b/config/bootstrap/session.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2010, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+
+/**
+ * This configures your session storage. The Cookie storage adapter must be connected first, since
+ * it intercepts any writes where the `'expires'` key is set in the options array.
+ */
+use lithium\storage\Session;
+
+Session::config(array(
+ 'cookie' => array('adapter' => 'Cookie'),
+ 'default' => array('adapter' => 'Php')
+));
+
+/**
+ * Uncomment this to enable forms-based authentication. The configuration below will attempt to
+ * authenticate users against a `User` model. In a controller, run
+ * `Auth::check('default', $this->request)` to authenticate a user. This will check the POST data of
+ * the request (`lithium\action\Request::$data`) to see if the fields match the `'fields'` key of
+ * the configuration below. If successful, it will write the data returned from `User::first()` to
+ * the session using the default session configuration. Once the session data is written, you can
+ * call `Auth::check('default')` to check authentication status or retrieve the user's data from the
+ * session. Call `Auth::clear('default')` to remove the user's authentication details from the
+ * session. This effectively logs a user out of the system. To modify the form input that the
+ * adapter accepts, or how the configured model is queried, or how the data is stored in the
+ * session, see the `Form` adapter API or the `Auth` API, respectively.
+ *
+ * @see lithium\security\auth\adapter\Form
+ * @see lithium\action\Request::$data
+ * @see lithium\security\Auth
+ */
+// use lithium\security\Auth;
+
+// Auth::config(array(
+// 'default' => array(
+// 'adapter' => 'Form',
+// 'model' => 'User',
+// 'fields' => array('username', 'password')
+// )
+// ));
+
+?>
\ No newline at end of file
diff --git a/config/routes.php b/config/routes.php
new file mode 100644
index 0000000..502d421
--- /dev/null
+++ b/config/routes.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2010, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+
+use lithium\net\http\Router;
+use lithium\core\Environment;
+
+/**
+ * Here, we are connecting '/' (base path) to controller called 'Pages',
+ * its action called 'view', and we pass a param to select the view file
+ * to use (in this case, /app/views/pages/home.html.php)...
+ */
+Router::connect('/', array('Pages::view', 'args' => array('home')));
+
+/**
+ * ...and connect the rest of 'Pages' controller's urls.
+ */
+Router::connect('/pages/{:args}', 'Pages::view');
+
+/**
+ * Connect the testing routes.
+ */
+if (!Environment::is('production')) {
+ Router::connect('/test/{:args}', array('controller' => 'lithium\test\Controller'));
+ Router::connect('/test', array('controller' => 'lithium\test\Controller'));
+}
+
+/**
+ * Finally, connect the default routes.
+ */
+Router::connect('/{:controller}/{:action}/{:id:[0-9]+}.{:type}', array('id' => null));
+Router::connect('/{:controller}/{:action}/{:id:[0-9]+}');
+Router::connect('/{:controller}/{:action}/{:args}');
+
+?>
\ No newline at end of file
diff --git a/controllers/PagesController.php b/controllers/PagesController.php
new file mode 100644
index 0000000..f4a5cf0
--- /dev/null
+++ b/controllers/PagesController.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace app\controllers;
+
+class PagesController extends \lithium\action\Controller {
+
+ public function view() {
+ $path = func_get_args();
+
+ if (empty($path)) {
+ $path = array('home');
+ }
+ $this->render(array('template' => join('/', $path)));
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/controllers/PostsController.php b/controllers/PostsController.php
new file mode 100644
index 0000000..9b71de3
--- /dev/null
+++ b/controllers/PostsController.php
@@ -0,0 +1,44 @@
+<?php
+
+namespace app\controllers;
+
+use \app\models\Post;
+
+class PostsController extends \lithium\action\Controller {
+
+ public function index() {
+ $posts = Post::all();
+ return compact('posts');
+ }
+
+ public function view() {
+ $post = Post::first($this->request->id);
+ if (!$post) {
+ return $this->redirect('Posts::index');
+ }
+ return compact('post');
+ }
+
+ public function add() {
+ $post = Post::create();
+
+ if (($this->request->data) && $post->save($this->request->data)) {
+ return $this->redirect(array('Posts::view', 'id' => $post->id));
+ }
+ return compact('post');
+ }
+
+ public function edit() {
+ $post = Post::find($this->request->id);
+
+ if (!$post) {
+ $this->redirect('Posts::index');
+ }
+ if (($this->request->data) && $post->save($this->request->data)) {
+ $this->redirect(array('Posts::view', 'id' => $post->id));
+ }
+ return compact('post');
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/extensions/adapter/empty b/extensions/adapter/empty
new file mode 100644
index 0000000..e69de29
diff --git a/extensions/command/empty b/extensions/command/empty
new file mode 100644
index 0000000..e69de29
diff --git a/extensions/data/source/empty b/extensions/data/source/empty
new file mode 100644
index 0000000..e69de29
diff --git a/extensions/helper/empty b/extensions/helper/empty
new file mode 100644
index 0000000..e69de29
diff --git a/index.php b/index.php
new file mode 100644
index 0000000..4718294
--- /dev/null
+++ b/index.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2010, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+
+require 'webroot/index.php';
+
+?>
\ No newline at end of file
diff --git a/libraries/_source/empty b/libraries/_source/empty
new file mode 100644
index 0000000..e69de29
diff --git a/models/Post.php b/models/Post.php
new file mode 100644
index 0000000..e30a3f6
--- /dev/null
+++ b/models/Post.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace app\models;
+
+class Post extends \lithium\data\Model {
+
+ public $validates = array();
+}
+
+?>
\ No newline at end of file
diff --git a/resources/g11n/empty b/resources/g11n/empty
new file mode 100755
index 0000000..e69de29
diff --git a/resources/tmp/cache/templates/empty b/resources/tmp/cache/templates/empty
new file mode 100755
index 0000000..e69de29
diff --git a/resources/tmp/logs/empty b/resources/tmp/logs/empty
new file mode 100755
index 0000000..e69de29
diff --git a/resources/tmp/tests/empty b/resources/tmp/tests/empty
new file mode 100755
index 0000000..e69de29
diff --git a/tests/cases/controllers/PostsControllerTest.php b/tests/cases/controllers/PostsControllerTest.php
new file mode 100644
index 0000000..9353aa9
--- /dev/null
+++ b/tests/cases/controllers/PostsControllerTest.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace app\tests\cases\controllers;
+
+use \app\controllers\PostsController;
+
+class PostsControllerTest extends \lithium\test\Unit {
+
+ public function setUp() {}
+
+ public function tearDown() {}
+
+ public function testIndex() {}
+ public function testView() {}
+ public function testAdd() {}
+ public function testEdit() {}
+}
+
+?>
\ No newline at end of file
diff --git a/tests/cases/extensions/adapter/empty b/tests/cases/extensions/adapter/empty
new file mode 100644
index 0000000..e69de29
diff --git a/tests/cases/extensions/command/empty b/tests/cases/extensions/command/empty
new file mode 100644
index 0000000..e69de29
diff --git a/tests/cases/extensions/data/source/empty b/tests/cases/extensions/data/source/empty
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/tests/cases/extensions/data/source/empty
@@ -0,0 +1 @@
+
diff --git a/tests/cases/extensions/helper/empty b/tests/cases/extensions/helper/empty
new file mode 100644
index 0000000..e69de29
diff --git a/tests/cases/models/PostTest.php b/tests/cases/models/PostTest.php
new file mode 100644
index 0000000..6b719a5
--- /dev/null
+++ b/tests/cases/models/PostTest.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace app\tests\cases\models;
+
+use \app\models\Post;
+
+class PostTest extends \lithium\test\Unit {
+
+ public function setUp() {}
+
+ public function tearDown() {}
+
+
+}
+
+?>
\ No newline at end of file
diff --git a/tests/functional/empty b/tests/functional/empty
new file mode 100644
index 0000000..e69de29
diff --git a/tests/integration/empty b/tests/integration/empty
new file mode 100644
index 0000000..e69de29
diff --git a/tests/mocks/empty b/tests/mocks/empty
new file mode 100644
index 0000000..e69de29
diff --git a/views/elements/empty b/views/elements/empty
new file mode 100644
index 0000000..e69de29
diff --git a/views/layouts/default.html.php b/views/layouts/default.html.php
new file mode 100644
index 0000000..a30b52b
--- /dev/null
+++ b/views/layouts/default.html.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2010, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+?>
+<!doctype html>
+<html>
+<head>
+ <?php echo $this->html->charset();?>
+ <title>Blog > <?php echo $this->title(); ?></title>
+ <?php echo $this->html->style(array('debug', 'lithium')); ?>
+ <?php echo $this->scripts(); ?>
+ <?php echo $this->html->link('Icon', null, array('type' => 'icon')); ?>
+</head>
+<body class="app">
+ <div id="container">
+ <div id="header">
+ <h1>Blog</h1>
+ <h2>
+ Powered by <?php echo $this->html->link('Lithium', 'http://lithify.me/'); ?>.
+ </h2>
+ </div>
+ <div id="content">
+ <?php echo $this->content(); ?>
+ </div>
+ </div>
+</body>
+</html>
\ No newline at end of file
diff --git a/views/layouts/default.xml.php b/views/layouts/default.xml.php
new file mode 100644
index 0000000..3eebc6a
--- /dev/null
+++ b/views/layouts/default.xml.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2010, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+?>
+<?=$this->xml->header();?>
+<?=$this->content;?>
\ No newline at end of file
diff --git a/views/pages/home.html.php b/views/pages/home.html.php
new file mode 100644
index 0000000..aecbda9
--- /dev/null
+++ b/views/pages/home.html.php
@@ -0,0 +1,171 @@
+<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2010, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+
+use \lithium\data\Connections;
+
+$checkName = null;
+$checkStatus = $solutions = array();
+
+$notify = function($status, $message, $solution = null) use (&$checkName, &$checkStatus, &$solutions) {
+ $checkStatus[$checkName] = $status === true;
+
+ if (!is_string($status)) {
+ $status = $status ? 'success' : 'fail';
+ }
+
+ $message = is_array($message) ? join("\n<br />", $message) : $message;
+
+ if (!empty($solution)) {
+ $default = array(
+ 'id' => 'help-' . $checkName,
+ 'title' => $checkName,
+ 'content' => null
+ );
+ if (is_array($solution['content'])) {
+ $solution['content'] = join("\n<br />", $solution['content']);
+ }
+ $solutions[$checkName] = $solution += $default;
+
+ }
+ return "<div class=\"test-result test-result-{$status}\">{$message}</div>";
+};
+
+$sanityChecks = array(
+ 'resourcesWritable' => function() use ($notify) {
+ if (is_writable($path = realpath(LITHIUM_APP_PATH . '/resources'))) {
+ return $notify(true, 'Resources directory is writable.');
+ }
+ return $notify(false, array(
+ "Your resource path (<code>$path</code>) is not writeable. " .
+ "To fix this on *nix and Mac OSX, run the following from the command line:",
+ "<code>chmod -R 0777 {$path}</code>"
+ ));
+ },
+ 'database' => function() use ($notify) {
+ $config = Connections::config();
+ $boot = realpath(LITHIUM_APP_PATH . '/config/bootstrap.php');
+ $connections = realpath(LITHIUM_APP_PATH . '/config/bootstrap/connections.php');
+
+ if (empty($config)) {
+ return $notify('notice', array('No database connections defined.'), array(
+ 'title' => 'Database Connections',
+ 'content' => array(
+ 'To create a database connection, edit the file <code>' . $boot . '</code>, ',
+ 'and uncomment the following line:',
+ '<pre><code>require __DIR__ . \'/bootstrap/connections.php\';</code></pre>',
+ 'Then, edit the file <code>' . $connections . '</code>.'
+ )
+ ));
+ }
+ return $notify(true, 'Database connection(s) configured.');
+ },
+ // 'databaseEnabled' => function() use ($notify, &$checkStatus) {
+ // if (!$checkStatus['database']) {
+ // return;
+ // }
+ // $results = array();
+ // $config = Connections::config();
+ // foreach ($config as $name => $options) {
+ // $enabled = Connections::enabled($name);
+ // if (!$enabled) {
+ // $results[] = $notify('exception', "Database for <code>{$options}</code> is not enabled.");
+ // }
+ // }
+ // if (empty($results)) {
+ // $results[] = $notify(true, "Database(s) enabled.");
+ // }
+ // return implode("\n", $results);
+ // },
+ // 'databaseConnected' => function() use ($notify, &$checkStatus) {
+ // if (!$checkStatus['database']) {
+ // return;
+ // }
+ // $results = array();
+ // $config = Connections::config();
+ // foreach ($config as $name => $options) {
+ // $enabled = Connections::enabled($name);
+ // if ($enabled) {
+ // $connection = Connections::get($name)->connect();
+ // if ($connection) {
+ // $results[] = $notify(
+ // true, "Connection to <code>{$name}</code> database verified."
+ // );
+ // } else {
+ // $results[] = $notify(
+ // false, "Could not connect to <code>{$name}</code> database."
+ // );
+ // }
+ // }
+ // }
+ // return implode("\n", $results);
+ // },
+ 'magicQuotes' => function() use ($notify) {
+ if (get_magic_quotes_gpc() === 0) {
+ return;
+ }
+ return $notify(false, array(
+ "Magic quotes are enabled in your PHP configuration. Please set <code>" .
+ "magic_quotes_gpc = Off</code> in your <code>php.ini</code> settings."
+ ));
+ },
+ 'registerGlobals' => function() use ($notify) {
+ if (!ini_get('register_globals')) {
+ return;
+ }
+ return $notify(false, array(
+ 'Register globals is enabled in your PHP configuration. Please set <code>' .
+ 'register_globals = Off</code> in your <code>php.ini</code> settings.'
+ ));
+ },
+);
+
+?>
+
+<?php
+
+foreach ($sanityChecks as $checkName => $check) {
+ echo $check();
+}
+
+?>
+<h3>Getting Started</h3>
+<p>
+ This is your application's default home page. To change this template, edit the file
+ <code><?php echo realpath(LITHIUM_APP_PATH . '/views/pages/home.html.php'); ?></code>.
+</p>
+
+<h4>Layout</h4>
+<p>
+ To change the application's
+ <em><a href="http://lithify.me/en/docs/lithium/template">layout</a></em> (the file containing
+ the header, footer and default styles), edit the file
+ <code><?php echo realpath(LITHIUM_APP_PATH . '/views/layouts/default.html.php'); ?></code>.
+</p>
+
+<h4>Routing</h4>
+<p>
+ To change the <em><a href="http://lithify.me/docs/lithium/net/http/Router">routing</a></em> of
+ the application's default page, edit the file
+ <code><?php echo realpath(LITHIUM_APP_PATH . '/config/routes.php'); ?></code>.
+</p>
+
+<?php if ($solutions) { ?>
+ <?php foreach ($solutions as $solution) { ?>
+ <h4 id="<?php echo $solution['id']; ?>"><?php echo $solution['title']; ?></h4>
+ <p><?php echo $solution['content']; ?></p>
+ <?php } ?>
+<?php } ?>
+
+<h4>Additional Resources</h4>
+<ul>
+ <li><a href="http://lithify.me/docs/lithium">Lithium API</a></li>
+ <li><a href="http://sphere.lithify.me/">Lithium Community</a></li>
+ <li><a href="http://dev.lithify.me/lithium/wiki">Lithium Development Wiki</a></li>
+ <li><a href="http://dev.lithify.me/lithium/source">Lithium Source</a></li>
+ <li><a href="irc://irc.freenode.net/#li3">#li3 irc channel</a></li>
+</ul>
\ No newline at end of file
diff --git a/views/posts/add.html.php b/views/posts/add.html.php
new file mode 100644
index 0000000..089fc78
--- /dev/null
+++ b/views/posts/add.html.php
@@ -0,0 +1,6 @@
+<?php
+echo $this->form->create();
+echo $this->form->field('title');
+echo $this->form->field('body', array('type' => 'textarea'));
+echo $this->form->submit('submit');
+
diff --git a/views/posts/edit.html.php b/views/posts/edit.html.php
new file mode 100644
index 0000000..9c5c396
--- /dev/null
+++ b/views/posts/edit.html.php
@@ -0,0 +1,5 @@
+<?php
+echo $this->form->create();
+echo $this->form->field('title');
+echo $this->form->field('body', array('type' => 'textarea'));
+echo $this->form->submit('submit');
\ No newline at end of file
diff --git a/views/posts/index.html.php b/views/posts/index.html.php
new file mode 100644
index 0000000..0455fcb
--- /dev/null
+++ b/views/posts/index.html.php
@@ -0,0 +1,7 @@
+<div class="posts">
+<?php
+foreach ($posts as $post) {
+ echo "<h3>" . $this->html->link($post->title, array('Posts::view', 'id' => $post->id)) . "</h3>";
+}
+?>
+</div>
\ No newline at end of file
diff --git a/views/posts/view.html.php b/views/posts/view.html.php
new file mode 100644
index 0000000..f6a0566
--- /dev/null
+++ b/views/posts/view.html.php
@@ -0,0 +1,5 @@
+<div class="posts">
+<h3><?=$post->title?></h3>
+<p><?=$post->body?></p>
+
+<p><?=$this->html->link('keep reading', array('Posts::index'));?></p>
\ No newline at end of file
diff --git a/webroot/.htaccess b/webroot/.htaccess
new file mode 100644
index 0000000..21796cf
--- /dev/null
+++ b/webroot/.htaccess
@@ -0,0 +1,7 @@
+<IfModule mod_rewrite.c>
+ RewriteEngine On
+ RewriteCond %{REQUEST_FILENAME} !-d
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteCond %{REQUEST_FILENAME} !favicon.ico$
+ RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
+</IfModule>
\ No newline at end of file
diff --git a/webroot/css/debug.css b/webroot/css/debug.css
new file mode 100644
index 0000000..a9ecb71
--- /dev/null
+++ b/webroot/css/debug.css
@@ -0,0 +1,594 @@
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2010, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+* {
+ margin: 0;
+ padding: 0;
+}
+
+body.test-dashboard {
+ font-family: Helvetica, Arial, sans-serif;
+ font-size: 16px;
+ margin: 0;
+ min-width: 800px;
+}
+
+body.test-dashboard a {
+ color: #333;
+}
+
+body.test-dashboard #header h1 {
+ margin: 0;
+ float:right;
+ font-weight: normal;
+}
+
+body.test-dashboard #header h1 a {
+ text-decoration: none;
+ display: block;
+ padding: .45em 0.75em 0 0;
+ color: rgba(0,0,0,.15);
+}
+
+body.test-dashboard .triangle:before {
+ content: '\25B2';
+ font-size: 1em;
+}
+
+body.test-dashboard #header {
+ padding: 0;
+}
+
+body.test-dashboard #header:after {
+ display: block;
+ content: ' ';
+ clear: both;
+}
+
+body.test-dashboard .article {
+ clear:both;
+}
+
+body.test-dashboard .test-content {
+ float:left;
+ padding: 2em 2% 4em;
+ width: 74%;
+}
+
+.test-content h2 {
+ font-weight: normal;
+ font-size: 1.45em;
+ margin-bottom: .5em;
+ float: left;
+}
+.test-content h2 span {
+ color: #bbb;
+ display: block;
+ font-size: .55em;
+}
+.test-content h3 {
+ font-weight: normal;
+ margin: 1.5em 0 1em;
+}
+
+body.test-dashboard a.test-button,
+body.test-dashboard a.test-button:link,
+body.test-dashboard a.test-button:visited,
+body.test-dashboard a.test-button:hover,
+body.test-dashboard a.test-button:active {
+ display: block;
+ float: right;
+ font-weight: bold;
+ font-size: 1.25em;
+ background-color:#f5f5f5;
+ border-color: #e6e6e6;
+ color: #999;
+ padding: .5em 1em;
+ margin: 0;
+ background-color: white;
+ border: 1px solid #e5e5e5;
+ text-decoration: none;
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+ -moz-box-shadow: 0 0 6px rgba(0,0,0,.1);
+ -webkit-box-shadow: 0 0 6px rgba(0,0,0,.1);
+ box-shadow: 0 0 6px rgba(0,0,0,.1);
+}
+
+body.test-dashboard a.test-button:hover,
+body.test-dashboard a.test-button:active {
+ color: black;
+ background: white;
+ -moz-box-shadow: inset 0 0 6px rgba(0,0,0,.15);
+ -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.15);
+ box-shadow: inset 0 0 6px rgba(0,0,0,.15);
+}
+
+body.test-dashboard ul {
+ margin: .25em 0;
+ padding: 0.2em 0 0 0;
+}
+
+body.test-dashboard ul ul li {
+ display: block;
+ margin: 0 0 1px .5em;
+ padding: 0.25em 0 0 0.75em;
+ border: 1px solid rgba(0,0,0,0.05);
+ border-width: 0 0 0 1px;
+}
+
+body.test-dashboard .test-menu {
+ float: left;
+ padding: .75em 0 1em 1%;
+ width: 20%;
+ background: #f6f6f6;
+ font-size: .85em;
+}
+
+.test-dashboard .test-menu > ul {
+ margin-top: 0;
+ padding-top: 1px;
+}
+.test-dashboard .test-menu ul li ul {
+ margin-top: .1em;
+}
+.test-dashboard .test-menu li:hover {
+}
+.test-dashboard .test-menu li > ul {
+ display: block;
+}
+.test-dashboard .test-menu li:hover > ul {
+ display: block;
+}
+ul.menu, ul.menu ul {
+ list-style: none;
+}
+ul.menu a {
+ color: #666;
+ text-decoration: none;
+ display: block;
+}
+
+ul.menu a:hover, ul.menu a:active, ul.menu a.menu-folder:hover {
+ color: black;
+}
+
+ul.menu a.menu-folder {
+ color: #333;
+ font-weight: bold;
+ text-decoration: none;
+ font-size: 1.2em;
+}
+
+
+a.test-all {
+ display: block;
+ float: left;
+ font-size: 1.5em;
+ text-align: center;
+ text-decoration: none;
+ padding: .75em 0;
+ width: 21%;
+ color: #666;
+ background: #e6e6e6;
+}
+a.test-all:hover {
+ background: #60AF12;
+ -moz-box-shadow: inset 0 0 12px rgba(0,0,0,.25);
+ -webkit-box-shadow: inset 0 0 12px rgba(0,0,0,.25);
+ box-shadow: inset 0 0 12px rgba(0,0,0,.25);
+ color: white !important;
+ text-shadow: 0px 0px 6px rgba(0,0,0,.5);
+}
+
+ul.menu a {
+ display: block;
+ padding: 0.1em 0;
+}
+
+ul.menu a:before, a.menu-folder:before, ul.metrics li:before {
+ display: inline !important;
+ float: none !important;
+ padding: 0 0.5em 0 0;
+ content: '\25B4';
+ font-weight: normal;
+ color: rgba(0,0,0,.1);
+}
+a.menu-folder:before {
+ padding: 0 !important;
+ content: '\25B2' !important;
+}
+ul.menu a:hover:before, a.menu-folder:hover:before, ul.metrics li:hover:before {
+ color: #60AF12;
+}
+
+/*--- Benchmarking ---*/
+table.metrics {
+ border: 1px solid #e6e6e6;
+ -moz-box-shadow: 0 0 6px rgba(0,0,0,.15);
+ -webkit-box-shadow: 0 0 6px rgba(0,0,0,.15);
+ box-shadow: 0 0 6px rgba(0,0,0,.15);
+}
+table.metrics {
+ border-collapse: collapse;
+}
+table.metrics th {
+ padding: .5em 1em;
+ font-size: 1.1em;
+ color: black;
+ background: #e6e6e6;
+ font-weight: normal;
+}
+table.metrics th, table.metrics td {
+ border-bottom: 1px solid rgba(0,0,0,.05);
+}
+
+td.metric-name {
+ text-align: left;
+ white-space: nowrap;
+ padding: 6px 8px;
+ background: #e6e6e6;
+ width: 35%;
+}
+tr:hover td.metric-name {
+ background: #f5f5f5;
+}
+td.metric {
+ font-family: 'Andale Mono', Monaco, Courier, monospace !important;
+ font-weight: bold;
+ padding: 6px 8px;
+ text-align: right;
+ width: 65%;
+ background: #f5f5f5;
+}
+tr:hover td.metric {
+ background: white;
+}
+
+ul.classes, ul.files {
+ list-style-type: none;
+ font-family: 'Andale Mono', Monaco, Courier, monospace !important;
+}
+
+ul.metrics {
+ list-style-type: none;
+ padding: .5em !important;
+}
+
+ul.metrics li {
+ padding: .25em;
+}
+
+/*--- Test Results ---*/
+div.test-result {
+ clear: both;
+ margin: 1em 0 .5em;
+ padding: .75em 1em .55em;
+ color: #FFFFFF;
+ background: #666;
+ border: 1px solid #000000;
+ border-width: 0 0 4px 0;
+ font-size: 1.15em;
+ -moz-box-shadow: inset 0 0 12px rgba(0,0,0,.25);
+ -webkit-box-shadow: inset 0 0 12px rgba(0,0,0,.25);
+ box-shadow: inset 0 0 12px rgba(0,0,0,.25);
+ text-shadow: 0px 0px 6px rgba(0,0,0,.5);
+}
+
+div.test-result-success {
+ background-color: #62B212;
+ border-color: #467F0D;
+}
+
+div.test-result-fail {
+ background-color: #CC1414;
+ border-color: #7F0D0D;
+}
+
+div.test-result-exception {
+ background-color: #E58F16;
+ border-color: #995F0F;
+}
+div.test-result-notice {
+ background-color: #E5D416;
+ border-color: #B2A511;
+}
+
+div.test-result code {
+ background: rgba(0,0,0,.25);
+ color: rgba(255,255,255,.85);
+ border: none;
+ font-size: .75em;
+ padding: .1em .5em !important;
+ text-shadow: none;
+}
+
+div.test-assert, div.test-exception, div.test-skip {
+ margin: 1px 0 0 0;
+ padding: .5em 0 .5em 1em;
+ color: #000000;
+ font-family: 'Andale Mono', Monaco, Courier, monospace !important;
+ font-size: 1em;
+ line-height: 1.5em;
+ position: relative;
+ border: 1px solid rgba(0,0,0,.05);
+ border-width:0 0 1px 8px;
+}
+
+div.test-assert-passed {
+ border-left-color: #D0F9E0;
+}
+
+div.test-assert-failed {
+ color: #7F0D0D;
+ border-left-color: #CC1414;
+}
+
+div.test-exception {
+ color: #995F0F;
+ border-left-color: #E58F16;
+}
+
+div.test-skip {
+ background-color: #fafafa;
+ color: #666;
+}
+
+.test-assert span.content,
+.test-exception span.content,
+.test-skip span.content,
+.test-assert span.trace,
+.test-exception span.trace,
+.test-skip span.trace {
+ display: block;
+ clear: both;
+ white-space: pre;
+ color: #777;
+ font-size: .9em;
+ padding: .5em 1em;
+ margin: .5em 0;
+ background: #fafafa;
+ border: 1px solid rgba(0,0,0,.1);
+ -moz-box-shadow: inset 0 0 6px rgba(0,0,0,.15);
+ -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.15);
+ box-shadow: inset 0 0 6px rgba(0,0,0,.15);
+}
+
+.test-assert span.trace {
+ padding: 0 .5em;
+ margin: .25em 0 .25em .5em;
+ background: #FAFAFA;
+}
+
+div.test-exception span.trace {
+ font-style: italic;
+}
+
+div.test-skip span.content {
+ color: #999;
+ padding: 0 1em;
+ -moz-box-shadow: none;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ border: none;
+}
+/*--- SQL Dumps ---*/
+.lithium-sql-log table {
+ background: #f4f4f4;
+}
+
+.lithium-sql-log td {
+ padding: 4px 8px;
+ text-align: left;
+}
+
+
+/*--- Debugger Dumps ---*/
+pre {
+ color: #000;
+ background: #f0f0f0;
+ padding: 1em;
+}
+
+pre.lithium-debug {
+ background: #ffcc00;
+ font-size: 1.2em;
+ line-height: 1.5em;
+ margin-top: 1em;
+ overflow: auto;
+ position: relative;
+}
+
+div.lithium-stack-trace {
+ background: #fff;
+ border: 4px dotted #ffcc00;
+ color: #333;
+ margin: 0px;
+ padding: 6px;
+ font-size: 1.2em;
+ line-height: 1.5em;
+ overflow: auto;
+ position: relative;
+}
+
+/*--- Code Highlighting ---*/
+div.lithium-code-dump pre {
+ position: relative;
+ overflow: auto;
+}
+
+div.lithium-stack-trace pre, div.lithium-code-dump pre {
+ color: #000;
+ background-color: #F0F0F0;
+ margin: 0px;
+ padding: 1em;
+ overflow: auto;
+}
+
+div.lithium-code-dump pre, div.lithium-code-dump pre code {
+ clear: both;
+ font-size: 1em;
+ line-height: 1.5em;
+ margin: 4px 2px;
+ padding: 4px;
+ overflow: auto;
+}
+
+div.lithium-code-dump span.code-highlight {
+ background-color: #ff0;
+ padding: 4px;
+}
+
+/*--- Code Coverage Analysis ---*/
+span.filters {
+ display: block;
+ float: right;
+ margin: 1em 0 .5em 0;
+}
+span.filters a {
+ display: block;
+ float: left;
+ padding: .5em 1em;
+ margin-left: .25em;
+ text-decoration:none;
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+ background: #e6e6e6;
+ color: #666;
+}
+span.filters a:hover, span.filters a.active {
+ -moz-box-shadow: none;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ color: black;
+ background: #f5f5f5;
+}
+
+span.filters a.active {
+ background: #62B212;
+ text-shadow: 0px 0px 6px rgba(0,0,0,.5);
+ color: white;
+}
+
+div.code-coverage-results, h4.code-coverage-name {
+ clear: both;
+ color: #000000;
+ font-size: .8em;
+ font-family: 'Andale Mono', Monaco, Courier, monospace !important;
+ background-color: #fafafa;
+ border: 1px solid #e6e6e6;
+ border: 1px solid rgba(0,0,0,.1);
+ -moz-box-shadow: 0 0 6px rgba(0,0,0,.15);
+ -webkit-box-shadow: 0 0 6px rgba(0,0,0,.15);
+ box-shadow: 0 0 6px rgba(0,0,0,.15);
+}
+
+h4.coverage {
+ color: #454545;
+ margin: 2em 0 .5em;
+ font-weight: normal;
+ padding: 0;
+}
+
+h4.code-coverage-name {
+ color: #999;
+ background-color: #ECECEC;
+ border-top: none;
+ padding: 0.25em 0.5em;
+ margin: 0 1px 0 0;
+ font-weight: normal;
+ float: right;
+}
+
+div.code-coverage-results div.code-line {
+ display: block;
+ float: none;
+ clear: both;
+}
+
+div.code-coverage-results span.content {
+ display: block;
+ clear: right;
+ white-space: pre;
+ line-height: 1.5em;
+ min-height: 1.5em;
+ background: black;
+}
+
+div.code-coverage-results div.uncovered span.content {
+ color: #FFD8D8;
+ background-color: #260000;
+}
+
+div.code-coverage-results div.covered span.content {
+ color: #DDFDCB;
+ background-color: #0C2600;
+}
+
+div.code-coverage-results div.ignored span.content {
+ color: rgba(255,255,255,.5);
+}
+
+div.code-coverage-results span.line-num {
+ display: block;
+ float: left;
+ width: 3em;
+ color: #999;
+ background-color: #ECECEC;
+ text-align: right;
+ border-right: 1px solid #ccc;
+ padding-right: 4px;
+ margin-right: 5px;
+ line-height: 1.5em;
+}
+
+div.code-coverage-results .code-line:hover span.line-num {
+ background: #ddd;
+ color: #666;
+}
+
+div.code-coverage-results span.line-num strong {
+ color: #666;
+}
+
+div.code-coverage-results div.start {
+ margin-top: 30px;
+ padding-top: 5px;
+ border: 1px solid #aaa;
+ border-width: 1px 1px 0px 1px;
+}
+
+div.code-coverage-results div.end {
+ margin-bottom: 30px;
+ padding-bottom: 5px;
+ border: 1px solid #aaa;
+ border-width: 0px 1px 1px 1px;
+}
+
+div.code-coverage-results div.realstart {
+ margin-top: 0px;
+}
+
+div.code-coverage-results p.note {
+ color: #bbb;
+ padding: 5px;
+ margin: 5px 0 10px;
+ font-size: .8em;
+}
+
+div.code-coverage-results span.result-bad {
+ color: #a00;
+}
+
+div.code-coverage-results span.result-ok {
+ color: #fa0;
+}
+
+div.code-coverage-results span.result-good {
+ color: #0a0;
+}
diff --git a/webroot/css/lithium.css b/webroot/css/lithium.css
new file mode 100644
index 0000000..be4deac
--- /dev/null
+++ b/webroot/css/lithium.css
@@ -0,0 +1,294 @@
+/*-------------------------------------------------------------------------------------------------
+ Lithium: the most rad php framework
+
+ @copyright Copyright 2009, Union of RAD (http://union-of-rad.org)
+ @license http://opensource.org/licenses/bsd-license.php The BSD License
+-------------------------------------------------------------------------------------------------*/
+
+/*--- Reset ---*/
+* { margin: 0; padding: 0; }
+html, body { height: 100%; min-height: 100%; }
+
+/*--- Layout ---*/
+body {
+ font-family: Helvetica, Arial, sans-serif;
+ font-size: 14px;
+ line-height: 1.5em;
+ color: #0d0d0d;
+ background-color: #fff;
+}
+#container {
+ position: relative;
+ padding: 60px 10%;
+}
+
+/*--- Basics ---*/
+h1, h2, h3, h4, h5, h6 {
+ font-weight:normal;
+ color:#111;
+ line-height: 1;
+ margin: 1.5em 0 0.5em 0;
+}
+h1 { font-size: 2.6em; }
+h2, h5 { font-size: 2em; color: #666; }
+h3, h6 { font-size: 1.7em; color: #00a8e6; }
+h4 { font-size: 1.4em; }
+h5 { font-size: 1.2em; }
+h6 { font-size: 1em; }
+p { margin-bottom: 1em; }
+strong { font-weight: bold; }
+em { font-style: italic; }
+a { text-decoration: none; color: #666; border-bottom: 1px dashed #00bbff; }
+a, h1 a, h2 a { text-decoration: none; }
+a:hover { color: #00bbff; }
+a:visited:hover { color: #ff59ff; }
+a img { border: none; }
+
+/*--- Code ---*/
+pre > code {
+ display: block;
+ color: white;
+ background: #141414;
+ border: 1px solid white;
+ padding: 1em !important; /* remove if base important is removed, too */
+ overflow: auto;
+ font-size: .9em;
+}
+a code {
+ background: transparent;
+ border: 0;
+}
+a:hover code {
+ color: inherit;
+}
+code, pre, .fixed {
+ font-family: Monaco, Courier, monospace !important;
+ font-weight: normal;
+ font-size: 0.85em;
+ white-space: pre;
+}
+code {
+ padding: .2em .25em !important;
+ border: 1px solid #F0F0F0;
+ background: #FAFAFA;
+}
+pre {
+ background: none;
+ padding: 0 0 .5em 0 !important;
+}
+
+/*--- Lists ---*/
+li ul, li ol { margin: 0; }
+ul, ol { margin: 0 0 1em 2.75em; }
+dt, dd {
+ font-style: italic;
+ margin: .5em 0;
+}
+dt {
+ font-weight: bold;
+}
+dd {
+ margin-left: 1em;
+}
+/*--- Header ---*/
+#header h1 {
+ margin: .1em 0;
+ font-size: 35px;
+}
+#header h2 {
+ width: 70%;
+ margin: .5em .5em 2em 0;
+ color: #666;
+ font-size: 22px;
+ line-height: 28px;
+}
+
+/*--- Tables ---*/
+table {
+ clear: both;
+ width: 100%;
+ border-collapse: collapse;
+ border-spacing: 0;
+ border: 1px solid #e6e6e6;
+ background: #fafafa;
+ margin: 12px 0;
+}
+td, th {
+ padding: .25em 1em;
+ border: 1px solid #e6e6e6;
+ vertical-align: middle;
+ text-align: left;
+ font-weight: normal;
+ color: #666;
+ font-size: 0.85em;
+}
+tr:nth-child(even) {
+ background: #fff;
+}
+thead th, tfoot td {
+ background: #f3f3f3;
+ color: #333;
+ text-align: left;
+ font-size: 1em;
+ font-weight: bold;
+ padding: .5em .75em;
+}
+/*--- Forms ---*/
+form {
+ display: block;
+ clear: both;
+ background: #fafafa;
+ padding: 1em 2em 2em 2em;
+ border: 1px solid #e6e6e6;
+}
+fieldset {
+ padding: 2em;
+ margin: 0 0 1em 0;
+ border: 1px solid #e6e6e6;
+ background: #f3f3f3;
+}
+legend {
+ padding: .5em 1em;
+ border: 1px solid #e6e6e6;
+ background: #fff;
+ font-size: 22px;
+}
+label {
+ padding: 0 1em 0 0;
+ color: #454545;
+ font-weight: normal;
+}
+input, textarea, button {
+ font-family: Helvetica, Arial, sans-serif;
+ padding: 2px 4px;
+ border: 1px solid #e5e5e5;
+ color: #454545;
+ font-size: 1em;
+ line-height: 1.25em;
+}
+input[type=text], input[type=password], input[type=submit], textarea {
+ clear: both;
+ display: block;
+ padding: .25em .5em;
+}
+input[type=text], input[type=password], textarea {
+ width: 97%;
+ max-width: 950px;
+ margin: .5em 0 1em 0;
+ padding:.5em;
+}
+input[type=submit], input[type=button], input[type=reset], input[type=file], button {
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+ padding: .5em 1em;
+ margin: 0 .75em 0 0;
+ background-color: white;
+ color: black !important;
+ border: 1px solid #e5e5e5 !important;
+ cursor: pointer;
+}
+select {
+ clear: both;
+ display: block;
+ margin: .5em 0 1em 0;
+}
+div.checkbox {
+ clear: both;
+ padding: 1em 0;
+}
+.checkbox label {
+ display: inline;
+}
+input[type=submit] {
+ margin: 1em inherit;
+ border: none;
+ color: #000;
+ font-size: 16px;
+ font-weight: bold;
+}
+input[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus {
+ border-color: #00a8e6;
+ outline: none;
+}
+
+/*--- Misc ---*/
+hr {
+ border: none;
+ height: 0;
+ border-bottom: 1px solid #e6e6e6;
+ margin:1em 0;
+}
+sup, sub {
+ color: #666;
+ font-size: .65em;
+}
+acronym {
+ font-weight: bold;
+ font-style: italic;
+ color: #333;
+}
+abbr {
+ color: #333;
+}
+
+blockquote {
+ padding: 0.15em .5em;
+ margin: 0.5em 0;
+ font-size: 2em;
+ color: #666;
+ display: block;
+ font-style: italic;
+}
+
+blockquote:before, blockquote:after {
+ display: inline;
+ color: #e5e5e5;
+ font-size: 3em;
+ position: relative;
+ top: 0.25em;
+ left: -0.1em;
+}
+
+blockquote:before {
+ content: '\D \201C';
+}
+
+blockquote:after {
+ content: '\201D';
+}
+
+/*--- Shadows ---*/
+code {
+ -moz-box-shadow: 0 0 3px rgba(0,0,0,.1);
+ -webkit-box-shadow: 0 0 3px rgba(0,0,0,.1);
+ box-shadow: 0 0 3px rgba(0,0,0,.1);
+ color: #666;
+}
+table, form, pre > code {
+ margin-top: 12px;
+ margin-bottom: 12px;
+}
+table, form, pre > code, .shadow {
+ -moz-box-shadow: 2px 2px 12px rgba(0,0,0,.15);
+ -webkit-box-shadow: 2px 2px 12px rgba(0,0,0,0.15);
+ box-shadow: 2px 2px 12px rgba(0,0,0,.15);
+}
+img.shadow {
+ border: 1px solid rgba(255,255,255,.15);
+}
+input[type=submit], input[type=button], input[type=reset], input[type=file], button {
+ -moz-box-shadow: 0 0 6px rgba(0,0,0,.1);
+ -webkit-box-shadow: 0 0 6px rgba(0,0,0,.1);
+ box-shadow: 0 0 6px rgba(0,0,0,.1);
+}
+input[type=submit]:hover, input[type=button]:hover, input[type=reset]:hover, button:hover {
+ -moz-box-shadow: inset 0 0 6px rgba(0,0,0,.15);
+ -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.15);
+ box-shadow: inset 0 0 6px rgba(0,0,0,.15);
+}
+input, textarea {
+ -moz-box-shadow: inset 0 0 3px rgba(0,0,0,.1);
+ -webkit-box-shadow: inset 0 0 3px rgba(0,0,0,.1);
+ box-shadow: inset 0 0 3px rgba(0,0,0,.1);
+}
\ No newline at end of file
diff --git a/webroot/favicon.ico b/webroot/favicon.ico
new file mode 100644
index 0000000..6924956
Binary files /dev/null and b/webroot/favicon.ico differ
diff --git a/webroot/img/empty b/webroot/img/empty
new file mode 100644
index 0000000..e69de29
diff --git a/webroot/index.php b/webroot/index.php
new file mode 100644
index 0000000..3b79fa0
--- /dev/null
+++ b/webroot/index.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2010, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+
+/**
+ * Welcome to Lithium! This front-controller file is the gateway to your application. It is
+ * responsible for intercepting requests, and handing them off to the `Dispatcher` for processing.
+ *
+ * If you're sharing a single Lithium core install or other libraries among multiple
+ * applications, you may need to manually set things like `LITHIUM_LIBRARY_PATH`. You can do that in
+ * `config/bootstrap.php`, which is loaded below:
+ */
+require dirname(__DIR__) . '/config/bootstrap.php';
+
+/**
+ * The following will instantiate a new `Request` object and pass it off to the `Dispatcher` class.
+ * By default, the `Request` will automatically aggregate all the server / environment settings, URL
+ * and query string parameters, request content (i.e. POST or PUT data), and HTTP method and header
+ * information.
+ *
+ * The `Request` is then used by the `Dispatcher` (in conjunction with the `Router`) to determine
+ * the correct controller to dispatch to, and the correct response type to render. The response
+ * information is then encapsulated in a `Response` object, which is returned from the controller
+ * to the `Dispatcher`, and finally echoed below. Echoing a `Response` object causes its headers to
+ * be written, and its response body to be written in a buffer loop.
+ *
+ * @see lithium\action\Request
+ * @see lithium\action\Response
+ * @see lithium\action\Dispatcher
+ * @see lithium\net\http\Router
+ */
+echo lithium\action\Dispatcher::run(new lithium\action\Request());
+
+?>
\ No newline at end of file
diff --git a/webroot/js/empty b/webroot/js/empty
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/webroot/js/empty
@@ -0,0 +1 @@
+