Полное руководство по настройке WordPress API, часть 7: валидация, очистка и элементы ввода

Содержание цикла статей «Полное руководство по настройке WordPress API»:

  1. Полное руководство по настройке WordPress API, часть 1: введение
  2. Полное руководство по настройке WordPress API, часть 2: секции, поля и настройки
  3. Полное руководство по настройке WordPress API, часть 3: все о создании меню
  4. Полное руководство по настройке WordPress API, часть 4: опции темы
  5. Полное руководство по настройке WordPress API, часть 5: закладочная навигация
  6. Полное руководство по настройке WordPress API, часть 6: страницы меню
  7. Полное руководство по настройке WordPress API, часть 7: валидация, очистка и элементы ввода
  8. Полное руководство по настройке WordPress API, часть 8: валидация, очистка и элементы ввода

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

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

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

Примечание: статья предполагает, что вы уже знакомы с Settings API и опциями темы. Рекомендуется сначала ознакомиться с предыдущими статьями цикла.

Понятие валидации и очистки

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

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

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

Самое важное это то, что валидация должна быть произведена до записи в базу данных, а очистка – между чтением данных и отправлением их на вывод в браузер.

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

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

Модификация нашего проекта

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

Найдите функцию sandbox_example_theme_menu и добавьте подпункт меню:

add_submenu_page(  
    'sandbox_theme_menu',  
    'Примеры полей ввода',  
    'Примеры полей ввода',  
    'administrator',  
    'sandbox_theme_input_examples',  
    create_function( null, 'sandbox_theme_display( "input_examples" );' )  
);

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

function sandbox_theme_initialize_input_examples() {  
  
    if( false == get_option( 'sandbox_theme_input_examples' ) ) {  
        add_option( 'sandbox_theme_input_examples' );  
    } // Конец конструкции if  
  
} // Конец функции sandbox_theme_initialize_input_examples  
add_action( 'admin_init', 'sandbox_theme_initialize_input_examples' );

Далее, обновим функцию sandbox_theme_display и заставим ее выводить закладку и переходить на соответствующую страницу при клике на пункте меню, по аналогии с примерами в предыдущих статьях.

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

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';  
} // Конец конструкции if/else

Далее, нужно добавить новую закладку. Обновите контейнер nav-tab-wrapper включив в него теги ссылок следующего вида:

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

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

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' );  
      
} // Конец конструкции if/else

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

административная панель

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

Типы элементов ввода

Есть пять базовых элементов ввода, которые могут быть использованы на страницах настроек WordPress. Это однострочные поля ввода (inputs), многострочные поля ввода (textareas), чекбоксы (checkboxes), радиокнопки (radio buttons) и выпадающие списки (select boxes).

В данной статье мы рассмотрим однострочные и многострочные поля ввода, остальные три типа элементов – в последней статье цикла.

Поле ввода

Элементы ввода идеальны для ситуаций, когда нам необходимо получить от пользователя короткую строку текста. Это может быть имя, телефонный номер, либо что-то более сложное – URL- или email-адрес.

На самом деле, мы уже использовали поля ввода на странице «Опции социальных сетей» для получения от пользователя информации о его профилях в социальных сетях.

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

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

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

Создаем новую секцию и поле, используя функцию sandbox_theme_initialize_input_examples:

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'  
);

Далее, определим callback-функцию:

function sandbox_input_examples_callback() {  
    echo '<p>Представление примера с пятью базовыми элементами ввода.</p>';  
}

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

function sandbox_input_element_callback() {  
      
    $options = get_option( 'sandbox_theme_input_examples' );  
      
    // Вывод на экран  
    echo '<input type="text" id="input_example" name="sandbox_theme_input_examples[input_example]" value="' . $options[ 'input_example' ] . '" />';  
      
}

Сейчас ваша страница опций должна выглядеть, так, как показано на изображении ниже:

страница опций

Создание разметки

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

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

Чтобы было понятно, обобщим:

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

