cakephp validation on multiple dates - php

I have a form which have add more functionality. user can enter their multiple education. now I want to add a validation rule for the below condition
if user started their first education in 2006 and completed in 2008
then he can not enter second education starting date 2008 or before
that
here are my validation rules
/**
* Validation
*
* #var array
* #access public
*/
public $validate = array(
'degree_type_id' => array(
'notEmpty' => array(
'rule' => 'notEmpty',
'message' => 'This field cannot be left blank.',
'last' => true,
),
'is_unique_degree' => array(
'rule' => 'is_unique_degree',
'message' => 'You have added same course multiple time.',
'last' => true,
),
),
'college_hospital' => array(
'notEmpty' => array(
'rule' => 'notEmpty',
'message' => 'This field cannot be left blank.',
'last' => true,
),
'size' => array(
'rule' => array('maxLength', 255),
'message' => 'This field must be no larger than 255 characters long.'
),
),
'year_passing' => array(
'notEmpty' => array(
'rule' => 'notEmpty',
'message' => 'This field cannot be left blank.',
'last' => true,
),
),
'start_date' => array(
'notEmpty' => array(
'rule' => 'notEmpty',
'message' => 'This field cannot be left blank.',
'last' => true,
),
'dateRule' => array(
'rule' => array('date', 'ymd'),
'message' => 'Enter a valid date in MM/YYYY format.',
'allowEmpty' => true
),
'validateDuration' => array(
'rule' => 'validateDuration',
'message' => 'This field cannot be left blank.',
'last' => true,
),
),
'end_date' => array(
'notEmpty' => array(
'rule' => 'notEmpty',
'message' => 'This field cannot be left blank.',
'last' => true,
),
'dateRule' => array(
'rule' => array('date', 'ymd'),
'message' => 'Enter a valid date in MM/YYYY format.',
'allowEmpty' => true
),
'validateEndDate' => array(
'rule' => 'validateEndDate',
'message' => 'End date should be greater than start date.',
'allowEmpty' => true
)
),
);
This is what I try and got success only for validating future date condition
public function validateDuration() {
$startDate = $this->data['DoctorEducation']['start_date'];
$endDate = $this->data['DoctorEducation']['end_date'];
if (strtotime(date('Y-m-d')) < strtotime($startDate)) {
return __('Education duration will not be future date');
}
if (strtotime(date('Y-m-d')) < strtotime($endDate)) {
return __('Education duration will not be future date');
}
//pr($this->data);
return true;
}
let me know if you want any other information.

Assuming I understood your question correctly, you should have a User model with a hasMany association with DoctorEducation. One approach could be to define in the User model:
var $usedDates = array;
public function beforeValidate($options = array()) {
$this->usedDates = array();
}
then the validation rules for the DoctorEducation model could use it:
public function validateStart( $dataToValidate ) {
foreach($this->ParentModel->usedDates as $usedDate) {
// Perform whatever check you need to ensure periods
// don't overlap and return errors
}
$key = count($this->ParentModel->usedDates);
$this->ParentModel->usedDates[$key]['start_date'] = $dataToValidate['start_date'];
return true;
}
public function validateEnd( $dataToValidate ) {
foreach($this->ParentModel->usedDates as $usedDate) {
// Perform whatever check you need to ensure periods
// don't overlap and return errors
}
$key = count($this->ParentModel->usedDates) - 1;
$this->ParentModel->usedDates[$key]['end_date'] = $dataToValidate['end_date'];
return true;
}
The above assumes you will be saving the User model together with the DoctorEducation model.

Related

Email Validation in cakephp Model

