yet another note for myself

Integrating CakePHP and ExtJS: A complete guide

Your Ad Here
+ = Awesome

CakePHP and ExtJS are two excellent frameworks that complement each other very well. However, CakePHP does not support ExtJS as it supports Prototype javascript library. Nevertheless, as this tutorial shows, it is still very simple to integrate the two to create a web 2.0 application. In this tutorial, I show how to create a simple user registration form using ExtJS and pass data back and forth between CakePHP and ExtJS. If you are interested in reading about developing ajax application using CakePHP and ExtJS, then, I recommend you reading this post and also my another post
You can download the complete tutorial from  here. To run this tutorial, you will need to follow these steps:

1. Unzip the file in your htdocs folder.
2. Create a new database schema (name it as “tutorial”) and create a user table (see step 2 for SQL code)
3. Modify app/config/database.php to define database connection
4. Go to http://localhost/CakeExtJS/users/register
5. Simply enter value in one of the fields and click on “Create Account” button. This sends form data (in this case it will be empty) to the server. Server then validates the data and reloads the register page. The register.ctp agains creates the form and loads user entered data and validation errors. Checkout step 6 on how to load validation errors and data returned by the server.

Some Notes about the tutorial:

  • This tutorial assumes that the reader has some level of expertise in CakePHP and, thereby, skips lot of details.  
  • The code is only for learning purpose and is not meant for production use. 


Step 1: Setting CakePHP and ExtJS


To integrate CakePHP and ExtJS setup, follow these steps:

  1. Download Ext JS 2.2. SDK library from here
  2. Unzip the folder somewhere on your desktop. Make sure it has following files and folders “adapter”, “resources”, “build”, and ext-js.all 
  3. In your vendor/js (at root level), now copy create a folder “extjs” and copy “build” and “adapter” from the above unzipped folder over here. Also copy ext-all.js file in your vendor/js folder. 
  4. Now, copy “css” and “images” folder from “resources” folder to your vendor/css/extjs folder. 
  5. Verify: The final cakephp folder should look something similar to shown in the image below

 

CakePHP + ExtJS Setup

CakePHP + ExtJS Setup

 

Step 2. Creating User Table:


Now, lets create a simple “User” table with six fields: id, name, email, username, passwd (password), and created. Below is the SQL command to create this table.

create table users (
               id int not null auto_increment primary key,
               name varchar(50) not null,
               email varchar(50) not null unique,
               username varchar(50) not null unique,
               passwd varchar(32) not null,
               created datetime )


Step 3: Create User Model 
In app/models create a user.php file. In user.php, we only define validation criteria for all the fields (see validate variable). CakePHP uses validate variable to verify incoming data. 


class User extends AppModel {

        var $name = 'User';

        //Validation
        //name cannot be empty
        //username has to be unique and alphanumeric
        //passwd has to be min of 5 characters,
        //email has to be a valid email
        var $validate = array(
             'name' => array(
                   'notEmpty' => array(
                            'rule' => 'notEmpty',
                            'required'=> true,
                            'message' => 'Name is required'
                    )
              ),
              'username'=> array(
                   'alphaNumeric' => array(
                            'rule' => alphaNumeric,
                            'required' => true,
                            'message' => 'username can only alphanumeric'
                    ),
                    'isUnique' => array(
                            'rule' => 'isUnique',
                            'message' => 'username is already registered',
                            'required' => true
                    )
               ),
               'passwd' => array(
                     'minLength' => array(
                             'rule' => array('minLength', 5),
                             'message' => 'Password should contain atleast 5 characters',
                             'required' => true
                     ) 
                ),
                'email' => array(
                     'email' => array(
                             'rule' => 'email',
                             'required' => true,
                             'message' => 'requires valid email id'
                      ),
                      'isUnique' => array(
                             'rule' => 'isUnique',
                             'required' => true,
                             'message' => 'email is already registered'
                       )
                )
        ); 

}


Step 4: creating user_controller.php


With model ready, now create user_controller.php file. In the controller file, we first setup authentication parameters in beforeFilter. Later, we define register function that handles data sent by register form. As discussed above, CakePHP uses validation variable defined in the model to validate data before saving it in the user table. If validation fails, it populates validationErrors variable. 


class UsersController extends AppController {

       var $name = 'Users';
       var $components = array('RequestHandler', 'Auth');
       var $helpers = array('Javascript', 'Html', 'Paginator');

