I want to check two field combination validation for duplicate values. I have two fields name and area group.
$this->validate['Name'] = array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => __('err_required', array(__('lbl_Name', true))),
),
'Name' => array(
'rule' => array('uniqueClick', 'GroupID'),
'message' => __(__('lbl_Combination', true)),
)
);
$this->validate['GroupID'] = array(
'notempty' => array(
'rule' => array('notEmpty'),
'allowEmpty' => true,
'message' => __('err_required', array(__('lbl_GroupID', true))),
)
);
public function uniqueClick ($ip)
{
$count = $this->find('count', array(
'conditions' => array(
'Name' => $ip,
'GroupID' => $this->data[$this->alias]['GroupID'])
));
return $count == 0;
}
By this code it check combination in both add and update case ,i want to check combination in both case but by this code it check in edit case always after add. so please give me appropriate solution. reply fast.
Create a custom method use it in either in name or group and pass the value of name/group to custom function and and place the check in function:
$this->validate['Name'] = array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => __('err_required', array(__('lbl_Name', true))),
)
);
$this->validate['GroupID'] = array(
'notempty' => array(
'rule' => array('notEmpty'),
'message' => __('err_required', array(__('lbl_GroupID', true))),
),
'duplicate' => array(
'rule' => array('isDuplicate', $this->data['ModelName']['name']),
'message' => __('err_required', array(__('lbl_GroupID', true))),
)
);
public function isDuplicate($data, $name){
// check here
}
Related
Below is my model function which is already working...
i need to validate name field.
when i submit blank form.....the form display Enter portfolio name.
and when i enter numeric value in name field the form display Enter valid portfolio name.
but when i submit the blank form the form does not display any message for name field.
and when i enter the numeric value in name textbox and submit then it display message properly.
please help me to make both the rule working for name field.
so plz suggest me how to implement this.
<?php
class Portfolio extends AppModel{
var $name = 'Portfolio';
var $validate = array(
'name' => array(
'rule' => 'notEmpty',
'message' => "Enter portfolio name."
),
'name' => array(
'rule' => '/^[a-zA-Z]*$/',
'message' => "Enter valid portfolio name."
),
'job_title' => array(
'rule' => 'notEmpty',
'message' => "Enter your quote request."
),
'freight_mode'=> array(
'rule'=>'notEmpty',
'message'=>"Enter your frieght mode."
),
'expected_transport_growth' => array(
'rule' => 'notEmpty',
'message' => "Select expected transport growth."
),
'current_annual_spend' => array(
'rule' => 'notEmpty',
'message' => "Select current annual spend."
),
'expected_annual_spend' => array(
'rule' => 'notEmpty',
'message' => "Select expected annual spend."
),
'quotes_expiry' => array(
'rule' => 'notEmpty',
'message' => "Enter deadline on quote request."
),
'quotes_required' => array(
'rule' => 'notEmpty',
'message' => "Select quote requrest required."
),
'contract_start_date' => array(
'rule' => 'notEmpty',
'message' => "Enter contract start date."
),
);
/*var $belongsTo = array(
'SupplierUquotes' => array(
'className' => 'SupplierUquotes',
'foreignKey' => 'id'
),);*/
}
?>
Try this
<?php
public $validate = array(
'name' => array(
'notEmpty' => array(
'rule' => 'notEmpty',
'message' => "Enter portfolio name."
),
'valid' => array(
'rule' => '/^[a-zA-Z]*$/',
'message' => "Enter valid portfolio name."
)
)
);
?>
Try this code:
<?php
class Portfolio extends AppModel{
var $name = 'Portfolio';
var $validate = array(
'name' => array( // here 'name' is the field name to be validated
'notEmpty'=>array( // here 'notEmpty' is user defined rule name, it should not be "rule" which is a cakephp reserved word, I think
'rule'=>'notEmpty', // here 'notEmpty' is the actual rule applied on the field 'name'
'message'=>'Enter portfolio name.'
),
'validName'=>array( // here 'validName' is another user-defined rule name. It should be different for a particular field.
'rule'=>'/^[a-zA-Z]*$/',
'message'=>'Enter valid portfolio name.'
)
),
'job_title' => array(
'rule' => 'notEmpty',
'message' => "Enter your quote request."
),
'freight_mode'=> array(
'rule'=>'notEmpty',
'message'=>"Enter your frieght mode."
),
'expected_transport_growth' => array(
'rule' => 'notEmpty',
'message' => "Select expected transport growth."
),
'current_annual_spend' => array(
'rule' => 'notEmpty',
'message' => "Select current annual spend."
),
'expected_annual_spend' => array(
'rule' => 'notEmpty',
'message' => "Select expected annual spend."
),
'quotes_expiry' => array(
'rule' => 'notEmpty',
'message' => "Enter deadline on quote request."
),
'quotes_required' => array(
'rule' => 'notEmpty',
'message' => "Select quote requrest required."
),
'contract_start_date' => array(
'rule' => 'notEmpty',
'message' => "Enter contract start date."
),
);
Database Structure
I have two tables, users and nicks.
In users table I have a field username and in nicks table I have a field nick_name
There is a hasMany association between users and nicks
public $hasMany = array(
'Nick' => array(
'className' => 'Nick',
'foreignKey' => 'user_id',
'dependent' => true
)
);
In the User model I am validating to allow only unique username during registration by
'username must be unique' => array(
'rule' => 'isUnique',
'message' => 'username is already taken'
)
but I also don't want to allow users to register any previously used nick names as their username. for that.
'somebody use that name as a nickname' => array(
'rule' => 'checkNickName',
'message' => 'That name is already in use'
)
and
public function checkNickName(){
$nick2 = $this->find('all');
$nickNames = array();
foreach($nick2 as $name2){
foreach($name2['Nick'] as $name1){
array_push($nickNames,strtolower($name1['nick_name']));
}
}
$username = strtolower($this->data['User']['username']);
return in_array($username,$nickNames);
}
But that's not working. What should I to make it work?
If I understand correctly, you want to ensure the username is unique but also that the username has not been used as a nickname by anybody also, so why not use something like this?
public function checkNickIsUnique($check = array()) {
$value = array_values($check);
$nicknameExists = $this->Nick->find('count', array(
'conditions' => array(
'Nick.nick_name' => $value[0]
)
));
return ($nicknameExists > 0) ? false : true;
}
And in your user model, assuming it's directly related to nick, have this in the validation.
public $validate = array(
'username' => array(
'isUnique' => array(
'rule' => 'isUnique',
'message' => 'That username has already been taken'
),
'checkNickIsUnique' => array(
'rule' => array('checkNickIsUnique'),
'message' => 'Your username has already been taken as a nickname'
)
),
);
All it's doing is passing the value from the validation to the method, and checking if that value exists as a nickname within the nicks table, if it does it fails validation otherwise it passes.
First find the nicknames.
$nick2 = $this->Nick->find('all');
Then the result array will be
nick2 = array(
0 => array( //first foreach
'Nick' => array(
nickname => 'TEST'
)
)
)
so remove the second foreach and save the value as using $name2['Nick']['nickname']
public function checkNickName(){
$nick2 = $this->Nick->find('all');
$nickNames = array();
foreach($nick2 as $name2){
array_push($nickNames,strtolower($name2['Nick']['nick_name']));
}
$username = strtolower($this->data['User']['username']);
return in_array($username,$nickNames);
}
just need use the username of the input form.
in your view example:
<?php echo $this->Form->input('username', array(
'label' => array(
'text' => 'Provide your username'
)
)); ?>
and in your model you need change
'username' => array(
'nonEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'not empty please',
'allowEmpty' => false
),
'unique' => array(
'rule' => array('isUniqueUsername'),
'message' => 'username is already taken'
),
),
'nickname' => array(
'nonEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'not empty',
'allowEmpty' => false
),
'unique' => array(
'rule' => array('checkNickName'),
'message' => 'That name is already in use'
)
)
your condition example for is validation is unique user name, use this:
EDIT
'username' => array(
'unique' => array(
'rule' => array('checkNickName'),
'message' => 'username is already taken'
),
),
in your function:
public function checkNickName($check) {
$this->loadModel('Nick');
$username = $this->Nick->find(
'first',
array(
'fields' => array(
'Nick.id',
'Nick.nickname'
),
'conditions' => array(
'Nick.nickname' => $check['username']
)
)
);
if(!empty($username)){
if($this->data[$this->alias]['id'] == $username['User']['id']){
return true;
}else{
return false;
}
}else{
return true;
}
}
A better solution that doesn't require tons of additional code is this:
$valid = $this->User->saveAll($this->request->data, array(
'atomic' => false,
'validate' => 'only'
));
debug($valid);
It will validate the record and all other records attached to it as well, no more code required, just make sure you have the isUnique rule in your associated nicknames model. It will as well invalidate the correct fields in your form.
I want cake php validation for tax percentage numeric field,In that field accept only numeric character like 5.00.Not greater than 100 and not accept spacial character.I try some pattern but it will not work on spacial character like,(!#$%^).My demo code is
$this->validate['TaxPercent'] = array(
'pattern' => array(
'rule' => '/^[\0-9]+$/',
'allowEmpty' => true,
'message' => __('err__numberfield', array(__('lbl_TaxPercent', true))),
),
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => __('err_required', array(__('lbl_TaxPercent', true))),
),
'decimal' => array(
'rule' => array('decimal', 2),
'allowEmpty' => true,
'message' => __("lbl_TaxPercentValid", array(__('lbl_TaxPercent', true))),
),
'range' => array(
'rule' => array('range', 0, 101),
'allowEmpty' => true,
'message' => __("err__percentage", array(__('lbl_TaxPercent', true))),
)
);
So please suggest me appropriate solution.
UPDATED AND WORKING
$this->validate['TaxPercent'] = array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => __('err_required', array(__('lbl_TaxPercent', true))),
),
'decimal' => array(
'rule' => array("decimal", "2", '/^[0-9]+(\.[0-9]{1,2})?$/') //this is working
'allowEmpty' => true,
'message' => __("lbl_TaxPercentValid", array(__('lbl_TaxPercent', true))),
),
'range' => array(
'rule' => array('range', 0, 100.01), //updated this one to so its only until 100.00
'allowEmpty' => true,
'message' => __("err__percentage", array(__('lbl_TaxPercent', true))),
)
);
<?php
App::uses('AppModel', 'Model');
class Announcement extends AppModel {
public $validate = array(
'id' => array(
'notempty' => array(
'rule' => array('notempty'),
),
'numeric' => array(
'rule' => array('numeric'),
),
),
'enabled' => array(
'numeric' => array(
'rule' => array('numeric'),
),
'boolean' => array(
'rule' => array('boolean'),
),
),
'firstPageEnterDate' => array(
'datetime' => array(
'rule' => 'compareDates',
'message' => 'attention to data interval',
),
),
'firstPageLeaveDate' => array(
'datetime' => array(
'rule' => array('datetime'),
),
'notempty' => array(
'rule' => array('notempty'),
),
)
);
public function compareDates() {
if ($this->data[$this->alias]['enabled'] == 1) {
return $this->data[$this->alias]['firstPageEnterDate'] < $this->data[$this->alias]['firstPageLeaveDate'];
}
}
}
The problem is:
It displays the validation message set on firstPageEnterDate, regardless, if
$this->data[$this->alias]['enabled'] == 1 or not.
Please note that this condition:
$this->data[$this->alias]['enabled'] == 1 is not always true. But even when it's false, so the contents inside don't run, still the message appears.
So, it seems that, if Cake sees a rule enabled and a message, regardless what is inside rule, it triggers the validation message associated!
Any clue why?
'firstPageEnterDate' => array(
'datetime' => array(
'rule' => 'compareDates',
'message' => 'attention to data interval',
),
Return true in compareDates() if it is valid -- or if you don't want to check it because that counts as valid.
public function compareDates() {
if ($this->data[$this->alias]['enabled'] != 1) return true; // we don't want to check
return $this->data[$this->alias]['firstPageEnterDate'] < $this->data[$this->alias]['firstPageLeaveDate'];
}
You can also check in beforeValidate() callback the value of enabled and unset that validation rule from there.
I'm really struggling with a table association in cakephp, all I'm trying to do is associate two tables together, however one table has two two foreign keys to the other table.
For some reason, I cannot get any information to be displayed in the field select form for home_id ....
Please see the database picture below and the associated code.
I'm really new to cakephp but feel if I can nail this it will be really useful - any help is greatly appreciated.
Database Schema
class SafcTeam extends AppModel {
var $name = 'SafcTeam';
var $displayField = 'name';
var $validate = array(
'name' => array(
'notempty' => array(
'rule' => array('notempty'),
),
),
'badge' => array(
'notempty' => array(
'rule' => array('notempty'),
),
),
);
var $hasMany = array(
'SafcTeam' => array(
'className' => 'SafcEvent',
'foreignKey' => 'home_id',
)
);
}
class SafcEvent extends AppModel {
var $name = 'SafcEvent';
var $displayField = 'id';
var $validate = array(
'safc_matchtype_id' => array(
'numeric' => array(
'rule' => array('numeric'),
),
),
'safc_league_id' => array(
'numeric' => array(
'rule' => array('numeric'),
),
),
'home_id' => array(
'numeric' => array(
'rule' => array('numeric'),
),
),
'away_id' => array(
'numeric' => array(
'rule' => array('numeric'),
),
),
'streamer_id' => array(
'numeric' => array(
'rule' => array('numeric'),
),
),
'safc_channel_id' => array(
'numeric' => array(
'rule' => array('numeric'),
),
),
'comments' => array(
'notempty' => array(
'rule' => array('notempty'),
),
),
'safc_profile_id' => array(
'numeric' => array(
'rule' => array('numeric'),
),
),
'safc_source_id' => array(
'numeric' => array(
'rule' => array('numeric'),
),
),
'event_info_url' => array(
'notempty' => array(
'rule' => array('notempty'),
),
),
);
var $belongsTo = array(
'SafcMatchtype' => array(
'className' => 'SafcMatchtype',
'foreignKey' => 'safc_matchtype_id'
),
'SafcLeague' => array(
'className' => 'SafcLeague',
'foreignKey' => 'safc_league_id'
),
'SafcChannel' => array(
'className' => 'SafcChannel',
'foreignKey' => 'safc_channel_id'
),
'SafcProfile' => array(
'className' => 'SafcProfile',
'foreignKey' => 'safc_profile_id'
),
'SafcSource' => array(
'className' => 'SafcSource',
'foreignKey' => 'safc_source_id'
),
'SafcTeam' => array(
'className' => 'SafcTeam',
'foreignKey' => 'home_id'
)
);
}
you have to use an alias for each of this relation of your SafcTeam Model:
var $belongsTo = array(
//relationship for your home_id fk
'SafcHomeTeam' => array(
'className' => 'SafcTeam',
'foreignKey' => 'home_id'
),
//relationship for your away_id key
'SafcAwayTeam' => array(
'className' => 'SafcTeam',
'foreignKey' => 'away_id'
)
);
and also in the related safc team model :
var $hasMany = array(
'SafcHomeTeam' => array(
'className' => 'SafcEvent',
'foreignKey' => 'home_id',
),
'SafcAwayTeam' => array(
'className' => 'SafcEvent',
'foreignKey' => 'away_id',
)
);
In your SafcEvents controller in the action add and edit add this:
//to respect cake conventions need the select list to be plural (Teams <--- with a s at the end)
$safcHomeTeams = $this->SafcEvent->SafcHomeTeam->find('list');
$safcAwayTeams = $this->SafcEvent->SafcAwayTeam->find('list');
//also pass those list to the view
$this->set(compact('SafcAwayTeams', 'SafcHomeTeams));
In the safcevent view Add and Edit
in the form section :
//to respect cake convention to construct your select input properly
//you need to refere to the list established in the controller ($SafcHomeTeams by using $SafcHomeTeam_id <--singular + "_" + "id")
echo $this->Form->input('SafcAwayTeam_id');
echo $this->Form->input('SafcHomeTeam_id');
Cake does not support complex FK out the box, you can define a relation with conditions like so
public $hasMany = array(
'TheRelation' => array(
'foreignKey' => false,
'conditions' => array(
... conditions ...
)
)
)