Upgrading from CakePHP 1.2 pre-beta to the beta version
Today, the beta version of CakePHP 1.2 has been released (see the announcement) and the website got a new design, which is really nice.
Here some things I noticed while upgrading Noserub from pre-beta to beta:
The folder “cake/locale” has been removed. It contained the template for translating the core. It seems this file has been moved to the translations project on CakeForge.
The files AppController, AppModel, and AppHelper have been moved from “cake” to “cake/libs/controller”, “cake/libs/model”, resp. “cake/libs/view/helpers”.
The folder “cake/libs/view/templates” has been removed and its subfolders are now direct subfolders of “cake/libs/view”.
In “app/config/sql” three files have been added: “db_acl.php”, “i18n.php”, and “sessions.php”.
In “app/config/core.php” the constant COMPRESS_CSS has been removed. On the other hand three new config entries were added: “App.encoding”, “Asset.filter.css”, and “Asset.filter.js”. The two latter are commented out by default.
While running the application I got some messages that the functions loadModel(), listClasses() and Model::generateList() are now deprecated. Thanks to the help messages it was easy to fix them.
The only bigger issue I encountered up to now was a change in the API for writing custom validation methods. Here some code from my model to illustrate the problem:
var $validate = array('passwd2' => array('rule' => 'validatePasswd2'));
function validatePasswd2($value, $params = array()) {
if ($this->data['Identity']['passwd'] !== $value) {
return false;
} else {
return true;
}
}
This code worked fine with the pre-beta, but with the beta version the type of $value has been changed, it is now an array instead of a string (see the explanation for ticket 3797). And so the code above will always return false. To fix it, the comparison has to be changed to:
if ($this->data['Identity']['passwd'] !== $value['passwd2'])
That’s it, good luck with upgrading :)




[...] Upgrading from CakePHP 1.2 pre-beta to the beta version - dho [...]
If you don’t want to “know” which field you are validating on your custom validation methods you can do the following to get the value you need to evaluate:
function customValidation($valueSet, $params=array()) {
$value = array_pop(array_reverse($valueSet));
}
Or if you don’t care about altering the original $value array just:
function customValidation($value, $params=array()) {
$value = array_shift($value);
}
Or just :
function customValidation($valueSet, $params=array()) {
$value = current($valueSet);
// If you want fieldname
$field = key($valueSet);
}
I have not tried the new version yet but I believe there is now a non custom equalTo function available which you could use instead to compare passwords.
The CakePHP site design changed as well, it’s very…HAPPY! I like it.
Or
function customValidation($valueSet, $params=array()) {
list($field, $value) = each($valueSet);
}
@all: Thanks for your comments!
@Mariano, Nao: To me the approach using “current()” looks the most promising.
@Tim: I think equalTo() is not thought for this purpose, see Nate’s comment: https://trac.cakephp.org/ticket/3594
So I guess the way equalTo is implemented now is to compare the fieldcontent to a fixed value/string?
So there is no way to compare 2 fields just yet…out of the cakebox that is?
@Tim: Yes, it is to compare the field content against a fixed value. I think there is no built-in way to compare two fields, you have to do it manually.
For comparing passwords I use:
function compareData ($valueSet, $field) {
list(, $value) = each($valueSet);
return ($value == $this->data[$this->name][$field]);
}
I’m now thoroughly confused for instances where additional parameters need to be provided to custom validation methods.
Here’s a function I was using in 1.2 pre-beta that ensures a field value is unique in a table. (It also prevents a false-positive for the current ID.) I can’t seem to understand right now how I should convert this to work in the new 1.2 beta.
function validateUnique($data, $name) {
$obj = $this->find(array($name => $data), null, null, -1);
$match = isset($this->id) && ($obj[$this->name]['id'] == $this->id);
return !$obj || ($obj && $match);
}
Also, here’s how I referenced the validation routine previously:
var $validate = array(
‘username’ => array(
‘unique’ => array(’rule’ => array(’validateUnique’, ‘username’)),
),
);
Any help in getting my head wrapped around this is greatly appreciated!
Sorry, one more question for anyone who might have figured it out. It seems that the FormHelper’s date method now stores the data in an associative array like this:
$data['Model']['date_column']['day']
$data['Model']['date_column']['month']
$data['Model']['date_column']['year']
I found in a Google Groups thread that this is automatically concatenated into $data['Model']['date_column']. However, when I try to validate that column via the “date” validation routine, the full controller dump shows that the data has not been concatenated, being passed as an array containing 3 items instead. How should I go about validating a date field then?
@Matt:
Try doing $this->cleanUpFields() within your controller prior to calling the save/validation routine. As I understand it, that method is where the concatenation takes place.
[...] The Model::generateList() function has also be deprecated, in favor of Model::find(’list’). It’s not an exact duplicate of generateList() but it gets the job done. Check out the cakebaker for more essential tips for upgrading from CakePHP 1.2 pre-beta to the fresh new CakePHP 1.2 beta. [...]
Also the classic validation constants (VALID_NOT_EMPTY, etc) are now deprecated.
The new validators are:
0 - getInstance
1 - alphaNumeric
2 - between
3 - blank
4 - cc
5 - comparison
6 - custom
7 - date
8 - decimal
9 - email
10 - equalTo
11 - extension
12 - file
13 - ip
14 - minLength
15 - maxLength
16 - money
17 - multiple
18 - numeric
19 - phone
20 - postal
21 - range
22 - ssn
23 - url
24 - userDefined
Thanks Brandon, that did the trick! :)
@all: Thanks for your comments!
@Spout: Yes, your solution is more generic than what I showed in the article.
@Matt, Brandon: Hm, cleanUpFields() shouldn’t work anymore, it has been deprecated in 1.2beta and the implementation has been removed ;-) According to the API docs you have now to use Model::deconstruct().
@Mariano: Yes, the validation constants are deprecated since quite some time.
@Matt, the validate unique custom method i come up with pre-beta doesn’t work any more, with nao’s “current” approach, here is what i can come up with
function validateUnique($data, $field) {
$condition = array(”{$this->name}.{$field}” => current($data));
if (!empty($this->id))
$condition += array(”{$this->name}.id” => “”.$this->id);
return ($this->findCount($condition) == 0);
}
This may not be the best place to ask this but I’m going anyway.
Is there a list of deprecated stuff?
[...] Bakery trovate un articolo in inglese di presentazione della beta, mentre su Cakebaker trovate un interessante articolo su alcune differenze che si incontrano nell’upgrade dalla [...]
[...] I got asked by Beth in a comment whether there is a list of deprecated stuff. As I am not aware of such a list I compiled one by [...]
Thanks for sharing, speedmax. I actually ended up getting my code to work in the following manner before seeing your response. However, I think I’ll change it since your way appears to be more efficient and readable.
function validateUnique($data) {
$value = current($data);
$field = key($data);
$obj = $this->find(array($field => $value), null, null, -1);
$match = isset($this->id) && ($obj[$this->name][$this->primaryKey] == $this->id);
return !$obj || ($obj && $match);
}
Also, thanks for the heads up on using “deconstruct” instead of “cleanUpFields”, cakebaker. Worked like a charm! :)
@Matt: Cool to hear it was useful for you :)
@speedmax
correct me if I’m wrong but with the new “find” approach, shouldn’t we write
return ($this->find(’count’, array(’conditions’ => $conditions)) == 0);
instead of
return ($this->findCount($condition) == 0);
?