Codeigniter 2 - Callback function in My_Controller

2019-01-29 03:01发布

I have all my callback functions in My_Controller so that they are not repeated throughout the website. This works fine but for some reason one of my functions is not working when I am posting information using AJAX but is working on other pages. The message I get back when I use the callback is:

Unable to access an error message corresponding to your field name.

But then I've created a message for it using set_message() and it works fine on the other page without AJAX.

If you were interested in the log, here is the relevant output when entering an invalid date:

ERROR - 2013-05-24 16:03:08 --> -----Valid date format called, 223013-05-15
ERROR - 2013-05-24 16:03:08 --> -----Should be okay = , 223013-05-15
ERROR - 2013-05-24 16:03:08 --> -----Valid date format = false, 223013-05-15

And with a valid date:

ERROR - 2013-05-24 16:06:00 --> -----Valid date format called, 2013-05-24
ERROR - 2013-05-24 16:06:00 --> -----Should be okay = , 2013-05-24
ERROR - 2013-05-24 16:06:00 --> -----Valid date format = true, 05,24,2013

Here is the callback:

class MY_Controller extends CI_Controller
{
    var $options;
    public function __construct()
    {
        parent::__construct();
        date_default_timezone_set('Europe/London');

        $this->options->calendar = FALSE;
    }

  //Check date format aggainst mysql format, valid dates only, no 30-2-2010.
  function _Valid_Date_Format($date)
  {
    log_message('error', '-----Valid date format called, '.$date);

    if( empty($date) )
    {
        $this->form_validation->set_message('_Valid_Date_Format', 'This date is required.');
        return FALSE;  
    }
    else
    {
        log_message('error', '-----Should be okay = , '.$date);
    }

    $parsed = explode('-',$date);

    if( checkdate($parsed[1],$parsed[2],$parsed[0]) )
    {
      log_message('error', '-----Valid date format = true, '.$parsed[1].','.$parsed[2].','.$parsed[0]);
      return TRUE;
    }

    log_message('error', '-----Valid date format = false, '.$date );

    $this->form_validation->set_message('_Valid_Date_Format', 'The Date entered is invalid.');
    return FALSE;
  }
}

Here is the AJAX Code:

//Submit time feature $("#submit_time").click(function() { var cct = $.cookie('csrf_simple_cookie');//Overcome ajax limitation with csrf function, see below:

        $.ajax({
        url: folder,
        type:"POST",
        context: document.body,
        data: {t_id:$('#t_id').val(),
        time_for:$('#time_for').val(),
        hrs_spent:$('#hrs_spent').val(),
        mins_spent:$('#mins_spent').val(),
        timer_description:$('#timer_description').val(),
        date_worked:$('#date_worked').val(),
        csrf_simple_collab:cct},
        dataType: "json",
        error: function(XMLHttpRequest,error)
        {
            if(error=='parsererror')//Not logged in.
            {
                window.location.replace(loginFolder)//redirect to login page
            }
        },
        success: function(data)
        {                   
              if(data.success)
              {
                    var message=$('#message-box').html('<span>Time data added successfully.</span>').hide();
                    message.fadeIn("slow"); 
                    javascript:location.reload(true);
              }
              else
              {
                    if(data.validation)
                    {
                        //var message=$('#message-box').html("<span>Database error</span>");
                        var message=$('#message-box').html(data.error);
                    }
                    else
                    {
                        var message=$('#message-box').html(data.error);
                        $('#time-for-error').html(data.time_for);
                        $('#date-worked-error').html(data.date_worked);
                        $('#mins-spent-error').html(data.mins_spent);
                        $('#hrs-spent-error').html(data.hrs_spent);
                        $('#timer-description-error').html(data.timer_description);
                    }
              }          
        }
        });

return false;

});

Here is the view:

    <?
        //If we are an admin we can alter the user the information is added for.            
        if($this->session->userdata('userType')=='admin'): ?>
        <div class="form_row">
            <div class="form_field">
                <label for="time_for">User:</label> 
            </div>      
            <div class="form_field name_element" id="time-for-container">
                <select name="time_for" id="time_for">
                    <?
                        foreach($users as $key => $u):
                            if($u->userId==$this->session->userdata('userId')):                             
                            ?>
                                <option selected="selected" value="<?=$u->userId?>"><?=$u->userName?></option> <?='\n'?>
                            <?
                            else:
                            ?>
                                <option value="<?=$u->userId?>"><?=$u->userName?></option> <?='\n'?>
                            <?
                            endif;
                        endforeach;
                    ?>
                </select>
                <p id="time-for-error"></p>
            </div>
        </div>      
    <? else: ?>
        <input type="hidden" id="time_for" name="time_for" value="<?=$this->session->userdata('userId')?>">
    <? endif; ?>

