Правило проверки пользовательской формы Codeigniter, возвращающее ложное срабатывание - PullRequest
1 голос
/ 09 января 2020

У меня есть несколько проектов на базе Codeigniter, над которыми я сделал точно такую ​​же вещь, но по какой-то причине в самом последнем проекте я не могу заставить его работать.

У меня есть некоторые настройки непосредственно в ядре CI (да, я знаю, что мне следует расширять ядро, а не модифицировать его, но до сих пор оно работало, и это облегчает запуск нового проекта со всеми уже внесенными изменениями). Одна из этих модификаций - это дополнительный метод в библиотеке Form_validation (system/libraries/Form_validation), называемый is_unique_sc, который позволяет проверить, не присутствует ли представленное поле в таблице (как обычный метод is_unique) с помощью единственное отличие состоит в том, что вместо аргумента table.field можно указать аргумент schema.table.field (это необходимо, поскольку многие проекты, над которыми я работаю, требуют использования нескольких отдельных схем)

Это пользовательский метод

public function is_unique_sc($str, $field)
{
    sscanf($field, '%[^.].%[^.].%[^.]', $schema, $table, $field);
    return isset($this->CI->db)
            ? ($this->CI->db->limit(1)->get_where($schema.'.'.$table, array($field => $str))->num_rows() === 0)
            : FALSE;
}

Для сравнения, это оригинальный is_unique метод:

public function is_unique($str, $field)
{
    sscanf($field, '%[^.].%[^.]', $table, $field);
    return isset($this->CI->db)
        ? ($this->CI->db->limit(1)->get_where($table, array($field => $str))->num_rows() === 0)
        : FALSE;
}

Это соответствует необходимой модификации языкового файла form_validation_lang в случае, если проверка вернет false:

$lang['form_validation_is_unique_sc']       = 'The {field} field must contain a unique value.';

Я использую это, как я уже говорил, во многих проектах без проблем до сих пор.

Однако в моем последнем проекте создание нового пользователя не выполняется из-за этого правила:

$this->form_validation->set_rules('new_email', 'Mail', 'required|trim|htmlspecialchars|strtolower|valid_email|is_unique_sc[accv_users.controllers.controller_email]');

Правило is_unique_sc всегда возвращает false (и, следовательно, отображает сообщение об ошибке проверки), даже если введенное пользователем сообщение электронной почты фактически уникально. Удаление правила is_unique_sc позволяет проверить правильность остальной части оператора, что исключает возможность неправильного имени поля для всего оператора set_rules.

Я дважды и трижды проверил, что имя схемы accv_users, имя таблицы controllers и имя поля controller_email. Query Builder включен в соответствии с требованиями метода, а соединение с базой данных правильно настроено и доступно.

Проверка правильности вывода функции sscanf() присваивает имя схемы $schema, имя таблицы $table и имя поля $field

Ради для полноты, это поле в виде формы:

<div class="col-12 col-lg-3">
   <input class="form-control" type="email" id="new_email" name="new_email" placeholder="Mail" required>
</div>

Ожидаемый результат, конечно, заключается в том, что при отправке формы с электронным письмом, которого еще нет в таблице, проверка проходит. проверка должна завершиться неудачей только тогда, когда электронная почта уже на столе. Я искал много подобных случаев в SO, но пока что ни одно решение не помогло.

Если кто-нибудь сможет помочь мне точно определить проблему, я буду чрезвычайно признателен.

1 Ответ

0 голосов
/ 10 апреля 2020

После нескольких месяцев забвения (я обходил эту неудачную проверку другими способами), я сделал еще один удар и взломал ее!

Похоже, что в последних версиях CI3 есть ошибка это препятствует правильному выполнению правила проверки формы is_unique.

Я сделал несколько глубоких копаний и в конце концов обнаружил, что эта функция:

public function is_unique($str, $field)
{
    sscanf($field, '%[^.].%[^.]', $table, $field);
    return isset($this->CI->db)
        ? ($this->CI->db->limit(1)->get_where($table, array($field => $str))->num_rows() === 0)
        : FALSE;
}

ВСЕГДА возвращает false (и, следовательно, делает проверку формы неудачной), потому что isset($this->CI->db) всегда возвращался логический FALSE, независимо от того, какие компоненты, связанные с базой данных, загружаются автоматически и активен Query Builder.

Исправление было простым. Всего одна строка кода в самой функции:

public function is_unique($str, $field)
{
    sscanf($field, '%[^.].%[^.]', $table, $field);

    // add the following line
    $this->CI->load->database();

    return isset($this->CI->db)
        ? ($this->CI->db->limit(1)->get_where($table, array($field => $str))->num_rows() === 0)
        : FALSE;
}

После добавления этой единственной строки проверка формы снова начала работать правильно. Он все равно потерпит неудачу, если произойдет сбой $this->CI->load->database(), что и следовало ожидать, учитывая, что правило is_unique (и мое собственное пользовательское правило тоже) зависят от возможности выполнения запросов. Но пока соединение с базой данных доступно, правило работает!

...