Lithium's Model finders is a great way to avoid repeating the same code blocks over and over. If you google `Lithium finders` you will find many tutorials on this subject but most of the examples don't make much sense (at least to me) since they can be replaced by static methods inside a model class. I have set a simple rule on this matter: methods that don't apply to more than one model class, shouldn't become finders.

To take advantage of finders you must create your own Base model that other models will extend. Below you can see what i use with my two most used finders that i would actually love to see them become official...

class Model extends \lithium\data\Model {
	public static function __init() {
		static::finder('columns', function($self, $params, $chain) {
			$options = &$params['options'];
			$options['return'] = 'resource';
			if ($options['fields'] === null || empty($options['fields'])) {
				$options['fields'] = array($self::meta('key'));
			} elseif (count($options['fields']) > 1) {
				$options['fields'] = array_slice($options['fields'], 0, 1);
			}

			$result = array();
			foreach ($chain->next($self, $params, $chain) as $data) {
				$result[] = $data[0];
			}
			return $result;
		});

		static::finder('pairs', function($self, $params, $chain) {
			$options = &$params['options'];
			$options['return'] = 'resource';
			if ($options['fields'] === null || count($options['fields']) < 2) {
				$key = $self::meta('key');
				$title = $self::meta('title');
				$options['fields'] = array($key, $title);
			} elseif (count($options['fields']) > 2) {
				$options['fields'] = array_slice($options['fields'], 0, 2);
			}

			$result = array();
			foreach ($chain->next($self, $params, $chain) as $data) {
				$result[$data[0]] = $data[1];
			}
			return $result;
		});
	}
}
Read More…

NetBeans allows you to define either global or project specific code formatting options. To apply the following rules globaly navigate to Tools > Options > Editor > Formatting and select PHP language. To define project specific rules right click on your project and go to Properties > Formatting and check the `Use project specific options` and of course select PHP language.

Because the default rules of NetBeans 7.3 are really close to Lithium's coding standarts, we don't need to change many options. Let's begin...


netbeans_lithium_formatting.jpgTabs and Indents

  • Expand Tabs to Spaces: Uncheck
  • Number of Spaces per Indent: 4
  • Tab Size: 4
  • Right Margin: 120
  • Line Wrap: Off
  • Continuation Indentation: 0
  • Array Declaration Indentation: 4

Blank Lines

  • After Function: 0
  • After Open PHP Tag: 0
  • Before Close PHP Tag: 1
Read More…

Lithium models are very flexible, schema can be lazy loaded by the first call to Model::schema(), unless it has been manually defined in the model subclass. Below there is an example of a model with predefined schema 

class UserGroups extends \lithium\data\Model
{
	protected $_schema = array(
		'id' => array('type' => 'id', 'length' => 10, 'null' => false, 'default' => null),
		'title' => array('type' => 'string', 'length' => 64, 'null' => false, 'default' => null),
		'description' => array('type' => 'string', 'length' => 255, 'null' => false, 'default' => null),
		'admin' => array('type' => 'integer', 'length' => 1, 'null' => false, 'default' => 0),
		'resources' => array('type' => 'string', 'length' => null, 'null' => false, 'default' => null),
	);

	protected $_meta = array(
		'key' => 'id',
		'locked' => true,
		'source' => 'user_groups'
	);
}

If you leave the schema configuration empty,lithium will retrieve the information directly from the data source. Which is nice until you understand that this extra step will be taken every time the model is initialized, which is a no no. That's why I am going to show you how to cache the model's schema. Firstly we need to set up a connection and the cache storage, here is some basic configuration:

use lithium\data\Connections;
use lithium\storage\Cache;

Cache::config(array(
	'default' => array(
		'adapter' => 'File',
		'strategies' => array('Serializer')))
);

Connections::add('default', array(
	'type' => 'database',
	'adapter' => 'MySql',
	'host' => 'localhost',
	'login' => 'root',
	'password' => '',
	'database' => 'database',
	'encoding' => 'UTF-8'
));

You probably have those two already in your application's bootstrap files, here is the piece of code that does the schema caching

Connections::get('default')->applyFilter('describe', function($self, $params, $chain) {
	if(!Environment::is('production')) {
		return $chain->next($self, $params, $chain);
	}

	$key = 'schema_' . md5(serialize($params['meta']));
	if(!$result = Cache::read('default', $key)) {
		$result = $chain->next($self, $params, $chain);
		Cache::write('default', $key, $result, '+1 month');
	}
	return $result;
});

By using Lithium's filters we can hook into the data source describe method to intercept default behavior. Firstly there is a check to skip caching if we are not in production environment. Then the system checks if schema has  already been in cache by using the model's meta as a unique key. If not, we allow the default procedure to run and we write the result to cache. 

Some notes
Recently Lithium's model and pretty much all data classes have been heavily updated, in many cases breaking backward compatibility. One of them is the model schema, when fully initialized is now an object instead of a simple arrray. The above snippet was written for the latest version in the dev branch but it will probably work for previous versions as well.

The best practice when writing a model is to manually define the schema. If you follow this principle I am not sure the above snippet will improve  much your app's performance. Initialize object vs retrieve object from cache. Maybe with a more advance cache adapter like APC???

Let me know how this worked for you!

Day number two of porting this application to zend framework 2. I only had a couple of hours today but still i have a couple of things i actually want to talk about. I keep encountering things that are not that much different from ZF1 like Zend\Navigation or Zend\Paginator. I was quite surprised i got them working in seconds.

In the app i have a paginated list of documents, and below is how the code changed:

Zend Framework 1

