I have a Model
class Model extends AppModel {
public function __construct() {
parent::__construct();
$this->validate=array(
'first_name' => array(
'NotEmpty' => array(
'rule' => 'NotEmpty',
'required' => true,
'message'=> 'Not empty'
)
),
'last_name' => array(
'NotEmpty' => array(
'rule' => 'NotEmpty',
'required' => true,
'message'=> 'Not empty'
)
),
);
}
}
The problem is in view I have a dynamic data need to validation (last_name and firstname up to 30). How can I add them dynamical into Model and validate in Controller?
You can dinamically change validation rules
Make a new function in the model that will update your validation rules, as described in the documentation.
In the controller, before validating the model, call the model function that changes the validation rules.
Related
I read from the cakePhp documentation , they only allow one rule per field.
However If my field require unique Date and must be date format. How should I place them ?
Current Code
<?php
App::uses('AppModel', 'Model');
class EventDate extends AppModel {
//public $useTable = 'eventdate';
public $primaryKey = 'event_date_id'; //I still need for Delete
public $validate = array(
'event_date' => array(
'rule' => array('date','ymd'),
'message' => 'Enter a valid date in YY-MM-DD format.',
'required' => true,
'allowEmpty' => false
)
// ,'event_date' => array(
// 'rule' => 'isUnique'
// )
);
}
There is no restriction on the number of rules a field can have in CakePHP. You can provide an associative array of rules for a specific field like this:-
public $validate = array(
'event_date' => array(
'format' => array(
'rule' => array('date','ymd'),
'message' => 'Enter a valid date in YY-MM-DD format.',
'required' => true,
'allowEmpty' => false
),
'unique' => array(
'rule' => 'isUnique',
'message' => 'This date already exists'
)
)
);
Just remember to make sure your array indexes are unique.
The array indexes for the individual rules (e.g. format and unique in the example code) can be anything, but make them descriptive to the rule being defined.
Using CakePHP 1.3 I developed engine for blog with posts and comments tables and recently I have noticed that in database I've got records with null values in content column despite of the fact that Comment model has defined proper validation:
<?php
class Comment extends AppModel {
var $name = 'Comment';
var $sequence = 'comments_seq';
var $belongsTo = array(
'Post' => array(
'className' => 'Post',
'foreignKey' => 'post_id'
)
);
var $validate = array(
'content' => array(
'required' => array (
'rule' => 'notEmpty',
'message' => 'Content can't be empty.'
)
),
'post_id' => array(
'rule' => 'notEmpty'
),
'created' => array(
'rule' => 'notEmpty'
)
);
?>
Is there a bug in CakePHP framework or validation defined above is not correct or insufficient?
In your validation rules, you're not actually requiring the field. Requiring means that the key must exist when it comes time to validate. The notEmpty rule requires only that the key is not empty but not that it exists.
To require that the field exists, use the required option in your validation rules:
var $validate = array(
'content' => array(
'required' => array ( // here, 'required' is the name of the validation rule
'rule' => 'notEmpty',
'message' => 'Content can\'t be empty.',
'required' => true // here, we say that the field 'content' must
// exist when validating
)
),
'post_id' => array(
'rule' => 'notEmpty'
),
'created' => array(
'rule' => 'notEmpty'
)
);
Without the required key, you could potentially save completely empty records by simply not including the 'content' key when saving. Now that it is required, validation will fail if 'content' is not in the data that you're saving.
I'm having trouble validating an input form and saving the data from that form. I suspect that perhaps these are both caused by an association problem, though I am not sure.
I'm using CakePHP 2.2.0 RC2.
I have three models: User, Member and Address. Each user can have several members in their account and each user can have many addresses (it remembers past addresses, too).
My model associations are:
User model:
class User extends AppModel {
public $name = 'User';
public $hasMany = array(
'Member' => array(
'className' => 'Member',
'foreignKey' => 'user_id',
'order' => 'Member.member ASC',
'dependent' => true
),
'Address' => array(
'className' => 'Address',
'foreignKey' => 'user_id',
'order' => 'Address.address ASC',
'dependent' => true
)
);
...
Member model:
class Member extends AppModel {
public $name = 'Member';
public $displayField = 'member';
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id'
)
);
...
Address model:
class Address extends AppModel {
public $name = 'Address';
public $displayField = 'address';
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id'
)
);
...
For my Form create statement, I have:
$this->Form->create( 'Member', array( 'url' => array( 'action' => 'add' ) ) );
I am using the Member model and controller to handle the form as it submits either only Member fields, or Member and Address fields, depending on whether the user already has an address entry or not (if the user doesn't, it adds address input fields to the form, otherwise it doesn't).
I am not submitting any User fields in the form.
Now, I would expect, if my associations were set up correctly, that any 'required' fields in any of the models would have an asterisk next to them. There are some fields set as required in both the Member and Address models, and while the Member fields show up on the form as being required (with an asterisk), the Address fields do not.
An example of required Address field code from the Address model:
public $validate = array(
'street1' => array(
'required' => array(
'rule' => array( 'notEmpty' ),
'required' => true, 'allowEmpty' => false,
'message' => 'Please enter a street address'
),
....
And here's some of my view/form code:
echo $this->Form->input( 'Member.firstname', array( 'label' => 'First name', 'type' => 'text' ) );
echo $this->Form->input( 'Member.middlename', array( 'label' => 'Middle name', 'type' => 'text' ) );
echo $this->Form->input( 'Member.lastname', array( 'label' => 'Last name', 'type' => 'text' ) );
echo '<p class="bold">Please enter current address details:</p>';
echo $this->Form->input( 'Address.street1', array( 'label' => 'Street address (line 1)', 'type' => 'text' ) );
echo $this->Form->input( 'Address.street2', array( 'label' => 'Street address (line 2)', 'type' => 'text' ) );
echo $this->Form->input( 'Address.suburb', array( 'label' => 'Suburb', 'type' => 'text' ) );
...
When I output $validationErrors on the form page (before form submission), I get this:
Array
(
[Member] => Array
(
)
[User] => Array
(
)
)
I'm assuming there should also be an [Address] section there.
I can't spot anything obvious but I'm new to CakePHP (though I do have PHP experience), so any ideas would be appreciated.
Thanks!
Peter.
Firstly you said you were using a release candidate (RC2) of Cake 2.2. There is now a stable release and I strongly encourage you to upgrade to that.
You create the form with the Member model but it doesn't have a direct relation(association) to Address. Address is associated to User. If you create the form via the User model it should work all right.
If this scenario - creating the form with the User model - doesn't work for you and your application
logic than your Database model and your Model associations are wrong and they do not comply with your business needs. If this is the case you should consider changing the Architecture of the application.
And a note on $uses: you shouldn't have to include the Address model in your controller's $uses in order to be able to validate inputs. Controller::$uses is for use of models (other than the controller's own model) directly in the Controller itself. For example:
public $uses = array('Article', 'News');
in any controller would make all Article and News Models' methods available in that controller with:
$this->Article->methodName();
or
$this->News->methodName();
New to unit testing... testing an articles controller and I am getting a fail on the $this->assertNotEmpty();
Shouldn't this be displaying an array full of validation errors? Instead I am getting an empty array.
It seems my validation rules are not being picked up... as further inspection show that Article::save() is returning true on data that should fail....
/**
* Admin Add
* #see controllers/MastersController::_admin_add()
* #return void
*/
public function admin_add(){
//parent::_admin_add();
if(!empty($this->request->data){
$this->Article->save($this->request->data);
}
}
/**
* Test Admin Add
*
* #return void
*/
public function testAdminAdd() {
#define sample passing data
$sampleDataPass = array(
'Article'=>array(
'title'=>'Test Article Add Will Pass',
'body'=>'Test Article Add Body',
'status_id'=>1,
'category_id'=>1,
)
);
#test action
$this->testAction('admin/articles/add', array('data'=>$sampleDataPass));
$this->assertEmpty($this->Articles->Article->validationErrors); #####PASSES#####
#define sample failing data
$sampleDataFail = array(
'Article'=>array(
'title'=>'Test Article Add Will Fail',
)
);
$this->testAction('admin/articles/add', array('data'=>$sampleDataFail));
$this->assertNotEmpty($this->Articles->Article->validationErrors); #####FAILS#####
}
class Article extends AppModel {
/*
* Name
*/
public $name = 'Article';
/*
* Validation Rules
*/
public $validate = array(
'title' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'You must supply an article title in order to save.',
),
),
'body' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'You must supply an article title in order to save.',
),
),
'status_id' => array(
'numeric' => array(
'rule' => array('numeric'),
'message' => 'You must choose a status.',
'allowEmpty' => false,
),
),
'category_id' => array(
'numeric' => array(
'rule' => array('numeric'),
'message' => 'You must choose a category.',
'allowEmpty' => false,
),
)
);
}
CakePHP will ignore validation rules if the field is not present in the data.
By setting the option 'required' to true the validation rule will always be checked.
For example:
'title' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'You must supply an article title in order to save.',
'required' => true
),
),
Documention on validation in CakePHP can be found here: http://book.cakephp.org/2.0/en/models/data-validation.html#one-rule-per-field
I am trying to get i18n to extract the strings from my model in Cakephp 2.0
The documentation states that
"CakePHP will automatically assume that all model validation error messages in your $validate array are intended to be localized. When running the i18n shell these strings will also be extracted."
http://book.cakephp.org/2.0/en/core-libraries/internationalization-and-localization.html
But my messages in my model are not being extracted into my po file when I run cake i18n and extract the data.
Does anyone know how to get the message strings into the po file?
App::uses('AuthComponent', 'Controller/Component');
class User extends AppModel {
public $validate = array(
'username' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A Username is required',
'rule' => 'isUnique',
'message' => 'This username has already been taken'
)
);
}
This is how you can solve the problem I came across.
App::uses('AuthComponent', 'Controller/Component');
class User extends AppModel {
function __construct() {
parent::__construct();
$this->validate = array(
'username' => array(
'required' => array(
'rule' => array('notEmpty'))
'message' => __('A Username is required', true)),
'unique' => array(
'rule' => 'isUnique',
'message' => _('This username has already been taken', true)
)
);}
}
The correct way of achieve this is:
class AppModel extends Model {
public $validationDomain = 'validation_errors';
.
.
.
}
internally cake will call:
__d('validation_errors', 'Username should be more fun bla bla');
http://book.cakephp.org/2.0/en/console-and-shells/i18n-shell.html#model-validation-messages
http://book.cakephp.org/2.0/en/core-libraries/internationalization-and-localization.html#translating-model-validation-errors
Your $validate structure is a little messed up, you have two identical array keys (rule,message) under the required key. It should be:
public $validate = array(
'username' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => __('A Username is required', true),
),
'unique'=>array(
'rule' => 'isUnique',
'message' => __('This username has already been taken', true)
)
)
);