Part of the EllisLab Network
   
 
Problem extending Form Validation class
Posted: 08 March 2010 08:58 AM   [ Ignore ]  
Summer Student
Total Posts:  7
Joined  01-19-2010

Hi guys,

My first post! so be nice!

The issue I am having is with extending the CI_Form_Validation class. I have a few extra validation methods that i need to integrate into my form validation, so thought, rather than using callbacks, i would try and the extend the class….

Now, i believe i have extended the class fine, but when calling any function on the class from my form validation array, it just doesn’t work. It doesn’t pick up the method at all.

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class 
MY_Formvalidation extends CI_Form_Validation {
  
  
var $CI;
  
  
/**
   * Contructor
   * Extends core Form Validation class. Sets CodeIgniter super object.
   * @param array $config
   * @author Craig Barber
   * @version 1.0
   */
   
 
function __construct()
  
{
    parent
::CI_Form_Validation();
    
$this->CI =& get_instance();
  
}

  
/**
   * Valid date
   * Checks if input is a valid date.
   * @param string $str
   * @return bool
   * @author Craig Barber
   * @version 1.0
   */
  
function valid_date($str)
  
{
    
if (preg_match('/([0-3][0-9])\/([0-9]{1,2})\/([1-2][0-9]{3})/'$str$date)):
      return 
checkdate($date[2]$date[1]$date[3]);
    else:
      return 
false;
    endif;
  
}
  
  
/**
   * Valid date
   * Checks if input matches a value.
   * @param string $str, string $val
   * @return bool
   * @author Craig Barber
   * @version 1.0
   */
  
function same_as($str$val)
  
{
    
if ($str === $this->CI->input->post($val)) return true;
    else return 
false;
  
}
 
  
  
/**
   * Check num of entries
   * Checks if input matches a value.
   * @param string $str, string $val
   * @return bool
   * @author Craig Barber
   * @version 1.0
   */
  
function check_num_entries($str){
      
if($str >= 4){
        
return true;
    
}else return false;    
  
}
  
  
function checkPayment($str$val){
      
if($this->CI->input->post($val) == 'regular_payments'){
      
//now we need to check whether the payment frequency is set when making regular payments
    
if($str == '0'){
        
//then return false if payment frequency is left blank
        
return false;
    
}else{
        
return true
    
}
  }
}
?> 

Now, I have my form validation in a config array, which sets the validation rules for the whole entire site. This array is stored on a php page named form_validation.php which is held in my config folder. Below is the section for the page which I am trying to write the extra form function for, all the functionality works apart from where i am trying to call my added function named checkPayment.

'payment/create' => array(
    array(
      
'field' => 'nbx_payment_amount',
      
'label' => 'Payment amount',
      
'rules' => 'required|numeric'),
    array(
      
'field' => 'nbx_payment_type',
      
'label' => 'Payment type',
      
'rules' => 'required'),
    array(
      
'field' => 'nbx_payment_date',
      
'label' => 'Payment date',
      
'rules' => 'required|valid_date'),
    array(
      
'field' => 'nbx_payment_number',
      
'label' => 'Number of payments',
      
'rules' => 'required|numeric'),
    array(
      
'field' => 'nbx_payment_frequency',
      
'label' => 'Payment frequency',
      
'rules' => 'checkPayment[nbx_payment_type]')), 

I have tried adding the extended library directly in my controller as seen below:

$this->load->library('MY_Formvalidation'); 

But this doesn’t seem to do anything either, I have also added the library to my autoload file to automatically load the library, no joy there either.

My first question really, is an you extend the CI Form Validation library, and call those extra functions from a validation array? All the examples I have seen on the web do not show this functionality working with a validation array, but setting up the rule in the controller itself (which I have also tried)

Does anyone know of the best way to get around this problem? I’m even residing to the fact that I might have to use callbacks, which is fine, but I couldn’t seem to get that working either!!!

It’s got to the point where I just want a fix….any help welcome!

thanks guys

Craig

Profile
 
 
Posted: 08 March 2010 09:33 AM   [ Ignore ]   [ # 1 ]  
Grad Student
Rank
Total Posts:  34
Joined  07-10-2009

I’m having exactly the same problem (extending CI_Form_validation breaks the whole library), and haven’t found a solution yet.

Using PHP 5.3.1.

Anyone?

 Signature 

cool smile

Profile
 
 
Posted: 08 March 2010 10:09 AM   [ Ignore ]   [ # 2 ]  
Grad Student
Rank
Total Posts:  34
Joined  07-10-2009

Update: it seems that CI_Form_validation is nicely initialized when you remove the constructor of your extending class.

 Signature 

cool smile

Profile
 
 
Posted: 08 March 2010 11:22 AM   [ Ignore ]   [ # 3 ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  1438
Joined  03-10-2009
class MY_Form_Validation extends CI_Form_validation {

    
function MY_Form_Validation()
    
{
        parent
::CI_Form_validation();
    
 Signature 

Isset | Isset Public Code Repo | Simple Message Library | Session Profiler for CI2.0 | CI session issues in IE

Profile
 
 
Posted: 08 March 2010 01:26 PM   [ Ignore ]   [ # 4 ]  
Summer Student
Total Posts:  7
Joined  01-19-2010

noxie, Piet, thanks for your responses!

I really don’t know what’s going on with this. There must be something that I have set up differently to cause this, because I have tried both the routes you suggested with no success!

My form_validation.php file with my validation array in is loaded in on autoload page. Do I need to load in my newly created extension of the validation class somewhere? or call my function on the extended class directly from my controller?

any help would be great guys! i’m going out of mind, going round in circles on this one!

cheers again

Craig

Profile
 
 
Posted: 08 March 2010 05:03 PM   [ Ignore ]   [ # 5 ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  1835
Joined  12-08-2009

n0xie was pointing out that your file and class should be MY_Form_Validation, not MY_Formvalidation. Also, you should still be loading form_validation… Your class is automatically loaded by CI if it exists.

 Signature 

@basdflasjk | BitAuth: Authentication and Role-based Permissions | Session Library Replacement


Please read the User Guide! (Upgrading from a previous version?)

Profile
 
 
Posted: 08 March 2010 05:19 PM   [ Ignore ]   [ # 6 ]  
Summer Student
Total Posts:  7
Joined  01-19-2010

Hey noctrum,

Thanks for posting. Well, i have tried renaming my class to MY_Form_Validation as well, but that still gives me no joy.

Could there be anything else that i am missing, or, in theory, should this work?

thanks

Craig

Profile
 
 
Posted: 09 March 2010 06:04 AM   [ Ignore ]   [ # 7 ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  1438
Joined  03-10-2009

Did you name your file like this?

MY_Form_validation.php 

Also you should autoload the ‘normal’ form_validation library. CI will automagically load you MY_Form_validation.

 Signature 

Isset | Isset Public Code Repo | Simple Message Library | Session Profiler for CI2.0 | CI session issues in IE

Profile
 
 
Posted: 09 March 2010 07:31 AM   [ Ignore ]   [ # 8 ]  
Grad Student
Rank
Total Posts:  34
Joined  07-10-2009

Still no luck for me.

My extended class system/application/libraries/ci_extend_Form_validation.php:

class ci_extend_Form_Validation extends CI_Form_validation {

    
function ci_extend_Form_Validation()
    
{    
        parent
::CI_Form_validation();        
    
}

In system/application/config/config.php I’ve set

$config['subclass_prefix''ci_extend_'

Very weird.

While debugging some stuff with log_message() and checking my log files, I can confirm that both constructors are being ran (from CI_Form_validation and ci_extend_Form_Validation). But, the CI_Form_validation class just doesn’t work.

EDIT: found some more information.

It seems that the validation rules aren’t loaded when extending the class if you’re using a config file with the rules in it. The rules are loaded from the config file, in the constructor of CI_Form_validation:

function CI_Form_validation($rules = array())
{    
    
/* snip */

    // Validation rules can be stored in a config file.
    
$this->_config_rules $rules;
    
    
/* snip */

But I can’t understand how those rules are passed to the constructor… Anybody?

EDIT: I’ve found the problem cheese  !

The loader class of CI checks for a corresponding config file when loading libraries. This is done at _ci_init_class() in CI_Loader. That all goes well, and the $config array defined at system/application/config/form_validation.php is passed to the extended class, NOT to CI_Form_validation.

So, we need to pass the $config array from our extended class to CI_Form_validation:

class ci_extend_Form_Validation extends CI_Form_validation {

    
function ci_extend_Form_Validation($config)
    
{    
        parent
::CI_Form_validation($config);        
    
}

That ‘fixes’ the problem for me. I can imagine this has to be done for every CI library that ‘supports’ configuration in a file while extending that library (f.e. CI_Email). I’m an experienced developer, but quite a newb at object oriented stuff. So, if anybody has a more decent solution, please post!

 Signature 

cool smile

Profile
 
 
Posted: 10 March 2010 11:53 AM   [ Ignore ]   [ # 9 ]  
Summer Student
Total Posts:  7
Joined  01-19-2010

thePiet!!

Good work mate, I have fixed it too!!

You’re right, i don’t know why i didn’t think of that! The extended class obviously needs the config array containing our validation rules to be able to reference to our newly created functions!!

Also, I hadn’t been COMPLETELY strict with my naming. The CI default form validation class is actually ‘Form_validation’ where I was extending ‘Form_Validation’

Drat, blast, christ and all the other swears under the earth!!! haha, you have released a lot of stress and anger!

cheers the Piet, at least we learned the hard way on extending CI classes eh?

PS, your OOP looks fine on your construct ; )

cheers again everyone!

Is there a way to solve this thread or close it?

Profile
 
 
Posted: 17 March 2010 03:51 PM   [ Ignore ]   [ # 10 ]  
Grad Student
Rank
Total Posts:  34
Joined  07-10-2009

Lol thank you BarberCraig. Don’t know if there’s any way to solve / close a thread, maybe prepend [Solved] or something to the thread title.

Cheers!

 Signature 

cool smile

Profile
 
 
Posted: 09 July 2010 07:04 PM   [ Ignore ]   [ # 11 ]  
Summer Student
Total Posts:  8
Joined  07-09-2010

I have the same problem and I’ve already tried your solution, but it doesn’t works yet. I’m using HMVC extension with CI 1.7 (last released) & php 5.3, I don’t have any idea if that affects.

This is MY_Form_validation.php

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
class 
MY_Form_validation extends CI_Form_validation{
    
    
function MY_Form_validation($config = array()){
        parent
::CI_Form_Validation($config);
        
$this->_config_rules $config;
        
log_message('debug''MY_Form_validation extensión de clase - inicializada');
    
}
    
        
/*
          this is the function that I added for the callback's in HMVC
        */
    
function run($module ''$group ''){
        log_message
('debug''Se ejecuta función para [CALLBACK] '.$module.' - '.$group);
        (
is_object($module)) AND $this->CI =& $module;
        return 
parent::run($group);
    
}

    
function mysql_date($str){
        log_message
('debug''Se ejecuta la función *****');
        
$pattern '^([1-3][0-9]{3,3})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$';
        
$this->set_message('mysql_date'"%s contains an invalid response");
        return 
preg_match($pattern$str);
    
}
}
/* End of file MY_Form_validation.php */
/* Location: ./system/application/libraries/MY_form_validation.php */ 

And my rule

$this->form_validation->set_rules('Datos[altahacienda]','Alta Hacienda''mysql_date'); 

on my log file, the debug message of the function that validates mysql format date, doesn’t appears, it seems that the function never is called.

Profile