Upgrading from CakePHP 1.2 pre-beta to the beta version

Published on and tagged with cakephp  problem  update

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 :)

32 comments baked

  • CakePHP 1.2 Beta :: {one true brace

    […] Upgrading from CakePHP 1.2 pre-beta to the beta version – dho […]

  • Mariano Iglesias

    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);
    }

  • nao

    Or just :

    function customValidation($valueSet, $params=array()) {
    $value = current($valueSet);
    // If you want fieldname
    $field = key($valueSet);
    }

  • Tim Daldini

    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.

  • Nao

    Or
    function customValidation($valueSet, $params=array()) {
    list($field, $value) = each($valueSet);
    }

  • cakebaker

    @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

  • Tim Daldini

    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?

  • cakebaker

    @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.

  • Spout

    For comparing passwords I use:

    function compareData ($valueSet, $field) {
    list(, $value) = each($valueSet);
    return ($value == $this->data[$this->name][$field]);
    }

  • Matt Huggins

    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!

  • Matt Huggins

    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?

  • Brandon P

    @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.

  • Upgrade to CakePHP 1.2 Beta | Web Development 2.0: Web Design, CakePHP, Javascript

    […] 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. […]

  • Mariano Guezuraga

    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

  • Matt Huggins

    Thanks Brandon, that did the trick! :)

  • cakebaker

    @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.

  • speedmax

    @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);
    }

  • Beth

    This may not be the best place to ask this but I’m going anyway.

    Is there a list of deprecated stuff?

  • CakePHP 1.2… beta!! « 32 in 23

    […] 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 […]

  • Deprecated stuff in CakePHP 1.2 - cakebaker

    […] 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 […]

  • Matt Huggins

    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);
    }

  • Matt Huggins

    Also, thanks for the heads up on using “deconstruct” instead of “cleanUpFields”, cakebaker. Worked like a charm! :)

  • cakebaker

    @Matt: Cool to hear it was useful for you :)

  • Dia

    @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);
    ?

  • Tara Page

    Hi,

    I’m new to Cake and am using Verison 1.2 and just did cake bake on a few of my tables. There seems to be a bug in the baker still that is putting in 1.1 code that isn’t accepted in 1.1 (like generateList instead of find->(‘list’))

    My newest problem is that after I bake the code (and didn’t make any changes) I try to add a new record to my table and I get:

    Fatal error: Call to undefined method PartiesController::cleanUpFields() in /var/www_spice/app/controllers/parties_controller.php on line 22

    Any help would be appreciated, if I take out cleanUpFields() then it doesn’t work, I get a blank page.

    Thanks

  • cakebaker

    @Tara: Hm, which version of CakePHP 1.2 do you use? RC3? If you are not yet using RC3, I recommend to upgrade.

    Hope that helps!

  • Tara Page

    Thanks, crazy question though.. My husband installed the newest Cake 1.2 (the stable release) last week, and when I bake my project, I still get the above error message:

    Fatal error: Call to undefined method PartiesController::cleanUpFields() in /var/www_spice/app/controllers/parties_controller.php on line 22

    My question is when you install the new Cake Php, does the cake command also get installed or upgraded? Is it in a different location and perhaps I have the wrong cake in my path? Let me know, I’m not sure why it seems as though I have an old cake baker, but newest cake php download….

    Very confused at the moment :) THanks for any suggestions…

    Tara

  • cakebaker

    @Tara: It seems like you are using an old version of bake. If you install a new version of CakePHP and replace the “cake” folder with the new “cake” folder, then bake is also updated.

    Make sure you use bake in a similar way as shown below:

    dho@dh:~/projects/cake_1.2.x.x/cake/console$ ./cake bake
    

    Hope that helps!

  • Herlia

    what happens with tara happens to me too.. maybe it because the method cleanupfields has no longer available.
    can u help me fix it?? what method i supposed to use?

    thx for ur suggestion :)

  • cakebaker

    @Herlia: Yes, the method Controller::cleanUpFields() no longer exists. It has been replaced by Model::deconstruct(), which is called automagically. So I think you simply have to remove those references to cleanUpFields() and it should work.

    Hope that helps!

  • Amit

    When I remove cleanUpFields and place deconstruct method, it said me

    Fatal error: Call to undefined method ImagesController::deConstruct() in /usr/home/apandya/test17.newave.int/testproj/app/controllers/images_controller.php on line 18

    OR

    Fatal error: Call to undefined method ImagesController::deconstruct() in /usr/home/apandya/test17.newave.int/testproj/app/controllers/images_controller.php on line 18

    and it is not working for me

    Regards
    Amit Pandya

  • cakebaker

    @Amit: Well, the deconstruct() method is defined in the Model class and not in the Controller class, hence the error messages. So you have to call this method in the following way:

    $this->YourModel->deconstruct(...);
    

    However, this method is usually called automatically by the framework.

    Hope this helps!

Bake a comment




(for code please use <code>...</code> [no escaping necessary])

© daniel hofstetter. Licensed under a Creative Commons License