Part of the EllisLab Network
   
1 of 4
1
CI 2.1.0 form validation external callbacks via the newly available param
Posted: 28 November 2011 10:13 PM   [ Ignore ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  1235
Joined  05-17-2009

I’ve done my share of bitching about CI lately, nevertheless, I thought I’d share a little code that makes working with bigger applications more manageable. CI does not by itself accommodate external callbacks for form validation, and models are a great place to store them, since the CI super object is accessible from inside them.

What I’ve done is created a generic external_callbacks method in MY_Controller. The method explodes the comma seperated string that contains the model name, method, and any arguments that should be passed along as an array.

Here is the method:

/*
 * external_callbacks method handles form validation callbacks that are not located
 * in the controller where the form validation was run.
 *
 * $param is a comma delimited string where the first value is the name of the model
 * where the callback lives. The second value is the method name, and any additional 
 * values are sent to the method as a one dimensional array.
 *
 * EXAMPLE RULE:
 *  callback_external_callbacks[some_model,some_method,some_string,another_string]
 */
public function external_callbacks$postdata$param )
{
 $param_values 
explode','$param ); 

 
// Make sure the model is loaded
 
$model $param_values[0];
 
$this->load->model$model );

 
// Rename the second element in the array for easy usage
 
$method $param_values[1];

 
// Check to see if there are any additional values to send as an array
 
if( count$param_values ) > )
 
{
  
// Remove the first two elements in the param_values array
  
array_shift$param_values );
  
array_shift$param_values );

  
$argument $param_values;
 
}

 
// Do the actual validation in the external callback
 
if( isset( $argument ) )
 
{
  $callback_result 
$this->$model->$method$postdata$argument );
 
}
 
else
 
{
  $callback_result 
$this->$model->$method$postdata );
 
}

 
return $callback_result;
}

/*******************************************************************/ 
 Signature 

Brian
Brian’s Web Design - Temecula
Community Auth - CodeIgniter Authentication Application