<div class="form_row">
  <div class="form_field">
    <label for="hrs_spent">Hours and minutes spent:</label> 
  </div>

  <div class="form_field name_element" id="mins-spent-container">
    <input type="text" maxlength="6" name="hrs_spent" id="hrs_spent" value="" />
            <span id="min-separator">:</span>
            <input type="text" maxlength="6" name="mins_spent" id="mins_spent" value="" />
    <p id="mins-spent-error"></p>
            <p id="hrs-spent-error"></p>
  </div>
</div>

<div class="form_row">
  <div class="form_field">
    <label for="date_worked">Date Worked:</label> 
  </div>

  <div class="form_field name_element" id="date-picker-container">
    <input type="text" name="date_worked" id="date_worked" />
    <p id="date-worked-error"></p>
  </div>
</div>    

<div class="form_row">
  <div class="form_field">
    <label for="timer_description">Description:</label> 
  </div>

  <div class="form_field name_element" id="description-container">
    <textarea name="timer_description" id="timer_description" value=""></textarea>
    <p id="timer-description-error"></p>
  </div>
</div>

<input type="hidden" id="c_id" name="c_id" value="<?=$task->c_id ?>" />
<input type="hidden" id="p_id" name="p_id" value="<?=$task->p_id ?>" />
<input type="hidden" id="t_id" name="t_id" value="<?=$task->t_id ?>" />

<input type="hidden" name="login-folder" id="login-folder" value="<?=base_url()?>login" />
<input type="hidden" name="submit-folder" id="submit-folder" value="<?=base_url()?>times/submit_time" />

<div class="form_row">      
    <div id="message-box"></div>
    <input type="button" name="submit" id="submit_time" class="button-styles button-three" value="Add time" />      
</div>

</div>    

Controller method:

class Times extends MY_Controller { var $options;

    //Ajax function used to submit the time information from task page form.
    function submit_time()
    {
        $options=array();

        $this->form_validation->set_rules("time_for","Time for","trim|required|is_natural_no_zero");
        $this->form_validation->set_rules("hrs_spent","Hrs spent","trim|required|is_natural|min_length[1]|max_length[5]");      
        $this->form_validation->set_rules("mins_spent","Mins spent","trim|required|is_natural|min_length[1]|max_length[2]|less_than[60]");
        $this->form_validation->set_rules("timer_description","Description","trim|min_length[5]|max_length[1000]");
        $this->form_validation->set_rules("date_worked","Date Worked","trim|required|callback__valid_date_format");

//$json->data=array('success'=>0,'validation'=>1,'error'=> validation_errors() );
//$this->load->view('data/json_encode',$json);

        if($this->form_validation->run())
        {
          $options['hrs_spent'] = $this->input->post('hrs_spent');
          $options['mins_spent'] = $this->input->post('mins_spent');            
          $options['timer_description'] = $this->input->post('timer_description');
          $options['date_worked'] = $this->input->post('date_worked');
          $options['t_id'] = $this->input->post('t_id');
          $options['u_id'] = $this->input->post('time_for');//Notice time for field here.

          $add = $this->time_model->add_time($options);

          if(!$add):
            $json->data=array('success'=>0,'validation'=>1,'error'=>'Database error');
          else:
                $json->data=array('success'=>1,'validation'=>1);    
                $this->log_model->add_log_entry( array('log_id'=>1,'item'=>'Time record "'.reduce_string($options['timer_description'],50).'" was added for user '.$options['u_id'].'.') );
            endif;

          $this->load->view('data/json_encode',$json);
        }
        else
        {
          $json->data = array(
            'time_for' => form_error('time_for'),
            'hrs_spent' => form_error('hrs_spent'),
            'mins_spent' => form_error('mins_spent'),           
            'timer_description' => form_error('timer_description'),
            'date_worked' => form_error('date_worked'),
            'success'=>0,
            'validation'=>0,
            'error'=>'There are errors in the form.'
          );

          $this->load->view('data/json_encode',$json);
        }
    }

}

1条回答
来,给爷笑一个
2楼-- · 2019-01-29 03:40

The problem is the capitalization used in the callback method name. The method name, and all subsequent references to it as a validation rule, should be all lowercase.

To explain, this is the relevant part of the Form Validation library that causes the message:

if ( ! isset($this->_error_messages[$rule]))
{
    if (FALSE === ($line = $this->CI->lang->line($rule)))
    {
        $line = 'Unable to access an error message corresponding to your field name.';
    }
}
else
{
    $line = $this->_error_messages[$rule];
}

All of your set_message() calls name the rule as _Valid_Date_Format, which is the array key that exists in $this->_error_messages.

Because your rule is defined as _valid_date_format, and because PHP is case-sensitive most of the time, the isset() rule fails, and you clearly don't have a language line defined for it, so it goes to the default.

In general, using capitalization in your controller methods will cause problems. So it's best to avoid doing so.

查看更多
登录 后发表回答