I have the below setup of validation rules. For some reason, 'on' => 'create' block doesn't work. The conditions to be implemented are standard create / modify regarding email. Also, in edit section, I'm getting the error from 'on' => 'create' block.
How to validate the email? I'm using CakePHP v 2.6.1.
public $validate = array(
'email' => array(
'required' => array(
'rule' => array('email'),
'message' => 'Kindly provide your email for verification.'
),
'maxLength' => array(
'rule' => array('maxLength', 255),
'message' => 'Email cannot be more than 255 characters.'
),
'editunique' => array(
'rule' => array('editunique'),
'message' => 'Provided Email address already exists.',
'on' => 'update'
),
'unique' => array(
'rule' => 'isUnique',
'message' => 'Provided Email already exists.',
'on' => 'create'
)
)
);
public function editunique($email) {
// email should be one and of the logged in user only.
if ($this->find('count', array(
'conditions' => array(
$this->alias . '.id <>' => $this->data[$this->alias]['id'],
$this->alias . '.email' => $email
)
)) > 1) {
return false;
}
}
Also, I'm not getting the $this->data[$this->alias]['id'] value.
My Controller has the following section:
if ($this->Client->hasAny(array('Client.id' => base64_decode(trim($this->request->query['client_id']))))){
if ( $this->request->is('ajax') && $this->request->is('post') ){
$this->Client->create();
$this->Client->id = base64_decode(trim($this->request->query['client_id']));
$this->Client->set($this->request->data);
// validate
if($this->Client->validates()) {
// save the data after validation
if($this->Client->save($this->request->data)){
}
}
}
}
I think you are misunderstanding what Cake's isUnique rule checks for and as a result over complicating things. Cake defines isUnique as:-
The data for the field must be unique, it cannot be used by any other rows
When it checks if a value is unique it is smart enough to exclude existing data of the current row (which appears to be what you are attempting to do with your editunique rule).
So you just need your validation rules to look like:-
public $validate = array(
'email' => array(
'required' => array(
'rule' => array('email'),
'message' => 'Kindly provide your email for verification.'
),
'maxLength' => array(
'rule' => array('maxLength', 255),
'message' => 'Email cannot be more than 255 characters.'
),
'unique' => array(
'rule' => 'isUnique',
'message' => 'Provided Email already exists.'
)
)
);
This removes the editunique rule and drops the on condition of your unique rule.
As of cakephp 3.0 in the entities table it should look something like this
namespace App\Model\Table;
public function validationDefault($validator)
{
$validator
->email('email')
->add('email', 'email', [
'rule' => [$this, 'isUnique'],
'message' => __('Email already registered')
])
->requirePresence('email', 'create')
->notEmpty('email', 'Email is Required', function( $context ){
if(isset($context['data']['role_id']) && $context['data']['role_id'] != 4){
return true;
}
return false;
});
return $validator;
}
}
function isUnique($email){
$user = $this->find('all')
->where([
'Users.email' => $email,
])
->first();
if($user){
return false;
}
return true;
}

Validating an ajax request with CakePHP ajax view returns all fields invalid always instead of the proper ones

