Custom validation rule in CakePHP - php

I'm trying to create a custom validation rule for when a checkbox is checked, an input field will need to be filled out in order to proceed to the next page. If unchecked, the input field will not be required.
Here's my code in View:
echo $this->Form->inputs(array(
'legend'=>'Certifications',
'rn_box'=>array(
'type'=>'checkbox',
'label'=>'RN',
'value' => $results['Education']['rn_box']
),
'rn_number'=>array(
'label'=>'RN Number:',
'value' => $results['Education']['rn_number']
),
));
In my Model I created a function:
public function rnCheck () {
if ($this->data['Education']['rn_box'] == '0') {
return false;
}
return true;
}
public $validate = array(
'rn_number' => array(
'rnCheck'=>array(
'rule'=>'rnCheck',
'message'=>'Please Provide a Number'
),
),
);
The checkbox returns a value of 1 if checked, and a value of 0 unchecked. The rn_number field is an input field that I'm trying to validate. I tried playing with 'required', 'allowEmpty', etc. with no luck. If anyone can point me in the right direct, that would be great, thanks!

You can probably just handle it all in the function callback for rn_number. I would also call the function and rule name rn_number to avoid any confusion.
For example, change your validate array to:
public $validate = array(
'rn_number' => array(
'rn_number'=>array(
'rule'=>'rn_number'
),
),
);
And then your custom validation function can look like:
public function rn_number () {
if ($this->data['Education']['rn_box'] == 1) {
if($this->data['Education']['rn_number'] == '')
$errors[] = "Please enter your RN Number.";
}
if (!empty($errors))
return implode("\n", $errors);
return true;
}
I'm handling the error message in the custom validation function - not in the validate array. Let me know if this doesn't work!

Related

Callback function ignoring other validation rules and executes first

On the HTML form, I have a field such as:
<?php
$token = array(
'name' => 'pc_token',
'id' => 'pc_token',
'class' => 'form-control'
);
echo form_input($token, set_value('pc_token')); ?>
The validation rules set on the field are:
$this->form_validation->set_rules(
'pc_token', 'Token number', 'trim|required|min_length[5]|max_length[12]|callback_token_exists',
array(
'required' => 'You have not provided %s.',
'token_exists' => 'The %s is not valid. Please recheck again'
)
);
And here is the function for the callback
public function token_exists($key)
{
$this->load->model('tokens');
return $this->tokens->IsValidToken($key); // will return true if found in database or false if not found
}
The problem here is that when I keep the pc_token field empty/blank and submit the form, I don't get the expected error message printed on screen.
Current Output
The Token number is not valid. Please recheck again
Expected Output
You have not provided Token number
So why does CI ignore the previous rules (such as required, min_length etc) in this case? If my assumption is correct, the direction is left to right and if even one fails, it does not move to the next rule.
try this in your callback function
check for empty
public function token_exists($key='')
{
if(empty($key)){
$this->form_validation->set_message('token_exists', 'The {field} field is required.');
return FALSE;
}else{
$this->load->model('tokens');
return $this->tokens->IsValidToken($key);
}
// will return true if found in database or false if not found
}
I'll post the approach that I took. But I'll accept Abhishek's answer as he led me in the right direction. It's a bit sad that CI3 did not address it so I'm forced to use an alternate approach.
So, the validation rules become:
$this->form_validation->set_rules(
'pc_token', 'Token number', 'callback_token_exists'
);
And the callback function becomes:
public function token_exists($key)
{
if(trim($key) == "" || empty($key))
{
$this->form_validation->set_message('token_exists', 'You have not provided %s.');
return FALSE;
}
else if(strlen($key) < 5)
{
$this->form_validation->set_message('token_exists', '%s should be at least 5 characters long.');
return FALSE;
}
else if(strlen($key) > 12)
{
$this->form_validation->set_message('token_exists', '%s cannot be greater than 12 characters long.');
return FALSE;
}
else
{
$this->load->model('tokens');
$isValid = $this->tokens->IsValidToken($key);
if(! $isValid)
{
$this->form_validation->set_message('token_exists', 'You have not provided %s.');
}
return $isValid;
}
}

CodeIgniter Anonymous Form Validation

I have a code like this given below:
$this->form_validation->set_rules("codetype", "Code Type", array(
"codecheck" => function ($str) {
// just return it false.
return false;
}
), array("codecheck"=>"return this message"));
I want it to return the codecheck error message. but codeigniter form validation class returns this message:
"Unable to access an error message corresponding to your field name
Code Type".
How can I write a fully anonymous CodeIgniter function with an error message?
Hope this will help you :
You can remove required if you want and also set your if condition
$this->form_validation->set_rules('codetype', 'Code Type',
array(
'required',
array(
'codecheck_callable',
function($str)
{
// Check validity of $str and return TRUE or FALSE
if ($str == 'test')
{
$this->form_validation->set_message('codecheck_callable', 'can not be test');
return false;
}
else
{
return TRUE;
}
}
)
)
);
For more : https://www.codeigniter.com/user_guide/libraries/form_validation.html#callbacks-your-own-validation-methods
According to CodeIgniter docs at https://www.codeigniter.com/userguide3/libraries/form_validation.html
you can do it like this
$this->form_validation->set_message('username_check', 'The {field} field can not be the word "test"');

Passing multiple callback in Code Igniter form validation rules