       function beforeFilter(){

          //Change Default Hashing Function
          Security::setHash('md5');

          //Modify Auth's Default Parameters
          $this->Auth->fields = array('username' => 'username', 'password' => 'passwd');

          //Allow Register function to be called without requiring users to login
          $this->Auth->allow('register');
       }

       // Register fucntion - creates a new account
       function register(){
           //If no data is available then simply render the form
           if(empty($this->data)) return;

          //Save data
          //if validation fails, errors are populated in validationErrors variable 

          if($this->User->save($this->data, true)){
                //User record was successfully created
                //redirect user to some other page
          }else{
               //Failed to create user record
               //send user back to registration form with all data and error
               //remove password as it has been hashed
               // and therefore is not same to be one that user provided

               unset($this->data['User']['passwd']);
               return;

 

          }
       }
}
?>


Step 5: Creatin ExtJS view


Now  is the exciting part. Create ‘register.ctp’ file in your app/views/users/register.ctp. Copy and paste  the following code in register.ctp file. There are certaings things to note about register.ctp.

  • CakePHP uses automatgic to convert “name” property of a form field into a PHP array and hence  name of the field has to be  as data[ModelName][FieldName]. 
     
  • While, it is not required to define “id” property, I use it to repopulate data in the form field and display validation errors. In order to achive this, I have written two form utility functions – loadData and loadError. The two functions are defined in app/webroot/js/FormUtil.js file and called after the form is rendered (see towards the end of the code ) 
     
  • Finally, note the line that renders the form [ simple.render('content') ]. Thus, the form is rendered in content div. Here ‘content’ refer to the id of a div that is defined in default layout file.  


Ext.onReady(function(){

       //To display error tips
       Ext.QuickTips.init();

      // Show validation errors on side
      Ext.form.Field.prototype.msgTarget = 'side';

      //Setup Registration From
      var simple = new Ext.FormPanel({

           labelWidth: 100,
           url:'<?php echo $html->url(); ?>',
           frame:true,
           width: 600,
           defaults: {width: 350},
           defaultType: 'textfield',
           onSubmit: Ext.emptyFn,
           submit: function(){
              this.getForm().getEl().dom.submit();
           },
           //Note the id and name property. 
           items: [

               { fieldLabel: 'Name', name: 'data[User][name]', id: 'data[User][name]' },
               { fieldLabel: 'Email', name: 'data[User][email]', id: 'data[User][email]'},
               { fieldLabel: 'username', name: 'data[User][username]', id: 'data[User][username]'},
               { fieldLabel: 'Password', inputType:'password', name: 'data[User][passwd]',id: 'data[User][passwd]'}
           ],
           buttons: [
                     { text: 'Create Account',
                       handler: function(){ simple.submit(); }

           }]
      });

       //Render the form in a content content div
       //(content refers to ehe id of a div specified in default layout)
      simple.render('content');

       //Utility functions to load data and errors. Checkout app/webroot/js/FormUtil.js
       loadData(<?php echo $javascript->object($this->data); ?>);
       loadError(<?php echo $javascript->object($this->validationErrors); ?>);
});

Don’t forget to download the whole application from

Related posts:

  1. Migrating from OthAuth to CakePHP Auth
  2. Making CakePHP controller independent of how parameters are sent
  3. Dummy's guide for converting character set of a web application
  4. Enhanced Caching of Views in CakePHP 1.2
  5. Removing default values from CakePHP result
This entry was posted in CakePHP, ExtJS and tagged , , , . Bookmark the permalink.

