Can anyone help me with a clear and complete example on how to set validations for 2 fields, say an email and password, with error messages?
From my understanding, the correct format is:
var $validate = array(
'password' => array(
'rule' => array('minLength', '8'),
'message' => 'Minimum 8 characters long'
),
'email_id' => array('email')
);
but I can’t seem to get it work (show a validation message, or halt the execution of the action) in my tests.
Validations work fine but no way for the custom messages to appear!
EDIT
The validations and page redirections work fine now. Only the specific messages do not appear. That is, if I enter a password less than 8 characters, the message "minimum 8 characters needed" should appear immediately or after I click the register button. Is there any method to do this?
EDIT 2
My view file
<!-- File: /app/views/forms/index.ctp -->
<?php
echo $javascript->link('prototype.js');
echo $javascript->link('scriptaculous.js');
echo $html->css('main.css');
?>
<div id="register">
<h3>Register</h3>
<?php
echo $form->create('User',array('action'=>'register'));
echo $form->input('User.name');
echo $form->input('User.email_id');
echo $form->input('User.password');
echo $form->end('Register');
?>
</div>
<div id="login">
<h3>Login</h3>
<?php
echo $form->create('User',array('action'=>'login'));
echo $form->input('User.email_id');
echo $form->input('User.password');
echo $form->end('Login');
?>
</div>
Controller:
<?php
class UsersController extends AppController
{
var $name = 'Users';
var $uses=array('Form','User','Attribute','Result');
var $helpers=array('Html','Ajax','Javascript','Form');
function register()
{
$userId=$this->User->registerUser($this->data);
$this->User->data=$this->data;
if (!$this->User->validates())
{
$this->Flash('Please enter valid inputs','/forms' );
return;
}
$this->Flash('User account created','/forms/homepage/'.$userId);
}
function login()
{
$userId=$this->User->loginUser($this->data);
$this->User->data=$this->data;
if (!$this->User->validates())
{
$this->Flash('Please enter valid inputs','/forms' );
return;
}
if($userId>0){
$this->Flash('Login Successful');
$this->redirect('/forms/homepage/'.$userId);
break;
}
else{
$this->flash('Username and password do not match.','/forms');
}
}
}
?>
Model:
<?php
class User extends AppModel {
var $name = 'User';
var $components=array('Auth');
var $validate = array(
'name' => array(
'rule' => VALID_NOT_EMPTY,
'message' =>'Name cannot be null.'
),
'password' => array(
'rule' => array('minLength', '6'),
'message' => 'Minimum 6 characters long.'
),
'email_id' => array(
'rule'=> array('email'),
'message'=>'Invalid email.'
)
);
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'];
if($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;
}
}
}
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;
}
}
?>
Here is a live example from my project..
This is how you set up your validation in your model: Article model
Ignore the fact that I'm initializing the validate array from constructor, you can keep doing it like you're doing it now if you don't plan on implementing I18n and L10n.
Handling validation errors in controller: Articles controller
From line 266 to 280 you can see validation and save errors being handled with setFlash() + return.
That's pretty much all you need to do, just don't forget you need to use the FormHelper for your forms for the messages to work as expected.
Common error: you must not do a $this->redirect() after failed validation.
Hopefully this will set you on the right track :)
Why dont you try $this->modelName->invalidFields(), which will return you an array with the fields that failed validation and the message to display.
http://book.cakephp.org/view/1182/Validating-Data-from-the-Controller
Related
I am new to CakePHP and have created a normal form to submit first name.
My table name is "registers. I have created a controller named RegistersController (RegistersController.php) and a model named Register (Register.php) . Each time i submit after entering first name, it still displays error (First name is must) which it should only if i submit it without entering anything. Next i added validation for having minimum 6 characters. That validation is also not working. I mean, cakephp is not validating that rule. Could anyone please tell me where i have done anything wrong?
Model:-
class Register extends AppModel {
//put your code here
//public $useTable = "registers";
public $validate = array(
'first'=>array(
'minLength' => array(
'rule' => array('minlength','6'),
'field' => 'first',
'message' => 'Minimum 6 characters required'
),
'required' => array(
'rule'=>array('notEmpty'),
'required' => true,
'message' => array('First name is must')
)
)
);
}
Controller:-
class RegistersController extends AppController {
public $uses = array("Register");
//put your code here
public function index() {
if($this->request->is('post')){
//echo "Data";
if($this->Register->validates()){
//$this->Register->create();
//echo "Data validated";
print_r($this->Register->validationErrors);
}else{
//echo "Data not validated";
print_r($this->Register->validationErrors);
}
}
}
My view is as follows:-
<?php
echo $this->Form->create('Register');
echo $this->Form->input('first');
echo $this->Form->end("Submit");
?>
You are missing this line
$this->Register->set($this->request->data);
Put it before the validation call, i.e.
$this->Register->validates()
I am using cake PHP for integrating my stuff; however it is not showing model validation errors in my view.I think some small think is missed from my code, but didn't find out.
Below is my model, view and controller code:
Model:
class Category extends Model {
var $validate = array(
'title' => array(
'rule' => 'notEmpty',
'message' => 'Title is required'
)
);
}
View:
<?php
echo $this->Form->create( 'Category', array( 'action'=>'add', 'enctype' => 'multipart/form-data' ) );
?>
<fieldset>
<legend>Add new category</legend>
<?php
echo $this->Form->input( 'title' );
?>
</fieldset>
<?php
echo $this->Form->submit( 'Add Category' );
echo $this->Form->end();
?>
Controller:
class CategoriesController extends AppController {
var $helpers = array( 'Form', 'Html', 'Js' );
function add() {
$this->loadModel('Category');
$this->Category->set( $this->data );
$this->Category->save( $this->data );
if( !$this->Category->validates() ){
$errors = $this->Category->validationErrors;
}
}
}
Thanks in advance.
if( !$this->Category->save( $this->data ) ){
$errors = $this->Category->validationErrors;
}
You just check wether data has been saved or not. If not then process validation errors. Set errors to the view or just debug in the controller itself.
this may help you.
The problem I am having is that the validation rules are being fired on edit, but none of them are fired on create. Here are few of the validation rules, even though the problem is most probably not here:
var $validate = array(
'date' => array(
'notempty' => array(
'rule' => array('notEmpty'),
'message' => 'Choose a date'
)
),
'minutes' => array(
'rule'=>'minutes',
'message' => 'Minutes cannot exceed 60',
'allowEmpty' => true
)
And here are the forms (edit and add):
<?php echo $this->Form->create('Event');?>
<?php echo $this->Form->input('date', array('class'=>'datepicker', 'type'=>'text', 'label'=>__('Date*')));?>
<?php echo $this->Form->end(__('Save edit'));?>
<?php echo $this->Form->create('Event');?>
<?php echo $this->Form->input('date', array('class'=>'datepicker', 'type'=>'text', 'value'=>$date, 'label'=>__('Date*'))); ?>
<?php echo $this->Form->end(__('Save'));?>
And the validation is not disabled in any controller function as they are the same all over the app and work perfectly with every other model. I guess it has to be something simple, but I just cannot get it to work.
Any help is much appreciated.
Try this code in your EventsController.php file.
In your add() function:
Code:
if ($this->request->is('post')) {
$this->Event->set($this->request->data);
if($this->Event->validates()) {
if ($this->Event->save($this->request->data)) {
// Data saved and validated
}
}
}
I hope this code will help you..
Thank You!!
you just need to use validation rules in both actions on model table separately.
public function validationadd(Validator $validator){
->notEmpty('first_name');
return $validator;
}
public function validationedit(Validator $validator){
->notEmpty('first_name');
return $validator;
}
In version 2.2.1 I could validate a form using rules and custom messages like below. But somehow the password rule isn't working as of version 2.3. Any help what I might be doing wrong here?
Model:
class User extends AppModel {
public $validate = array(
'password' => array(
'rule' => array ('between', 5, 10 ),
'message' => 'Password must between 5 and 10 characters long'
)
);
public function beforeSave($options = array()) {
$this->data['User']['password'] = Security::hash($this->data['User']['password'], 'sha1', true);
return true;
}
}
View:
<?php
echo $this->Form->create();
echo $this->Form->input('firstname', array('label' => 'First name'));
echo $this->Form->input('lastname', array('label' => 'Last name'));
echo $this->Form->input('adminrole', array('type' => 'checkbox', 'label' => 'Is admin?<br /><br />'));
echo $this->Form->input('email', array('label' => 'E-mail address'));
echo $this->Form->input('password', array('label' => 'Password'));
echo $this->Form->input('picturethumb', array('type' => 'file', 'label' => 'Profile picture'));
echo $this->Form->end('Save');
?>
Please bare in mind that this exact same code validates correctly in 2.2.1
Controller:
class UsersController extends AppController {
public function index() {
$users = $this->User->find('all');
$this->set('users', $users);
}
public function add() {
if ($this->request->is('post')) {
$this->User->save($this->request->data);
$this->redirect('/users');
}
}
}
Try this-
public function add() {
if ($this->request->is('post')) {
$this->User->create();
if($this->User->save($this->request->data)){
$this->redirect('/users');
}else{
$this->Session->setFlash('Opps... Something is wrong');
}
}
}
I don't work with cake sometime, but I remember had this problem before. The problem is, the cakephp will create a hash of password, so when Model get password is already big. What I did in time was make another validate, like password_tmp and use it like field and create the hash by myself in controller for the real field password.
I just need a bit of help with identifying the email of the user which is also the username in the database, I used the 'isUnique' in the model but for some reason it is not giving an error message and it still registers the user please can someone give me a bit of help here is the code...
MODEL
App::uses('AuthComponent','Controller/Component');
class User extends AppModel {
public $validate = array(
'email' => 'email',
'email' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'Please enter a valid email address for username',
'unique' => array(
'rule' => 'isUnique',
'message' => 'Please enter another email, this one is already taken'
)
)
),
'password' => array(
'required'=> array(
'rule' => array('notEmpty'),
'message' => 'Please enter a valid password',
'rule' => array('minLength','8'),
'message' => 'Please enter minimum 8 characters'
)
)
);
public function beforeSave($options = array()) {
if (isset($this->data[$this->alias]['password'])) {
$this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password']);
}
return true;
}
}
**CONTROLLER**
<?php
class usersController extends AppController
{
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('add');
}
var $name = 'Users';
public function add()
{
if (!empty($this ->data))
{
$this->User->create();
if ($this->User->save($this->data))
{
$this->Session->setFlash('Thank you for registering');
$this->redirect(array('action'=>'index'));
}
else
{
// Make the password fields blank
unset($this->data['User']['password']);
unset($this->data['User']['confirm_password']);
$this->Session->setFlash('An error occurred, try again!');
}
}
}
function index()
{
}
public function login() {
if ($this->request->is('post')) {
if ($this->Auth->login()) {
return $this->redirect($this->Auth->redirectUrl());
}
$this->Session->setFlash(__('Invalid username or password, try again'));
}
}
public function logout() {
return $this->redirect($this->Auth->logout());
}
}
VIEW
<h2>End a problem registration</h2>
<p>Please fill out details to register</p>
<?php
echo $this->Form->Create('User',array('action' => 'add'));
echo $this->Form->input('title');
echo $this->Form->input('name');
echo $this->Form->input('surname');
echo $this->Form->input('email');
echo $this->Form->input('password');
echo $this->Form->input('password');
echo $this->Form->end('Register');
Your array declarations for your validation rules are wrong.
They have the wrong "level", thus making them invalid.
E.g. email key is used twice.
Please correct them according to the documentation - and using correct 1 tab indentation.
This will make them both correct and readable and easily prevents the mistake you made above.