Итак, если кто-то хочет знать ответ, я говорю, как решил свою проблему.
Было несколько ошибок с этим кодом.
Во-первых, потому что мои функции обратного вызова, такие как form_checkArrivalDate
, были не в классе контроллера, а в другом файле, точнее во вспомогательном custom_form_helper.php
. И эти функции должны быть в классе контроллера; это то, что документация недостаточно точна.
Если вы хотите, чтобы ваши проверочные функции были найдены валидатором, вам нужно удалить callback_
в начале имени в функции set_rules
. Функция должна быть вызываемой и возвращать TRUE или FALSE в зависимости от проверок.
Вторая ошибка была в том, что мои поля POST не были видны в моих функциях проверки. Поскольку функции находятся за пределами класса, атрибут $this->input->post
не наследуется. Чтобы сделать «суперобъект» CodeIgniter доступным в функции, вам нужно добавить $CI =& get_instance();
в начале функции и использовать объект $CI
вместо $this
.
Итак, в конце концов мой контроллер выглядит следующим образом (я также добавил еще несколько вещей, например языковые строки):
public function booking($data, $lang, $page)
{
$this->load->helper('form');
$this->load->helper('captcha');
$this->load->helper('custom_form');
$this->load->library('form_validation');
$this->form_validation->set_error_delimiters('', '<br />');
$data['captcha'] = form_captcha();
$this->session->captcha = $data['captcha']['word'];
$this->form_validation->set_rules('form_place', 'Place', 'required', ['required' => $this->lang->line('form_noPlace')]);
$this->form_validation->set_rules('form_nbPeople', 'Number of people', 'required');
$this->form_validation->set_rules('form_dateArrivalDay', 'Arrival date', 'required|form_checkArrivalDate|form_checkDateConsistency', ['form_checkArrivalDate' => $this->lang->line('form_incorrectDateArrival'), 'form_checkDateConsistency' => $this->lang->line('form_inconsistentDates')]);
$this->form_validation->set_rules('form_dateDepartureDay', 'Departure date', 'required|form_checkDepartureDate', ['form_checkDepartureDate' => $this->lang->line('form_incorrectDateDeparture')]);
$this->form_validation->set_rules('form_name', 'Name', 'required');
$this->form_validation->set_rules('form_phone', 'Phone number', 'form_checkEmailOrPhone', ['form_checkEmailOrPhone' => $this->lang->line('form_incorrectMailOrTel')]);
$this->form_validation->set_rules('form_captcha', 'Captcha', 'form_checkCaptcha', ['form_checkCaptcha' => $this->lang->line('form_incorrectCaptcha')]);
if ($this->form_validation->run() == FALSE)
{
$this->load->view($lang.'/'.$page, $data);
}
else
{
$this->load->view($lang.'/'.$page.'-success', $data);
}
}
А вот и мой помощник:
function form_checkArrivalDate()
{
$CI =& get_instance();
$d = intval($CI->input->post('form_dateArrivalDay'));
$m = intval($CI->input->post('form_dateArrivalMonth'));
$y = intval($CI->input->post('form_dateArrivalYear'));
return(checkdate($m, $d, $y));
}
function form_checkDepartureDate()
{
$CI =& get_instance();
$d = intval($CI->input->post('form_dateDepartureDay'));
$m = intval($CI->input->post('form_dateDepartureMonth'));
$y = intval($CI->input->post('form_dateDepartureYear'));
return(checkdate($m, $d, $y));
}
function form_checkDateConsistency()
{
$CI =& get_instance();
$da = intval($CI->input->post('form_dateArrivalDay'));
$ma = intval($CI->input->post('form_dateArrivalMonth'));
$ya = intval($CI->input->post('form_dateArrivalYear'));
$dp = intval($CI->input->post('form_dateDepartureDay'));
$mp = intval($CI->input->post('form_dateDepartureMonth'));
$yp = intval($CI->input->post('form_dateDepartureYear'));
$a = mktime(0, 0, 0, $ma, $da, $ya);
$p = mktime(0, 0, 0, $mp, $dp, $yp);
return($a < $p);
}
Также, возможно, не связанная, но другая проблема, с которой я столкнулся, заключается в проверке двух полей - form_email
и form_phone
.
У меня есть поле для номера телефона, а другое - для электронной почты; пользователь должен заполнить хотя бы один из двух. Поэтому я поместил в form_phone
функцию, которая возвращает FALSE, только если оба поля пусты. Поскольку одно из двух полей может быть пустым, я не поставил «обязательное» условие.
Но это не сработало, по некоторым причинам оно всегда возвращало ИСТИНА, независимо от того, что было в полях. Дело в том, угадайте, что: если CodeIgniter увидит, что вы не поставили «обязательное» условие, он не проверяет другие условия . Да, это совершенно глупое поведение, и я серьезно удивляюсь, почему оно было реализовано - потому что, исходя из того, что я видел, это очевидный выбор разработчиков.
Поэтому я должен был закомментировать это в библиотеке form_validation.php, чтобы мой валидатор работал.
if (
($postdata === NULL OR $postdata === '')
&& $callback === FALSE
&& $callable === FALSE
&& ! in_array($rule, array('required', 'isset', 'matches'), TRUE)
)
{
continue;
}