Callback function ignoring other validation rules and executes first - php

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;
}
}

Related

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;
}
}

Custom Callback Validation Function to Achieve a Custom Error Message

I have a CI form with a field requiring a decimal number. Currently when the field fails validation the user gets an unhelpful message. "The field must be decimal". This is a poor user experience for a user that feels they should be able to use a leading period. e.g. ".4". I am trying to create a Custom callback validation function to achieve a custom error message. Here is my controller (simplified)...
<?php
class Form extends CI_Controller {
function index()
{
$this->load->helper(array('form', 'url'));
$this->load->library('form_validation');
$this->form_validation->set_rules('expenses', 'Expenses', 'trim|max_length[50]|callback_decimalcustom|xss_clean');
if ($this->form_validation->run() == FALSE)
{
$parent_data = array('country' => $countrydata, 'currency' => $currencydata, 'tour' => $tourdata, 'riders' => $ridersdata, 'measurement' => $measurementdata, 'tourdistance' => $tourdistance);
$this->load->view('myform', $parent_data);
}
else
{
$sql= array (
'expenses'=>$this->input->post('expenses'),
);
$ins = $this->db->insert('donations',$sql);
$this->load->view('formsuccess');
}
}
public function decimalcustom($str) //Custom decimal message
{
if (preg_match('/^[\-+]?[0-9]+\.[0-9]+$/', $str))
{
$this->form_validation->set_message('decimalcustom', 'The %s field is required in 0.00 format.');
return FALSE;
}
else
{
return TRUE;
}
}
}
?>
When testing, the error is not thrown, ever since I changed the validation from decimal to decimal custom. Am I missing something?
preg_match() returns TRUE when it's a valid number but you're trying to throw an error. Do the oposite.. (note the exclamation mark before preg_match)
if ( !preg_match('/^[\-+]?[0-9]+\.[0-9]+$/', $str) ) {
$this->form_validation->set_message('decimalcustom', 'The %s field is required in 0.00 format.');
return FALSE;
}
else {
return TRUE;
}

Custom validation rule in CakePHP

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!

Codeigniter form validation error message

I have a form on my website header where i allow the user to log in with his username/password... then i POST to /signin page and check if the username exists to allow the user to log in.. if there is a problem upon login i output these errors...
i tried using the following code to show a custom error but with no luck
if ($this->form_validation->run() == false){
$this->load->view("login/index", $data);
}else{
$return = $this->_submitLogin();
if ($return == true){
//success
}else{
$this->form_validation->set_message('new_error', 'error goes here');
//error
}
$this->load->view("login/index", $data);
}
how does set_message work and if this is the wrong method, which one allow me to show a custom error in this case?
EDIT :
validation rules:
private $validation_rules = array(
array(
'field' => 'username',
'label' => 'Username',
'rules' => 'trim|required|callback__check_valid_username|min_length[6]|max_length[20]|xss_clean'
),
array(
'field' => 'password',
'label' => 'Password',
'rules' => 'trim|required|min_length[6]|max_length[32]'
),
);
The set_message method allows you to set your own error messages on the fly. But one thing you should notice is that the key name has to match the function name that it corresponds to.
If you need to modify your custom rule, which is _check_valid_username, you can do so by perform set_message within this function:
function _check_valid_username($str)
{
// Your validation code
// ...
// Put this in condition where you want to return FALSE
$this->form_validation->set_message('_check_valid_username', 'Error Message');
//
}
If you want to change the default error message for a specific rule, you can do so by invoking set_message with the first parameter as the rule name and the second parameter as your custom error. E.g., if you want to change the required error :
$this->form_validation->set_message('required', 'Oops this %s is required');
If by any chance you need to change the language instead of the error statement itself, create your own form_validation_lang.php and put it into the proper language folder inside your system language directory.
As you can see here, you can display the custom error in your view in the following way:
<?php echo form_error('new_error'); ?>
PS: If this isn't your problem, post your corresponding view code and any other error message that you're getting.
The problem is that your form is already validated in your IF part! You can fix the problem by this way:
if ($this->form_validation->run() == false){
$this->load->view("login/index", $data);
}else{
$return = $this->_submitLogin();
if ($return == true){
//success
}else{
$data['error'] = 'Your error message here';
//error
}
$this->load->view("login/index", $data);
}
In the view:
echo $error;
The CI way to check user credentials is to use callbacks:
$this->form_validation->set_rules('username', 'Username', 'callback_username_check');
...
public function username_check($str) {
// your code here
}
I recommend you to read CI documentation: http://codeigniter.com/user_guide/libraries/form_validation.html
The way I did this was to add another validation rule and run the validation again. That way, I could keep the validation error display in the view consistent.
The following code is an edited excerpt from my working code.
public function login() {
$this->form_validation->set_rules('email', 'Email', 'required');
$this->form_validation->set_rules('password', 'Password', 'required');
$data['content'] = 'login';
if($this->form_validation->run()) {
$sql = "select * from users where email = ? and password = ?";
$query = $this->db->query($sql, array($this->input->post('email'), $this->input->post('password')));
if($query->num_rows()==0) {
// user not found
$this->form_validation->set_rules('account', 'Account', 'callback__noaccount');
$this->form_validation->run();
$this->load->view('template', $data);
} else {
$this->session->set_userdata('userid', $query->id);
redirect('/home');
}
} else {
$this->load->view('template', $data);
}
}
public function _noaccount() {
$this->form_validation->set_message('_noaccount', 'Account must exist');
return FALSE;
}
Require Codeigniter 3.0
Using callback_ method;
class My_controller extends CI_Controller {
function __construct() {
parent::__construct();
$this->form_validation->set_message('date_control', '%s Date Special Error');
}
public function date_control($val, $field) { // for special validate
if (preg_match("/^[0-9]{2}.[0-9]{2}.[0-9]{4}$/", $val)) {
return true;
} else {
return false;
}
}
public function my_controller_test() {
if ($this->input->post()) {
$this->form_validation->set_rules('date_field', 'Date Field', 'trim|callback_date_control[date_field]|xss_clean');
if ($this->form_validation->run() == FALSE) {
$data['errors']=validation_errors();
$this->load->view('my_view',$data);
}
}
}
}
Result:
if date = '14.07.2017' no error
if date = '14-7-2017' Date Field Date Special Error

Categories