I want to pass multiple callbacks in codeigniter form validation rules.... but only one of the callbacks work
I am using this syntax in my contoller
$this->form_validation->set_rules(
array(
'field' => 'field_name',
'label' => 'Field Name',
'rules' => 'callback_fieldcallback_1|callback_fieldcallback_2[param]',
'errors' => array(
'fieldcallback_1' => 'Error message for rule 1.',
'fieldcallback_2' => 'Error message for rule 2.',
)
),
);
and the callback functions are....
function fieldcallback_1 (){
if(condition == TRUE){
return TRUE;
} else {
return FALSE;
}
}
function fieldcallback_2 ($param){
if(condition == TRUE){
return TRUE;
} else {
return FALSE;
}
}
Someone please help me out with this problem.... any other solutions regarding passing multiple callbacks in form validation rules are also appreciated...
All validation routines must have at least one argument which is the value of the field to be validated. So, a callback that has no extra arguments should be defined like this.
function fieldcallback_1($str){
return ($str === "someValue");
}
A callback that requires two arguments is defined like this
function fieldcallback_2 ($str, $param){
//are they the same value?
if($str === $param){
return TRUE;
} else {
$this->form_validation->set_message('fieldcallback_2', 'Error message for rule 2.');
//Note: `set_message()` rule name (first argument) should not include the prefix "callback_"
return FALSE;
}
Maybe like this?
$this->form_validation->set_rules(
array(
'field' => 'field_name',
'label' => 'Field Name',
'rules' => 'callback_fieldcallback_1[param]'),
);
// Functions for rules
function fieldcallback_1 ($param){
if(condition == TRUE){
return fieldcallback_2($param);
} else {
$this->form_validation->set_message('callback_fieldcallback_1', 'Error message for rule 1.');
return FALSE;
}
}
function fieldcallback_2 ($param){
if(condition == TRUE){
return TRUE;
} else {
$this->form_validation->set_message('callback_fieldcallback_1', 'Error message for rule 2.');
return FALSE;
}
}

Create a dynamic conditional validation in Cakephp

I want to set these validation rule in CakePHP
Rule:
One of these fields is required but not both.
discount_percent
discount_amount
If discount_amount is input as 0 a NULL should be saved and then discount_percent is required to be > 1 but <=100.
If discount_percent is input a 0 then a NULL should be saved and then discount_amount is required to be > 0 but <= products.price for the selected product.
I have tried but not getting right way to perform this validation.
Modal Code:
App::uses('AppModel', 'Model');
class Code extends AppModel {
public $validate = array(
'discount_amount' => array(
'rule' => array('checkLimit'),
'message' => 'Please supply a valid discount_amount'
),
'discount_percent' => array(
'rule' => array('checkLimit'),
'message' => 'Please supply a valid discount_percent'
)
);
public function checkLimit($field) {
$passed = true;
if (isset($this->data[$this->alias]['discount_amount']) && empty($this->data[$this->alias]['discount_amount'])) {
??????
} else {
??????
}
}
}
Validation rules should not change any data!
So "if 0, save null" is not allowed in a validation rule.
You should implement that logic in a beforeSave() callback rather.
Regarding the validation, there is a second parameter provided containing all the $data you could use to validate other fields (and pull additional required data from the database - your product price probably).
Good documentation is at http://book.cakephp.org/2.0/en/models/data-validation.html#adding-your-own-validation-methods
Be careful using empty and isset, they're not exact opposites. empty('0') returns true, while isset('0') also return true. I think you want to use isset and !isset instead.
public function checkLimit($field) {
if ((!isset($this->data[$this->alias]['discount_amount']) && isset($this->data[$this->alias]['discount_percent'])) {
//only percent is set
if ($this->data[$this->alias]['discount_percent'] >= 1 && $this->data[$this->alias]['discount_percent'] <= 100) {
//percent is in correct range
return true;
}
} else if ((isset($this->data[$this->alias]['discount_amount']) && !isset($this->data[$this->alias]['discount_percent'])) {
//only amount is set
if ($this->data[$this->alias]['discount_amount'] >= 0 && $this->data[$this->alias]['discount_amount'] <= $products.price) {
//amount is in correct range
return true;
}
}
//either neither or both fields are set, or values aren't in correct range
return false;
}

CodeIgniter form validation, show errors in order

Lets say I have a login form and it has fields username and password. Both of the fields are required to be filled in and when you submit the form it has two different lines for them.
Username field is required.
Password field is required.
What I want to do is to show only the username field errors and when they don't have any errors with username field, it will show the password field errors.
How would this be done?
Also, I remember there is a way to show errors only regarding a field, what was the snippet for it?
I suggest using a custom callback function tied to just one input, that checks both inputs and conditionally sets the desired message.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class YourController extends CI_Controller {
public function save()
{
//.... Your controller method called on submit
$this->load->library('form_validation');
// Build validation rules array
$validation_rules = array(
array(
'field' => 'username',
'label' => 'Username',
'rules' => 'trim|xss_clean|callback_required_inputs'
),
array(
'field' => 'password',
'label' => 'Password',
'rules' => 'trim|xss_clean'
)
);
$this->form_validation->set_rules($validation_rules);
$valid = $this->form_validation->run();
// Handle $valid success (true) or failure (false)
if($valid)
{
//
}
else
{
//
}
}
public function required_inputs()
{
if( ! $this->input->post('username'))
{
$this->form_validation->set_message('required_inputs', 'The Username field is required');
return FALSE;
}
else if ($this->input->post('username') AND ! $this->input->post('password'))
{
$this->form_validation->set_message('required_inputs', 'The Password field is required');
return FALSE;
}
return TRUE;
}
}

Categories