Feed items

Deleting 100.000 records with CakePHP

If you have a table with 1.000.000 records and you want to delete 100.000 of them by a certain condition, don’t use Model::deleteAll(). DeleteAll will fetch the ID’s of every record and then make a single query to delete them all which hold all these ids. Like:

MVC Rape

In case you have a colleague, friend or any other idiot who screwed up his/her CakePHP app. Here is what you should give him/her, in case he/she doesn’t listen.

Link: http://www.frankdegraaf.net/cake/bad_cake.jpg
MVC rape 2

Link: http://www.frankdegraaf.net/cake/mvc_rape_2.jpg
MVC rape 2

Link: http://www.frankdegraaf.net/cake/mvc_rape.jpg
MVC rape 1

Thanks to alkemann for the ideas/pictures.

Auth redirects inconsistent?

No.

A lot of people seem to have the wrong expectations of the Auth component. The automagic redirects after the user has logged in seems to be misunderstood a lot. Here is what it does. Say you have defined this in your AppController’s beforeFilter():

$this->Auth->logoutRedirect = array(
	'controller' => 'dashboards',
	'action' => 'index',
	'admin' => false
);

$this->Auth->loginRedirect = array(
	'controller' => 'dashboards',
	'action' => 'index',
	'admin' => false
);

So what happens when a user clicks the login link and logs in? The user will then be redirected to /dashboards/index. If a user enters a page that is denied by Auth, the user is redirected to the login page. When the user logs in then, the user gets redirected to that specific page that wasn’t allowed before login.

How many seconds in a day?

Recently while at work I needed to add a few days to a date. It was about extending a membership with a variable number of days. Usually you would do something like:

$time = strtotime($datestring) + ($n * 86400);
$date = date('Y-m-d H:i:s', $time);

In that example, 86400 is the number of seconds in a day. But by accident I found in basics.php of CakePHP the following code:

define('SECOND', 1);
define('MINUTE', 60 * SECOND);
define('HOUR', 60 * MINUTE);
define('DAY', 24 * HOUR);
define('WEEK', 7 * DAY);
define('MONTH', 30 * DAY);
define('YEAR', 365 * DAY);

This is always loaded since it is in basics.php. So this will make the example:

Multiple field validation

Validating fields based on the values of other fields can be hard to understand when you are new to CakePHP. A simple example of this can be comparing two values, like e-mail addresses or passwords. It is actually pretty easy because in the custom validation method you have access to $this->data.

So here is how it goes. This will also invalidate the value compared with, so you will have to call this validation rule only once.

public function compare($value, $options = array(), $rule = array()) {
	$valid = current($value) == $this->data[$this->alias][$options[0]];
	if (!$valid) {
		$this->invalidate($options[0], $rule['message']);
	}
	return $valid;
}

In $validate it will look like this:

Nested tree of folders and files

Yesterday in the CakePHP IRC channel someone was looking for a nested array of files and folders. He found the Folder class in the CakePHP API and saw the tree() method. When trying to get the nested tree, he found out the tree() method didn’t return a nicely nested array of folders and files, but two arrays of paths. Which is usually easier to use when you need paths.

However this guy needed this, so for the fun of it, I built a Component for him that returns this nicely nested array.

Have fun playing with it.

Usage