Создание плагина для WordPress. Часть 3

13-02-25 WordPress PHP, WordPress 6

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

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

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

Options API

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

<?php get_option('opting_name'); ?>
<?php update_option('option_name', $new_value); ?>

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

Страница настроек плагина

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

<?php add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $output_function, $icon_url, $position ); ?>

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

<?php add_submenu_page( $parent_slug, $page_title, $menu_title, $capability, $menu_slug, $function ); ?>

В параметре $parent_slug необходимо передавать ID главной страницы. Если нет необходимости создавать несколько страниц, вы можете создать страницу в составе уже существующего меню — обычно “Settings” (Параметры), в параметре $parent_slug необходимо передать options-general.php. Также есть функции для регистрации страниц под определенным меню, в случае с меню «Параметры» — add_options_page().

Settings API

Settings API позволяет создать интерфейс для настроек плагина. Зарегистрируйте страницу настроек (для автоматического управления вводом), создайте секции и поля для ввода. Сделать это можно следующим образом:

<?php register_setting($option_group, $option_name, $sanitise_callback); ?>
<?php add_settings_section( $id, $title, $callback, $page ); ?>
<?php add_settings_field( $id, $title, $callback, $page, $section, $args ); ?>

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

После регистрации наших настроек и полей, надо их показать на странице настроек — следующая функция должна вызываться внутри тега <form>:

<?php settings_fields($option_group); ?>
<?php do_settings_sections($page); ?>

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

Безопасность

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

Еще один вопрос безопасности — права пользователей. В WordPress есть механизмы для управления ролями и возможностями пользователей, с помощью которых можно блокировать доступ к некоторым функциям пользователям с недостаточными правами. При создании страницы настроек, необходимо присвоить ей какой-либо уровень доступа (обычно ‘manage_options’) и не позволить доступ к ней пользователям с недостаточными правами (для более подробной информации прочтите документацию).

Собираем все вместе

Соберем все вместе посмотрим как это работает.

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

Ранее мы создали разметку для блока об авторе. Сейчас мы сделаем возможным изменять шаблон нашего блока пользователем. Наш плагин содержит два подключаемых файла: core.php (содержит основной код) и admin.php (содержит код для администратора).

Создание страницы настроек (admin.php):

/* register menu item */
function msp_helloworld_admin_menu_setup() {
    add_submenu_page(
        'options-general.php',
        'Helloworld Settings',
        'Helloworld',
        'manage_options',
        'msp_helloworld',
        'msp_helloworld_admin_page_screen'
    );
}

//menu setup
add_action('admin_menu', 'msp_helloworld_admin_menu_setup');

/* display page content */
function msp_helloworld_admin_page_screen() {
    global $submenu;

    // access page settings
    $page_data = array();

    foreach ($submenu['options-general.php'] as $i => $menu_item) {
        if ($submenu['options-general.php'][$i][2] == 'msp_helloworld') {
            $page_data = $submenu['options-general.php'][$i];
        }
    }
    // output
?>
    <div class="wrap">
        <?php screen_icon(); ?>
        <h2><?php echo $page_data[3]; ?></h2>
        <form id="msp_helloworld_options" action="options.php" method="post">
            <?php
            settings_fields('msp_helloworld_options');
            do_settings_sections('msp_helloworld');
            submit_button('Save options', 'primary', 'msp_helloworld_options_submit');
            ?>
        </form>
    </div>
    <?php
}

/* settings link in plugin management screen */

function msp_helloworld_settings_link($actions, $file) {
    if (false !== strpos($file, 'msp-helloworld')) {
        $actions['settings'] = '<a href="options-general.php?page=msp_helloworld">Settings</a>';
    }

    return $actions;
}

add_filter('plugin_action_links', 'msp_helloworld_settings_link', 2, 2);

Функция msp_helloworld_admin_menu_setup создает страницу-подпункт меню «Settings»(Параметры), для правильной работы, эта функция должна выполниться в хуке ‘admin_menu’. Затем создаем форму с настройками в функции msp_helloworld_admin_page_screen. Обратите внимание на атрибут тега <form>: он  должен указывать на «options.php» для правильной работы с настройками. И в конце функция msp_helloworld_settings_link создает ссылку на страницу с настройками со страницы управления плагинами.

Plugin settings link
Plugin settings link

Регистрация настроек плагина и полей

/* регистрация настроек в системе */
function msp_helloworld_settings_init() {
    register_setting(
        'msp_helloworld_options',
        'msp_helloworld_options',
        'msp_helloworld_options_validate'
    );

    add_settings_section(
        'msp_helloworld_authorbox',
        'Author\'s box',
        'msp_helloworld_authorbox_desc',
        'msp_helloworld'
    );

    add_settings_field(
        'msp_helloworld_authorbox_template',
        'Template',
        'msp_helloworld_authorbox_field',
        'msp_helloworld',
        'msp_helloworld_authorbox'
    );
}

