home / blog / Lithium-0-9-5-Dont-Stop-Till-You-Get-Enough
# Lithium 0.9.5: Don't Stop Till You Get Enough

Just a week and a half after 0.9,  the Lithium team are very proud to announce version 0.9.5. This does not put us off of our standard release schedule,  but we've done so much this week that we wanted to push an interim release, so that our developer community can try out these great features: 

**HTTP Auth Adapter**: An `Auth` adapter has been added to allow you to validate against HTTP authentication. You can even use this in parallel with the `Form` adapter if, for example, you want to allow users to authenticate web service requests via the same credentials as their standard logins (think Twitter clients).

**Redesigned `Logger` API**: For our first (and probably only) major BC break, we've redesigned the `Logger` API to provide a more intuitive interface. Instead of configuration names being specified as priority levels, only allowing one adapter per priority, each configuration can now be given an arbitrary name, along with a `'priority'` key, which designates the priority level(s) which the adapter responds to. This additional flexibility allows, among other things, high-priority messages to be written to multiple logs. See [the` Logger` API documentation](http://lithify.me/docs/lithium/analysis/Logger) for details.  

**`Growl` Logger Adapter**: Along with the redesigned API, `Logger` now ships with an adapter for Growl, the popular notification system for OS X. Props to [Sean Coates](http://twitter.com/coates) for the original implementation.  The shipped version has been rewritten from scratch with no external dependencies, and can be a great aid for rapid development tools. 

**Refactoring model initialization**: The bootstrap process for model classes has been refactored and streamlined significantly, and it is now possible to have model classes inherit from one or more base classes (which extend `lithium\data\Model`). Classes will also inherit any properties 

**Read-through caching**: While caching operations are normally a two-step process, where you check to see if a cache key is set, perform the cacheable operation if not, and write the cache, read-through caching makes this process much more intuitive. Consider the following code example:

{{{
$id = $this->request->id;
$user = Cache::read("storage", "user.{$id}", array('write' => function() use ($id) {
	return array('+2 days' => serialize(User::find($id)->data()));
}));
}}}

If the cache key is not present, the passed function is called, and the returned data is saved to the key, using the array key of the return value as the cache expiration time. Using this interface, you can check and set the cache in a single operation.

**New source organization convention for vendor libraries**: We've added two directories to the default distribution: `libraries/_source` and `app/libraries/_source`. The purpose of these directories is for you to drop copies or checkouts of other vendor libraries, and make them easier to link into your applications. After placing vendor libraries into `_source` unaltered, you can symlink the directory containing actual source code into the corresponding `libraries` directory.

For example, I have an app that utilizes some PEAR classes. My current configuration looks like this:
{{{
Libraries::add("PEAR", array(
	"prefix" => false,
	"includePath" => true,
	'path' => LITHIUM_LIBRARY_PATH . "/PEAR/pear/php",
	"transform" => function($class) { return str_replace("_", "/", $class) . ".php"; }
));
}}}

The actual PEAR source code is nested inside `PEAR/pear/php`. This is ugly. Instead, I can move the `PEAR` directory into `app/libraries/_source`, and add a symlink from `app/libraries/_source/PEAR/pear/php` to `app/libraries/PEAR`. Then I can simplify my configuration to:
{{{
Libraries::add("PEAR", array(
	"prefix" => false,
	"includePath" => true,
	"transform" => function($class) { return str_replace("_", "/", $class) . ".php"; }
));
}}}

For libraries that follow the PHP 5.3 naming standard, the difference is even more apparent. PEAR2, for example, could be imported simply with {{{ Libraries::add('PEAR2'); }}}

This convention has other advantages as well, including being able to transparently switch between multiple versions of a library, just by changing a symlink. This convention was inspired by the work of [Paul M. Jones](http://twitter.com/pmjones) on the [SolarPHP project](http://solarphp.com/).

**MongoDB conditional operators**: While we'll always support native MongoDB query operators, we've just added support for SQL-style query operators. Using the standard query syntax, for example:
{{{
Article::find('all', array('conditions' => array(
	'expires' => array('>' => time())
)));
}}}

...this will automatically be translated into native MongoDB query operations. While not a replacement for Mongo's (awesome) syntax, our goal is two-fold: to give plugin developers a loose abstraction tool with which to write queries that work across multiple types of data sources (given a few constraints, naturally), and to lower the barrier-to-entry for application developers who are new to non-relational databases, and are interested in getting their feet wet, or porting their apps.

Finally, thanks to the whole team, and especially [John Anderson](http://twitter.com/raisinbread), our documentation lead, we've added a ton of new API docs, and have almost reached our goal of 100% API coverage for framework classes. So go [wiki:releases/0_9_5 check out the changes], [browse the new API docs](http://lithify.me/docs/lithium), or [download the new release](http://rad-dev.org/lithium/versions).

Enjoy!

~ nate ~