Reputation: 87
I am unable to get the callable form validation feature of CodeIgniter 3 to work when the validation rules are placed in a separate config file.
I am getting the following error message:
A PHP Error was encountered
Severity: Notice
Message: Undefined property: CI_Config::$form_validation_callback_library
The config file with the form validation rules are as follows (config/fvalidation.php):
$config['client_details'] = array(
array(
'field' => 'client_abn',
'label' => 'Client ABN',
'rules' => array('trim', 'required', array('abn_callable', array($this->form_validation_callback_library, 'abn_check'))),
'errors' => array('abn_callable' => 'Invalid ABN has been entered %s.')
)
);
The form validation class attempting to be called is (i.e. $this->form_validation_callback_library):
class Form_validation_callback_library
{
public function abn_check()
{
$this->load->library('abn_validator');
$abn = $this->input->post_get('abn', TRUE);
if (!$this->abn_validator->isValidAbn($abn)) {
return FALSE;
}
return TRUE;
}
}
The controller is:
$this->config->load('fvalidation');
$validation_rules = $this->config->item('client_details');
$this->form_validation->set_rules($validation_rules);
if ($this->form_validation->run() == FALSE) {
// show form
} else {
// process form data
}
Any help would be greatly appreciated.
Cheers, VeeDee
Upvotes: 1
Views: 4903
Reputation: 646
This is a most common problem we face when we run custom form validation in CI. Whether the callback function is in the same controller or it is in the a library of callback function we need to pass the accessible object of the class containing the callback function. So when your run the
$callable_validations = new Form_validation_callback_library();
$this->form_validation->run($callable_validations)
Upvotes: 1
Reputation: 47
I've simply do (config/form_validation.php):
$CI =& get_instance();
$CI->load->model('form_validation_callback_library');
$config['client_details'] = array(
array(
'field' => 'client_abn',
'label' => 'Client ABN',
'rules' => array('trim', 'required', array('abn_callable', array($CI->form_validation_callback_library, 'abn_check'))),
'errors' => array('abn_callable' => 'Invalid ABN has been entered %s.')
)
And it works to me...
I'm running on Codeigniter 3.0.4
Upvotes: 0
Reputation: 328
I did something similar to Vidura, but extended the Form Validation library by adding MY_Form_validation.php with the following code
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class GS_Form_validation extends CI_Form_validation {
public function set_rules($field, $label = '', $rules = array(), $errors = array())
{
if (is_array($rules))
{
foreach ($rules as &$rule)
{
if (is_array($rule))
{
if (is_array($rule[1]) and is_string($rule[1][0]))
{
// handles rule like ['password_check', ['library:passwords', 'check_valid_password']]
// You would set_message like $this->form_validation->set_message('password_check', 'Incorrect password');
// The advantage of defining the rule like this is you can override the callback functions error message
list ($load_type, $load_name) = explode(":", $rule[1][0]);
$CI =& get_instance();
$CI->load->$load_type($load_name);
$rule[1][0] = $CI->$load_name;
}
else if (is_string($rule[0]))
{
// handles rule like ['library:password', 'check_valid_password']
// You would set_message like $this->form_validation->set_message('check_valid_password', 'Incorrect password');
list ($load_type, $load_name) = explode(":", $rule[0]);
$CI =& get_instance();
$CI->load->$load_type($load_name);
$rule[0] = $rule[1];
$rule[1] = [$CI->$load_name, $rule[1]];
}
}
}
}
return parent::set_rules($field, $label, $rules, $errors);
}
}
Then you can define callbacks to library functions like:
$this->form_validation->set_rules(['library:passwords', 'check_valid_password']);
Where passwords is the library and check_valid_password is the method.
Upvotes: 0
Reputation: 87
Looks like this is not possible currently on CodeIgniter 3.
I have created a crude workaround.. so please go ahead an improve it because it doesn't look pretty :)
Update the config file like so (/config/fvalidation.php):
$config['client_details'] = = array(
array(
'field' => 'client_abn',
'label' => 'Client ABN',
'rules' => array('trim', 'required', array('abn_callable', array("library:form_validation_callback_library", 'abn_check'))),
'errors' => array('abn_callable' => 'Invalid %s has been entered .')
)
);
Note the following line in the config file above as we will be using them as flags in the controller code:
array('abn_callable', array("library:form_validation_callback_library", 'abn_check'))
The Library is pretty much the same except we load the instance (/libraries/Form_validation_callback_library.php):
class Form_validation_callback_library
{
private $_CI;
function Form_validation_callback_library() {
$this->_CI =& get_instance();
log_message('info', "Form_validation_callback_library Library Initialized");
}
public function abn_check($abn)
{
$this->_CI->load->library('abn_validator');
if (!$this->_CI->abn_validator->isValidAbn($abn)) {
return FALSE;
}
return TRUE;
}
}
In the controller we load the library (/controllers/Foo.php):
// load the config file and store
$this->config->load('fvalidation', TRUE);
$rule_dataset = $this->config->item('client_details', 'fvalidation');
// search and load the 'callable' library
foreach ($rule_dataset as $i => $rules) {
if (isset($rules['rules'])) {
foreach ($rules['rules'] as $k => $rule) {
if (is_array($rule) && preg_match("/_callable/",$rule[0]) && isset($rule[1][0])) {
list ($load_type, $load_name) = explode(":", $rule[1][0]);
// load the library
$this->load->$load_type($load_name);
$rule_dataset[$i]['rules'][$k][1][0] = $this->$load_name;
}
}
}
}
// set the rules
$this->form_validation->set_rules($rule_dataset);
// load the form
if ($this->form_validation->run() == FALSE) {
// show form
} else {
// process form data
}
Upvotes: 0
Reputation:
I would use codeigniter callback example below callback
<?php
class Example extends CI_Controller {
public function index() {
$this->load->library('form_validation');
$this->form_validation->set_rules('client_abn', 'ABN Number', 'required|callback_checkabn');
if ($this->form_validation->run() == FALSE) {
$this->load->view('something');
} else {
// Redirect to success page i.e login or dashboard or what ever
redirect('/'); // Currently would redirect to home '/'
}
}
public function checkabn() {
$this->load->library('abn_validator');
$abn = $this->input->post('abn');
if (!$this->abn_validator->isValidAbn($abn)) {
$this->form_validation->set_message('checkabn', 'Invalid ABN has been entered %s.');
return FALSE;
} else {
return TRUE;
}
}
}
And on your view in or above form add
<?php echo validation_errors('<div class="error">', '</div>'); ?>
<form action="<?php echo base_url('example');?>" method="post">
<input type="text" name="client_abn" placeholder="" value="" />
</form>
Upvotes: 1