Атрибут id представляет собой ключ, указывающий на значение в массиве опций, а атрибут name – имя массива с ключом, указывающим на значение элемента в массиве.

Реализация механизмов валидации и очистки

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

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

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

<?php $input_examples = get_option('sandbox_theme_input_examples'); ?>  
<?php echo $input_examples['input_example']; ?>

Обновите главную страницу вашего сайта, и вы увидите тег <iframe>:

тег iframe

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

Еще серьезнее обстоит ситуация, когда пользователи могут вставить вредоносный SQL-код и повредить/украсть информацию из вашей базы данных.

Поэтому, давайте добавим код, реализующий валидацию. Как было замечено выше, задача состоит в удалении любой HTML-разметки и проблемных символов. Чтобы это сделать, нам сперва нужно определить callback-функцию для нашей секции с элементами ввода. Мы переопределим вызов функции register_setting следующим образом:

register_setting(  
    'sandbox_theme_input_examples',  
    'sandbox_theme_input_examples',  
    'sandbox_theme_validate_input_examples'  
);

Теперь определим саму функцию:

function sandbox_theme_validate_input_examples( $input ) {  
} // Конец функции sandbox_theme_validate_input_examples

Заметьте, что эта функция принимает единственный параметр input. Данный аргумент представляет собой не прошедший валидацию массив опций, который WordPress передает функции со страницы опций, которую мы только что сохранили.

Так как мы добавили дополнительный элемент опций, будем использовать ту же функцию.

Создание функции валидации происходит в три шага:

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

Давайте реализуем данный алгоритм. Взгляните на код ниже, обращая особое внимание на комментарии:

function sandbox_theme_validate_input_examples( $input ) {  
  
    // Создание массива для хранения прошедших валидацию опций  
    $output = array();  
      
    // Цикл для обработки всех входящих опций  
    foreach( $input as $key => $value ) {  
          
        // Проверка на то, имеет текущая опция значение или нет. Если да, то обрабатываем её  
        if( isset( $input[$key] ) ) {  
          
            // Вырезаем все HTML- и PHP-теги, а также правильным образом обрабатываем строки в кавычках  
            $output[$key] = strip_tags( stripslashes( $input[ $key ] ) );  
              
        } // Конец конструкции if  
          
    } // Конец конструкции foreach  
      
    // Возврат обработанного массива
    return apply_filters( 'sandbox_theme_validate_input_examples', $output, $input );  
  
}

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

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

Наконец, мы можем просто возвратить массив $output в конце функции, но возврат результата работы функции apply_filters лучше.

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

И в завершение, давайте изменим кое-что в файле index.php и посмотрим, как можно осуществлять очистку при выводе. Рекомендуется всегда очищать опции перед выводом.

Найдите следующую строку:

<?php echo $input_examples[ 'input_example' ]; ?>

И замените её на:

<?php echo sanitize_text_field( $input_examples[ 'input_example' ] ); ?>

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

Многострочное поле ввода (textarea)

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

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

add_settings_field(   
    'Многострочный элемент ввода',                       
    'Многострочный элемент ввода',                           
    'sandbox_textarea_element_callback',      
    'sandbox_theme_input_examples',   
    'input_examples_section'              
);

Далее, давайте определим callback-функцию, необходимую для отображения нашего поля:

function sandbox_textarea_element_callback() {  
      
    $options = get_option( 'sandbox_theme_input_examples' );  
      
    // Вывод на экран  
    echo '<textarea id="textarea_example" name="sandbox_theme_input_examples[textarea_example]" rows="5" cols="50">' . $options[ 'textarea_example' ] . '</textarea>';  
      
}

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

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

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

<?php if( $input_examples[ 'textarea_example' ] ) { ?>  
    <?php echo sanitize_text_field( $input_examples[ 'textarea_example' ] ); ?>  
<?php } // Конец конструкции if ?>

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

Заключение

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

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

Перевод статьи «The Complete Guide To The WordPress Settings API, Part 7: Validation, Sanitisation, and Input I» был подготовлен дружной командой проекта Сайтостроение от А до Я.