Печать
PDF

Защищённые метаданные в WordPress

Автор: Administrator.

 

Некоторые поля метаданных не предназначены для изменения пользователями. Их можно "защитить". Термин взят в кавычки, потому что защита эта - лишь соглашение: не давать пользователям возможности непосредственно их редактировать. Например, метабокс "Произвольные поля" такие поля скрывает.

 


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

Принятие решения о защищённости поля возложено на функцию is_protected_meta. Критерием является её результат:

if (is_protected_meta($meta_key, $meta_type)) {
// поле является защищённым
...
}


Аргумент $meta_type - тип владеющих полем данных - тут опционален. Защищённость определяется главным образом по имени. Условия два:
1) ключ начинается с символа подчёркивания: '_meta_key';
2) вызов фильтра 'is_protected_meta' даёт истину;

Первый критерий реализован, например, в произвольных полях постов. Данные с такими ключами скрыты.

Второй критерий весьма интересен. С его помощью можно отменять первый критерий или защищать не подпадающие под него поля. Вот пример такого фильтра:

add_filter('is_protected_meta', 'hide_my_meta', 10, 2);

function hide_my_meta ($protected, $meta_key) {
if ($meta_key == "my_previously_unprotected_meta")
return true; // скрыть
return $protected; // не реагировать на остальное
}



Чтобы защитить поле, надо вернуть для него истину. Соответственно, чтобы защиту снять, возвращать следует ложь. Менять защищённость чужих полей не следует, поэтому для них фильтруемый $protected не меняется.

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

Проиллюстрируем возможности на примере.

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

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

Первая версия этого плагина может выглядеть, например, так:

<?php
/*
* Plugin Name: Мерцающий заголовок поста
*/

add_action('wp_print_scripts', 'bph_add_scripts');

$bph_script_path = trailingslashit(get_bloginfo('wpurl')).PLUGINDIR.'/'.dirname(plugin_basename(__FILE__)).'/js/mdh.js';

function bph_add_scripts () {
global $bph_script_path;
global $wp_query;

if ($wp_query->is_single) {
$p = $wp_query->post;
if (!isset($p->bph_blinking_header) || !$p->bph_blinking_header)
return;
$args = array('mode' => 'single');
} else {
$args = array('mode' => 'list', 'ids' => array());
foreach ((array)$wp_query->posts as $p)
if (isset($p->bph_blinking_header) && $p->bph_blinking_header)
$args['ids'][] = $p->ID;
if (!$args['ids'])
return;
}
wp_enqueue_script('bph_script', $bph_script_path, array('jquery', 'jquery-color'));
wp_localize_script('bph_script', 'bph_script_args', $args);
}



Этот скрипт находится в wp-content/plugins/blinking_post_header/blinking_post_header.php. Он заставляет WordPress отправлять пользователю другой скрипт, находящийся в wp-content/plugins/blinking_post_header/js/mdh.js:

(function($) {
$.fn.one_more_time = function () {
return $(this).animate({color: "red"}, 200)
.animate({color: "black"}, 300, "swing",
function() {
$(this).one_more_time();
});
}
$(document).ready(function () {
if ("list" == bph_script_args.mode) {
var i, ids = bph_script_args.ids;
for (i in ids)
$("article#post-" + String(ids[i]) + " header h1.entry-title a").one_more_time();
} else
$("h1.entry-title").one_more_time();
});
})(jQuery);



После активации плагина заголовки постов, имеющих ненулевое поле метаданных 'mdh_blinking_header', будут мерцать.

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

add_filter('is_protected_meta', function ($protected, $key) {
return 'bph_blinking_header' == $key || $protected;
}, 10, 2);

Обратите внимание: для всех остальных полей флаг защищённости возвращается без изменений.

Оставшаяся часть плагина следует непосредственно за фильтром. Здесь создаётся метабокс с галочкой и сохраняется её значение:

add_action('add_meta_boxes', function () {
add_meta_box('bph_metabox', 'Мерцающий заголовок', 'bph_metabox', 'post', 'side');
});

function bph_metabox ($post, $metabox) {
echo "<p>Включить: <input type='checkbox' name='bph_blinking_flag'"
. checked(isset($post->bph_blinking_header) && $post->bph_blinking_header, true, false)
. " /></p>";
}

add_action('save_post', function ($id) {
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
return;
update_post_meta($id, 'bph_blinking_header', isset($_POST['bph_blinking_flag']));
});



Дополнение: пояснение работы плагина

Плагин создавался для тем "twenty-eleven" и "twenty-twelve". Использовался WordPress ветки 3.5 с PHP 5.4.

Мы расширяем прототип класса jQuery функцией one_more_time, начинающей изменение цвета заголовка, завершающееся её же вызовом. Текст, таким образом, будет постоянно мерцать.

Включение мигания выполняется сразу после загрузки документа. Причём, если происходит просмотр списка постов (режим "list"), перекраска осуществляется для каждого поста из списка. Когда же просматривается отдельный пост - задействуется только один заголовок с классом "entry-title".

Решение о посылке скрипта и формирование входных аргументов происходит на стороне сервера в функции bph_add_scripts. Выполняется она в момент вставки скриптов на страницу. При подготовке запроса мы вручную роемся в $wp_query, чтобы избежать активации хуков, связанных с циклом вывода контента. Ко времени формирования страницы запрос на посты уже сделан самим WordPress'ом. Его результат находится в глобальном $wp_query.

К полю метаданных мы обращаемся, как к полю класса WP_Post. Это позволяется его реализацией.

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


Предыдущие материалы: