Программируем лайки на Вордпрессе

Рассмотрим, как можно самостоятельно запрограммировать кнопку Like для записей в Вордпрессе (WordPress).

Для этого нам понадобиться одна таблица для хранения лайков, назовем ее wp_hp_likes. Вот SQL запрос для ее создания:

CREATE TABLE `wp_hp_likes` (
`post_id` int(10) unsigned NOT NULL,
`likes` int(10) unsigned NOT NULL,
`log` longtext NOT NULL,
PRIMARY KEY (`post_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Мы добавили поле `log` для хранения логов лайков для текущей записи. Если вам не нужен лог, можете удалить это поле или создать отдельную таблицу для лога (этот вариант мы не будем рассматривать).

Затем надо надо будет модифицировать несколько файлов для текущей темы.

Нам надо добавить ajax запрос для отсылки информации в вордпресс по лайку.

Для этого надо в основной файл javascript добавить следующий код:

$(document).ready(function() {
$('[data-like]').on('click', function() {
	var t=$(this), is = t.data('like-is');
	if(is) {
		alert('Вы уже проголосовали');
		return false;
	}
	var post_id = parseInt(t.data('like'));
	if(isNaN(post_id)) return false;
	var data = { action: 'like', nonce : myajax.nonce, post_id: post_id };
	$.post( myajax.url, data, function( response ) {
	if(/^\d+$/.test(response)) {
		t.data('like-is', 1);
		t.text(response);
		var tmpl = t.data('like-title-tmpl');
		if(tmpl) t.attr('title', tmpl.replace('#', response));
	}
	else alert( response );
	});
})
}

Этот код использует библиотеку JQuery. Если она не подключена в теме, вам нужно будет переписать код без использования этой библиотеки.

Кпопка лайка должна содержать атрибут data-like со значением ID поста и текстом с числом лайков, например <span data-lake="1">10</span>. Также кнопка может содержать атрибуты data-like-is, равный 1 или 0, если за пост уже проголосовал посетитель или нет, like-title-tmpl — шаблон для задания атрибута title, в котором символ решетки # заменяется на количество лайков после выполнения ajax запроса.

Если вы не хотите лезть в чужие скрипты, можно добавить в файл footer.php темы, предварительно завернув его в теги <script></script>.

Код минималистичен, но для демонстрации нам подойдет.

В файле functions.php текущей темы надо добавить несколько правок.

1) Нужно добавить обработку ajax запроса

if( wp_doing_ajax() ){
	add_action('wp_ajax_like', 'do_like');
	add_action('wp_ajax_nopriv_like', 'do_like');
}

function do_like() {
// простые проверки параметров ajax запроса
	if(!isset($_POST['nonce'], $_POST['post_id'])) die( 'Oops');
	$nonce = $_POST['nonce'];
	$post_id = intval($_POST['post_id']);
	if($post_id < =0) die( 'Oops'); // проверяем nonce код, если проверка не пройдена прерываем обработку if( ! wp_verify_nonce( $nonce, 'myajax-nonce' ) ) die( 'Oops'); // обрабатываем данные и возвращаем // проверяем установлены ли cookie для посетителя и есть ли в них информация по лайку для данного поста $my_likes = array(); if(isset($_COOKIE['wp-likes'])) { $my_likes = @json_decode($_COOKIE['wp-likes']); if(!is_array($my_likes)) $my_likes = array(); } $isLike = false; if(!in_array($post_id, $my_likes)) $my_likes[] = $post_id; else $isLike = true; // если $isLike == true, посетитель уже голосовал за пост, ему надо просто отдать текущее количество лайков. global $wpdb; //ищем в базе информацию по лайкам данного поста $ps = $wpdb->get_results(sprintf("SELECT * FROM `wp_hp_likes` WHERE `post_id`=%u", $post_id) );

//формируем лог, если лог не нужен удалите следующую строку и другие строки для записи лога
	$log = sprintf("%s\t%s\t%s", time(), GetVisitorIP(), isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '');
	if(count($ps) == 0) {
//информации по лайкам нет, надо добавить пост с лайком 1
		$likes = 1;
		$wpdb->insert( 'wp_hp_likes', array('post_id'=>$post_id, 'likes' => $likes, 'log' => $log));
	}
	else {
//информации по лайкам есть, если пользователь уже проголосовал ($isLike == true), просто отдаем его количество лайков
		if($isLike) $likes = $ps[0]->likes;
		else {
//обновляем количество лайков, увеличенным на 1
			$likes = $ps[0]->likes + 1;
			$log = $ps[0]->log."\r\n".$log;
			$wpdb->update( 'wp_hp_likes', array('likes' => $likes, 'log' => $log), array('post_id' => $post_id));
		}
	}
//запишем в куки данные по лайках пользователя, чтобы потом отсекать накрутку	
	$_COOKIE['wp-likes'] = json_encode($my_likes);
	setcookie('wp-likes', $_COOKIE['wp-likes'], time() + 30*24*60*60, '/', $_SERVER['HTTP_HOST']);
//выдадим количество лайков
	print $likes;
	wp_die();
}
// вешаем хук для очистки таблицы при удалении поста 
add_action( 'deleted_post', 'h_deleted_post' );
function h_deleted_post( $post_id ){
	global $wpdb;
	$wpdb->query(sprintf('DELETE FROM `wp_hp_likes` WHERE `post_id`=%u', $post_id));
}

2) Генерация nonce. Надо найти секцию в файле functions.php, где подключаются javascript-скрипты (поищите по коду wp_enqueue_script или wp_register_script).
К одному из скриптов нужно прикрепить локализатор. В нашем примере код скрипта ‘main-js’, вам надо поменять на свой. Желательно найти скрипт, который будет подключен ко всем страницам, где будет выводится кнопка лайка.

wp_localize_script('main-js', 'myajax', 
	array(
		'url' => admin_url('admin-ajax.php'),
		'nonce' => wp_create_nonce('myajax-nonce')
	)
);  

Это добавит нам на страницу javascript-объект myajax с полями url (адресом для отправки ajax запросов) и nonce (одноразовым числом для простенькой защиты). Этот объект используется в нашем коде javascript.

По ajax запросам и nonce есть хорошая обзорная статья.

3) Вспомогательные функции

// получение IP адреса голосующего
function GetVisitorIP(){
	if (($IP = getenv('HTTP_CLIENT_IP'))===false)
	if (($IP = getenv('HTTP_X_FORWARDED_FOR'))===false)
	if (($IP = getenv('HTTP_X_FORWARDED'))===false)
	if (($IP = getenv('HTTP_FORWARDED_FOR'))===false)
	if (($IP = getenv('HTTP_FORWARDED'))===false)
		$IP = $_SERVER['REMOTE_ADDR'];
	return $IP;
}
// определим, голосовал ли посетитель за пост с id = $post_id (функция возвращает true, если голосовал)
function is_my_post_like($post_id) {
	static $my_likes = false;
	if($my_likes === false) {
		$my_likes = array();
		if(isset($_COOKIE['wp-likes'])) {
			$my_likes = @json_decode($_COOKIE['wp-likes']);
			if(!is_array($my_likes)) $my_likes = array();
		}
	}
	return in_array($post_id, $my_likes);
}

// функция возвращает количество лайков для поста с id = $post_id
function get_post_likes($post_id) {
	global $wpdb;
	$likes = 0;
	$ps = $wpdb->get_results(sprintf("SELECT `likes` FROM `wp_hp_likes` WHERE `post_id`=%u", $post_id) );
	if(count($ps) != 0) $likes = $ps[0]->likes;
	return $likes;
}

Теперь нам надо добавить html разметку для кнопки Лайк.

Требования к кнопке были описаны выше при описании javascript кода.
При выводе записи, например, в списках или на отдельных страницах (page.php, single.php), нужно указать примерно такой код:

<?php
	$likes = get_post_likes($post->ID);
	$iLike = is_my_post_like($post->ID);
?>
<span class="like-button" data-like="<?=$post->ID?>" data-like-is="<?=intval($iLike)?>" data-like-title-tmpl="Понравилось #" title="Понравилось <?=$likes?>"><?=$likes?><span>

Здесь переменная $post является выборкой из базы постов в цикле Вордпресса (WordPress Loop). Конкретное название переменной может отличатся в различных случаях.

Ну и напоследок нам осталось стилизовать кнопку. В нашем случае ей присвоен класс like-button, который надо описать в файлах стилей темы.

Это все! Надеюсь, что приведенная информация поможет в разработке новых тем или плагинов для популярной CMS Вордпресс.

P.S. Аналогично можно запрограммировать дислайки, убавляя поле likes в таблице wp_hp_likes на единицу, а также сделать аналогичный функционал для комментариев.

Программируем лайки на Вордпрессе: 1 комментарий

  1. А как получить количество лайков конкретного поста? Например, что бы рассчитывать рейтинг пользователя?

Обсуждение закрыто.