Публикация в группе: Кастомизация WP-Recall и Wordpress

На самом деле мы будем производить подсчет не "скачиваний" а кликов по нужным ссылкам, т.е. если в посте кликнули по ссылке "скачать" - считаем что файл скачан, не важно что там дальше сделает пользователь.

1. Создаем новую таблицу в базе

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

Назовем таблицу: wp_day_download

Сделаем столбцы: post_id | date | dl

2. Создаем файл редиректа

Теперь в корне нашего сайта надо создать новый php файл, который будет использоваться для редиректа нужных ссылок. Через него то и будут считаться скачивания (заноситься в базу)

Доп. бонус редиректа в том, что мы можем поставить на нем задержку, например в 10 сек, и показать там рекламу и через 10 сек перенаправить пользователя по ссылке.

Назовем файл dl.php и добавим в него следующий код:

<?php 
// Смотрим есть ли что то в url
$url=isset($_REQUEST['url']) ? $_REQUEST['url'] : '';
// Если есть декодируем
$url = urldecode($url);
//Смотрим есть ли что то в id
$post_id = (int) isset($_REQUEST['id']) ? $_REQUEST['id'] : '';
// Проверяем что id поста - число и оно больше 0
  if(is_numeric($post_id) AND $post_id > 0){
  // указываем, что нам нужен минимум от WP
  define('SHORTINIT', true);
  // подгружаем среду WordPress
  // WP делает некоторые проверки и подгружает только самое необходимое для подключения к БД
  require_once( $_SERVER['DOCUMENT_ROOT'] . '/wp-load.php' );
  // тут мы можем общаться с БД. Но практически никакие функции WP работать не будут.
  // Глобальные переменные $wp, $wp_query, $wp_the_query не установлены...
  global $wpdb;
  // Проверяем есть ли пост с переданным id
  $pst = $wpdb->query ( "SELECT * FROM wp_posts WHERE ID = $post_id AND post_type = 'post' LIMIT 1" );
     // Если пост с нашим id есть в базе
     if ($pst == 1) {
        // берем -- meta_id с meta_key downloads --  нашего поста
        $row =(int) $wpdb->get_var( "SELECT meta_id FROM wp_postmeta WHERE post_id=$post_id AND meta_key='downloads' LIMIT 1"  );
        // сегодня в формате 2016-02-29 (+3 часа для МСК)
        $date = date('Y-m-d', strtotime("+3 hours"));
        // Заносим суммарные скачивания поста в мета-данные этого поста
        $wpdb->query("INSERT INTO wp_postmeta SET meta_id = $row, post_id = $post_id,meta_key = 'downloads',meta_value = 1 ON DUPLICATE KEY UPDATE meta_value=meta_value + 1");
        // Заносим в нашу созданную таблицу суточные скачивания поста
        $wpdb->query("INSERT INTO wp_day_download SET post_id = $post_id, date = '$date', dl = 1 ON DUPLICATE KEY UPDATE dl=dl + 1");
        // Перенаправляем пользователя по ссылке с задержкой 0 сек
        header("Refresh:0; URL=".$url."");
        //Так же тут можно вывести какой-то HTML код и изменить задержку перенаправления
        // что позволит показать рекламку или вывести кнопку --перейти--
     // Если поста с нашим id в базе нет, показываем ошибку
     } else {
        exit ("Ошибка. Хакер что ли?2");
  // Если ид поста не число или оно равно или меньше 0 то редиректим на страницу 404
  } else {
  header("Location: /page/404.html"); 
  exit; 
  }
?>

Как вы заметили мы будем использовать  define('SHORTINIT', true); а это значит что почти никакие функции wordpress в этом файле работать не будут, но тут этого и не нужно. А нагрузки нет никакой!

Ну что же, теперь думаю понятно что ссылки на скачивание у нас будут иметь вид:

site.ru/dl.php?url=<закодированный url>&id=<ид поста>

3. Конвертируем ссылки в постах в нужный формат

Теперь нам осталось только конвертировать ссылки в нужный формат.

Т.к. у меня на сайте больше 10.000 записей - отредактировать все ссылки ручками это очень тяжело, тогда решено было написать функцию которая будет фильтровать контент поста и заменять ссылки на НУЖНЫЕ домены.

Да-да, мы будем заменять ссылки только на те домены, где лежит файл. Конечно если писать сайт с нуля, я бы сделал для ссылок какое-то мета-поле и заменял бы только ссылки из него, но и в нашем случае все будет работать отлично.

В functions.php необходимо добавить следующий код

function filter_function_name_11( $content ) {
	
global $post;
 
$posttype = get_post_type($post->ID);
// Работаем только с постами типа post
if ($posttype == 'post') {
  // Массив с доменами ссылки на которые НАДО заменить
  $blacklists = array ('fileplanet.', 'yadi.sk' );
  // Берем содержимое HREF всех ссылок постов и записываем в $links
  preg_match_all('~<a.*?href="([^"]+)".*?>(.*?)</a>~s', $content, $links);
     // Просматриваем каждую ссылку отдельно
     foreach ($links[1] as $l) {
        // Берем по 1ой ссылку из массива с теми доменами, на которые надо заменять ссылки
        foreach ($blacklists as $blacklist) {
           // Если в Nой ссылке есть домент из черного списка - заменяем
           if (strpos($l,$blacklist)) {
                  $content = str_replace('href="'.$l,'href="/dl.php?url='.urlencode($l).'&id='.$post->ID.'" class="dl-link" target="_blank" rel="nofollow', $content);
           }
	}
     }
}
		
	return $content;
}

add_filter( 'the_content', 'filter_function_name_11' );

Тут конечно 99% что не самый "Оптимальный" способ проверки, но вроде никакой особой нагрузки нет. В любом случае буду рад любым замечаниям - с радостью внесу их и у себя на сайте, а не только тут.

Так же, как вы могли заменить, нужным ссылкам мы присвоим class="dl-link" - можно использовать его для выделения таких ссылок.

4. Важно. Код для single.php

Как вы поняли общие скачивания мы будем заносить в мета поле поста, однако его немного геморно создавать в файле dl.php, но выход очень прост:

В single.php добавьте (в цикле конечно же):

$downloads = get_post_meta($post->ID, "downloads", true);

if (!$downloads) { add_post_meta($post->ID, 'downloads', '0', true); }

И все будет отлично: после того как кто-то откроет пост - проверится есть ли у него мета поле downloads и если нет - добавится. А значит клик по нашей сгенерированной ссылке внутри поста нормально отработается.

Ну и итог:

Как показать общие скачивания?

get_post_meta($post->ID, "downloads", true);

Как показать скачивания за сутки?

global $wpdb;
$date = date('Y-m-d', strtotime("+3 hours"));
$post_id = $post->ID;
$dlToDay = $wpdb->get_var("SELECT dl FROM wp_day_download WHERE post_id=$post_id AND date='$date'");
echo $dlToDay;

Как показать скачивания за N дней?

global $wpdb;
$day = 7; // Кол-во дней за которые показать скачивания
$post_id = $post->ID;
$dlByDay = $wpdb->get_var("SELECT SUM(dl) FROM wp_day_download WHERE post_id=$post_id AND date>=DATE_ADD(CURRENT_TIMESTAMP,INTERVAL -".$day." DAY)");
echo $dlByDay;
5

Автор публикации

не в сети 2 дня

Preci

1 493
Telegram: https://t.me/preci_123
Комментарии: 495Публикации: 83Регистрация: 11-11-2014Продаж/Покупок: 0/0