Profile
 
 
Posted: 19 December 2011 03:24 PM   [ Ignore ]   [ # 1 ]  
Grad Student
Avatar
Rank
Total Posts:  83
Joined  05-17-2008

Thank you Brian for this simple workaround!

I’ve updated my old method to reflect that it is unmaintained and recommend yours instead.
http://codeigniter.com/wiki/MY_Form_validation_-_Simple_Callbacks_into_Models

 Signature 

janogarcia.es, @janogarcia
margenn - web studio, San Sebastian (Spain) $CI = new $class();

Profile
 
 
Posted: 19 December 2011 09:38 PM   [ Ignore ]   [ # 2 ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  1235
Joined  05-17-2009
janogarcia - 19 December 2011 03:24 PM

Thank you Brian for this simple workaround!

I’ve updated my old method to reflect that it is unmaintained and recommend yours instead.
http://codeigniter.com/wiki/MY_Form_validation_-_Simple_Callbacks_into_Models

Thank you to you too. I used your solution for a long time, but now that CI allows callbacks to have parameters, it is easy to have external callbacks in models or libraries. I still prefer models.

 Signature 

Brian
Brian’s Web Design - Temecula
Community Auth - CodeIgniter Authentication Application

Profile
 
 
Posted: 20 December 2011 12:18 AM   [ Ignore ]   [ # 3 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  238
Joined  05-05-2009

do you mind posting a short code/demo how this works? I understand the idea - just not sure how I implement it?

Profile
 
 
Posted: 20 December 2011 02:08 AM   [ Ignore ]   [ # 4 ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  1235
Joined  05-17-2009
theshiftexchange - 20 December 2011 12:18 AM

do you mind posting a short code/demo how this works? I understand the idea - just not sure how I implement it?

For instance, when setting form validation rules:

$this->form_validation->set_rules('required|integer|callback_external_callbacks[formval_callbacks,test]'); 

This means that the validation method named “test” is located in the model formval_callbacks.php. You could have also passed in other parameters, but I’m just giving the most basic example of usage.

This is the formval_callbacks.php model:

class Formval_callbacks extends CI_Model {

 
public function test$value )
 
{
  
if( $value )
  

          $this
->form_validation->set_message(
                  
'external_callbacks'
                  
'Supplied number must not be 0'
          
);
          return 
FALSE;
  
}

  
return $value;
 
}

This simple callback simply checks to see if the value is greater than zero, and if not, sets an error message. It’s really that simple, and now you don’t have to have a single form validation config file that has hundreds of callbacks in it. If you have a big site with lots of callbacks, separating them into groups is really essential.

 Signature 

Brian
Brian’s Web Design - Temecula
Community Auth - CodeIgniter Authentication Application

Profile
 
 
Posted: 20 December 2011 12:25 PM   [ Ignore ]   [ # 5 ]  
Lab Assistant
RankRank
Total Posts:  159
Joined  08-15-2010

I’ve been using janogarcia’s method for a long time. This is indeed an improved version.

Good job.

Profile
 
 
Posted: 20 December 2011 01:18 PM   [ Ignore ]   [ # 6 ]  
Grad Student
Avatar
Rank
Total Posts:  83
Joined  05-17-2008

For those visiting this thread:

Dont’t forget to vote for the feature request “Callbacks into models” on UserVoice
http://codeigniter.uservoice.com/forums/40508-codeigniter-reactor/suggestions/1292335-callbacks-into-models

 Signature 

janogarcia.es, @janogarcia
margenn - web studio, San Sebastian (Spain) $CI = new $class();

Profile
 
 
Posted: 20 December 2011 01:21 PM   [ Ignore ]   [ # 7 ]  
Grad Student
Avatar
Rank
Total Posts:  83
Joined  05-17-2008

skunkbad, it would be great if you host this snippet on Gist https://gist.github.com/, that way we could monitor any updates/changes of the code, as well as copying/forking it.

Thanks!

 Signature 

janogarcia.es, @janogarcia
margenn - web studio, San Sebastian (Spain) $CI = new $class();

Profile
 
 
Posted: 20 December 2011 01:59 PM   [ Ignore ]   [ # 8 ]  
Summer Student
Total Posts:  9
Joined  11-18-2009
skunkbad - 20 December 2011 02:08 AM
theshiftexchange - 20 December 2011 12:18 AM

do you mind posting a short code/demo how this works? I understand the idea - just not sure how I implement it?

For instance, when setting form validation rules:

$this->form_validation->set_rules('required|integer|callback_external_callbacks[formval_callbacks,test]'); 

This means that the validation method named “test” is located in the model formval_callbacks.php. You could have also passed in other parameters, but I’m just giving the most basic example of usage.

This is the formval_callbacks.php model:

class Formval_callbacks extends CI_Model {

 
public function test$value )
 
{
  
if( $value )
  

          $this
->form_validation->set_message(
                  
'external_callbacks'
                  
'Supplied number must not be 0'
          
);
          return 
FALSE;
  
}

  
return $value;
 
}

This simple callback simply checks to see if the value is greater than zero, and if not, sets an error message. It’s really that simple, and now you don’t have to have a single form validation config file that has hundreds of callbacks in it. If you have a big site with lots of callbacks, separating them into groups is really essential.

Tested with wiredesignz / codeigniter-modular-extensions-hmvc ?
I try for it, but seem nothing executed.

 

Profile
 
 
Posted: 20 December 2011 02:32 PM   [ Ignore ]   [ # 9 ]  
Lab Assistant
RankRank
Total Posts:  159
Joined  08-15-2010
kodai - 20 December 2011 01:59 PM

Tested with wiredesignz / codeigniter-modular-extensions-hmvc ?
I try for it, but seem nothing executed.

Did you load your model correctly? i.e. module/model path

Profile
 
 
Posted: 20 December 2011 03:11 PM   [ Ignore ]   [ # 10 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  2537
Joined  02-19-2009

Hi Brian,

Thank you for your contribution!
Does this still work if you need to use the brackets, [], in your own callback?

Like if I had a rule, “must_contain”, which I like to use to validate radio buttons, etc., and requires the arguments to be made in the brackets so it can get passed to the validation function?

$this->form_validation->set_rules('a_field''A Field''trim|must_contain[one|two|three]');

function 
must_contain($str$args)
{
  $args 
explode('|'$args);
  
$this->set_message('must_contain''Please make a valid selection from %s.');
  return (
in_array($str$args));

Also, is there a reason why you didn’t extend the form validation library with this and extended the controller instead?

 Signature 
Profile
 
 
   
1 of 4
1