Validation differences from CakePHP and Lithium

Validation rules are one of the changes between CakePHP and Lithium. Instead of creating the rules in the model you wish to use them with, they are now managed by a validation class. The way of calling them has also changed slightly and the way of creating custom rules has changed massively.

Assignments

To use validation rules in CakePHP you assign them to the object variable “validate” with an associative array. The key of the each array item being the name for the data field and the value being another array which can either be filled with arrays of the validation rules. With a validation rule being an associative array having the key rule and value being either a string with the name of the validation rule or an array with the fist item being a string with the validation rule and other items being arguments or the rule. Below you can see a basic example code of this.

In Lithium it’s pretty much the same with some small changes. Firstly the variable is now validates. also the defining of the validation rule no has the key ‘rule’ but is an integer 0. Also you can longer pass arguments to the validation rule in the same way, instead you can send extra options in the same way you would one of the default rules. Below is a the above code refactored into a Lithium model.

Creating

The creation of validation rules have changed massively. In CakePHP you would create a public object function named as the rule with at least one argument. The first argument is an array with contains one item which is the value of the field that is to be validated. Below is a match another field rule in CakePHP.

Below is the same rule in Lithium. Instead of it being in the model class which is awesome because it’s now decoupled from your model meaning can be used independently of your models as well as shared between models. 

Options

The options are pretty much the same, however I’ve noticed some new ones and I’ve yet to find a list of all the Model options in Lithium so I figured I would just list some of them all out.

message - string - The message that the user should see if the validation rule fails.
last - Boolean - if the validation rule should be run last.
skipEmpty - Boolean - If true it means the rule is skipped when the field is empty.
required - Boolean - If true it means the field is required to pass this validation
on - String - Create/update are actions where the rule is to be implemented. Such as you’ll only want to validate some information on the creation of the row.

There is also information in the $options array that are set automatically that can contain information that can be useful.

model - String - The name of the model class.
values - Array - the contents of the $_POST array.
event - String - the type of model event, update or create.
field - String - the field name that is currently being validated.

Changing rules on fly

From time to time I need to change the validation rules that the model applies at execution. You can do this by passing an options array to the validates method with the rules in them.

The main problem I found was trying to get access to the validation rules. The reason I needed to get access to the validation rules is that the rules array passed to the validates function over writes the default rules for the model. So unless you wish to completely rewrite all the rules or not have the default rules run you need to get access to the default rules. In CakePHP it’s as simple as calling validate member from the model object. But with Lithium the model saving is done by an Entity object and not a model object. So I had to create a model object just to get the validates rules. Below you can find how I did it.

Unit Testing

Like everything code wise I want automated testing. With the validation class over the methods in the model class, unit testing validation rules became a lot easier. In fact it’s so easy it only takes a few lines of code to properly test simple validation rules, which majority are. For more advance ones obviously more advanced unit tests would be needed. Below you can find the test for the match validation rule.

Summary

While the assigning of validation rules has only changed slightly the best improvement can be found in the development and implementation of the validation rules.

Setting up Jenkins with Lithium

After my blog post about how I set up Jenkins and Phing to build lithium apps I was asked if I could share my Jenkins set up. So I figured I might as well document the entire install. Easiest way to document the entire process is to start from fresh and document each step, so I fired up a ubuntu cloud server instance and here’s what I did to get Jenkins to successfully build my lithium app.

Step one install Jenkins, mercurial and MySQL. Jenkins to for obvious reasons. MySQL since my lithium application requires MySQL database usage. During this it’ll ask me to set my root password for MySQL. Since this is a temporary instance that won’t be about for more than an hour or so I’ve just used root. With mercurial being the version control system being used to store the code.

root@Jenkins# apt-get install mysql-server jenkins mercurial

Step two is to install php and pear. Easy enough.

root@Jenkins# apt-get install php5 php-pear php5-mysql

Step three install phing

root@Jenkins# pear channel-discover pear.phing.info
root@Jenkins# pear install [--alldeps] phing/phing

Step four set up the database. Since I’m using MySQL in my app I have to create the database and the table structure. I’ve whacked all the SQL to do this in a SQL file.

root@Jenkins:~# mysql -u root -p < structure.sql

Step five configure Jenkins, to do that I just have to access the server on the port 8080 which is the default port for Jenkins.

Jenkins dashboard

Step six manage Jenkins, I need to install some plugins for my build since I’m using phing and mercuical.

Configure plugins step 1

Step seven select the phing plugin.

Configure plugins step 2

Step eight select mecurial plugin

Configure plugins step 3

Step nine install the plugins.

Configure plugins step 4

