Form validation custom message in codeigniter? - php

In codeigniter I have used codeigniter form validation library in many controller,
ex: -
$this->form_validation->set_rules('rank', 'Rank', 'required');
If form validation failed, Then it displays
"The Rank field is required."
Here I want to display custom message,One method I can follow is
$this->form_validation->set_message('required', '%s can not be blank');
If I using this method then I need to repeat this code in every controller wherever I am using "required" form validation method
My question is there is any method to declare this custom message in configure file and automatically use this custom message whenever I using form validation rule "required"?

If you want to permanently over-ride the error message just hard code it into the form_validation_lang.php file.
(Located at system/language/english)
It you want the choice the extend the form_validation class adding your custom required function and add the appropriate error message in the lang file.
For example;
class MY_Form_validation {
public function custom_required($str) {
if ( ! is_array($str)) {
return (trim($str) == '') ? FALSE : TRUE;
} else {
return ( ! empty($str));
}
}
}
Then in the lang file;
$lang['custom_required'] = "%s can not be blank.";

From the CI docs themselves:
"All of the native error messages are located in the following language file: language/english/form_validation_lang.php
To set your own custom message you can either edit that file, or use the following function:
$this->form_validation->set_message('rule', 'Error Message');"
http://codeigniter.com/user_guide/libraries/form_validation.html#settingerrors

class MY_Form_validation extends CI_Form_validation {
public function __construct()
{
parent::__construct();
}
function required_select($input)
{
$this->set_message('required_select','select %s');
return FALSE;
}
}
Works for me : )

Related

Unable to find custom callback validation rule (CodeIgniter 3 HMVC)

