Commit 0cc852b1 authored by Vadim's avatar Vadim

Version 1.1

1. Доработан список Популярных Постов 2. Добавлена обработка ошибок в БД
parent e231635f
......@@ -3,7 +3,7 @@
Plugin Name: Bg Az-Counter
Plugin URI: https://bogaiskov.ru
Description: Подсчет количества посещений страниц на базе stat.azbyka.ru
Version: 1.0
Version: 1.1
Author: VBog
Author URI: https://bogaiskov.ru
License: GPL2
......@@ -38,7 +38,7 @@ if ( !defined('ABSPATH') ) {
die( 'Sorry, you are not allowed to access this page directly.' );
}
define('BG_COUNTER_VERSION', '1.0');
define('BG_COUNTER_VERSION', '1.1');
define('BG_COUNTER_LOG', dirname(__FILE__ ).'/bg_counter.log');
define('BG_COUNTER_STAT_COUNTERS','https://stat.azbyka.ru/counters');
define('BG_COUNTER_STAT_RAITING','https://stat.azbyka.ru/rating');
......@@ -46,24 +46,8 @@ define('BG_COUNTER_STAT_SET','https://stat.azbyka.ru/set-counter');
define('BG_COUNTER_REALTIME_VIEW','wss://stat.azbyka.ru/realtime-view');
$upload_dir = wp_upload_dir();
define('BG_COUNTER_ARCHIVE',str_replace(ABSPATH, '', $upload_dir['basedir']).'/bg_az_counter.json');
// Регистрируем крючок на удаление плагина
if (function_exists('register_uninstall_hook')) {
register_uninstall_hook(__FILE__, 'bg_counter_deinstall');
}
function bg_counter_deinstall() {
delete_option('bg_counter_options');
delete_option('bg_pvc_loaded');
delete_option('bg_wppp_loaded');
delete_option('bg_wppm_loaded');
delete_option('bg_archive_status');
delete_option('bg_counter_period');
}
// Снять комментарий, чтобы сбросить флаг загрузки:
//delete_option('bg_pvc_loaded'); // - " - из Post Views Counter
//delete_option('bg_wppp_loaded'); // - " - из WP Popular Posts
//delete_option('bg_wppm_loaded'); // - " - из произвольных полей "views"
define('BG_COUNTER_DEFECT',str_replace(ABSPATH, '', $upload_dir['basedir']).'/bg_az_counter_defect.json');
// Определяем имя проекта
if (!isset($project)) {
if (wp_parse_url( site_url(), PHP_URL_HOST ) == 'azbyka.ru') {
$project = wp_parse_url( site_url(), PHP_URL_PATH );
......@@ -86,18 +70,22 @@ add_action( 'wp_enqueue_scripts' , 'bg_counter_enqueue_frontend_styles' );
include_once ("inc/options.php");
// Виджеты
include_once ("inc/widgets.php");
// Импорт данных из внешних источников и архива
include_once ("inc/import.php");
// JS скрипт
function bg_counter_enqueue_frontend_scripts () {
global $project;
$option = get_option('bg_counter_options');
if (is_single() || is_page()) {
$postID = get_post()->ID;
$type = 'post';
} else {
$postID = '';
$type = '';
$postID = '';
$type = '';
if (is_single() || is_page()) { // Только записи и страницы
$post = get_post();
if ($post->post_status == 'published') { // Только опубликованные
$postID = $post->ID;
$type = 'post';
}
}
wp_enqueue_script( 'bg_counter_proc', plugins_url( 'js/counter.js', __FILE__ ), false, BG_COUNTER_VERSION, true );
wp_localize_script( 'bg_counter_proc', 'bg_counter',
......@@ -115,20 +103,17 @@ if ( !is_admin() ) {
add_action( 'wp_enqueue_scripts' , 'bg_counter_enqueue_frontend_scripts' );
}
date_default_timezone_set (get_option('timezone_string'));
// Расписание ежедневной обработки. Начало в полночь текущего часового пояса
if ( !wp_next_scheduled( 'bg_counter_stack_cron_action' ) ) {
wp_schedule_event( ceil((time()-date('Z'))/DAY_IN_SECONDS)*DAY_IN_SECONDS, 'daily', 'bg_counter_stack_cron_action' );
// Регистрируем крючок на удаление плагина
if (function_exists('register_uninstall_hook')) {
register_uninstall_hook(__FILE__, 'bg_counter_deinstall');
}
add_action( 'bg_counter_stack_cron_action', 'bg_counter_daily_action' );
// Ежедневная обработка
function bg_counter_daily_action () {
date_default_timezone_set (get_option('timezone_string'));
// Сохраняем архив результатов
$result = bg_counter_saveStatictics();
if ($result !== false) update_option( 'bg_archive_status', "<div class='notice notice-info'><p><b>".date("Y-m-d H:i:s", time())."</b> сохранено <b>". $result ."</b> записей в файле архива статистики: <code>". BG_COUNTER_ARCHIVE ."</code></p></div>" );
else update_option( 'bg_archive_status', "<div class='notice notice-error'><p><b>".date("Y-m-d H:i:s", time())."</b> Ошибка при сохранении данных статистки. См. журнал ошибок: <code>". BG_COUNTER_LOG ."</code></p></div>" );
function bg_counter_deinstall() {
delete_option('bg_counter_options');
delete_option('bg_pvc_loaded');
delete_option('bg_wppp_loaded');
delete_option('bg_wppm_loaded');
delete_option('bg_archive_status');
delete_option('bg_counter_period');
}
......@@ -163,7 +148,7 @@ GET /rating/project/test/author/1?limit=5&offset=3
}
Если счётчик не существует, возвращает пустой массив потомков.
******************************************************************************************/
function getPopularPosts ($limit, $offset=0) {
function getPopularPosts ($limit, $offset=0, $number=false) {
global $project;
$option = get_option('bg_counter_options');
......@@ -186,17 +171,20 @@ function getPopularPosts ($limit, $offset=0) {
if ($response->success == true){
$the_key='getPopularPostss_key';
if(false===($quote=get_transient($the_key))) {
$quote = '<ul class="bg-az-top-posts">'. PHP_EOL;
if ($number) $quote = '<ol class="bg-az-top-posts">'. PHP_EOL;
else $quote = '<ul class="bg-az-top-posts">'. PHP_EOL;
foreach ($response->data as $p) {
if ($p->type!='post') continue;
$id = intval($p->id);
if (!$id) continue;
$post = get_post($id);
if (!$post) continue;
$title = $post->post_title;
$link = '<a href="'.site_url().'/?p='.$id.'" title="'.$title.'">'.$title.'</a>';
$link = '<a href="'. get_permalink($post).'" title="'.$title.'" data-ID="'.$p->id.'" data-type="'.$p->type.'" data-value="'.$p->value.'" data-status="'.$post->post_status.'">'.$title.'</a>';
$quote .= '<li>'.$link.' - <span class="bg-az-count">'.number_format($p->value, 0, ',', '&nbsp;').'</span></li>'. PHP_EOL;
}
$quote .= '</ul>'. PHP_EOL;
if ($number) $quote .= '</ol>'. PHP_EOL;
else $quote .= '</ul>'. PHP_EOL;
set_transient( $the_key, $quote, $option['period'] );
}
return $quote;
......@@ -323,185 +311,10 @@ function bg_counter_shortcode( $atts ) {
function bg_counter_top_posts_shortcode( $atts ) {
global $post;
extract( shortcode_atts( array(
'limit' => '10'
'limit' => '10',
'number' => false
), $atts ) );
$quote = getPopularPosts ($limit);
$quote = getPopularPosts ($limit, 0, $number);
return "{$quote}";
}
/*****************************************************************************************
Получить данные из произвольного поля views
и отправить на сервер
******************************************************************************************/
function bg_counter_getWPPostMeta() {
global $wpdb;
global $project;
// Получить данные из таблицы
// postid(bigint(20)), day(datetime), last_viewed(datetime), pageviews(bigint(20))
$old_data = $wpdb->get_results("SELECT post_id,meta_value FROM ".$wpdb->prefix."postmeta WHERE meta_key='views'", ARRAY_A);
// Формируем запрос
$i = 0;
$data = array();
$point = array();
foreach ($old_data as $row) {
$point['path'] = $project.'/post/'.$row['post_id'];
$point['counter'] = (int)$row['meta_value'];
$data[] = $point;
$i++;
}
$json = json_encode($data, JSON_UNESCAPED_SLASHES);
echo $json."<br>";
// Отправить данные на сервер
if (!setAllCounts ($json)) return false;
return $i;
}
/*****************************************************************************************
Получить данные из плагина WP Popular Posts
и отправить на сервер
******************************************************************************************/
function bg_counter_getWPPopularPosts() {
global $wpdb;
global $project;
// Получить данные из таблицы
// postid(bigint(20)), day(datetime), last_viewed(datetime), pageviews(bigint(20))
$old_data = $wpdb->get_results("SELECT postid,pageviews FROM ".$wpdb->prefix."popularpostsdata", ARRAY_A);
// Формируем запрос
$i = 0;
$data = array();
$point = array();
foreach ($old_data as $row) {
$point['path'] = $project.'/post/'.$row['postid'];
$point['counter'] = (int)$row['pageviews'];
$data[] = $point;
$i++;
}
$json = json_encode($data, JSON_UNESCAPED_SLASHES);
echo $json."<br>";
// Отправить данные на сервер
if (!setAllCounts ($json)) return false;
return $i;
}
/*****************************************************************************************
Получить данные из плагина Post Views Counter
и отправить на сервер
******************************************************************************************/
function bg_counter_getPostViewsCounter() {
global $wpdb;
global $project;
// Получить данные из таблицы
// postid(bigint(20)), day(datetime), last_viewed(datetime), pageviews(bigint(20))
$raw_data = $wpdb->get_results("SELECT id,count FROM ".$wpdb->prefix."post_views", ARRAY_A);
// Суммируем count по id
$old_data = array();
foreach ($raw_data as $row) {
if (empty($old_data[$row['id']])) $old_data[$row['id']] = 0;
$old_data[$row['id']] = (int)$row['count'];
}
// Формируем запрос
$i = 0;
$data = array();
$point = array();
foreach ($old_data as $id => $count) {
$point['path'] = $project.'/post/'.$id;
$point['counter'] = $count;
$data[] = $point;
$i++;
}
$json = json_encode($data, JSON_UNESCAPED_SLASHES);
echo $json."<br>";
// Отправить данные на сервер
if (!setAllCounts ($json)) return false;
return $i;
}
/*****************************************************************************************
Получить данные с сервера
и сохранить их в файле
******************************************************************************************/
function bg_counter_saveStatictics() {
global $project;
$limit = 100;
$offset = 0;
$count = $limit;
$data = array();
// Получить данные с сервера
while ($count >= $limit) {
$result = wp_remote_get (BG_COUNTER_STAT_RAITING.$project."?limit=".$limit."&offset=".$offset."&type=post");
if( is_wp_error( $result ) ) {
error_log( PHP_EOL .date("Y-m-d H:i:s ", time())." АРХИВ. Ошибка при получении данных с сервера: ".$result->get_error_message(), 3, BG_COUNTER_LOG ); // сообщение ошибки
error_log( " " .$result->get_error_code(), 3, BG_COUNTER_LOG ); // ключ ошибки
return false;
}
if (($code = wp_remote_retrieve_response_code( $result )) != 200) {
error_log( PHP_EOL .date("Y-m-d H:i:s ", time())." АРХИВ. Сервер вернул код ошибки: ".$code, 3, BG_COUNTER_LOG ); // сообщение ошибки
error_log( " " .wp_remote_retrieve_response_message( $result ), 3, BG_COUNTER_LOG ); // ключ ошибки
return false;
}
$json = wp_remote_retrieve_body($result);
$response = json_decode($json, false);
if (!$response->success) {
error_log( PHP_EOL .date("Y-m-d H:i:s ", time())." АРХИВ. Сервер вернул ответ неудачи: ".print_r($response, true), 3, BG_COUNTER_LOG );
return false;
}
$count = count($response->data);
if ($count) $data = array_merge($data, $response->data);
$offset += $limit;
}
$json = json_encode($data, JSON_UNESCAPED_SLASHES);
if (file_put_contents ( ABSPATH.BG_COUNTER_ARCHIVE, $json ) === false) {
error_log( PHP_EOL .date("Y-m-d H:i:s ", time())." АРХИВ. Ошибка записи в файл: ".BG_COUNTER_ARCHIVE, 3, BG_COUNTER_LOG );
return false;
}
return ($offset-$limit+$count);
}
/*****************************************************************************************
Получить данные из файла архива
и отправить на сервер
******************************************************************************************/
function bg_counter_sendArchiveData() {
global $project;
// Получить данные из файла архива
$json = file_get_contents ( ABSPATH.BG_COUNTER_ARCHIVE);
if (!$json) {
echo "<br>" ."Ошибка чтения файла: ".BG_COUNTER_ARCHIVE;
return false;
}
$old_data = json_decode($json, true);
// Формируем запрос
$i = 0;
$data = array();
$point = array();
foreach ($old_data as $row) {
$point['path'] = $project.'/'.$row['type'].'/'.$row['id'];
$point['counter'] = $row['value'];
$data[] = $point;
$i++;
}
$json = json_encode($data, JSON_UNESCAPED_SLASHES);
echo $json."<br>";
// Отправить данные на сервер
if (!setAllCounts ($json)) return false;
return $i;
}
<?php
// Снять комментарий, чтобы сбросить флаг загрузки:
//delete_option('bg_pvc_loaded'); // - " - из Post Views Counter
//delete_option('bg_wppp_loaded'); // - " - из WP Popular Posts
//delete_option('bg_wppm_loaded'); // - " - из произвольных полей "views"
/*****************************************************************************************
Получить данные из произвольного поля views
и отправить на сервер
******************************************************************************************/
function bg_counter_getWPPostMeta() {
global $wpdb;
global $project;
// Получить данные из таблицы
// postid(bigint(20)), day(datetime), last_viewed(datetime), pageviews(bigint(20))
$old_data = $wpdb->get_results("SELECT post_id,meta_value FROM ".$wpdb->prefix."postmeta WHERE meta_key='views'", ARRAY_A);
// Формируем запрос
$i = 0;
$data = array();
$point = array();
foreach ($old_data as $row) {
$point['path'] = $project.'/post/'.$row['post_id'];
$point['counter'] = (int)$row['meta_value'];
$data[] = $point;
$i++;
}
$json = json_encode($data, JSON_UNESCAPED_SLASHES);
echo $json."<br>";
// Отправить данные на сервер
if (!setAllCounts ($json)) return false;
return $i;
}
/*****************************************************************************************
Получить данные из плагина WP Popular Posts
и отправить на сервер
******************************************************************************************/
function bg_counter_getWPPopularPosts() {
global $wpdb;
global $project;
// Получить данные из таблицы
// postid(bigint(20)), day(datetime), last_viewed(datetime), pageviews(bigint(20))
$old_data = $wpdb->get_results("SELECT postid,pageviews FROM ".$wpdb->prefix."popularpostsdata", ARRAY_A);
// Формируем запрос
$i = 0;
$data = array();
$point = array();
foreach ($old_data as $row) {
$point['path'] = $project.'/post/'.$row['postid'];
$point['counter'] = (int)$row['pageviews'];
$data[] = $point;
$i++;
}
$json = json_encode($data, JSON_UNESCAPED_SLASHES);
echo $json."<br>";
// Отправить данные на сервер
if (!setAllCounts ($json)) return false;
return $i;
}
/*****************************************************************************************
Получить данные из плагина Post Views Counter
и отправить на сервер
******************************************************************************************/
function bg_counter_getPostViewsCounter() {
global $wpdb;
global $project;
// Получить данные из таблицы
// postid(bigint(20)), day(datetime), last_viewed(datetime), pageviews(bigint(20))
$raw_data = $wpdb->get_results("SELECT id,count FROM ".$wpdb->prefix."post_views", ARRAY_A);
// Суммируем count по id
$old_data = array();
foreach ($raw_data as $row) {
if (empty($old_data[$row['id']])) $old_data[$row['id']] = 0;
$old_data[$row['id']] = (int)$row['count'];
}
// Формируем запрос
$i = 0;
$data = array();
$point = array();
foreach ($old_data as $id => $count) {
$point['path'] = $project.'/post/'.$id;
$point['counter'] = $count;
$data[] = $point;
$i++;
}
$json = json_encode($data, JSON_UNESCAPED_SLASHES);
echo $json."<br>";
// Отправить данные на сервер
if (!setAllCounts ($json)) return false;
return $i;
}
/*****************************************************************************************
Получить данные из файла архива
и отправить на сервер
******************************************************************************************/
function bg_counter_sendArchiveData() {
global $project;
// Получить данные из файла архива
$json = file_get_contents ( ABSPATH.BG_COUNTER_ARCHIVE);
if (!$json) {
echo "<br>" ."Ошибка чтения файла: ".BG_COUNTER_ARCHIVE;
return false;
}
$old_data = json_decode($json, true);
// Формируем запрос
$i = 0;
$data = array();
$point = array();
foreach ($old_data as $row) {
$point['path'] = $project.'/'.$row['type'].'/'.$row['id'];
$point['counter'] = $row['value'];
$data[] = $point;
$i++;
}
$json = json_encode($data, JSON_UNESCAPED_SLASHES);
echo $json."<br>";
// Отправить данные на сервер
if (!setAllCounts ($json)) return false;
return $i;
}
/*****************************************************************************************
Получить данные с сервера
и сохранить их в файле
******************************************************************************************/
function bg_counter_saveStatictics() {
global $project;
ini_set('memory_limit', '1024M');
$limit = 100;
$offset = 0;
$count = $limit;
$data = array();
// Получить данные с сервера
while ($count >= $limit) {
$result = wp_remote_get (BG_COUNTER_STAT_RAITING.$project."?limit=".$limit."&offset=".$offset."&type=post");
if( is_wp_error( $result ) ) {
error_log( PHP_EOL .date("Y-m-d H:i:s ", time())." АРХИВ. Ошибка при получении данных с сервера: ".$result->get_error_message(), 3, BG_COUNTER_LOG ); // сообщение ошибки
error_log( " " .$result->get_error_code(), 3, BG_COUNTER_LOG ); // ключ ошибки
return false;
}
if (($code = wp_remote_retrieve_response_code( $result )) != 200) {
error_log( PHP_EOL .date("Y-m-d H:i:s ", time())." АРХИВ. Сервер вернул код ошибки: ".$code, 3, BG_COUNTER_LOG ); // сообщение ошибки
error_log( " " .wp_remote_retrieve_response_message( $result ), 3, BG_COUNTER_LOG ); // ключ ошибки
return false;
}
$json = wp_remote_retrieve_body($result);
$response = json_decode($json, false);
if (!$response->success) {
error_log( PHP_EOL .date("Y-m-d H:i:s ", time())." АРХИВ. Сервер вернул ответ неудачи: ".print_r($response, true), 3, BG_COUNTER_LOG );
return false;
}
$count = count($response->data);
$i=0;
if ($count) {
// Верификация и очистка записей
foreach ($response->data as &$row) {
$status = verify_post ($row->id);
if ($status != 'publish') {
if ($row->value) {
$defect = " ".$row->id." ".$row->type." ".$row->value." ".$status;
error_log( PHP_EOL .date("Y-m-d H:i:s ", time())." АРХИВ. Неверный статус записи: ".$defect, 3, BG_COUNTER_LOG );
// Обнуляем счетчик в ошибочной записи
$row->value = 0;
// и отправляем нулевое значение на сервер для удаления
$path = '/'.$row->type.'/'.$row->id;
if (!setCount ($path, 0)) {
error_log( PHP_EOL .date("Y-m-d H:i:s ", time())." АРХИВ. Не удалось обнулить запись: ".$path, 3, BG_COUNTER_LOG );
}
}
}
// Удаляем записи с нулевыми значениями из сохраняемого массива
if ($row->value == 0) unset($response->data[$i]);
$i++;
}
unset($row);
$data = array_merge($data, $response->data);
}
$offset += $limit;
}
$count = count($data);
$json = json_encode($data, JSON_UNESCAPED_SLASHES);
if (!$json) error_log( PHP_EOL .date("Y-m-d H:i:s ", time())." АРХИВ. Ошибка преобразования в json.", 3, BG_COUNTER_LOG );
if (file_put_contents ( ABSPATH.BG_COUNTER_ARCHIVE, $json ) === false) {
error_log( PHP_EOL .date("Y-m-d H:i:s ", time())." АРХИВ. Ошибка записи в файл: ".BG_COUNTER_ARCHIVE, 3, BG_COUNTER_LOG );
return false;
}
return ($count); // Количество записей для данного проекта
}
/*****************************************************************************************
Проверяет и возвращает статус поста по его ID
******************************************************************************************/
function verify_post ($id) {
$id = (int)$id;
if ($id <= 0) return 'incorrect_id';
$post = get_post($id);
if (!$post) return 'no_post';
$type = $post->post_type;
if ($type != 'post' && $type != 'page') return $type;
$status = $post->post_status;
return $status;
}
/*****************************************************************************************
Расписание ежедневной обработки.
Начало в полночь текущего часового пояса
******************************************************************************************/
date_default_timezone_set (get_option('timezone_string'));
if ( !wp_next_scheduled( 'bg_counter_stack_cron_action' ) ) {
wp_schedule_event( ceil((time()-date('Z'))/DAY_IN_SECONDS)*DAY_IN_SECONDS, 'daily', 'bg_counter_stack_cron_action' );
}
add_action( 'bg_counter_stack_cron_action', 'bg_counter_daily_action' );
// Ежедневная обработка
function bg_counter_daily_action () {
date_default_timezone_set (get_option('timezone_string'));
// Сохраняем архив результатов
$result = bg_counter_saveStatictics();
if ($result !== false) update_option( 'bg_archive_status', "<div class='notice notice-info'><p><b>".date("Y-m-d H:i:s", time())."</b> сохранено <b>". $result ."</b> записей в файле архива статистики: <code>". BG_COUNTER_ARCHIVE ."</code></p></div>" );
else update_option( 'bg_archive_status', "<div class='notice notice-error'><p><b>".date("Y-m-d H:i:s", time())."</b> Ошибка при сохранении данных статистки. См. журнал ошибок: <code>". BG_COUNTER_LOG ."</code></p></div>" );
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment