xbreaker's

Статистика просмотра страниц без использования плагинов в WordPress

Многие знают, что в WordPress есть такая замечательная штука как Произвольные поля (Custom Fields), и что, благодаря им, можно реализовывать практически что угодно. Сегодня мы рассмотрим пример то, как с помощью простого кода и этих полей можно сделать сбор статистики по количеству просмотров постов и страниц в WordPress, а также организуем удобный вывод, рейтинги по общему количеству просмотров, просмотров за сегодня и за вчера.

Так как WordPress отличается довольно большим аппетитом, то наверняка у многих включено кеширование, а кто-то только планирует его включить, в любом случае, это не должно отобразиться на сборе статистики, поэтому мы будем использовать простой AJAX запрос при отображении поста. Итак, приступим.


Первое, что нам необходимо сделать – организовать структуру Произвольных полей, пусть она будет выглядеть так:

  • views – количество просмотров за все время существования топика;
  • tviews — количество просмотров за сегодня;
  • yviews – количество просмотров за вчера;
  • tdate – дата текущего дня, нужна для копирования данных с tviews в yviews при изменении даты.

Далее создаем файл view.php и кладем его в нужный вам каталог, например, в корень сайта, у меня он будет располагаться в папке /js/. В него методом GET мы будем передавать параметр views_id — id открываемого поста, он, в свою очередь, будет увеличивать значение полей views и tviews на 1. Вот его код:

<?php
require_once($_SERVER['DOCUMENT_ROOT'].'/wp-load.php'); //загружаем окружение wordpress, файл wp-load.php лежит в корне структуры каталогов WordPress
if (function_exists('get_post_custom')) { //проверяем загрузилось ли оно
  global $wpdb;
  global $OFFSET; //получение настроек часового пояса
  $nowtime = gmdate('Y-m-d', time() + 3600*$OFFSET); //генерация текущей даты
  $post_id = intval($_GET['views_id']); //инициализируем переменную с id поста
        if($post_id > 0) {
                $post_views = get_post_custom($post_id); //получаем Custom Fields
                $post_views_t = intval($post_views['views'][0]);
                /* пытаемся обновить значения просмотров, если не получается, то создаем такое поле */
                if(!update_post_meta($post_id, 'views', ($post_views_t+1))) {
                        add_post_meta($post_id, 'views', 1, true);
                }
                $today_date = $post_views['tdate'][0];
                $today_views = intval($post_views['tviews'][0]);
                if(!$today_date) {
                  add_post_meta($post_id, 'tdate', $nowtime, true);
                }
                /* проверяем текущую дату, если совпадает, то обновляем, если нет, то копируем в yviews и обнуляем */
                if($today_date == $nowtime) {
                  if(!update_post_meta($post_id, 'tviews', ($today_views+1))) {
                          add_post_meta($post_id, 'tviews', 1, true);
                        }
                } else {
                  if(!update_post_meta($post_id, 'yviews', $today_views)) {
                          add_post_meta($post_id, 'yviews', $today_views, true);
                        }
                        update_post_meta($post_id, 'tviews', 1);
                        update_post_meta($post_id, 'tdate', $nowtime);
                }
        }
}
?>

Код достаточно простой, поэтому для его понимания должно хватить комментраиев по коду. Вызывать этот файл мы будет в шаблоне заголовка вашей темы — header.php. Для этого нам понадобится библиотека jQuery, а так же следующие строки (вставить перед вызовом wp_head ()):

<?php
wp_enqueue_script('jquery'); /* подключаем jQuery */

global $post;
$views_id = intval($post->ID);

if(is_single() || is_page()) {
        echo '<script type="text/javascript">'."\n";

        echo '/* <![CDATA[ */'."\n";
        echo "jQuery.ajax({type:'GET',url:'http://site.ru/js/view.php',data:'views_id=".$views_id."',cache:false});"."\n";

        echo '/* ]]> */'."\n";
        echo '</script>'."\n";
}
?>

Теперь при открытии страницы количество просмотров будет сохраняться, а если страница открыта в начале следующего дня, то значение просмотров за текущий день скопируется и обнулится. Можно переходить к выводу различной статистики. Для начала напишем функцию вывода общего количества просмотров для возможности их показа. Открываем файл functions.php, если он не существует, то создаем и записываем следующую функцию:

<?php
/* Отображение количества просмотров      */

