CakePHP validation always true - validation

I've been struggling with this for the last hour or so, wondering if some fresh eyes can help.
Model
class User extends AppModel {
public $name = 'User';
public $validate = array(
'email' => array(
'valid' => array(
'rule' => 'email',
'message' => 'The email is not valid'
),
'required' => array(
'rule' => 'notEmpty',
'message' => 'Please enter an email'
)
)
);
}
Controller
class UserController extends AppController {
var $uses = array('User');
function index(){
$users = $this->User->find('all');
$this->set(compact('users'));
}
public function add() {
$this->set('title_for_layout', 'Add new user');
if(isset($this->data) && !empty($this->data)) {
$this->User->set($this->data);
$this->log($this->User->invalidFields(), "debug");
if($this->User->validates()){
if ($this->User->save($this->data)) {
$this->Session->setFlash("Added " . $this->data['User']['name']);
$this->redirect('index');
}
} else {
$this->Session->setFlash('There are errors with your form submit, please see below.');
}
}
}
}
View
<?php
echo $this->Form->create('User');
echo $this->Form->input('name', array('label' => 'Name'));
echo "<div class='clear'></div>";
echo $this->Form->input('email', array('label' => 'Email'));
echo "<div class='clear'></div>";
echo $this->Form->button('Reset', array('type' => 'reset'));
echo $this->Form->button('Add Useer', array('type' => 'submit'));
echo $this->Form->end();
?>
But I never get invalid fields for email? Have I missed something glaring?
If it makes any difference, this is a plugin Im developing so it doesnt sit directly in app/ but in app/Plugins
Thanks
EDIT: So I've been struggling with this for a while now, and still no joy. One thing I have noticed though, when I print out the model details (using var_dump($this->User) ), the [validate] array is empty. For example:
[validate] => Array
(
)
[validationErrors] => Array
(
)
Im presuming this is what the issue is, even though I have declared my $validate array, its somehow being overwritten? Anyone come across this before? Any solutions?

public $validate = array(
'email' => array(
'valid' => array(
'rule' => array('email'),
'message' => 'The email is not valid'
),
'required' => array(
'rule' => array('notEmpty'),
'message' => 'Please enter an email',
'allowEmpty' => false
)
)
);
Try adding rules as array and adding 'allowEmpty' key set to false on the required validation.

Damn! So simple. If I read the cookbook properly at http://book.cakephp.org/1.3/en/view/1114/Plugin-Models it would have told me that
If you need to reference a model within your plugin, you need to include the plugin name with the model name, separated with a dot.
Thus..
var $uses = array('Plugin.User');
works.. Hope this helps someone else!

Related

nothing is working except 'not empty' validation in cakephp

I'm new to CakePHP. I'm validating my form, but the problem is that no validation is working except the not empty validation.
My model file is:
class User extends AppModel {
public $name = 'User';
public $validate = array(
'rule_name' => array(
'alphaNumeric' => array(
'rule' => 'Numeric',
'required' => true,
'message' => 'Letters and numbers only'
)
)
);
}
My View file is:
echo $this->Form->create('User');
echo $this->Form->input('rule_name',array('class'=>'form-control','autocomplete'=>'off'));
Please suggest how I can fix this.
General usage pattern adding a rule for a single field:
public $validate = array(
'fieldName1' => array(
'rule' => 'ruleName',
'required' => true,
'allowEmpty' => false,
'message' => 'Your Error Message'
)
);
Must be look at Data Validation in cakePHP

cake 2.1 data validation not working

