Статьи

API настроек WordPress, часть 7: проверка, санация и ввод

Если вы только что присоединились к нам, мы рассмотрели много тем в этой серии — мы попытались дать полный обзор API настроек WordPress, а также связанных с ним функций. Мы обсудили настройки , опции , навигацию и меню . Мы также работали над практическими примерами, используя каждую из обсуждаемых тем.

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

Прежде чем мы начнем: в этой статье предполагается, что вы следовали вместе с остальной частью серии, установили рабочую копию примера кода и теперь относительно знакомы с API настроек и параметрами темы. Если вы не уверены в каком-либо из вышеперечисленных, я настоятельно рекомендую прочитать остальные статьи, прежде чем углубляться в этот пост.


Прежде чем мы начнем писать какой-либо код, нам нужно точно понять, что именно мы собираемся выполнить, а именно: проверка и очистка. Проще говоря, это два аспекта безопасной записи и чтения данных со страницы параметров WordPress и базовой базы данных.

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

  • Валидация — это процесс, с помощью которого мы проверяем данные, поступающие со страницы параметров (или, скорее, пользовательский ввод), и определяем, приемлемо ли их сохранение.
  • Санитарная обработка — это процесс, с помощью которого мы проверяем, что данные, поступающие из базы данных, чистые и правильно отформатированы для отображения на странице.

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

Часто проверка связана с сохранением данных, а очистка связана с извлечением данных, но также можно полностью очистить данные после того, как они прошли проверку, чтобы убедиться, что в базу данных сохраняются только чистые данные. Когда мы работаем с нашим собственным кодом, это проще сделать; однако мы не всегда можем рассчитывать на то, что другие разработчики очистят свои данные, поэтому ответственность за очистку всех данных, поступающих из базы данных, ложится на нас.


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

Сначала найдите функцию sandbox_example_theme_menu и добавьте следующий элемент подменю:

1
2
3
4
5
6
7
8
add_submenu_page(
    ‘sandbox_theme_menu’,
    ‘Input Examples’,
    ‘Input Examples’,
    ‘administrator’,
    ‘sandbox_theme_input_examples’,
    create_function( null, ‘sandbox_theme_display( «input_examples» );’ )
);

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

1
2
3
4
5
6
7
8
function sandbox_theme_initialize_input_examples() {
 
    if( false == get_option( ‘sandbox_theme_input_examples’ ) ) {
        add_option( ‘sandbox_theme_input_examples’ );
    } // end if
 
} // end sandbox_theme_initialize_input_examples
add_action( ‘admin_init’, ‘sandbox_theme_initialize_input_examples’ );

Наконец, нам нужно обновить функцию sandbox_theme_display чтобы отобразить вкладку и правильно выбрать ее при доступе либо через вкладки, либо через элемент подменю. Сначала давайте обновим условие, которое проверяет строку запроса и аргументы функции. В частности, он должен обрабатывать случай для входных примеров. Обновите условное выражение, чтобы оно выглядело так:

1
2
3
4
5
6
7
8
9
if( isset( $_GET[ ‘tab’ ] ) ) {
    $active_tab = $_GET[ ‘tab’ ];
} else if( $active_tab == ‘social_options’ ) {
    $active_tab = ‘social_options’;
} else if( $active_tab == ‘input_examples’ ) {
    $active_tab = ‘input_examples’;
} else {
    $active_tab = ‘display_options’;
} // end if/else

Далее нам нужно добавить новую вкладку в навигацию. Обновите контейнер nav-tab-wrapper чтобы включить этот новый якорь:

1
<a href=»?page=sandbox_theme_options&tab=input_examples» class=»nav-tab <?php echo $active_tab == ‘input_examples’ ? ‘nav-tab-active’ : »; ?>»>Input Examples</a>

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
if( $active_tab == ‘display_options’ ) {
 
    settings_fields( ‘sandbox_theme_display_options’ );
    do_settings_sections( ‘sandbox_theme_display_options’ );
     
} elseif( $active_tab == ‘social_options’ ) {
 
    settings_fields( ‘sandbox_theme_social_options’ );
    do_settings_sections( ‘sandbox_theme_social_options’ );
     
} else {
 
    settings_fields( ‘sandbox_theme_input_examples’ );
    do_settings_sections( ‘sandbox_theme_input_examples’ );
     
} // end if/else

Предполагая, что вы включили весь код правильно, ваша панель администратора должна выглядеть следующим образом:

Начальные примеры

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


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

Элементы ввода идеально подходят для ситуаций, когда нам нужно захватить небольшое количество текста от пользователя. Это может быть что-то вроде их имени или номера телефона или что-то более сложное, например, URL, адрес электронной почты или ключ API. Фактически, мы фактически уже используем поля ввода на странице «Параметры социальных сетей», когда запрашиваем адреса профиля в социальной сети пользователя.

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

