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;

 }

}

?>