I'm not sure why I keep receiving all the errors instead of just the invalid fields even when I fill out some of the required fields properly.
Submissions Controller:
public function submit() {
$this->set('title_for_layout', 'Submit - ');
if ($this->request->is('ajax')) {
if (!empty($this->request->data)) {
$this->Submission->set($this->request->data);
if ($this->Submission->invalidFields($this->request->data)) {
$formErrors = $this->Submission->validationErrors;
} else {
$formErrors = null;
}
} else {
$formErrors = null;
}
$this->set(compact('formErrors'));
}
/Submissions/json/submit.ctp:
<?php
$toReturn = array(
'formErrors' => $formErrors
);
echo json_encode($toReturn);
Submission model:
var $validate = array(
'title' => array(
'title' => array(
'rule' => 'notEmpty',
'required' => true,
'allowEmpty' => false,
'message' => 'Please enter a title'
),
'minLength' => array(
'rule' => array('minLength', 5),
'message' => 'Please make your title longer (e.g. IJL John F. Kennedy donated his presidential salary to charity)'
),
'maxLength' => array(
'rule' => array('maxLength', 300),
'message' => 'Your title needs to be shorter'
),
),
'description' => array(
'shortDescription' => array(
'rule' => array('shortDescription'),
'message' => 'Your description needs to be longer'
),
'longDescription' => array(
'rule' => array('longDescription'),
'message' => 'Your description needs to be shorter'
),
),
'source' => array(
'source' => array(
'rule' => 'notEmpty',
'required' => true,
'allowEmpty' => false,
'message' => 'Enter a valid source URL (e.g. http://en.wikipedia.org/wiki/Penguins)'
),
'website' => array(
'rule' => 'url',
'message' => 'Enter a valid source URL (e.g. http://en.wikipedia.org/wiki/Penguins)'
),
),
'category' => array(
'category' => array(
'rule' => 'notEmpty',
'required' => true,
'allowEmpty' => false,
'message' => 'Please choose a category'
)
)
);
Form values that are getting serialized and sent:
Errors I'm getting in a json response:
Pulling hair out over here :|
You seem to have got a little muddle up with validates() and invalidFields()
invalidFields() returns the invalid fields after a validates(), see: http://book.cakephp.org/2.0/en/models/data-validation/validating-data-from-the-controller.html
So your code should look something like this:
$this->Submission->set($this->request->data);
if (!$this->Submission->validates()) {
$formErrors = $this->Submission->invalidFields();
} else {
$formErrors = null;
}
First, set the data to the model:
$this->ModelName->set($this->request->data);
Then, to check if the data validates, use the validates method of the model, which will return true if it validates and false if it doesn’t:
if ($this->ModelName->validates()) {
// it validated logic
} else {
// didn't validate logic
$errors = $this->ModelName->validationErrors;
}
Validating Data from the Controller

Validation for "at least one phone number is required" in CakePHP

This is the model file vechile_enquiry.php
<?php
class VechileEnquiry extends AppModel{
var $name ='VechileEnquiry';
var $validate = array('name' => array
('rule' => 'notEmpty',
'message' => 'Please type name')
);
}
?>
This is the view file vechile.ctp
<?php
echo $this->Form->input('name', array('label'=>false));
?>
At least one phone number is required:
<?php
echo $this->Form->input('mobile_phone', array('label'=>false));
echo $this->Form->input('work_phone', array('label'=>false));
echo $this->Form->input('home_phone', array('label'=>false));
?>
Validation is working in the name field but I'm not getting how to implement validation in mobile_phone,
work_phone, home_phone for the condition that at least one phone number is required.
This should do it for you:
var $validate = array(
'name' => array(
'rule' => 'notEmpty',
'message' => 'Please type name'
),
'mobile_phone' => array(
'check_phone' => array(
'rule' => array('hasPhone'),
'required' => false,
'allowEmpty' => true,
'message' => 'At least one phone number is required.'
)
),
'work_phone' => array(
'check_phone' => array(
'rule' => array('hasPhone'),
'required' => false,
'allowEmpty' => true,
'message' => 'At least one phone number is required.'
)
),
'home_phone' => array(
'check_phone' => array(
'rule' => array('hasPhone'),
'required' => false,
'allowEmpty' => true,
'message' => 'At least one phone number is required.'
)
)
);
function hasPhone($field){
if(!empty($this->data[$this->name]['mobile_phone']) || !empty($this->data[$this->name]['work_phone']) || !empty($this->data[$this->name]['home_phone'])){
return true;
} else {
return false;
}
}

cakephp: model validation rules, form field, ===

After studying Miles Jones cupcake forum plugin, I have a couple of questions here:
1)Is it compulsory for each field (that appears in a model's validation rules) to be a field in a database table? I found the following validation rules in the User model of cupcake forum plugin. oldPassword and newPassword are not fields in the users table. I'm confused coz' I thought I should only make validation rules for fields of table.
public $validate = array(
'username' => array(
'isUnique' => array(
'rule' => 'isUnique',
'message' => 'That username has already been taken',
'on' => 'create'
),
'notEmpty' => array(
'rule' => 'notEmpty',
'message' => 'Please enter a username'
)
),
'password' => array(
'rule' => 'notEmpty',
'message' => 'Please enter a password'
),
'oldPassword' => array(
'rule' => array('isPassword'),
'message' => 'The old password did not match'
),
'newPassword' => array(
'isMatch' => array(
'rule' => array('isMatch', 'confirmPassword'),
'message' => 'The passwords did not match'
),
'custom' => array(
'rule' => array('custom', '/^[-_a-zA-Z0-9]+$/'),
'message' => 'Your password may only be alphanumeric'
),
'between' => array(
'rule' => array('between', 6, 20),
'message' => 'Your password must be 6-20 characters in length'
),
'notEmpty' => array(
'rule' => 'notEmpty',
'message' => 'Please enter a password'
)
),
'email' => array(
'isUnique' => array(
'rule' => 'isUnique',
'message' => 'That email has already been taken',
'on' => 'create'
),
'email' => array(
//'rule' => array('email', true),//boolean true as second parameter verifies that the host for the address is valid -- to be uncommented once website is uploaded
'rule' => array('email'),
'message' => 'Your email is invalid'
),
'notEmpty' => array(
'rule' => 'notEmpty',
'message' => 'Your email is required'
)
)
);
2)Does each form field need to be a field in a database table?
For example when I ask a user to signup there will be: username, email addr, password and confirm password. But confirm password field doesn't need to be a field in a table right?
Is that a good practice?
I found the following isMatch function in form_app_model.php:
/**
* Validates two inputs against each other
* #access public
* #param array $data
* #param string $confirmField
* #return boolean
*/
public function isMatch($data, $confirmField) {
$data = array_values($data);
$var1 = $data[0];
$var2 = (isset($this->data[$this->name][$confirmField])) ? $this->data[$this->name][$confirmField] : '';
return ($var1 === $var2);
}
Can someone tell me on what is === in the last line of the above code?
Thank you.
That mean exactly equal (without type conversion) . For example: if y = 25, then y === 25 is true and y == '25' is true, but y === '25' is not true.
== means equal
=== mean identical
http://www.techsww.com/tutorials/web_development/php/tips_and_tricks/difference_between_equal_and_identical_comparison_operators_php.php

