CodeIgniter: обратный вызов проверки формы всегда возвращает False - PullRequest
0 голосов
/ 31 марта 2019

У меня есть форма с некоторыми сложными правилами для обработки;например, я должен проверить два набора данных, которые разделены на три поля (день, месяц, год), и я должен проверить, что первое находится перед вторым.

Вот мой контроллер:

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');
    $this->form_validation->set_rules('form_nbPeople', 'Number of people', 'required');
    $this->form_validation->set_rules('form_dateArrivalDay', '', 'callback_form_checkArrivalDate');
    $this->form_validation->set_rules('form_dateDepartureDay', '', 'callback_form_checkDepartureDate');
    $this->form_validation->set_rules('form_dateArrivalDay', '', 'callback_form_checkDateConsistency');
    $this->form_validation->set_rules('form_name', 'Name', 'required');
    $this->form_validation->set_rules('form_phone', '', 'callback_form_checkEmailOrPhone');
    $this->form_validation->set_rules('form_captcha', '', 'callback_form_checkCaptcha');

    if ($this->form_validation->run() == FALSE)
    {
        $this->load->view($lang.'/'.$page, $data);
    }
    else
    {
        $this->load->view($lang.'/'.$page.'-success', $data);

    }
}

Вот мой helpers/custom_form_helper.php файл:

function form_checkArrivalDate()
{
    $d = intval($this->input->post('form_dateArrivalDay'));
    $m = intval($this->input->post('form_dateArrivalMonth'));
    $y = intval($this->input->post('form_dateArrivalYear'));

    return(checkdate($m, $d, $y));
}

function form_checkDepartureDate()
{
    $d = intval($this->input->post('form_dateDepartureDay'));
    $m = intval($this->input->post('form_dateDepartureMonth'));
    $y = intval($this->input->post('form_dateDepartureYear'));

    return(checkdate($m, $d, $y));
}

function form_checkDateConsistency()
{
    $da = intval($this->input->post('form_dateArrivalDay'));
    $ma = intval($this->input->post('form_dateArrivalMonth'));
    $ya = intval($this->input->post('form_dateArrivalYear'));

    $dp = intval($this->input->post('form_dateDepartureDay'));
    $mp = intval($this->input->post('form_dateDepartureMonth'));
    $yp = intval($this->input->post('form_dateDepartureYear'));

    $a = mktime(0, 0, 0, $ma, $da, $ya);
    $p = mktime(0, 0, 0, $mp, $dp, $yp);

    return($a < $p);
}

Что бы я ни указывал в поле "form_dateArrivalDay" и других, проверки всегда заканчиваются неудачей.Другие валидаторы, которые не используют пользовательские обратные вызовы, не имеют этой проблемы.

Если я извлекаю имя поля из set_rules (первый параметр), валидация всегда проходит.

Есть личто-то я упускаю?

1 Ответ

0 голосов
/ 28 апреля 2019

Итак, если кто-то хочет знать ответ, я говорю, как решил свою проблему.

Было несколько ошибок с этим кодом.

Во-первых, потому что мои функции обратного вызова, такие как 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...