$db = Zend_Db_Table_Abstract::getDefaultAdapter();
$select = $db->select()->from('document', $orders)->order(array("$order $way"));
$paginator = Zend_Paginator::factory($select);
$paginator->setDefaultItemCountPerPage($perpage);
$paginator->setCurrentPageNumber($this->_getParam('page'));

Zend Framework 2

$db = $this->getServiceLocator()->get('db');
$select = new Select('document');
$select->columns($orders)->order("$order $way");
$paginator = new Paginator(new DbSelect($select, $db));
$paginator->setDefaultItemCountPerPage($perpage);
$paginator->setCurrentPageNumber($page);

 

 Which if you exclude all the Use Statements you have to add on top it's not bad, i actually think it pretty much the same. It would be nice to be able to get the Select object from the adapter but it's not a big deal. The second thing of the day was how actively the ZF2 is developed. I found a couple bugs today working with v2.0.3. The most important was with the Zend\Mvc\Router\Http\Query which was adding the controller, action and namespace parameters to the query string, instead of only adding the extra parameters it was receiving. But guess what download the latest version from github and voila bugs are gone. (Lithium are you there... ;p). That really made my day, i make it a habit not following popular trends or rooting for the underdogs, see my history. I started learning php with LDU cms probably the most unkown cms of all and now choosing Lithium for Komposta Core instead of one of the most popular frameworks like Zend or Symphone or CakePHP for pete sake. So it felt great to go from the disappointing moment  of finding a bug to see that i was fixed in a minute. People are whining how much ZF2 changed and that it got a bit Java-ish but today at least, in my mind ZF2 will succeed because of the active developers and contributors.

Komposta cmf is using a a lot of third party libraries except lithium one of them is HTML Purifier. It is used to ensure security in pages and comments. Komposta has an extended configuration page to setup multiple profiles and you can absolutely play with all the settings from purifier for 100% control. In my last post i embedded a youtube video and it only took me 45 minutes to setup the pages profile lol.

 

komposta_purifier_1.png komposta_purifier_2.png komposta_purifier_3.png komposta_purifier_4.png komposta_purifier_5.png komposta_purifier_8.png

 

There are a lot of applications out there relying on html purifier but with limited configuration. I like configuration ;p

komposta_purifier_6_4.png komposta_purifier_6_8.png komposta_purifier_6.png komposta_purifier_7.png komposta_purifier_8_5.png 

 

Updated Screenshots 2012/11/16

 

The idea of building a cmf came to me 2 years ago, at the time i wasn't into php frameworks, i intended to build it from scratch and i came very close to a release candidate a year ago but my pet project had to be put on hold. I started work at Greek Ministry of Education and i was involved on a lot of web projects and to speed up the procedure i choose Zend Framework as the industry standard choice. That's when i fall in love with php frameworks. Zend 1.11.x was easy to work with, it didn't bound the programmer to follow a strict path and had (probably still has) a huge variety of libraries to accommodate any programmers need. Another big factor on choosing Zend was the excellent documentation and on-line sources.

Six weeks ago when i decided to restart my pet project i had to choose between continuing with my php framework or go Zend. Unfortunately my php framework had to die young because i wanted to have something ready for production this year. Zend framework 2.0 was well under the way but at the time only beta versions had surfaced. I have to admit that after peaking at the source code of ZF2 i wasn't impressed but i won't comment on it until i have the time to check the stable version that was released last week.  

After that i was on a php framework hunt and limited the options pool to Symphony2, Kohana and Lithium. I quickly eliminated Symphony because it looked like it has a very steep learning curve. Kohana, although i promise to keep in touch, is lacking in cutting edge PHP features. After quick tests i was impressed with Lithium. It's relatively small and fast, it doesn't impose stupid restrictions to the programmers and has a better than good in-house Data Model solution. Of course it has some grey areas but because it's so flexible you can bypass any problem or bug easily.

But i have to admit the number one reason for my choice was the news about Lithium getting sponsored by Engine Yards. Honestly Lithium development has slowed down a lot this year and until the news from Engine Yards i wasn't sure if Lithium was dead or alive. Documentation is sketchy at best, online sources are limited and git support is, well hrm... If you are new to php go with a framework with good documentation and community like CakePHP, otherwise be prepared for a lot of code reading or stay tuned, lithium tutorials are on the way...

Hello my name is Chris i am 26 years old, i am a web developer with almost ten years of experience in php and mysql. This site is my personal blog/portfolio. In the past i developed plugins, templates for applications like LDU/Seditio (R.I.P), wordpress, joomla, phpbb, vbulletin and Xbits, you might have stumbled upon me on T3-Design.com where everything used to happen. The last couple of years i was in an on-line hiatus because i was determined to finally take my degree in computer science from the Technological Educational Institute of Athens. This site is my come back to active duty if you will. For this endeavour to succeed i needed to start over from scratch

In the beginning, back in 2005, T3-Design.com was powered by ldu , seditio later and finally wordpress. For years i loathed to have my own base application that i will be able to use for my projects and ideas. For komposta.net i decided to go all out and did that. I started my own CMS or what i prefer to call it CMF,  content management framework. It's called Komposta CMF and as i write this post it's only 96 commits old and hopefully i will make it public later this year.

In the past year i worked a lot with Zend Framework. These were probably the most productive months in my career, so using a php framework was only natural. After research and a lot of consideration i picked Lithium to be the brute force behind komposta for reasons i will explain later...

More info about the Komposta is coming soon for now just have a look

 routes.png resources.png options.png mainSettings.png cron.png adminNavigation.png

I will slowly add all the content from T3-Design for those who miss it, for now just step in and leave a comment please!