Wordpress изнутри – Плагин LikeIt! | DAndreev.com

WordPress изнутри – Плагин LikeIt!

wp_codex

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

Теория

И так, хранить показатели счетчика будем (ну где же еще) в мета полях поста.
Ну, это легко, а вот как сделать вывод постов, отсортировав их по данным этого счетчика, вот это уже задача сложнее.
Я для этого решил залезть в WordPress на уровень SQL запросов и там использовать JOIN инструкции.
Суть их заключается в том, что из двух таблиц по определенному условию строки связываются между собой, и становятся одной единой таблицей и соответственно уже по ней можно делать сортировку.
Вот и присоединим, мета поля со значениями ‘Like’ к соответствующим постам, и можно будет уже осуществлять сортировку.
Ну в теории всё просто, а вот на практике это же другое дело.

Практика

Итак для того, чтобы присоединить необходимые мета поля к данным поста, необходимо добавить в SQL запрос, который посылает WordPress при загрузке, необходимые JOIN инструкции. Сделать это можно благодаря встроенному фильтру “posts_join”, добавим к нему нашу функцию, в которой и будем писать в SQL запрос всё, что нам нужно.

add_filter('posts_join','sortAsLike');
function sortAsLike($join)
{
global $wp_query;
global $wpdb;

if(isset($wp_query->query_vars['like_sort']))
{
if($wp_query->query_vars['like_sort'])
{
$join .= "LEFT JOIN {$wpdb->postmeta} pmeta ON pmeta.post_id = {$wpdb->posts}.ID AND pmeta.meta_key = 'like' ";
}
}
return $join;
}

Обратите внимание, я добавил переменную поиска “like_sort” для тогда, чтобы сортировка по полю Like не была постоянной, а ее можно было использовать как дополнительную инструкцию.
А чтобы можно было использовать переменную поиска “like_sort”, добавим ее к списку уже существующих переменных объекта WP_Query при помощи фильтра “query_vars”.

add_filter('query_vars','queryVars');
function queryVars($query_vars)
{
// добавим переменную 'like_sort'
array_push($query_vars,'like_sort');
return $query_vars;
}

Теперь осталось отсортировать посты в запросе по полю “Like”, для этого добавим инструкцию, в которой описаны поля и тип сортировки посредством фильтра “posts_orderby”.

add_filter('posts_orderby', 'posts_orderby', 10, 2);

function posts_orderby($orderby, $query)
{
global $wpdb;
global $wp_query;

if(isset($wp_query->query_vars['like_sort']))
{
$orderby = " CAST(pmeta.meta_value AS signed) DESC ";
}
return $orderby;
}

Функционал сортировки постов готов, теперь осталось совсем немного, сделать функцию для увеличения счетчика Like для выбранного поста.
Для начала получим поля поста, если поле ‘like’ пустое, то создаем новое, если же нет, то увеличиваем счетчик и обновляем поле.

function addLikeToPost($post_id, $n = 1)
{
$post_meta = get_post_custom($post_id);
$like = (!empty($post_meta['like'])) ? implode($post_meta['like']) : $like = 0;

$total = intval($like) + $n;

update_post_meta($post_id, 'like', $total);

return $total;
}

Такую функцию некрасиво использовать без AJAX, потому сделаем обработку нажатия на ссылку через Ajax запрос, для этого подключим нашу функцию к соответствующим событиям, а возвращать она будет объект JSON c конечной суммой счетчика:

add_action('wp_ajax_likeit', 'addLike');
add_action('wp_ajax_nopriv_likeit','addLike');
function addLike()
{
$response = array(
'count' => 0
);

if(!empty($_POST['post_id']))
$response['count'] = addLikeToPost($_POST['post_id']);

die(json_encode($response));
}

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

jQuery(document).ready(function()
{

// действие инициируется ссылкой
// с назначенным классом "like-it"
jQuery('a.like-it').click(function()
{
var id = jQuery(this).attr('rel');
var link = jQuery(this);
var counter_wrapper = jQuery(this).parent().find('.like-counter span');

// параметры Ajax запроса:
// название события
// ID поста
params = {
action : 'likeit',
post_id : id
};

// Отправляем Ajax запрос, и ожидаем JSON
// при получении ответа, обновляем счетчик на странице,
// или добавляем, если его не было
jQuery.post(likeit_vars.ajax_url,params, function(response){

if( counter_wrapper.html() == null)
jQuery(link).before('
<div class="like-counter">Понравилось: <span>' + response.count + '</span></div>
');
else
jQuery(counter_wrapper).html(response.count);

},'json');

return false;
});
});

Чтобы этот скрипт работал, необходимо его добавить и локализовать при помощи следующих функций:
$plugin_dir = basename(dirname(__FILE__));
wp_enqueue_script('likeit', '/wp-content/plugins/'.$plugin_dir.'/likeit.js', array('jquery'));
wp_localize_script('likeit', 'likeit_vars', array(
'ajax_url' =>; get_bloginfo('url').'/wp-admin/admin-ajax.php',
));

Ну и в завершении осталось сделать функцию, которая будет выводить элементы управления на странице. Можно, конечно их и самостоятельно выводить, но мне нравится, когда всё сделано аккуратно, потому они будут выводится с через событие ‘like_it_inteface’.
В качестве параметра она принимает текст ссылки «Like», но также в нее можно вставить и html код, например, изображения.

function likeItInteface($param_link = '')
{
$link = $param_link != '' ? $param_link : __('Голосовать');

global $post;
$fields = get_post_custom($post->;ID);

if(!empty($fields['like']))
echo '
<div class="like-counter">'.__('Понравилось') .': <span>' . implode($fields['like']) . '</span></div>
';

echo '<a class="like-it" rel="'. $post->;ID .'" href="#">'. $link .'</a>';
}

И теперь в цикле loop вывода постов вызываем её простым выводом:

< ?php do_action('like_it_inteface','Like this!!!'); ?>

Заключение

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

Полностью файл плагина вы можете скачать сдесь

Retweet

Похожие статьи

Комментарии

Maksim
07 May, 2011в21:28

Привет,
как раз искал что-то подобное, поставил твой плагин, но разобраться как его инсталировать в пост не могу. Можешь подсказать? Спасибо заранее.

Дмитрий Андреев
08 May, 2011в12:26

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

< ?php do_action('like_it_inteface','Like this!!!'); ?>

Maksim
08 May, 2011в18:53

Вроде бы все так и сделал…
Результата пока не видно(

Оставить комментарий