Вместо этого мы будем следить за тем, чтобы вредоносный код не записывался в базу данных. Это означает, что когда пользователь вводит текст в наше текстовое поле, мы собираемся удалить все теги HTML и потенциально проблемные символы. Но прежде чем сделать это, давайте введем новую опцию, разберемся в разметке и посмотрим, что произойдет, если мы не введем никакой тип проверки.

sandbox_theme_initialize_input_examples представим новый раздел и поле с sandbox_theme_initialize_input_examples функции sandbox_theme_initialize_input_examples :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
add_settings_section(
    ‘input_examples_section’,
    ‘Input Examples’,
    ‘sandbox_input_examples_callback’,
    ‘sandbox_theme_input_examples’
);
 
add_settings_field(
    ‘Input Element’,
    ‘Input Element’,
    ‘sandbox_input_element_callback’,
    ‘sandbox_theme_input_examples’,
    ‘input_examples_section’
);
 
register_setting(
    ‘sandbox_theme_input_examples’,
    ‘sandbox_theme_input_examples’
);

Затем определите обратный вызов для раздела:

1
2
3
function sandbox_input_examples_callback() {
    echo ‘<p>Provides examples of the five basic element types.</p>’;
}

Наконец, представьте фактический элемент ввода, который мы собираемся использовать для захвата ввода:

1
2
3
4
5
6
7
8
function sandbox_input_element_callback() {
     
    $options = get_option( ‘sandbox_theme_input_examples’ );
     
    // Render the output
    echo ‘<input type=»text» id=»input_example» name=»sandbox_theme_input_examples[input_example]» value=»‘ . $options[ ‘input_example’ ] . ‘» />’;
     
}

Ваша страница настроек теперь должна выглядеть следующим образом:

Элемент ввода

До этого момента мы создавали наши элементы option, и я упоминал, что в конечном итоге мы обсудим каждый из атрибутов позже в этой серии. Это статья, в которой мы начинаем рассматривать значение атрибутов id и name .

Обратите внимание, что в начале функции мы читаем опции для этой конкретной вкладки, используя функцию get_option WordPress. Эта функция вернет параметры в массиве. Атрибут id входного элемента идентифицирует значение этого элемента в массиве. Атрибут name — это имя массива с ключом ID. Есть смысл?

Чтобы быть законченным, думайте об этом так:

  • WordPress создаст массив на основе названия раздела, который вы определили. В данном случае это sandbox_theme_input_examples
  • Каждый элемент будет идентифицирован атрибутом id . В этом примере это « input_example »
  • Вы можете прочитать значение этого массива, используя sandbox_theme_input_examples[input_example]

Таким образом, id элемента представляет ключ значения в массиве параметров, атрибут name представляет имя массива с ключом значения в массиве.

На этом этапе можно полностью начать ввод значений в элемент ввода и сохранить параметр. Попробуйте и попробуйте — установите значение, нажмите «Сохранить изменения», и вы увидите, что элемент ввода отображает значение, которое вы только что создали. Но вот проблема: попробуйте вставить что-то вроде этого в поле ввода:

1
<iframe src=’http://wp.tutsplus.com’ width=’640′ height=’480′></iframe>

Затем перейдите к index.php и добавьте следующий блок кода:

1
2
<?php $input_examples = get_option(‘sandbox_theme_input_examples’);
<?php echo $input_examples[‘input_example’];

Обновите домашнюю страницу, и вы должны заметить, что в середине главной страницы вашей темы появляется iframe:

Элемент ввода

Кажется, это относительно небольшая проблема, но это именно то, что нам нужно предотвратить. Мы не хотим, чтобы пользователи имели такой контроль над базой данных, страницами сайта и так далее. Конечно, сохранение простого iframe является второстепенным примером — если пользователи могут вставлять JavaScript, они могут влиять на определенные аспекты всего вашего сайта. Еще серьезнее, если пользователи смогут вставить вредоносный SQL, ваша база данных может быть скомпрометирована.

Итак, давайте введем некоторую проверку. Как упоминалось выше, мы хотим удалить любую разметку и проблемные символы. Чтобы сделать это, нам нужно сначала определить обратный вызов проверки для нашего раздела входных элементов. Чтобы сделать это, давайте вернемся к вызову register_setting и обновим его так, чтобы он выглядел так:

1
2
3
4
5
register_setting(
    ‘sandbox_theme_input_examples’,
    ‘sandbox_theme_input_examples’,
    ‘sandbox_theme_validate_input_examples’
);

