views:

2388

answers:

1

I'm trying to display custom messages like, 'this field should not be empty' or 'name not null' using the $validate array in the model. I have two controllers, main and users.

The index file of the main controller has the login and registration views. The action part of the login and register functions are in the user_controller. If the login and register function validate, they are redirected to the home page of the main controller,else they remain in the index page itself.

I want the validation messages to be displayed in the index page itself. But those messages appear only if there is a separate view file for login and register,i.e, /views/forms/register.ctp and /views/forms/login.ctp exist.

Is there a way to display those validation messages without having a separate view file for those functions? I have given my code below.Someone guide me please.

Model Class:

<?php 
class User extends AppModel {
    var $name = 'User';
var $components=array('Auth');

  var $validate = array(
    'name' => array(
        'rule' => 'notEmpty',
          'message'  =>'Name cannot be null.'
    ),
    'password' => array(
        'rule' => 'notEmpty'
    ),
    'email_id' => array(
        'rule' => 'notEmpty'
    )
);

function registerUser($data)
{
    if (!empty($data)) 
    {
        $this->data['User']['name']=$data['User']['name'];
        $this->data['User']['email_id']=$data['User']['email_id'];    
        $this->data['User']['password']=$data['User']['password'];

        $existingUsers= $this->find('all');
        foreach($existingUsers as $existingUser):
            if($this->data['User']['email_id']==$existingUser['User']['email_id']){
                return 0;
            }
            else{
                $this->save($this->data);
                $this->data['User']['id']= $this->find('all',array('fields' => array('User.id'),
                                'order' => 'User.id DESC'         
                                ));
                 $userId=$this->data['User']['id'][0]['User']['id'];
                return $userId;
            }
        endforeach;

    }
}

function loginUser($data)
{
    $this->data['User']['email_id']=$data['User']['email_id'];    
    $this->data['User']['password']=$data['User']['password'];            

    $login=$this->find('all');
    foreach($login as $form):
        if($this->data['User']['email_id']==$form['User']['email_id'] && $this->data['User']['password']==$form['User']['password'])
        {
            $this->data['User']['id']= $this->find('all',array('fields' => array('User.id'),
                                'conditions'=>array('User.email_id'=> $this->data['User']['email_id'],'User.password'=>$this->data['User']['password'])        
                                ));
             $userId=$this->data['User']['id'][0]['User']['id'];

            return $userId;

        }
    endforeach;
   }
  }
 ?>

Controller Class:

<?php 
class UsersController extends AppController 
{

var $name = 'Users';
var $uses=array('Form','User','Attribute','Result');
var $helpers=array('Html','Ajax','Javascript','Form');

function register()
{

    $this->Session->write('userId',$this->User->registerUser($this->data));
    $this->User->data=$this->data;
        if (!$this->User->validates())
        {

              $this->Session->setFlash('Please enter valid inputs');
              $this->redirect('/main' );
            return;    
        }

       if($this->Session->read('userId')==0){

           $this->Session->setFlash('You are already a registerd member.Log in your account');
           $this->redirect('/main');
       }
       else{
        $this->Session->setFlash('User account created');
        $this->redirect('/main/home'); 
       }       


   }   

 function login()
   {

    //$userId=$this->User->loginUser($this->data);
    $this->Session->write('userId',$this->User->loginUser($this->data));
    $this->User->data=$this->data;

    if (!$this->User->validates())
        {
              $this->Session->setFlash('Please enter valid inputs');
              $this->redirect('/main' );
            return;    
        }
    if($this->Session->read('userId')>0){
        $this->Session->setFlash('Login Successful');
        $this->redirect('/main/home');
        break;        
    }
    else{
         $this->Session->setFlash('Username and password do not match.');
         $this->redirect('/main');

    }    
  }
 }
?>

View Template:

<!-- File: /views/main/index.ctp-->

<div id="register">
<h3>Register</h3>
<?php
     echo $form->create('User',array('action'=>'register'));
     echo $form->input('name');
     echo $form->input('email_id');
     echo $form->input('password');
     echo $form->end('Register');
?>
</div>

<div id="login">
<h3>Login</h3>
<?php
      echo $form->create('User',array('action'=>'login'));
      echo $form->input('email_id');
      echo $form->input('password');
      echo $form->end('Login');
?>
</div>
+2  A: 

I think you're going about it the wrong way. You're doing way too much in the model, and you're also doing almost the same thing in the controller again after the fact. That's not good. Overall, honestly, the code is quite a mess for something so simple.

A huge WTF flag pops up here:

$existingUsers= $this->find('all');
foreach($existingUsers as $existingUser):
    if($this->data['User']['email_id']==$existingUser['User']['email_id']){

You're seriously retrieving all users from the database (potentially a hugely expensive task) and then go through them one by one to compare a single field?!
You can simply define a validation rule that says 'email_id' should be unique, and Cake will automatically ask the database if the 'email_id' already exists. http://book.cakephp.org/view/472/isUnique

About your specific problem: You have the same form field twice on the same page, password and email_id fields for the same User model. There's no way for Cake to know which instance of the two fields is supposed to get the error message, they both have the same name. Also, I don't think you want to use validation error messages for the login form, you just want to see if the login was successful or not. Use Session::flash() instead to display an error message for a failed login, it's not field specific.

Take the login and register methods out of your model, they don't belong there. Only specify proper validation rules for the email, name and password fields in the model, they will automatically be checked upon calling $this->User->save() in the controller.

Don't hand-validate anything, unless there's really no way to do it with Cake validation rules (not the case here). If the built-in validation rules don't satisfy what you need to do, you can even make custom rules. http://book.cakephp.org/view/150/Custom-Validation-Rules

PS: Components are not for models. I think you need to learn more about the basics of Cake before continuing: http://book.cakephp.org/view/218/Tutorials-Examples

deceze
Okay, I'll do the changes as you have mentioned, But I do want the specific validation errors to be displayed in the login page.
Angeline Aarthi
As I said, if you have basically the same form twice on the same page you'll run into problems with the automatic error message generation. Also let me repeat that I think it's unnecessary for a login form. Having said that, if you separate your forms you can use the methods described here: http://book.cakephp.org/view/410/Validating-Data-from-the-Controller
deceze