4

Q2W3 Screen Options Hack Demo. Изменение панели «Настройки экрана»

В процессе написания плагина Q2W3 Inc Manager пришлось решить несколько проблем. Одна из которых отсутствие в WP стандартных средств, позволяющих изменить под себя панель «Настройки экрана». Ниже я привожу код демонстрационного плагина, решающего эту проблему.



Выглядит измененная панель примерно так:

Измененная панель Настройки экрана

Измененная панель настройки экрана

Скачать демонстрационный плагин (комментарии на английском).

Данная статья актуальна при разработке плагинов под WP 2.8.x -2.9.x.

Код демонстрационного плагина с комментариями:

<?php
/*
Plugin Name: Q2W3 Screen Options Hack Demo
Plugin URI: http://www.q2w3.ru/2010/01/08/1155/
Description: This plugin shows how to create your own web-form for `screen options` panel
Version: 1.0
Author: Max Bond
Author URI: http://www.q2w3.ru/
*/

add_action('init', array('q2w3_screen_options_hack_demo','reg_hooks')); // инициализация плагина

register_deactivation_hook(__FILE__, array('q2w3_screen_options_hack_demo', 'de_activate')); // регистрируем функцию деактивации плагина

if (class_exists('q2w3_screen_options_hack_demo', false)) return; // если класс уже загружен возвращает управление основному скрипту

class q2w3_screen_options_hack_demo {

  public static $plugin_page_id; // переменная для хранения ID страницы настроек плагина

  public static $user_option_name = 'sohdemo'; // имя поля meta_key в таблице wp_usermeta. Важно!!! Имя поля не должно содержать цифры! Необходимо для сохранения данных формы

  public static function de_activate() { // Функция деактивации плагина. Удаляет все записи, созданные плагином в таблице wp_usermeta

    global $wpdb;

    $wpdb->query('DELETE FROM '. $wpdb->usermeta ." WHERE meta_key = '". self::$user_option_name ."'"); // delete all plugin entries in usermeta table

  }

  public static function reg_hooks() { Функция регистрирующая действия плагина

    if (is_admin()) { // только для административной части

      add_action('admin_menu', array(__CLASS__, 'reg_menu')); // функция, регистрирующая страницу настроек плагина в главном меню

      add_filter('set-screen-option', array(__CLASS__, 'screen_options_save'), 10, 3); // функция обработки данных формы перед записью в БД

    }

  }

  public static function reg_menu() { // Функция регистрирующая страницу настроек плагина в главном меню, а также дополнительные действия для которых требуется ID страницы настроек

    self::$plugin_page_id = add_submenu_page('plugins.php', 'Q2W3 Screen Options Hack DEMO', 'Q2W3 SOH DEMO', 8, plugin_basename(__FILE__), array(__CLASS__,'settings_page')); // создаем ссылку на страницу настроек плагина в разделе Плагины

    add_action('manage_'. self::$plugin_page_id .'_columns', array(__CLASS__, 'screen_options_form')); // внедряемся в панель Настройки экрана

    add_action('contextual_help_list', array(__CLASS__, 'help_form')); // внедряемся в панель Помощь (это не обязательно для изменения Настроек экрана, просто бонус)

  }

  public static function settings_page() { // Функция выводящая содержание страницы настроек плагина

    $res = '<div>'.PHP_EOL;

    $res .= '<h2>Q2W3 Screen Options Hack Demo</h2>'.PHP_EOL;

    $res .= '<p>Check screen options panel</p>';

    $res .= '</div><!--wrap-->'.PHP_EOL;

    echo $res;

  }

  public static function screen_options_form($columns) { // Функция добавляющая произвольные поля в панель Настройки экрана

    $checkboxes = array('option_1'=>'Option 1', 'option_2'=>'Option 2', 'option_3'=>'Option 3'); // массив для отображения чекбоксов (аналогично можно добавить другие элементы веб-формы)

    $text_fields = array('option_4'=>'Option 4'); // массив для отображения текстовых полей

    $default_values = array('option_1'=>'1', 'option_2'=>'0', 'option_3'=>'1', 'option_4'=>'This is a text'); // массив значений по умолчанию

    $values = get_user_option(self::$user_option_name); // загружаем данные из БД

    if ($values !== false) { если в БД есть данные

      $values = unserialize($values); // конвертация необходима чтобы восстановить массив значений

    } else { // если в БД нет данных

      $values = $default_values; // используем значения по умолчанию

    }

    // Начало формирования данных формы

    $hack = '</label><script>jQuery("label[for=\'screen_options_hack-hide\']").hide()</script>'.PHP_EOL; // этот код jQuery необходим чтобы скрыть ненужный чекбокс, вставляемый WP автоматически

    foreach ($checkboxes as $key=>$name) { // создаем чекбоксы

      $hack .= '<div style="float: left; margin-left: 9px">'; // при желании форматирование можно вынести в отдельный файл, но для наглядности оставляю его тут

      if ($values[$key] == '1') $checked = ' checked="checked"'; else $checked = false;

      $hack .= '<input type="checkbox" name="wp_screen_options[value]['. $key .']" value="1" '. $checked .'/>'. $name; // в названии элемента wp_screen_options[value] должно присутствовать всегда

      $hack .= '</div>';

    }

    $hack .= '<div style="clear: left; font-size: 0px">&nbsp;</div>'.PHP_EOL;

    $hack .= '<h5>Other options</h5><div>';

    foreach ($text_fields as $key=>$name) { // создаем текстовые поля

      $hack .= $name .' <input type="text" name="wp_screen_options[value]['. $key .']" value="'. $values[$key] .'" />'.PHP_EOL;

    }

    $hack .= '<input type="hidden" name="wp_screen_options[option]" value="'. self::$user_option_name .'" />'; // для передачи meta_key. name="wp_screen_options[option]" - не изменять!

    $hack .= '<input type="submit" class="button" value="Apply" />'; // Кнопка отправки формы

    $hack .= '</div>';

    return array('screen_options_hack'=>$hack); // функция должна возвращать ассоциативный массив

    // Попробую теперь объяснить смысл произведенных действий. WP из массива возвращенного данной функцией попытается в панели `Настройки экрана` создать чекбоксы (якобы для управления столбцами таблицы). Мы подсовываем WP массив из одного элемента, где индекс элемента массива (screen_options_hack) будет использоваться для идентификации чекбокса, созданного WP, и последующего его скрытия с помощью jQuery (см начало переменной $hack), а значение элемента массива WP использует как подпись для чекбокса. Подпись может содержать любые теги, этим мы пользуемся, чтобы добавить собственные элементы формы.

  }

  public static function screen_options_save($value, $option_name, $new_settings) { // Функция обрабатывающая данные формы перед записью в БД

    // можно использовать для проверки введенных пользователям данных и т.п.

    $new_settings['option_4'] = strip_tags(trim($new_settings['option_4']));

    return serialize($new_settings); // возвращаем массив уже подготовленный к записи в БД

  }

  public static function help_form($help_content) { Функция для внедрения в панель Помощь

    $help_content[self::$plugin_page_id] = 'Help for plugin settings page'; // используем идентификатор страницы, чтобы добавить текст только для страницы настроек плагина

    return $help_content;

  }

}

?>