Далее давайте определим эту функцию:

1
2
function sandbox_theme_validate_input_examples( $input ) {
} // end sandbox_theme_validate_input_examples

Обратите внимание, что эта функция принимает один параметр, который мы назвали input . Этот аргумент представляет непроверенный набор параметров, которые WordPress отправляет этой функции со страницы параметров, которую мы только что сохранили. Также обратите внимание, что при добавлении дополнительных элементов option мы будем использовать эту же функцию.

Создание функции проверки обычно выполняется в три этапа:

  1. Создать массив, который будет использоваться для хранения проверенных параметров
  2. Проверить (и очистить, если необходимо) все входящие параметры
  3. Вернуть массив, который мы создали ранее

Давайте сделаем это сейчас. Посмотрите на следующую реализацию, обращая пристальное внимание на комментарии:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
function sandbox_theme_validate_input_examples( $input ) {
 
    // Create our array for storing the validated options
    $output = array();
     
    // Loop through each of the incoming options
    foreach( $input as $key => $value ) {
         
        // Check to see if the current option has a value.
        if( isset( $input[$key] ) ) {
         
            // Strip all HTML and PHP tags and properly handle quoted strings
            $output[$key] = strip_tags( stripslashes( $input[ $key ] ) );
             
        } // end if
         
    } // end foreach
     
    // Return the array processing any additional functions filtered by this action
    return apply_filters( ‘sandbox_theme_validate_input_examples’, $output, $input );
 
}

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

  • Мы используем функцию strip_tags , которая является родной для PHP, для удаления всех тегов HTML и PHP
  • Мы используем функцию stripslashes , которая является другой нативной функцией PHP, которая будет правильно обрабатывать кавычки вокруг строки.

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

Теперь попробуйте дать пример ввода в элемент ввода. Попробуйте указать простую строку, номер телефона, адрес электронной почты, URL-адрес, блок HTML, строку JavaScript и т. Д. Аккуратно, а?

Наконец, давайте вернемся к index.php и предоставим последнее изменение, чтобы продемонстрировать, как мы можем выполнить очистку выходных данных. Помните, что рекомендуется дезинфицировать параметры, даже если вы работаете со значениями, которые не являются результатом вашей собственной работы.

Найдите строку, которая гласит:

1
<?php echo $input_examples[ ‘input_example’ ];

И обновите его так, чтобы оно гласило:

1
<?php echo sanitize_text_field( $input_examples[ ‘input_example’ ] );

Функция sanitize_text_field — это еще одна встроенная функция WordPress, которая специально предназначена для очистки пользовательского ввода из текстовых полей или из базы данных.

Мы рассмотрим больше в этой и следующей статьях, но в Кодексе WordPress есть полный список этих функций.

При рассмотрении элементов ввода мы рассмотрели много вопросов. К счастью, многие из тех же принципов применимы не только к текстовым областям, но и к остальным элементам. Таким образом, нам не нужно тратить столько времени на каждый элемент. Это освободит нас, чтобы взглянуть на некоторые особенности, которые идут с каждым из типов элементов.

А пока давайте введем элемент textarea. В нашем примере этот конкретный элемент позволит пользователям вводить несколько предложений о себе — думать об этом как о короткой биографии. Сначала добавьте следующий вызов в функцию sandbox_theme_initialize_input_examples :

1
2
3
4
5
6
7
8
     
add_settings_field(
    ‘Textarea Element’,
    ‘Textarea Element’,
    ‘sandbox_textarea_element_callback’,
    ‘sandbox_theme_input_examples’,
    ‘input_examples_section’
);

Далее, давайте определим обратный вызов, необходимый для визуализации текстовой области:

1
2
3
4
5
6
7
8
function sandbox_textarea_element_callback() {
     
    $options = get_option( ‘sandbox_theme_input_examples’ );
     
    // Render the output
    echo ‘<textarea id=»textarea_example» name=»sandbox_theme_input_examples[textarea_example]» rows=»5″ cols=»50″>’ .
     
}

Обратите внимание, что этот вызов очень похож на элемент ввода, определенный выше. В частности, мы предоставили атрибут id для придания этому значению ключа в массиве параметров и указали точное имя и ключ в атрибуте name элемента. Мы также дали текстовой области определенный размер, хотя это чисто произвольно.

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

Наконец, давайте обновим общедоступную страницу нашей темы, чтобы получить это значение и правильно санировать его для отображения. В index.php добавьте следующий блок кода:

1
2
3
<?php if( $input_examples[ ‘textarea_example’ ] ) { ?>
    <?php echo sanitize_text_field( $input_examples[ ‘textarea_example’ ] );
<?php } // end if ?>

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


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

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