21 Responses to Integrating CakePHP and ExtJS: A complete guide

  1. Nik Chankov says:

    Nice,

    although I will mention few things which are (at least for me) stoppers.

    1. Most important – you cannot use the console auto bake script. At least first generation is based on that.
    2. With this you can not use Security Component /ensuring that the form fields are not modified by user + extra require insert or require update which I am not using now, but are useful/

    I remember that me and my colleague started with a helper which should be replacer of Cake’s Form helper but instead of regular fields it will produce the ExtJS form, but unfortunately we had too short time and we abandon the helper.

    Apart from this I think Ext JS is the best way for creating rich user interface.

    Thanks for the article.

  2. ianemv says:

    Btw, what can you say about ExtJS licensing?

  3. John says:

    ExtJS is licensed under GPLv3 for open source applications. It is commerical for closed source applications. It looks like a reasonable policy.

  4. Joshua McNeese says:

    i’m sorry, not to be dickish, but how exactly is this a “complete” guide to integrating the two? all i see is a very one-off solution for users?

  5. ragrawal says:

    hi Joshua,

    I agree with your view. I guess, the article by itself is not a complete guide. However, if you refer to my another post that talks about how to develop Ajax solution using CakePHP, you might the two together to be more holistic.

  6. Joshua McNeese says:

    i’m glad you saw it for what i intended: constructive criticism. the main problem i see with articles about this sort of thing, is that they generally make too many assumptions.

    yours here makes the assumptions that:

    * i want to use md5 hashed passwords (i don’t)
    * i don’t want to use the users email as their username (i do).
    * i want to have each page be it’s own little separate ext app, so each pageload will have to bring in all of ext js and css/image resources each time (i definitely don’t want that)
    * i only want to use ext to add users to my app (i want to use a datagrid to manage them too!)

    and the list goes on. perhaps it might be better to have a series of more in-depth and generic articles. i might even be able to give you some pointers on how i accomplished this: http://statler.weaver-group.com/joshua/screencast.html , since that seems like the level of cake+extjs integration you’ve been striving for.

  7. ragrawal says:

    Hi Joshua,

    I agree with your criticism. But, with any tutorial, there will be some assumptions. Tutorials are meant to show what’s possible and how to do some of those things and not to build a working solution that fits anyone’s particular needs. Everyone has to put some effort in understanding the concepts behind the tutorial and re-implementing them to meet their own needs.

  8. ianemv says:

    Agree with ragrawal. This tutorial has been one of my sources to develop my contacts directory.

  9. wirtsi says:

    I’ve made this whole approch a little more generic, namely a Cake helper that feeds an extended Ext Panel class.

    Demo is at http://blog.mykita.com/2009/08/introducing-cakext-create-slick-single-page-guis-with-cakephp-and-extjs/, the project lives at http://cakext.mykita.com

  10. Burt Hayes says:

    Very helpful post. Very clear commentary and suggested phrasing are most impressive, as are his and your generosity in sharing this explanation and example

  11. saavedrajj says:

    i tried to make this tutorial with:
    CakePHP 1.2.5
    ExtJS 3.1

    but in ExtJS 3.1 there is no “build” folder that i can put on:
    cakeroot/vendors

    when i test the code, the following error appears:
    Notice (8): Undefined variable: javascript [APP\views\layouts\default.ctp, line 23]
    Fatal error: Call to a member function link() on a non-object in C:\Apache2.2\htdocs\www.portalvinos.com\app\views\layouts\default.ctp on line 23

    where line 23 is:
    link(‘extjs/ext-all.js’); ?>

    any suggestions?

    • ragrawal says:

      Hi,

      Sorry I haven’t used either cakephp or extjs for q while and not sure about the file structure. However, I think the build should be there. Are you sure you have the complete ExtJS file system ?

  12. Pingback: links for 2010-02-13 « Minesa IT

  13. Uzzal Masud says:

    That’s really nice! thanks a lot.

  14. Sgt Seixas says:

    Thank you a lot! But i have a problem…

    In the “app\vendors\js\extjs” doesn’t working.
    does it matter..

    Nevertheless on changing the local of the Library to app\webroot\js\extjs and app\webroot\css\extjs, makes everything pretty well so far

    Do you know why?

  15. Martijn says:

    The LoadData() can be replaced by flattening the data serverside (works also if the data is more than 2 levels deep.

    function flatten($array, $prefix = ‘data’, $start_string = ‘[', $end_string = ']‘) {
    $return = array();
    foreach ($array as $key => $value) {
    $flat_key = $prefix.$start_string.$key.$end_string;
    if (is_array($value)) {
    $return = array_merge($return, $this->flatten($value, $flat_key, $start_string, $end_string));
    } else {
    $return[$flat_key] = $value;
    }
    }
    return $return;
    }

  16. there’s already a function in cake for that: Set::flatten()

  17. Pingback: Integrating CakePHP and ExtJS: A complete guide « memento

  18. vimax says:

    Amazing article, thank you, I will visit again later. Regards: SB2011LAIN_AING

  19. Hi there, I stumbled on your page from stumbleupon. This isn’t not an article I would regularly read, but I liked your spin on it. Thanks for creating something worth reading!

  20. I’ll right away grab your rss as I can not find your email subscription link or newsletter service. Do you have any? Please let me know in order that I could subscribe. Thanks.