Проверка массива опций

21 июн. 2012 г., 19:55:26
Просмотры: 5.66K
Голосов: 3

Мы используем стандартную функцию WordPress register_setting() для проверки опций темы. Например, такой вызов:

register_setting( 'options-group', 'option1', 'intval' );

Проверит, является ли $option1 целым числом.

Что я могу использовать для передачи массива опций, чтобы проверить каждый элемент массива?

Например:

$options = array(
    'options1' => 4,              // целое число
    'options2' => '127.0.0.1',    // IP-адрес
    'options3' => 'test@test.com' // email-адрес
);
2
Комментарии

Проверка существования элементов в массиве — это не совсем вопрос по WordPress... Это базовый PHP.

EAMann EAMann
21 июн. 2012 г. 20:07:58

вообще-то я привёл простой пример, но с callback-функциями это уже специфичный для WP вопрос, имхо.. это не обычный вопрос по валидации -.-

Ünsal Korkmaz Ünsal Korkmaz
21 июн. 2012 г. 21:01:06
Все ответы на вопрос 2
3
11

Вам необходимо создать собственную функцию валидации данных. Ozh ранее написал отличное руководство на эту тему, но вот суть...

Предположим, ваш массив настроек называется $my_options и содержит три поля: 'text', 'age' и 'isauthorized'.

Вы по-прежнему регистрируете его тем же способом:

register_setting( 'my_setting', 'my_options', 'my_validation_function' );

Но видите, как мы использовали пользовательский callback для третьего параметра? Теперь нам просто нужно определить эту пользовательскую функцию:

function my_validation_function( $input ) {
    // Валидация возраста как целого числа
    $input['age'] = intval( $input['age'] );

    // Удаление HTML-тегов из текста для безопасности
    $input['text'] = wp_filter_nohtml_kses( $input['text'] );

    // Убеждаемся, что isauthorized может быть только true или false (0 или 1)
    $input['isauthorized'] = ( $input['isauthorized'] == 1 ? 1 : 0 );

    return $input;
}

Альтернативный вариант

Если вы хотите сделать ваши функции валидации более гибкими, вы можете использовать встроенные фильтры WordPress, чтобы избежать повторения кода. Вы по-прежнему регистрируете валидацию тем же способом:

register_setting( 'my_setting', 'my_options', 'my_validation_function' );

Но вместо проверки каждого элемента массива внутри функции валидации вы перебираете массив и делегируете проверку фильтрам:

function my_validation_function( $input ) {
    foreach( $input as $key => $value ) {
        $input[$key] = apply_filters( 'my_validation_' . $key, $value );
    }

    return $input
}

Теперь вы можете подключить любую необходимую логику валидации:

add_filter( 'my_validation_age', 'validate_numeric' );
function validate_numeric( $numeric ) {
    return intval( $numeric );
}

add_filter( 'my_validation_text', 'validate_text' );
function validate_text( $text ) {
    return wp_filter_nohtml_kses( $text );
}

add_filter( 'my_validation_isauthorized', 'validate_bool' );
function validate_bool( $bool ) {
    return $bool == 1 ? 1 : 0;
}

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

Допустим, у вас есть два числовых поля в массиве — age и numberChildren. Вместо создания дополнительной функции валидации для обработки поля numberChildren, вы просто добавляете его в фильтр:

add_filter( 'my_validation_numberChildren', 'validate_numeric' );
21 июн. 2012 г. 21:47:52
Комментарии

Мне нравится этот альтернативный подход, но как вы сохраняете чекбоксы? Они отправляются через POST только если отмечены, поэтому цикл foreach, перебирающий все результаты, не сохранит неотмеченный чекбокс.

donnapep donnapep
12 дек. 2015 г. 14:57:57

Ребята, разве это валидация? Если введённые данные неверны, ничего не должно сохраняться, пользователю должно быть показано неверное поле и полезное сообщение об ошибке. add_settings_error() — это то, что нужно!

Markus Malkusch Markus Malkusch
13 мар. 2016 г. 22:04:59

Это не валидация, а санитизация. Однако в WordPress немало плохо спроектированных или некорректно названных функций. Эта функция совмещает в себе и санитизацию, и валидацию. Чтобы не обновлять опцию из-за неверных значений, просто верните старое значение. Также разумно добавить полезное сообщение об ошибке с помощью add_settings_error().

Dhaval Shah Dhaval Shah
13 мар. 2019 г. 07:08:32
1

Кажется, решение "разные функции для каждой опции в массиве" не совсем такое, как я представлял, но думаю, это должно сработать:

register_setting( 'my_setting', 'my_options', 'my_validation_function' );

function my_validation_function( $input ) {
    foreach ($input as $option=>$value){
        do_action('my_validation_'.$option, $option, $value);
    }
    return $input;
}

И затем я могу использовать собственные функции для валидации каждой опции, например:

add_action('my_validation_age', 'my_validation_function_for_age', 10, 2);
function my_validation_function_for_age($option, $value) {
    $input[$option] = intval( $value );
}

add_action('my_validation_text', 'my_validation_function_for_text', 10, 2);
function my_validation_function_for_text($option, $value) {
    $input[$option] = wp_filter_nohtml_kses( $value );
}

add_action('my_validation_isauthorized', 'my_validation_function_for_isauthorized', 10, 2);
function my_validation_function_for_isauthorized($option, $value) {
    $input[$option] = ( $value == 1 ? 1 : 0 );
}

Пишу здесь для будущих посетителей. Принимаю решение EAMann.

21 июн. 2012 г. 23:56:22
Комментарии

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

EAMann EAMann
22 июн. 2012 г. 00:31:26