I tried every method, but it cake php data validation does not working.would you tell me what is the wrong part?
I add all types of validations but still the form saves without validation data!
My model:
class contacts extends AppModel
{
public $name = 'contact';
public $useTable='contacts';
public $validate=array(
'name' => array(
'requierd'=>array(
'rule'=>array('Not empty'),
'message' => 'A username is required'
)
)
);
}
My controller
class ContactsController extends AppController
{
public $helpers=array('Html','Form');
public $components=array('session','Email');
public function index()
{
if($this->request->is('post'))
{
$this->Contact->create();
if($this->Contact->save($this->request->data))
{
$this->Session->setFlash('Thank you we will contact you soon');
$this->redirect(array('action'=>'index'));
}
else
{
$this->Session->setFlash('Unable to send your message.');
}
}
}
}
My view:
echo $this->Form->create('Contact');
echo $this->Form->input('name');
echo $this->Form->input('email');
echo $this->Form->input('subject');
echo $this->Form->input('message',array('rows' => '3'));
//echo $this->Form->checkbox('Send me a coppy');
echo $this->Form->end('Send');
Try with
public $validate=array(
'name' => array(
'rule' => 'notEmpty',
'message' => 'A username is required'
)
);
as seen in the docs example. Don't know why you added an extra array.
You can add required and allowEmpty indexes just to be strict-er
public $validate=array(
'name' => array(
'rule' => 'notEmpty',
'message' => 'A username is required',
'required' => true,
'allowEmpty' => false
)
);
I figured it out. the reason that they were not working was because the model name!!

cakePHP Validations : one model for to forms in the same view