Custom validation rule in CakePHP not working as intended

I wrote a custom validation method inside my Submission model that basically allows a blank input field, but once someone enters something in it, it'll validate the data entered.
The validation inside my Submission Model looks like this (All other validation rules are working except for 'description'):
var $validate = array(
'title' => array(
'title' => array(
'rule' => 'notEmpty',
'required' => true,
'allowEmpty' => false,
'message' => 'Please enter a title'
),
'minLength' => array(
'rule' => array('minLength', 5),
'message' => 'Please make your title longer'
),
'maxLength' => array(
'rule' => array('maxLength', 300),
'message' => 'Your title needs to be shorter'
),
),
'description' => array(
'checkDescription' => array(
'rule' => array('validateDescription'),
'message' => 'Description must be greater than 5 characters'
),
),
'source' => array(
'source' => array(
'rule' => 'notEmpty',
'required' => true,
'allowEmpty' => false,
'message' => 'Enter a valid source URL'
),
'website' => array(
'rule' => 'url',
'message' => 'Please enter a valid source URL'
),
)
);
My method which is also in my Submission model (below the above code) is:
public function validateDescription($data) {
if(empty($data['Submission']['description']))
return true;
if((strlen($data['Submission']['description'])) <= 5)
return false;
}
I'm not sure why this isn't working at all. In my view, I've got this to display the error:
if ($form->isFieldError('Submission.description'))
echo ($form->error('Submission.description', null, array('class' => 'error')));
The only reason I'm trying to do this, is because using the normal validation with required => false and allowEmpty => true along with a minLength and maxLength validation rule weren't behaving how I intended.
Any help would be greatly appreciated! :)
The $data variable passed into the validation method only contains array($fieldname => $value). You're also not returning true for strings over length of 5. Your method should look like this:
public function validateDescription(array $data) {
$value = current($data);
return !$value || strlen($value) > 5;
}

Categories