Upload via GUI (30 Dateien)
This commit is contained in:
+126
-19
@@ -62,7 +62,8 @@ function wp_multi_track_user_activity($user_id, $action, $post_id = null) {
|
|||||||
$post_id = get_the_ID();
|
$post_id = get_the_ID();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$user_id || !$action) {
|
// user_id 0 ist gewollt: Die Seite bietet keinen Login, Aufrufe sind anonym.
|
||||||
|
if (!$action) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,26 +93,93 @@ function wp_multi_comment_activity($comment_id) {
|
|||||||
add_action('comment_post', 'wp_multi_comment_activity');
|
add_action('comment_post', 'wp_multi_comment_activity');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verfolgt Beitragsaufrufe.
|
* Erkennt Bots und Crawler anhand des User-Agents.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
function wp_multi_is_bot_request() {
|
||||||
|
$user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? strtolower(sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT']))) : '';
|
||||||
|
|
||||||
|
// Ohne User-Agent ist es so gut wie nie ein echter Besucher
|
||||||
|
if ($user_agent === '') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$signatures = apply_filters('wp_multi_bot_signatures', [
|
||||||
|
'bot', 'crawl', 'spider', 'slurp', 'archiver', 'preview', 'monitor', 'validator',
|
||||||
|
'facebookexternalhit', 'headless', 'phantomjs', 'python', 'curl', 'wget', 'go-http',
|
||||||
|
'java/', 'okhttp', 'axios', 'scrapy', 'lighthouse', 'pingdom', 'uptime',
|
||||||
|
]);
|
||||||
|
|
||||||
|
foreach ($signatures as $signature) {
|
||||||
|
if (strpos($user_agent, $signature) !== false) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prüft, ob dieser Besucher den Beitrag gerade erst aufgerufen hat.
|
||||||
|
*
|
||||||
|
* Ohne Login gibt es keine Benutzer-ID, deshalb dient ein kurzlebiger Hash aus
|
||||||
|
* IP und User-Agent als Erkennungsmerkmal. Gespeichert wird nur der Hash, nie
|
||||||
|
* die IP selbst – ein Reload zählt damit nicht mehrfach.
|
||||||
|
*
|
||||||
|
* @param int $post_id Beitrag-ID.
|
||||||
|
* @return bool True, wenn der Aufruf bereits gezählt wurde.
|
||||||
|
*/
|
||||||
|
function wp_multi_view_already_counted($post_id) {
|
||||||
|
$ip = isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR'])) : '';
|
||||||
|
$user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '';
|
||||||
|
|
||||||
|
$key = 'wp_multi_view_' . md5($post_id . '|' . $ip . '|' . $user_agent . '|' . wp_salt());
|
||||||
|
|
||||||
|
if (get_transient($key)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sperrfrist je Besucher und Beitrag
|
||||||
|
$ttl = (int) apply_filters('wp_multi_view_throttle', 30 * MINUTE_IN_SECONDS);
|
||||||
|
set_transient($key, 1, $ttl);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verfolgt Beitragsaufrufe – auch von nicht eingeloggten Besuchern.
|
||||||
*/
|
*/
|
||||||
function wp_multi_post_view_activity() {
|
function wp_multi_post_view_activity() {
|
||||||
if (is_single() && is_user_logged_in()) {
|
if (is_admin() || !is_single() || is_feed()) {
|
||||||
$user_id = get_current_user_id();
|
return;
|
||||||
$post_id = get_the_ID();
|
|
||||||
wp_multi_track_user_activity($user_id, 'view', $post_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Eigene Aufrufe der Redaktion verfälschen die Zahlen
|
||||||
|
if (is_user_logged_in() && current_user_can('edit_posts') && !apply_filters('wp_multi_track_editor_views', false)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wp_multi_is_bot_request()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$post_id = get_the_ID();
|
||||||
|
if (!$post_id || wp_multi_view_already_counted($post_id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ohne Login ist die Benutzer-ID 0 – der Aufruf zählt trotzdem
|
||||||
|
wp_multi_track_user_activity(get_current_user_id(), 'view', $post_id);
|
||||||
}
|
}
|
||||||
add_action('wp_head', 'wp_multi_post_view_activity');
|
add_action('wp_head', 'wp_multi_post_view_activity');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ruft rohe Analytics-Daten aus der Datenbank ab.
|
* Baut die WHERE-Bedingung für den gewählten Zeitraum.
|
||||||
*
|
*
|
||||||
* @param string $date_query Datum für die Abfrage.
|
* @return array [WHERE-Fragment, Parameter]
|
||||||
* @return array Rohe Analytics-Daten.
|
|
||||||
*/
|
*/
|
||||||
function wp_multi_fetch_raw_analytics($start_datetime = null, $end_datetime = null) {
|
function wp_multi_analytics_date_where($start_datetime = null, $end_datetime = null) {
|
||||||
global $wpdb;
|
|
||||||
|
|
||||||
if (!$start_datetime) {
|
if (!$start_datetime) {
|
||||||
$start_datetime = gmdate('Y-m-d H:i:s', strtotime('-7 days'));
|
$start_datetime = gmdate('Y-m-d H:i:s', strtotime('-7 days'));
|
||||||
}
|
}
|
||||||
@@ -124,22 +192,60 @@ function wp_multi_fetch_raw_analytics($start_datetime = null, $end_datetime = nu
|
|||||||
$params[] = $end_datetime;
|
$params[] = $end_datetime;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql = "SELECT DATE(timestamp) AS date, action, post_id, COUNT(*) AS count, user_id, timestamp
|
return [$where, $params];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ruft die Tagessummen je Aktion ab – Grundlage für das Diagramm.
|
||||||
|
*
|
||||||
|
* Aggregiert in der Datenbank statt in PHP: Seit auch anonyme Aufrufe gezählt
|
||||||
|
* werden, kämen hier sonst zehntausende Einzelzeilen an.
|
||||||
|
*
|
||||||
|
* @return array Zeilen mit date, action und count.
|
||||||
|
*/
|
||||||
|
function wp_multi_fetch_analytics_totals($start_datetime = null, $end_datetime = null) {
|
||||||
|
global $wpdb;
|
||||||
|
|
||||||
|
list($where, $params) = wp_multi_analytics_date_where($start_datetime, $end_datetime);
|
||||||
|
|
||||||
|
$sql = "SELECT DATE(timestamp) AS date, action, COUNT(*) AS count
|
||||||
FROM " . WP_MULTI_ANALYTICS_TABLE . "
|
FROM " . WP_MULTI_ANALYTICS_TABLE . "
|
||||||
$where
|
$where
|
||||||
GROUP BY date, action, post_id, user_id, timestamp
|
GROUP BY date, action
|
||||||
ORDER BY date ASC";
|
ORDER BY date ASC";
|
||||||
|
|
||||||
return $wpdb->get_results($wpdb->prepare($sql, $params));
|
return $wpdb->get_results($wpdb->prepare($sql, $params));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ruft die jüngsten Einzelereignisse ab – Grundlage für die Detailtabelle.
|
||||||
|
*
|
||||||
|
* @return array Rohe Analytics-Daten (begrenzt).
|
||||||
|
*/
|
||||||
|
function wp_multi_fetch_raw_analytics($start_datetime = null, $end_datetime = null) {
|
||||||
|
global $wpdb;
|
||||||
|
|
||||||
|
list($where, $params) = wp_multi_analytics_date_where($start_datetime, $end_datetime);
|
||||||
|
|
||||||
|
// Ohne Limit würde die Detailtabelle bei anonymem Tracking die Seite sprengen
|
||||||
|
$params[] = (int) apply_filters('wp_multi_analytics_detail_limit', 200);
|
||||||
|
|
||||||
|
$sql = "SELECT DATE(timestamp) AS date, action, post_id, 1 AS count, user_id, timestamp
|
||||||
|
FROM " . WP_MULTI_ANALYTICS_TABLE . "
|
||||||
|
$where
|
||||||
|
ORDER BY timestamp DESC
|
||||||
|
LIMIT %d";
|
||||||
|
|
||||||
|
return $wpdb->get_results($wpdb->prepare($sql, $params));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verarbeitet rohe Analytics-Daten für Diagramm und Tabelle.
|
* Verarbeitet rohe Analytics-Daten für Diagramm und Tabelle.
|
||||||
*
|
*
|
||||||
* @param array $results Rohe Analytics-Daten.
|
* @param array $results Rohe Analytics-Daten.
|
||||||
* @return array Verarbeitete Daten.
|
* @return array Verarbeitete Daten.
|
||||||
*/
|
*/
|
||||||
function wp_multi_process_analytics_data($results) {
|
function wp_multi_process_analytics_data($results, $recent = null) {
|
||||||
$dates = [];
|
$dates = [];
|
||||||
$comment_counts = [];
|
$comment_counts = [];
|
||||||
$view_counts = [];
|
$view_counts = [];
|
||||||
@@ -184,7 +290,7 @@ function wp_multi_process_analytics_data($results) {
|
|||||||
'fill' => false,
|
'fill' => false,
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'data' => $results
|
'data' => ($recent === null) ? $results : $recent
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,8 +308,9 @@ function wp_multi_get_analytics_data($start_datetime = null, $end_datetime = nul
|
|||||||
return $cached_data;
|
return $cached_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
$results = wp_multi_fetch_raw_analytics($start_datetime, $end_datetime);
|
$totals = wp_multi_fetch_analytics_totals($start_datetime, $end_datetime);
|
||||||
$data = wp_multi_process_analytics_data($results);
|
$recent = wp_multi_fetch_raw_analytics($start_datetime, $end_datetime);
|
||||||
|
$data = wp_multi_process_analytics_data($totals, $recent);
|
||||||
|
|
||||||
set_transient($cache_key, $data, HOUR_IN_SECONDS);
|
set_transient($cache_key, $data, HOUR_IN_SECONDS);
|
||||||
return $data;
|
return $data;
|
||||||
@@ -308,7 +415,7 @@ function wp_multi_display_user_analytics() {
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php foreach ($results['data'] as $row) : ?>
|
<?php foreach ($results['data'] as $row) : ?>
|
||||||
<tr>
|
<tr>
|
||||||
<td><?php echo esc_html($row->user_id); ?></td>
|
<td><?php echo $row->user_id ? esc_html($row->user_id) : esc_html__('Gast', 'wp-multi'); ?></td>
|
||||||
<td><span class="wpm-badge <?php echo $row->action === 'comment' ? 'wpm-badge--success' : ''; ?>"><?php echo esc_html($row->action); ?></span></td>
|
<td><span class="wpm-badge <?php echo $row->action === 'comment' ? 'wpm-badge--success' : ''; ?>"><?php echo esc_html($row->action); ?></span></td>
|
||||||
<td>
|
<td>
|
||||||
<?php
|
<?php
|
||||||
|
|||||||
+1815
-93
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user