EDIT2: Scroll down for most up-to-date information!
In CodeIgniter 3, I recently moved callback rules across all of my controllers to application/libraries/MY_Form_validation.php to prevent code repetition etc., and to clean up.
Right now, they don't seem to be working anymore.
MY_Form_validation.php starts like this:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
class MY_Form_validation extends CI_Form_validation
{
public $CI;
function run($module = '', $group = '')
{
log_message('debug',"Now running the MY_Form_validation");
(is_object($module)) AND $this->CI = &$module;
return parent::run($group);
}
Then a whole list of callback function follows, all defined as public function callback_name(){}.
I also have one (in the same class) which checks if the provided user login information is correct (and thus, if the user can login etc.), but the form validation can't find the rule.
The error log looks like this:
INFO - 2016-06-23 13:33:18 --> Form Validation Class Initialized
DEBUG - 2016-06-23 13:33:18 --> Now running the MY_Form_validation
INFO - 2016-06-23 13:33:18 --> Language file loaded: language/english/form_validation_lang.php
DEBUG - 2016-06-23 13:33:18 --> Unable to find callback validation rule: check_database
The first DEBUG message indicates that MY_Form_validation is loaded (as its overwritten run() method is used, hence the debug logging), but it somehow can't find the callback functions clearly defined below.
I also included language file application/language/english/form_validation_lang.php with the following line:
$lang['form_validation_check_database'] = 'The password does not match the username. Try again.';, which it catches correctly (i.e. this message is displayed when performing the form validation), but it somehow cannot find the callback function itself.
EDIT: I checked to see if methods weren't inherited correctly:
public function __construct($rules = array())
{
$this->CI =& get_instance();
var_dump(get_class_methods($this));
The var_dump() does output the correct, full array of methods, both my own custom callbacks and the built-in ones.
EDIT2:
I read the system/libraries/Form_validation.php and investigated where the debug message occurs, which can be seen in this code sample (line 734-749) :
// Call the function that corresponds to the rule
if ($callback OR $callable !== FALSE)
{
if ($callback)
{
if ( ! method_exists($this->CI, $rule))
{
log_message('debug', 'Unable to find callback validation rule: '.$rule);
$result = FALSE;
}
else
{
// Run the function and grab the result
$result = $this->CI->$rule($postdata, $param);
}
}
It seems as though callbacks are only looked for in the main CI object, but not in the form validation library itself. I could add some hacky exceptions that would pick the library callbacks, but I doubt that that's the best thing to do and I guess I'm overlooking something simple...
If any additional info is required, please let me know.
Alright, I found out...
Apparently, as soon as you move callback functions to MY_Form_validation.php, they are actually built-in validation rules, and no longer act as callbacks.
When setting form rules, I still had the callback_ prefix applied, which makes the Form_validation library look for the rule in the normal CI object (i.e. in the controller) rather than the (MY_)Form_validation class.
The fix for me was to simply remove this prefix from the applied validation rule settings. Now it finds the 'callback' functions correctly.
Please Try This
<?php
class Form extends CI_Controller {
public function index()
{
$this->load->helper(array('form', 'url'));
$this->load->library('form_validation');
$this->form_validation->set_rules('username', 'Username', 'callback_username_check');
$this->form_validation->set_rules('password', 'Password', 'required');
$this->form_validation->set_rules('passconf', 'Password Confirmation', 'required');
$this->form_validation->set_rules('email', 'Email', 'required|is_unique[users.email]');
if ($this->form_validation->run() == FALSE)
{
$this->load->view('myform');
}
else
{
$this->load->view('formsuccess');
}
}
public function username_check($str)
{
if ($str == 'test')
{
$this->form_validation->set_message('username_check', 'The {field} field can not be the word "test"');
return FALSE;
}
else
{
return TRUE;
}
}
}
?>

Validation callback never calling function

I have the following form validation:
$this->CI->form_validation->set_rules(
'email', 'lang:email', 'callback_validate_email');
In the same controller I have the following function (excuse the debugging here):
public function validate_email($string) {
echo 'test val';
exit;
$valid = $this->CI->force_model->validate_email($string);
if(!$valid) {
$this->CI->form_validation->set_message('validate_email', 'lang:email');
return false;
} else {
return true;
}
}
My issue is, the function is never called via the callback. Could anyone suggest what the issue might be here?
I saw someone else having this problem, and strangely they were also using $this->CI->...
Their solution was to extend the Validation library and add your custom validation callback there. More info here: CodeIgniter Validation in Library does not accept callback
Does it work if you set the form validation rules using $this->form_validation->... instead? E.g.
$this->form_validation->set_rules(
'email', 'lang:email', 'callback_validate_email');

Same function for jquery and php validation

So I have this problem. I'm doing a server side validation and a jquery validation.
In server side validation what I do is to use codeigniter's form_validation library, more specifically:
$this->form_validation->set_rules('documentn', 'Passport number', 'required|min_length[7]|max_length[20]|is_natural|callback_checkDocAndUser');
which needs a return true or return false.
I have this user edit form, to change user data. But there are some restrictions... user when stored in database has a unique passport number. I need to be able to change this passport number if it's wrong... but passport numbers should not be repeated on the database.
This is the php function that is called from callback_checkDocAndUser :
public function checkDocAndUser(){
if ((isset($_POST['documentn'])) && (isset($_POST['id']))) {
$dn = UserManager::getInstance()->checkUserDocument($_POST['documentn'],$_POST['id']);
if ($dn) {
//passport belongs to the user
echo "true";
// return true;
}else{
//does the passport entered belong to another user?
$exists = UserManager::getInstance()->getByDocument($_POST['documentn']);
if (!$exists) {
//passport belongs to another user
echo "true";
// return true;
}else{
//passport number is free to use
echo "false";
// return false;
}
}
}
}
As you can see I put some "echo" in the functions. This is because I want to use the same function for a jQuery validation (which needs echo, doesn't work with "return").
documentn: {
required: true,
minlength: 7,
maxlength: 20,
remote: {
url: '/admin/checkDocAndUser',
type: 'POST',
data: {
id: function(){
return $('#id').val();
}
}
}
},
So how can I use the same function for both kind of validations...? is there a way to make jquery function receive a return..or codeigniter's function to receive an echo?
I do the same thing in my CodeIgniter projects and the solution is quite simple. The following answer is generically named where you only need to add your validation logic.
This answer follows the DRY principle where your validation code is not repeated, as well as CodeIgniter structure.
This MODEL does the actual validation for both CodeIgniter (server-side) validation and jQuery Validate (client-side) remote...
// file name 'models/demo_model.php'
class Demo_model extends CI_Model {
public function check_demo($params)
{
// insert your validation logic here...
// the entirety of your validation logic, check the DB, etc.
// if it passes validation
return TRUE;
// if it fails validation
return FALSE;
}
}
This CONTROLLER is only called by client-side remote for jQuery Validation...
// file name 'controllers/demo.php'
class Demo extends CI_Controller {
public function remote_demo($params = FALSE)
{
// call the Model to do the actual validation
$valid = $this->demo_model->check_demo($params);
if ($valid)
{
echo 'true'; // passes validation
}
else
{
echo 'false'; // fails validation
}
}
}
This LIBRARY is only used for server-side validation by CodeIgniter...
// file name 'libraries/MY_Form_validation.php'
class MY_Form_validation extends CI_Form_validation {
public function __construct()
{
parent::__construct();
$this->ci =& get_instance();
}
public function demo_check($params)
{
$this->ci->form_validation->set_message('demo_check', 'The %s is incorrect.');
// call the Model to do the actual validation
return $this->ci->demo_model->check_demo($params);
}
}
The way it's organized, you'll have ONE centrally located validation function residing with your CodeIgniter Models. I chose Models as the central location because the code is primarily interacting with the database.
The following uses the same Model function for both kinds of validation.
Server-side CodeIgniter validation: Calls the Model from MY_Form_validation and the Model will return TRUE or FALSE back to your other CodeIgniter Controllers as per your CodeIgniter validation rules.
Client-side jQuery Validate remote: Calls the Model from the Controller and the Model will return TRUE or FALSE back to the Controller. Then the Controller function will echo true or false based on this boolean response from the Model.
Validation functions always need to return a boolean value.
In your controller, try to retrieve the return value of the validation methods and echo "true" or "false" there.
Put an exit at the end of your function.
EDIT:
If you want to use the same set of validations for both client and server side validation, divide your call to two functions, one which handles client and the another which handles server. check the following code:
In you jquery function call url - admin/validate_form_client
function validate_form_client(){
$op = $this->checkDocAndUser($_POST['documentn'],$_POST['id']);
echo $op;
exit;
}
function validate_form_server(){
if ((isset($_POST['documentn'])) && (isset($_POST['id']))) {
return $this->checkDocAndUser($_POST['documentn'],$_POST['id']);
}
}
public function checkDocAndUser($documentn,$id){
$dn = UserManager::getInstance()->checkUserDocument($documentn,$id);
if ($dn) {
//id belongs to the user
return true;
}else{
//does the id entered belong to another user?
$exists = UserManager::getInstance()->getByDocument($documentn);
if (!$exists) {
// id number belongs to another user
return "true";
}else{
//id number is free to use
return "false";
}
}
}
}
Note: the given function names are just for example. please follow standard practice in the variable and function naming conventions.

How can I pass validationErrors from controller to a view?

Well I have set validationErrors for login in my UsersController:
public function login() {
if ($this->request->is('post')) {
$this->User->set($this->request->data);
if ($this->User->validates() && $this->Auth->login()) {
$this->set('ui', $this->Auth->user('id'));
$this->Session->setFlash(__('Loged in!'), 'flash_success');
$this->redirect($this->Auth->redirect());
} else {
$errors = $this->User->validationErrors;
}
}
}
Now how can I use $error in my view or as an element to be listed above my form?
Plz help I have searched a lot, but the answers were for old CakePHP, and I am using CakePHP 2.3.8.
Validation errors are available in the view automatically
There is no action required to get validation errors in the view, as they are a property of the view class. They can be inspected simply with:
debug($this->validationErrors);
In the view.
But you probably don't need to access them
Note however that it's not normal to need to look at this property directly. Using the form helper errors are displayed automatically, or you can generate errors individually
if ($this->Form->isFieldError('email')) {
echo $this->Form->error('email');
}

Limited validation for edit form in codeigniter

I am using modular MVC with codeigniter. I have a module playlist in which I have a admin controller and I am having a private $rules variable for setting the form validation rules.
I have both create and edit functions in the same file and validating both the forms (add,edit which are also created dynamically from only one file form.php).
$this->load->library('form_validation');
$this->form_validation->set_rules($this->rules);
$this->form_validation->set_error_delimiters(' <p class="error">', '</p>');
These are used in both create and edit functions. some of the fields i dont want to validate in edit mode. Should I need to create different private rules for both of them or is there any better way to handle this in codeigniter since I am new to it. I want to remove validation for FILE tag as user dont need to upload at edit mode.
Thanks
Here is an answer from the CI forums (original link).
You can define the rules for create/edit using some form of heirachy, then;
<?php
$this->form_validation->set_group_rules('createModule');
$this->form_validation->set_group_rules('editModule');
if($this->form_validation->run() == FALSE) {
// whatevere you want
}
?>
Or, you could do this;
<?php
// This will validate the 'accidentForm' first
$this->form_validation->set_group_rules('createModule');
if($this->form_validation->run() == FALSE) {
// whatevere you want
}
// Now we add the 'locationForm' group of rules
$this->form_validation->set_group_rules('editModule');
// And now we validate *both* sets of rules (remember that the createModule rules are still
// there), but it doesn't necessarily matter, since it will simply redo the 'createModule'
// validation while also doing the 'editModule' validation
if($this->form_validation->run() == FALSE) {
// whatevere you want
}
?>
Below is the code for the extended Form_validation class, saved in the application libraries folder as MY_Form_validation.php
<?php
class MY_Form_validation extends CI_Form_validation {
/**
* Set Rules from a Group
*
* The default CodeIgniter Form validation class doesn't allow you to
* explicitely add rules based upon those stored in the config file. This
* function allows you to do just that.
*
* #param string $group
*/
public function set_group_rules($group = '') {
// Is there a validation rule for the particular URI being accessed?
$uri = ($group == '') ? trim($this->CI->uri->ruri_string(), '/') : $group;
if ($uri != '' AND isset($this->_config_rules[$uri])) {
$this->set_rules($this->_config_rules[$uri]);
return true;
}
return false;
}
}
?>

Categories