add_action('admin_init', 'msp_helloworld_settings_init');

/* обработка ввода */

function msp_helloworld_options_validate($input) {
    global $allowedposttags, $allowedrichhtml;

    if (isset($input['authorbox_template'])) {
        $input['authorbox_template'] = wp_kses_post($input['authorbox_template']);
    }

    return $input;
}

/* описание */

function msp_helloworld_authorbox_desc() {
    echo "<p>Enter the template markup for author box using placeholders: [gauthor_name], [gauthor_url], [gauthor_desc] for name, URL and description of author correspondingly.</p>";
}

/* вывод полей */

function msp_helloworld_authorbox_field() {
    $options = get_option('msp_helloworld_options');
    $authorbox = (isset($options['authorbox_template'])) ? $options['authorbox_template'] : '';
    $authorbox = esc_textarea($authorbox);
?>
    <textarea id="authorbox_template" name="msp_helloworld_options[authorbox_template]" cols="50" rows="5" class="large-text code">
    <?php echo $authorbox; ?>
    </textarea>
<?php
}

Все настройки плагина должны храниться в массиве. Несмотря на то, что у нас всего одна опция (authorbox_template), мы включаем её в массив. Функция msp_helloworld_settings_init должна выполниться в хуке ‘admin_init’. Функция msp_helloworld_options_validate обрабатывает входные данные с помощью фильтра wp_kses_post. Функция  msp_helloworld_authorbox_desc создает описание для секции с формой, а msp_helloworld_authorbox_field выводит поле для ввода разметки.

Настройки плагина WordPress
Настройки плагина WordPress

Функция для вывода блока автора (core.php)

Эта функция будет заменять в шаблоне из базы данных метки ([gauthor_name], [gauthor_url], [gauthor_desc]) на соответствующие значения.

function msp_helloworld_author_block() {
    global $post;
    $author_terms = wp_get_object_terms($post->ID, 'gauthor');

    if (empty($author_terms)) {
        return;
    }

    $name = stripslashes($author_terms[0]->name);
    $url = esc_url(get_term_link($author_terms[0]));
    $desc = wp_filter_post_kses($author_terms[0]->description);

    //get template from option
    $options = get_option('msp_helloworld_options');
    $out = (isset($options['authorbox_template'])) ? $options['authorbox_template'] : '';

    $out = str_replace(
        array('[gauthor_url]','[gauthor_name]', '[gauthor_desc]'), array($url, $name, $desc), $out
    );

    return $out;
}

Конечный вид плагина:

WordPress плагин
WordPress плагин

Наш плагин готов!

Хочешь получать статьи на почту?

Подпишись на обновления!
* Ваш email не будет разглашен/продан. Вы сможете отписаться в любое время.

6 Комментариев

  1. yesworld:

    Добрый день!

    Вы могли бы объяснить этот кусок кода:
    $page_data = array();
    foreach($submenu[‘options-general.php’] as $i => $menu_item) {
    if($submenu[‘options-general.php’][$i][2] == ‘msp_helloworld’)
    $page_data = $submenu[‘options-general.php’][$i];
    }

    1. root:

      Здравствуйте!
      Глобальный объект $submenu содержит всю информацию о меню на странице администратора. Данный код пробегает по всем подпунктам меню «Настройки» (options-general.php) и когда находит нашу собственную страницу достает всю информацию о ней. Этот массив будет содержать данные, которые мы передали в функцию add_submenu_page:

      add_submenu_page(
          'options-general.php',
          'Helloworld Settings',
          'Helloworld',
          'manage_options',
          'msp_helloworld',
          'msp_helloworld_admin_page_screen'
      );
      
  2. yesworld:

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

    1. root:

      Плагин в сборе. Для проверки работоспособности необходимо создать пост с указанием новой таксономии (Guest authors), которую мы сами создали.

  3. Александр:

    root:, а как сделать ключ активации для своего плагина? Вот есть у меня предположим плагин, не для всех, и что бы он не гулял в свободном доступе, как можно для него сделать ключ активации? Очень хотелось бы увидеть подобный урок ну или поверхностное описание! Спасибо!

  4. Uglion:

    А как бы сделать, чтобы можно было поставить ссылку на автора на другом сайте? Например на его страничку в соц. сети. Просто сейчас он ссылается на страницу авторов, где гостевых авторов как раз и нет. Я даже попытался поставить ссылку в описании автора, но она получается такого вида: site.ru://v.com/id12345678

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *