Abdullah Solutions Using PHP

This blog is about the PHP solutions I have to think of when I'm developing systems almost every single day...

Friday, December 5, 2008

New things in cakePHP core

Quite a while back I updated the cakePHP core in MyMeeting. Because of that update I broke so many things in MyMeeting because of some new ways cakePHP implements stuff. Here is a summary of some of the changes I had to make to make it work again.

Complex query is by itself now
This is the single most important update which broke a lot of stuff in MyMeeting. So now you cannot do things like:


$this->mystuff->find(array('conditions'=>array('updated'=>'<=!-now())))

That won't work anymore. !- no longer stops the value from being put in quotes. Now you've got to do this way:

$this->mystuff->find(array('conditions'=>array('updated <= now()')))

That would work. No need to asssign value to key and stuff. Just what is the query. Same thing that this won't work anymore:

$this->mystuff->find(array('conditions'=>array('deleted'=>'!=1')))

It now has to be:

$this->mystuff->find(array('conditions'=>array('deleted != 1')))

Just as some example of how the new queries should be.

Unicode is broken in some of the older system and new cakePHP uses unicode in validation

This kinda caused me a lot of grief. Validation worked very well on my dev machine which ran on Ubuntu. But as soon as I moved it to production server (CentOS & Mandriva) it didn't work anymore. As it turned out that in the pcre library, unicode support is not enabled by default. To counter this I had to change back the regex not to use unicode and just use normal regex. So I changed the file cake/libs/validation.php in the function alphaNumeric the regex is from using unicode:

$_this->regex = '/^[\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}]+$/mu';

to not use unicode:

$_this->regex = '/^[a-zA-Z0-9_-]+$/mu';

It now works on all systems but I've got to be more carefull now whenever I upgrade cakePHP core so that I do the necessary hack (this is a hack. A proper implementation would detect whether there is unicode support and use the approriate regex then)

Core now have contain. No more need for the Bindable behaviour to be added


Using contain which comes with the core would better guarantee that it'd be properly supported in the future. The syntax is almost the same. So now whenever you need to restrict what models are queried or maybe even drop off all association so that only the specified model is queried, contain is the way to do it. How to drop off all of the associations? Like this:

$this->mymodel->find(array('contain'=>false))

Of course you can put in conditions and stuff, but basically setting false to contain would query only the table for that model. Neat.

Unit tests rocks

I can't say this enough. Unit test allows for very quick testing of whether things work or not. And actually it would (in the future) easily catch errors which might be caused by changes in the query syntax and stuff. To learn how to set up unit test you can go to http://book.cakephp.org/1.2/en/The-Manual/Common-Tasks-With-CakePHP/Testing.html. To access unit tests you need to enable debug in app/config/core.php. And then access the test page by going to http://location-of-app/test.php. Over there you'll see a whole lot of tests already provided to test cakePHP core functions. And then you can add new test cases for your app by adding the file model.test.php into app/tests/cases/model. You can add fixtures to your test by adding model_fixture.php to your app/tests/fixtures folder.

For more CakePHP resources, check out http://www.whoishostingthis.com/compare/cakephp/resources/.

Monday, June 30, 2008

Using functions in cakephp queries

Sometimes you need to use functions in your queries for example using datediff. How would you do it in cakephp? Simply don't assign any value to the key and it will be inserted as it is. For example to get the query "where datediff(deadline,now())<7" you'd do

$this->Decision->find(array('datediff(deadline,now())<7'));

Simple, efficent, nice.

The guts of a query

Sometimes to create more complex queries in cakephp you'd have to refer directly to the source code. If you want to know how do they change all of that array into the where clause of your query just search the api for conditionKeysToString.

Monday, May 12, 2008

Using mysql functions in cakephp

Sometimes it's just easier to use mysql functions in the conditions. But cakephp automatically quote them. To disable the automatic quoting for any field just prefix the variable with a -! for example:


$notifications=$this->Notification->findAll(array('notification_date'=>'>= -!now()'));

Thursday, April 24, 2008

Advanced routing in CakePHP

Wow.. routing in Cakephp is pretty good. Works both ways. To learn more go to:
http://debuggable.com/posts/new-router-goodies:480f4dd6-4d40-4405-908d-4cd7cbdd56cb

The most important part for me in the post was the past variable. Finally I'd be able to pass variables to the function. So for something like:


Router::connect('/:committee/:controller/:action/:id',array(),array('pass'=>array('committee','id')));

The empty array means you want to just pass to the default controller and action you keyed into the url. The pass array means you want to pass the committee as the first variable of the action and id as the second variable. Pretty cool stuff.

Wednesday, April 23, 2008

I need to migrate

Fuh.. I need to get out of this country.. :P

Anyway.. that may be a long time coming. But first here's a good reference on how to migrate databases using cakephp at:
http://cakebaker.42dh.com/2008/04/13/migrations-the-cakephp-way/

To sum it up you have to follow these steps:


  1. Update the tables in sql
    You can use phpmyadmin, mysql console or anything you want

  2. Create/Update your models
    Make sure your models are created for each table you add. Easy using `cake bake model`

  3. Update the schema
    Run `cake schema generate`. This will create the app/config/sql/schema.php file. This file is needed for others to compare with.

  4. Commit your changes and others update theirs
    Use whatever you use, svn, cvs, git, mercurial. As long as everyone get the new version of app/config/sql/schema.php

  5. Update your database
    Just run `cake schema run update`. And walah.. you've got your database all nice and update.



Have I said cakephp is cool.. Oh yeah, it sure is... :)

Wednesday, April 2, 2008

Using components in shell class

One of the great things about cake is it's shell functions. It makes it easy to write shell scripts for your app. First step is to create the file cake/console/libs. Lets name this file myapp.php. Then inside you would do:


class MyappShell extends Shell {
function main(){
.....
}
}

Do whatever you want inside that class. You can even define the $uses array in the class to use whatever models your app have. And if you want to use a certain component, lets say the Auth component, you'd do:

App::import('Component','Auth');
$this->Auth=& new AuthComponent(null);

Then you can use stuff like $this->Auth->password and such. Great stuff this cakephp.. :)

About Me