/* display - отображать или возвращать    */
/* prefix - текст перед числом просмотров */
/* postfix - текст после числа просмотров */
function get_views($display = true, $prefix = '', $postfix = '') {

        $post_views = intval(post_custom('views'));

        $output = $prefix.$post_views.$postfix;
        if($display) {

                echo $output;
        } else {

                return $output;
        }
}
?>

Теперь в файле-шаблоне страницы/поста single.php мы можем выводить количество просмотров (стоит только убедиться, что вызов функции происходит внутри условия while (have_posts ())), например, так:

<span class="view" title="просмотры"><?php get_views(); ?></span>

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

<span class="view" title="просмотры"><?php printf('%s', get_post_meta($post->ID, 'views', true)); ?></span>

Для вывода самых просматриваемых постов «за все время», «за сегодня» и «за вчера» также можно обойтись без функции, например, для постов «за все время» код получится таким:

<?php  
$temp_query = $wp_query; $temp_post = $post; /* сохранение текущих значений для избежания конфликтов с другими запросами на странице */

$post = $posts[0]; /* хук для верного даты поста, если она понадобится */ ?>
<ul>
<?php

$query= 'meta_key=views&meta_compare=>=&meta_value=1&orderby=meta_value_num&order=DESC&showposts=30'; // составление запроса
query_posts($query);

if (have_posts()) : while (have_posts()) : the_post(); ?>

<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a><span><?php printf('%s',get_post_meta($post->ID, 'views', true)); ?></span></li>

<?php  endwhile; endif;
$post = $temp_post; $wp_query = $temp_query;
?>
</ul>

Его можно использовать в любом шаблоне вашей темы, например, в sidebar.php. Аналогично можно выводить статистику по просмотрам «за вчера» и «за сегодня», а количество выводимых записей можно регулировать параметром showposts при составлении запроса. Стоит только отметить, что сортировка по meta_value_num появилась в WordPress 3.0 и в более младших версиях 2.х, без правки файлов самого WP, работать не будет. Если же у вас версия 2.х, а использовать такую сортировку хочется, то открываем файл /wp-includes/query.php и в двух местах редактируем следующим образом:

После строчек

if ( !empty($q['meta_key']) ) {
  $allowed_keys[] = $q['meta_key'];
  $allowed_keys[] = 'meta_value';

добавляем

$allowed_keys[] = 'meta_value_num';

А после

case 'meta_value':
  $orderby = "$wpdb->postmeta.meta_value";
  break;

добавляем

case 'meta_value_num':
  $orderby = "$wpdb->postmeta.meta_value+0";
  break;

Теперь сортировка по числовому значению произвольного поля будет работать в версиях WordPress 2.х.

В итоге мы получили достаточно простую реализацию функции подсчета просмотра страниц/постов в WordPress и обошлись без использования каких-либо плагинов. Я уверен, что мой пример далек от идеала, но с поставленной задачей он справляется на отлично.

  1. Преогромная благодарность автору! Очень полезно!

    Насколько я понимаю модифицировать для вывода популярных не за сегодня или вчера, а например за неделю или месяц не совсем просто? (не во всем смог разобраться).

    • Спасибо за отзыв! А переделать не сложно, как раз таки проще простого :)

      В переменную $nowtime переделать таким образом:

      $nowtime = gmdate('Y-m', time() + 3600*$OFFSET);

      то есть она будет возвращать только год и месяц и аналогичным образом сравнивать поменялся месяц или нет, а про неделю нужно просто сравнивать количество дней

  2. Все хорошо расписано!

  3. всё, разрулил полностью еще раз спасибо!

  4. Подскажите пожалуйста как вывести популярные записи в single.php, но только из той категории к которой принадлежит эта запись.

    • с строку:

      $query= 'meta_key=views&meta_compare=>=&meta_value=1&orderby=meta_value_num&order=DESC&showposts=30';

      добавьте параметр category с номером категории, к которой принадлежит ваш пост

      • Это я делал, но мне нужно чтобы категория сама определялась в зависимости от поста и от категории в которой находится этот пост.

        Хотел подробнее объяснить, сообщает что комментарий длянный

  5. Приветствую! Что-то не получается :( Вроде все сделал как по инструкции — а внизу страницы (badablog.ru/kolonka-razra... -sdk/#more-14245) просто висит 0. Может что-то не так делаю? Версия 3.х. Хотя сам в этом я не мастер

  6. Здравствуйте, а как сделать вывод просмотров за 7 дней? зараннее благодарен

    • Привет, для статистики за неделю нужно просто обнулять просмотры в tdate с промежутком в 7 дней, то есть между ydate и tdate разница должна быть не 1 день как сейчас, а 7 дней.