I have one view wich has 2 forms one for login and one for registration as following :
signup.ctp //my view
<div>
<?php
echo $this->Form->create("Tbluser");
echo $this->Form->hidden('formsent', array('value' => 'signup'));
echo $this->Form->input('username' ,array('label'=>'Username'));
echo $this->Form->input('password' ,array('label'=>'Password','type' => 'password'));
echo $this->Form->input('email' ,array('label'=>'Email'));
echo $this->Form->end('Register');
?>
</div>
<div>
<?php
echo $this->Form->create("Tbluser"); ?>
echo $this->Form->hidden('formsent', array('value' => 'login'));
echo $this->Form->input('username' ,array('label'=>"Username :"));
echo $this->Form->input('password' ,array('label'=>"Password :",'type' => 'password'));
echo $this->Form->end('Login');
?>
<div>
The model I'm using for both forms is as following :
<?php
class Tbluser extends AppModel{
public $validate = array(
'username'=>array(
array(
'rule'=>'alphaNumeric',
'allowEmpty'=>false,
'message'=>'Invalide Username!'
),
array(
'rule' => array('minLength', '4'),
'message' => 'Username has to be more than 3 chars'
),
array(
'rule'=>'isUnique',
'message'=>'Username already taken!'
)
),
'password' => array(
array(
'rule' => 'alphaNumeric',
'allowEmpty'=>false,
'message' => 'Password must be AlphaNumeric!'
),
array(
'rule' => array('minLength', '4'),
'message' => 'Username has to be more that 3 chars'
)
),
'email'=>array(
array(
'rule'=>array('email',true),
'required'=>true,
'allowEmpty'=>false,
'message'=>'Invalide email adress!'
),
array(
'rule'=>'isUnique',
'message'=>'Mail adress already taken!'
)
)
);
}
?>
The controller I'm using is as following :
<?php
class TblusersController extends AppController
{
public $uses = array(
'Tbluser'
);
public function signup()
{
if ($this->request->is('post')) {
if ('signup' === $this->request->data['Tbluser']['formsent']) {
// Registration part.
}else if('login' === $this->request->data['Tbluser']['formsent']){
//Login part
}
}
}
?>
My AppController looks like :
<?php
class AppController extends Controller {
public $helpers = array('Form', 'Html');
public $components = array('Session','Cookie','Auth'=>array(
'authenticate'=>array(
'Form' => array(
'userModel' => 'Tblforumuser',
'fields' => array(
'username' => 'username',
'password' => 'password'
)
)
)
));
}
?>
Right now if I fill wrong data into the signup form and submit it the validation occurs but also in the login form fields so How can I set the validation only to apply to that signup form and not to both forms? Thanks.
It looks like all validation is being invoked on every read and write because you are telling your model to run all validation without restriction. A better way to handle this would be a separate model for each form.
By creating two new models userLogin and userRegister that extend Tbluser, you can set specific validation rules for each form. You could do something like :
View/Tbluser/signup.ctp
<div>
<?php
echo $this->Form->create("userRegister");
echo $this->Form->hidden('formsent', array('value' => 'signup'));
echo $this->Form->input('username' ,array('label'=>'Username'));
echo $this->Form->input('password' ,array('label'=>'Password','type' => 'password'));
echo $this->Form->input('email' ,array('label'=>'Email'));
echo $this->Form->end('Register');
?>
</div>
<div>
<?php
echo $this->Form->create("userLogin"); ?>
echo $this->Form->hidden('formsent', array('value' => 'login'));
echo $this->Form->input('username' ,array('label'=>"Username :"));
echo $this->Form->input('password' ,array('label'=>"Password :",'type' => 'password'));
echo $this->Form->end('Login');
?>
<div>
Here, since we're using two separate models with each $this->Form-create(); helper, only the validation in the specified model will be run. Your models will contain only the validation that applies to the form assigned to it:
Model/userRegister.php
class userRegister extends Tbluser{
public $validate = array(
'username'=>array(
array(
'rule'=>'alphaNumeric',
'allowEmpty'=>false,
'message'=>'Invalide Username!'
),
array(
'rule' => array('minLength', '4'),
'message' => 'Username has to be more than 3 chars'
),
array(
'rule'=>'isUnique',
'message'=>'Username already taken!'
)
),
'password' => array(
array(
'rule' => 'alphaNumeric',
'allowEmpty'=>false,
'message' => 'Password must be AlphaNumeric!'
),
array(
'rule' => array('minLength', '4'),
'message' => 'Username has to be more that 3 chars'
)
),
'email'=>array(
array(
'rule'=>array('email',true),
'required'=>true,
'allowEmpty'=>false,
'message'=>'Invalide email adress!'
),
array(
'rule'=>'isUnique',
'message'=>'Mail adress already taken!'
)
)
);
}
Model/userLogin.php
class userLogin extends Tbluser{
public $validate = array(
'username'=>array(
array(
'rule'=>'alphaNumeric',
'allowEmpty'=>false,
'message'=>'Invalide Username!'
),
array(
'rule' => array('minLength', '4'),
'message' => 'Username has to be more than 3 chars'
),
array(
'rule'=>'isUnique',
'message'=>'Username already taken!'
)
),
'password' => array(
array(
'rule' => 'alphaNumeric',
'allowEmpty'=>false,
'message' => 'Password must be AlphaNumeric!'
),
array(
'rule' => array('minLength', '4'),
'message' => 'Username has to be more that 3 chars'
)
)
);
}
Then in your signup(); method, you will want to load the two new models you just created accordingly:
Controller/TblusersController.php
class TblusersController extends AppController {
public $uses = array(
'Tblforumuser'
);
public function signup() {
$this->loadModel('userLogin');
$this->loadModel('userRegistration');
if ($this->request->is('post')) {
if ('signup' === $this->request->data['Tblforumuser']['formsent']) {
// Registration part.
}else if('login' === $this->request->data['Tblforumuser']['formsent']){
//Login part
}
}
}
Hope this helps

Validate form fields in controller with a hasMany relation

I'm having some issues with validating form fields inside my controller, for testing purposes.
I have my model Experience with hasMany ExperienceDetail. ExperienceDetail belongsTo Experience.
I created a form using the FormHelper which contains the following:
index.ctp
<?php
echo $this->Form->create('Experience', array('action' => 'index'));
echo $this->Form->input('Experience.date', array(
'label' => array(
'text' => 'Datum'),
'type' => 'date',
'dateFormat' => 'DMY',
'monthNames' => false,
'minYear' => date('Y') - 10,
'maxYear' => date('Y')
)
);
echo $this->Form->input('Experience.test');
echo $this->Form->input('ExperienceDetail.vertrekstation');
echo $this->Form->end('Verstuur!');
?>
There are some more fields provided with ExperienceDetail, but these are irrelevant for this matter.
Experience.php
<?php
class Experience extends AppModel {
public $name = 'Experience';
public $hasMany = 'ExperienceDetail';
public $validate = array(
'vertrekstation' => array(
'rule' => 'notEmpty',
'message' => 'Voer een vertrekstation in',
'required' => true
),
'test' => array(
'rule' => 'notEmpty',
'message' => 'Test mag niet leeg zijn!'
)
);
}
?>
ExperienceDetail.php
<?php
class ExperienceDetail extends AppModel {
public $name = 'ExperienceDetail';
public $belongsTo = 'Experience';
public $validate = array(
'vertrekstation' => array(
'rule' => 'notEmpty',
'message' => 'Voer een vertrekstation in'
)
);
}
?>
ExperiencesController.php
<?php
class ExperiencesController extends AppController {
public $helpers = array('Html', 'Form', 'Session');
public function index() {
// $this->layout = 'default_orig';
$this->set('title_for_layout', 'De OV-Ervaringenmeter!');
// LOAD Model Carrier
$this->loadModel('Carrier');
$this->set('carrier', $this->Carrier->find('list', array('order' => array('Carrier.name' => 'asc'))));
// Check if form is allready filled
if($this->request->is('post')) {
$this->Experience->set($this->request->data);
$this->Session->setFlash('No if or else statement is called');
if ($this->Experience->validates()) {
$this->Session->setFlash('Validates!');
}
}
}
}
?>
The problem is: when I send the form and leave test empty, it provides me the validation error which I've set up in the Model. But when I leave vertrekstation empty, it doesn't provide me any errors that belongs to the input field.
What am I doing wrong and how am I able to get these errors printed?

CakePHP 2.1 - Custom Validation Rule - Check for Unique Field Value Combination

I have a couple of columns (ip, provider_id) for which I want combinations of values to always be unique. Therefore, I am trying to build a custom validation function. But I am having issues grabbing on the value of the secondary field. This is my code so far in the model:
public $validate = array(
'ip' => array(
'rule' => array('uniqueClick', 'provider_id'),
'message' => 'The click is not unique.'
)
);
public function uniqueClick ($ip, $field) {
$count = $this->find('count', array('conditions' => array('ip' => $ip, 'provider_id' => $field)));
// echo $field;
return $count == 0;
}
So the problem is that when I am testing what value is loaded into $field, it's just 'provider_id', a string. I was hoping it would contain the value of the 'provider_id' field. Does anyone know how to grab that value (and all other secondary model field values if necessary) and send it to the custom validation function?
My reading in the CookBook and people who've discussed similar problems seemed to suggest this solution would work, but not for me unfortunately.
Thanks in advance!
Cake is definitely behaving the way it's supposed to there. The second paramameter that you pass in that 'rule' array is meant to be passed as a static value.
However, your provider_id should be available in $this->data['MyModel']['provider_id']
So you should be able to forget about that second parameter completely, and do:
public function uniqueClick ($ip) {
$count = $this->find('count', array(
'conditions' => array(
'ip' => $ip,
'provider_id' => $this->data[$this->alias]['provider_id'])
));
return $count == 0;
}
Hope that helps!
To complement Joshua's answer, the validation array should be build like this:
// Validation rules
public $validate = array(
'ip' => array(
'rule' => array('uniqueClick', 'ip'),
'message' => 'The click is not unique.'
)
);
/**
* Checks if there are records on the datasource with the same ip and same provider_id
*
*/
public function uniqueClick ($ip) {
$count = $this->find('count', array(
'conditions' => array(
'ip' => $ip,
'provider_id' => $this->data[$this->alias]['provider_id'])
));
return $count == 0;
}
you can also use my rule with is able to work with as many fields as you need
try http://www.dereuromark.de/2011/10/07/maximum-power-for-your-validation-rules/
and
https://github.com/dereuromark/tools/blob/master/Model/MyModel.php#L930
so basically the same than you tried:
'ip' => array(
'validateUnique' => array(
'rule' => array('validateUnique', array('provider_id')),
'message' => 'You already have an entry',
),
),
You can directly go with this solution without passing anything in validation rules except the custom unique function.
// Validation rules
public $validate = array(
'ip' => array(
'rule' => array('uniqueClick'),
'message' => 'The click is not unique.'
)
);
/**
* Checks if there are records on the datasource with the same ip and same provider_id
*
*/
public function uniqueClick ($ip) {
$count = $this->find('count', array(
'conditions' => array(
'ip' => $ip,
'provider_id' => $this->data[$this->alias]['provider_id'])
));
return $count == 0;
}
$this->data[$this->alias]['provider_id'] automatically gets the value of the provider_id.

Resources