2

I've the following form validation running;

$this->form_validation->set_rules('pricing_group', 'Pricing Group', 'callback_pricing_group');

with the callback function:

public function pricing_group($pricing_group) {
        if ($pricing_group > 0) {
            return true;
        } else {
            $this->form_validation->set_message('pricing_group', 'Invalid Price Group Specified.');
            return false;
        }
    }

This is returning with the error:

"pricing_group":"Unable to access an error message corresponding to your field name Pricing Group.(pricing_group)"

I have also attempted to place the set_message function before the true/false checks took place. Note that the logic right now (just checking if it's greater than zero) is not anything like the intended final logic - it's just a basic example I'm putting in place to try and find out what the problem is.

Can anyone spot if I'm making some stupid mistake here? The only difference between this and my using the callback function before, is that this form validation is taking place within a model (as it'll be checking this value against the db), rather than within a controller. If I remove the callback_pricing_group rule and swap it to something like "numeric", it works fine.

Eoghan
  • 1,720
  • 2
  • 17
  • 35

3 Answers3

1

Finally figured this out after contacting the CI Dev team via Github. The documentation is a little unclear - so I've post the solution below.

Firstly, in-model validation does not work natively, and that's unfortunately a fact. Unless you want to extend the core libraries, it's not happening.

Instead, the form_validation functions must be called from the controller - and the validation functions themselves can sit within the model. So, using my question as an example, this would become;

Controller:

$this->form_validation->set_rules('pricing_group', 'Pricing Group', array('valid_pricing_group', array($this->pricing_group_model, 'valid_pricing_group')));

Note the nested array wrapping around the valid_pricing_group callback. Failing to nest this array and including the field name will cause the aforementioned "error message not found" problem.

Pricing Model:

public function valid_pricing_group($pricing_group) {
        if ($this->get_pricing_group($pricing_group) === false) {
            $this->form_validation->set_message('valid_pricing_group', 'Pricing group does not exist.');
            return false;
        }

        return true;
    }

Again, naming conventions are important. Note that the field names as used in arrays match up with the error message, and function name.

With this then, we can run validation - but again, it must be from the controller.

Controller:

if ($this->form_validation->run() === false) {
   var_dump($this->form_validation->error_array());
} else {
   // continue
}

This is the 'cleanest' approach available without extending any core libraries, or hacking around the problem. It does require some code duplication across controllers in the case of having a separate api/web controller - but as one small benefit, you can use JSON-expected field names for your API, while using 'user-friendly' field names for output on your web controller.

Hope this helps someone out in the future.

Eoghan
  • 1,720
  • 2
  • 17
  • 35
  • This helped. My problem was validating in the model. I moved the CB function to the Controller. The next issue was setting the function private. Corrected these two items and all was right in the Universe. – DanimalReks Dec 01 '20 at 02:16
0

Hi try with 'trim' before callback and get the parameter with null assigned like below. Because you didn't validating 'required'.So it might be a reason to return null from the callback. Also pass the field-name as parameter in callback function

$this->form_validation->set_rules('pricing_group', 'Pricing Group', 'trim|callback_pricing_group[pricing_group]');

public function pricing_group($pricing_group=0) {
    if ($pricing_group > 0) {
        return true;
    } else {
        $this->form_validation->set_message('pricing_group', 'Invalid Price Group Specified.');
        return false;
    }
}
Simbu Dev
  • 71
  • 8
0

I have tested the following codes in my project and it's working fine. Try it now, I'm 100% sure It will work.

Please make sure subclass_prefix in application/config/config.php. It should

$config['subclass_prefix'] = 'MY_';

to work following custom validation function.

If you already changed the subclass_prefix value. example ABC_, then your validation file should like this ABC_Form_validation.php in application/libraries

Your Controller

class Your_Controller extends CI_Controller{
    function Your_Function(){
        $this->load->library('form_validation');
        if($this->input->post()){
            if($this->form_validation->run('pricing_group_validation') == TRUE){ 
                    // success          
                _e($this->input->post());
            }else{
                _e($this->form_validation->error_array());
            }
        }
    }
}

application/config/form_validation.php

$config = array(   
    'pricing_group_validation' => array(
        array(
            'field' => 'pricing_group',
            'label' => 'Pricing Group',
            'rules' => 'trim|pricing_group'
        )
    )
);

application/libraries/MY_Form_validation.php

class MY_Form_validation extends CI_Form_validation{    
    function __construct($config = array()){
        parent::__construct($config);
        $this->CI =& get_instance();
        $this->_config_rules = $config;
    }
    public function pricing_group($pricing_group){
        if ($pricing_group > 0) {
            return true;
        } else {
            $this->CI->form_validation->set_message('pricing_group', 'Invalid Price Group Specified.');
            return false;
        }
    }
}
Anfath Hifans
  • 1,588
  • 1
  • 11
  • 20