Step eleven wait for Jenkins to restart, this will take a minute or so.

Configure plugins step 5

Step twelve create a new job. I’ve just gone for the free style software project since my build is currently rather simple.

Jenkins job creation step 1

Step thirteen enter the mercurial details. I’ve blanked them out for obvious reasons. Then I needed to create a build step from the drop down and select phing and put “main” in the target input field. (I forgot to take a screenshot of this)

Jenkins job creation step 2

Step fourteen run a build, this will do the mercurial cloning for me. It fails the first time, because I’ve not included the connections.php file in mercurial due to everyone having different settings and it’s a pain when someone changes it and it breaks a bunch of peoples dev environments. (yes I know about the enviroment ability, it’s still just a pain)

Jenkins failed build

Step fifthteen run another build after I’ve added the connections.php file. And see the successful build. (For some reason the circle image didn’t change to yellow/green like it should)

Jenkins successful build

My current phing build file is extremely basic, since the project is in a very early stage it just runs the tests. Since Lithium has it’s own test framework I’ve created my own phing test tasks which can be found here on github. The build file I use can be found below.

Conclusion

This should be pretty much everything anyone should need to use Jenkins with Lithium. If anyone has any questions or better ways of doing things just leave a comment.

Using Phing to run Lithium tests

Since Continuous Integration is awesome and I’m going be using Lithium a lot, it was clear I needed away to run my Lithium unit tests via Jenkins. Since I use Phing for builds on Jenkins and that Lithium uses it’s own testing framework there was only one solution. Build a phing task to run Lithium tests. So after a quick hacking session I completed a quick task that allows for the running of Lithium tests and fails the build if all of them don’t pass. You can find it on github at https://github.com/icambridge/phing_li3.

Install

To install is simple, just copy the directory into the directory you have your build file in.

Build File

The build file implementation is simple, you just defined a new task with taskdef, then you can just call the task, currently it only has two parameters both of which are required. 

li3Base : The location where you have the Lithium application.
tests : The namespace for the tests. It also allows for “all” to run all the tests that can be found.

Mock Request

Since the way Lithium finds the base path for the application we need to mock the Request and replace the _base() method. This will stop Lithium using the base location of Phing for the base location of the lithium app and prepending it to redirects.

Conclusion

Currently it’s a quick and rough way of running the tests, I don’t doubt as I need to do different things I’ll expand this task to allow me to achieve them. I’ll also improve the functionality of it as well.

You can download it at https://github.com/icambridge/phing_li3

How unit testing with Lithium

At work we’re starting to use Lithium for our main product. So once I found out, the first thing I wanted to do was to find out how I could unit test with it. In some cases it makes life really easy in other cases it made it bitch. So here’s what I’ve figured out so far. If you know a better way please tell me.

Original Controller

This is a simple controller that just sets a view variable called test with “test” as it’s content.

Mocks

To unit test the controller I’ve found that you need to mock the controller to allow you to use the dependency injection ability to use a mock response class to stop the view from being outputted. Below I’ve included a basic starting point for the mock controller in which it changes the response to the mock response and I added a getter function to allow me to access internal variables such as the render.

Here is the mock response class which just disables the rendering of the page view.

So now we have a mock controller that we can run tests on that won’t output HTML on every test. Now I’ll create a simple test which it checks to see if the test view variable has been set.

Mocking models for use in a controller test is more difficult, it looks rather nasty as lithium’s models are called statically. While lithium does allow you to use a test connection with your tests it means you can’t just test the logic of the code without testing the database layer. While I do agree that you should also do tests with your database layer, I also think you should do tests without a database connection so as you can see what is failing, the data being inputted into the model or the database layer. So after some trying to do some namespace magic, I finally remembered you can call static classes from a variable string. So to use a mock model I decided use the lithium dependency injection system classes array and retrieve the class name from it.

Controller

Mock Controller

In the mock controller we just replace the articles class with our mock Article class.

Mock Model

Here is a very simple mock Article class which just replaces the find method and returns two sets of data. In reality you would want a much better find and replace the insert as well. Currently I haven’t done too much in mocking models I just wanted to be able to do, due to how nasty it seems we’ve went for just using Fixtures.

Fixtures

Now I’ve shown how to do the unpopular mocking of the model class, I’ll link you to the Lithium fixtures, instead of basically duplicating what the author of the fixture plugin has to say you may as well get it from the horses mouth here.

Conclusion

Lithium unit testing is pretty simple, although this is a rather simple run though, I hope to post other snippets about unit testing when I run into stuff I need to figure out. I am sure there is probably stuff I could be doing better, if you know anything please do alert me.