I'm trying to validate credit card numbers and so far I am able to get a result from it. However, whenever it fails, the validation message for the form won't turn up. I've been trying several methods including setting a callback. I'm not sure what I'm missing. Hope someone can take a look and help me.
Controller
public function next(){
$this->form_validation->set_error_delimiters('<p class="error">', '</p>');
$this->form_validation->set_rules('inputcardtype','Select Card Type','required|callback_check_default');
$this->form_validation->set_message('check_default', 'Please select the month of expiration');
$this->form_validation->set_rules('inputcardnumber', 'Card Number', 'trim|required|xss_clean');
$this->form_validation->set_rules('inputexpirationdatemonth','Select Month','required|callback_check_default');
$this->form_validation->set_message('check_default', 'Please select the month of expiration');
$this->form_validation->set_rules('inputexpirationdateyear','Select Year','required|callback_check_default');
$this->form_validation->set_message('check_default', 'Please select the year of expiration');
$this->form_validation->set_rules('inputnameoncard', 'Name on Card', 'trim|required|xss_clean');
$inputcardnumber = $this->input->post('inputcardnumber');
$inputcardtype = $this->input->post('inputcardtype');
// var_dump($this->cardnumber_validation($inputcardnumber,$inputcardtype));
if($this->form_validation->run()==false||$this->cardnumber_validation($inputcardnumber,$inputcardtype)==FALSE){
$this->index();
}else{
}
}
function cardnumber_validation($string = NULL,$cardtype=NULL) {
$this->load->helper('creditcardvalidation');
if(checkCreditCard ($string, $cardtype, $ccerror, $ccerrortext)) {
return TRUE;
}
else{
$this->form_validation->set_message("inputcardnumber", 'Invalid Card Number');
return FALSE;
}
}
function check_default($post_string){
return $post_string == '0' ? FALSE : TRUE;
}
So I found out you can do this to pass 2 variables into a callback
$this->form_validation->set_rules('inputcardnumber', 'Card Number', 'trim|required|xss_clean|callback_cardnumber_validation['.$this->input->post('inputcardtype').']');
Related
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;
}
}
I have found a credit card validator. However, I am unsure of how to use it with callbacks. The function I want to use requires 4 inputs. However I can only pass one through the form validation now. Hope someone can help me with this.
Controller
public function next(){
$this->form_validation->set_error_delimiters('<p class="error">', '</p>');
$this->form_validation->set_rules('inputcardtype','Select Card Type','required|callback_check_default');
$this->form_validation->set_message('check_default', 'Please select the month of expiration');
$this->form_validation->set_rules('inputcardnumber', 'Card Number', 'trim|required|xss_clean|callback_cardnumber_validation');
$this->form_validation->set_rules('inputexpirationdatemonth','Select Month','required|callback_check_default');
$this->form_validation->set_message('check_default', 'Please select the month of expiration');
$this->form_validation->set_rules('inputexpirationdateyear','Select Year','required|callback_check_default');
$this->form_validation->set_message('check_default', 'Please select the year of expiration');
$this->form_validation->set_rules('inputnameoncard', 'Name on Card', 'trim|required|xss_clean');
$inputcardnumber = $this->input->post('inputcardnumber');
$inputcardtype = $this->input->post('inputcardtype');
if($this->form_validation->run()==false){
$this->index();
}else{
}
}
function cardnumber_validation($string = NULL) {
$this->load->helper('creditcardvalidation');
if(checkCreditCard ($string, $cardtype, $ccerror, $ccerrortext)) {
return TRUE;
}
else{
$this->form_validation->set_message("cardnumber_validation", 'The %s is not valid.');
return FALSE;
}
}
The callbacks need to be named after a function.
If you have:
callback_check_default
You need to have a function called:
function check_default() {
//Your validation here
}
Does that answer your question?
I've this registration function and the related callback to check if an username already exists in the database. It works all perfectly, but I have problems with flashdata message
Here's the code:
/*
* Checks registration
*/
public function verify(){
$this->form_validation->set_rules('nome', 'Nome', 'trim|required|min_length[2]|xss_clean');
$this->form_validation->set_rules('cognome', 'Cognome', 'trim|required|min_length[2]|xss_clean');
$this->form_validation->set_rules('username', 'Username', 'trim|required|min_length[4]|xss_clean|callback_check_username');
$this->form_validation->set_rules('email', 'Email', 'trim|required|valid_email');
$this->form_validation->set_rules('password', 'Password', 'trim|required|min_length[4]|max_length[32]');
$this->form_validation->set_rules('password_conf', 'Password Confirmation', 'trim|required|matches[password]');
if($this->form_validation->run() == FALSE)
{
$this->session->set_flashdata('error_reg', 'Something goes wrong, please check your registration form');
redirect('registration');
}
else
{
$this->registration_m->add_user();
$this->session->set_flashdata('success_reg', 'Registration Successful!');
redirect('registration');
}
}
public function check_username($username){
$result = $this->registration_m->check_username_m($username);
if ($result) {
$this->session->set_flashdata('username', 'Username già in uso, riprovare.');
return false;
} else {
return true;
}
}
As you can see there's a redirect on the function verify(), and the flashdata before is correctly shown in case of errors.
My Question is: is there a way to show (in case of error) the flashdata inside the callback function without changing the logic of this piece of code?
Hope I was clear at all, cheers.
Modify your code as below
public function check_username($username){
$result = $this->registration_m->check_username_m($username);
if ($result) {
$this->form_validation->set_message('check_username', 'The %s field can not be the empty');
return false;
} else {
return true;
}
}
See differences in code
$this->session->set_flashdata('username', 'Username già in uso, riprovare.');
$this->form_validation->set_message('check_username', 'The %s field can not be the empty');
I have a form that I submit with jQuery ajax and have it being sent to a controller function called submit to validate and do any other tasks I need to with the form data. I'm trying to find out why my form validation library isn't showing an error when the username doesn't contain only lowercase letters and numbers.
$this->form_validation->set_rules('username', 'Username', 'trim|required|xss_clean|strtolower');
POST Value after form submission:
username TestingUSER
EDIT:
As far as I know it gets to the php server side properly.
PHP:
public function submit()
{
$output_status = 'Notice';
$output_title = 'Not Processed';
$output_message = 'The request was unprocessed!';
$this->form_validation->set_rules('username', 'Username', 'trim|required|xss_clean|strtolower');
$this->form_validation->set_rules('password', 'Password', 'trim|required|xss_clean');
$this->form_validation->set_rules('remember', 'Remember Me', 'trim|xss_clean|integer');
if ($this->form_validation->run() == TRUE)
{
}
else
{
$output_status = 'Error';
$output_title = 'Form Not Validated';
$output_message = validation_errors();
}
echo json_encode(array('output_status' => $output_status, 'output_title' => $output_title, 'output_message' => $output_message));
}
EDIT 2:
Based off of Sheikh answer. I am getting a response back that says "Unable to access an error message corresponding to your field name." It does say Form Not Validated for the title so the message isn't working.
public function check_username($str)
{
if (preg_match('#[0-9]#', $str) && preg_match('#[a-z]#', $str))
{
return TRUE;
}
$this->form_validation->set_message('username', 'This is not have an accepted value!');
return FALSE;
}
EDIT 3:
What I'm wanting to do is have it report back that there there are validation errors but not the specific errors in the pnotify response. However I do want it to display the specific errors under the form elements.
jQuery Code:
http://pastebin.com/1KehMJkh
Login Form:
http://pastebin.com/EfpBfbfN
I think you can use a callback function in your controller
public function check_username($str)
{
if (preg_match('#[a-z0-9]#', $str)) {
return TRUE;
}
$this->form_validation->set_message('check_username', 'This is not have an accepted value!');
return FALSE;
}
Validation rules for username
$this->form_validation->set_rules('username', 'Username', 'trim|required|xss_clean|callback_check_username');
You may like this too.
Hi there I am having a problem with my form validation, basically the problem is that I am getting a repeated view loaded if the validation fails, please see my code snippet,
else {
//the user is a new customer so we need to show them
//the card details form
$this->addViewData('returningCustomer', false);
$this->load->library('form_validation');
if($this->input->post('carddetails') == 'Submit') {
$this->form_validation->set_rules('inpcardtype', 'Card type', 'cardTypeCheck'); //custom callback
$this->form_validation->set_rules('inpcardnumber', 'Card number', 'required|trim|exact_length[16]');
$this->form_validation->set_rules('startmonth', 'Start month', 'trim|required');
$this->form_validation->set_rules('startyear', 'Start year', 'trim|required');
$this->form_validation->set_rules('endmonth', 'End month', 'trim|required');
$this->form_validation->set_rules('endyear', 'End year', 'trim|required');
$this->form_validation->set_rules('inpissuenumber', 'Issue number', 'trim|integer');
$this->form_validation->set_rules('inpccv', 'CCV Code', 'required|trim|exact_lenght[3]');
if($this->form_validation->run() == FALSE) {
$this->renderTemplate('cv/search/pf_shortlist.php', $this->viewData);
} else {
// validation is passed we need to safe the user details
// it is probable that we will need to hash the users card details
//#TODO: HASH USER CARD DETAILS LEAVE ONLY THE FINAL DIGITS
$this->load->model('checkout_model');
}
}
$this->renderTemplate('cv/search/pf_shortlist.php', $this->viewData);
basically if a condtion fails futher up the script a view is loaded with a form, the form is submitted and if validation fails the user is passed back to the form but is show the errors, however the original view is also present. Can I stop it doing this?
After
$this->renderTemplate('cv/search/pf_shortlist.php', $this->viewData);
You should do return; as after the else statement theres another view loading.#
//the user is a new customer so we need to show them
//the card details form
$this->addViewData('returningCustomer', false);
$this->load->library('form_validation');
if($this->input->post('carddetails') == 'Submit') {
$this->form_validation->set_rules('inpcardtype', 'Card type', 'cardTypeCheck'); //custom callback
$this->form_validation->set_rules('inpcardnumber', 'Card number', 'required|trim|exact_length[16]');
$this->form_validation->set_rules('startmonth', 'Start month', 'trim|required');
$this->form_validation->set_rules('startyear', 'Start year', 'trim|required');
$this->form_validation->set_rules('endmonth', 'End month', 'trim|required');
$this->form_validation->set_rules('endyear', 'End year', 'trim|required');
$this->form_validation->set_rules('inpissuenumber', 'Issue number', 'trim|integer');
$this->form_validation->set_rules('inpccv', 'CCV Code', 'required|trim|exact_lenght[3]');
if($this->form_validation->run() == FALSE) {
$this->renderTemplate('cv/search/pf_shortlist.php', $this->viewData);
return;// HERE
} else {
// validation is passed we need to safe the user details
// it is probable that we will need to hash the users card details
//#TODO: HASH USER CARD DETAILS LEAVE ONLY THE FINAL DIGITS
$this->load->model('checkout_model');
}
}
$this->renderTemplate('cv/search/pf_shortlist.php', $this->viewData);
return;