September 7, 2010

Cache Problem in CakePHP

I recently had a problem on our website with caching in our CakePHP framework. We initially had caching turned on. And then we started noticing when we submitted a form, our changes wound not be updated until we manually refreshed the page.

So let’s say I have a row of users. I choose to delete one of the users. I click on delete, hit submit and cake removes that user from my table. Cake then redirects me back to same page, but the deleted user is still listed on our page. Once we manually hit the refresh button on our browser, then our deleted user disappears from our form page.

We scratched our heads and tried figuring out why this was happening. We turned off all caching and even added the <cake:nocache> tag. No matter what we did, we could not get rid of the problem.

After much research, we realized that the browser itself was actually caching the previous form page. So we added this snippet of code to our app controller.

$this->disableCache();

This is used to tell the user’s browser not to cache the results of the current request. The headers sent to this effect are:

Expires: Mon, 26 Jul 1997 05:00:00 GMT
Last-Modified: [current datetime] GMT
Cache-Control: no-store, no-cache, must-revalidate
Cache-Control: post-check=0, pre-check=0
Pragma: no-cache

I hope this saves you some time. If you find a better way fixing this problem, please leave a comment.

April 6, 2010

How to Select Field Names in Table in CakePHP

In php you can use mysql_field_name to get the field name of the specified field in a result. Someone asked me the following question.

If Employee table has three rows id,name and address. How do we fetch those names (id,name,address) using sql query in cakephp?

First of all, you can’t actually use mysql_field_name() in cakephp. But there are workarounds. Say you want to find the field names of the the table ‘Post’. Here is what you can do.

$array = $this->Post->find('all');
 
$array = Set::extract('/0/Post', $array);
pr($array);
 
$field_names = array_keys($array[0]['Post']);
pr($field_names);

The result of the print statements will display the following

Array
(
    [0] => Array
        (
            [Post] => Array
                (
                    [id] => 2
                    [title] => A title once again
                    [body] => And the post body follows.
                    [created] => 2010-02-08 07:48:03
                    [modified] => 
                )
 
        )
 
)
 
Array
(
    [0] => id
    [1] => title
    [2] => body
    [3] => created
    [4] => modified
)

I hope this helps. Feel free to comment on this page. I’ll get notified immediately.

March 24, 2010

How to Save Multiple Models in CakePHP

It’s inevitable that you will have a form where you will need to save multiple models at once. Here is a small hack on how you might do that.

if (!empty($this->data)) {
    $this->ModelName->create();
    $allSaved = true;
 
    foreach($this->data as $model => $data) {
        switch ($model) {
            case 'ModelName1' :
                /*manipulate ModelName1 data here*/
                if (!$this->ModelName1->saveAll($this->data['ModelName1']))
                    $allSaved = false;
                break;
            case 'ModelName2' :
                /*manipulate ModelName2 data here*/
                if (!$this->ModelName2->saveAll($this->data['ModelName2']))
                    $allSaved = false;
                break;
        }
    }
 
    if ($allSaved) {
        /*Print Success Message*/
    }
}

Write Custom SQL in CakePHP

There may be a time when you want to simply just write your own custom sql in cakephp. Now, cakephp doesn’t want you to do this. The find() and save() calls should be able to do everything you need to do. But, I’ve found it useful to write custom sql queries for testing purposes. Here is how you do it.

$query = $this->ModelName->query("SELECT * FROM TableName");