diff --git a/wp-multi.php b/wp-multi.php
index e3139cb..62631d0 100644
--- a/wp-multi.php
+++ b/wp-multi.php
@@ -3,7 +3,7 @@
* Plugin Name: WP Multi
* Plugin URI: https://git.viper.ipv64.net/M_Viper/wp-multi
* Description: Erweiterter Anti-Spam-Schutz mit Honeypot, Keyword-Filter, Link-Limit und mehr. Jetzt mit Statistik im Dashboard und HappyForms-Integration.
- * Version: 2.9
+ * Version: 3.0
* Author: M_Viper
* Author URI: https://m-viper.de
* Requires at least: 6.7.2
@@ -60,10 +60,6 @@ if (wp_multi_check_dependency()) {
}
-
-
-
-
/*
* Admin - Panel Banner
*/
@@ -421,14 +417,19 @@ add_action( 'wp_login', 'wp_multi_block_login_if_disabled', 10, 2 );
/*
-* Auto Tag
-*/
+ * Verbessertes Auto-Tag-Plugin mit optimierter Sicherheit, Performance und Benutzerfreundlichkeit
+ */
+define('WP_MULTI_AUTO_TAGS_OPTION', 'wp_multi_custom_stopwords');
+define('WP_MULTI_AUTO_TAGS_QUEUE', 'wp_multi_auto_tags_queue');
+define('WP_MULTI_AUTO_TAGS_NONCE', 'wp_multi_auto_tags_nonce');
-
-// Automatische Tags zu Beiträgen hinzufügen
+/**
+ * Fügt automatische Tags zu einem Beitrag hinzu.
+ *
+ * @param int $post_id ID des Beitrags.
+ */
function wp_multi_auto_add_tags($post_id) {
- // Prüfe nur den Post-Typ, da wp_is_post_revision redundant ist
if (get_post_type($post_id) !== 'post') {
return;
}
@@ -440,33 +441,19 @@ function wp_multi_auto_add_tags($post_id) {
$post = get_post($post_id);
if (!$post) {
- return; // Sicherheitsprüfung, falls der Beitrag nicht existiert
+ error_log("WP Multi Auto Tags: Beitrag $post_id nicht gefunden.");
+ return;
}
$content = strip_tags($post->post_content);
- $content = strtolower($content);
+ $content = mb_strtolower($content, 'UTF-8');
- // Stopwörter aus der Admin-Eingabe holen
- $custom_stopwords = get_option('wp_multi_custom_stopwords', '');
- $custom_stopwords = array_filter(array_map('trim', explode(',', $custom_stopwords)));
-
- // Standard-Stopwörter
- $default_stopwords = [
- 'und', 'oder', 'ein', 'eine', 'der', 'die', 'das', 'in', 'mit', 'auf', 'zu', 'von',
- 'für', 'ist', 'es', 'im', 'an', 'am', 'bei', 'auch', 'aber', 'so', 'dass', 'kann',
- 'wenn', 'wie', 'wir', 'man', 'nur', 'nicht', 'mehr', 'als', 'sein', 'wurde', 'werden',
- 'hat', 'haben', 'schon', 'doch', 'denn', 'diese', 'dieser', 'dieses', 'nach', 'sehr', 'allgemein'
- ];
-
- // Alle Stopwörter kombinieren
- $stopwords = array_merge($default_stopwords, $custom_stopwords);
-
- // Wörter mit mindestens 4 Buchstaben extrahieren
- preg_match_all('/\b[a-zäöüß]{4,}\b/u', $content, $matches);
- $words = array_unique(array_diff($matches[0], $stopwords));
+ // Stopwörter laden
+ $stopwords = wp_multi_get_stopwords();
+ $words = wp_multi_extract_words($content, $stopwords);
if (empty($words)) {
- return; // Keine Tags, wenn keine Wörter übrig sind
+ return;
}
$word_counts = array_count_values($words);
@@ -474,11 +461,53 @@ function wp_multi_auto_add_tags($post_id) {
$top_tags = array_slice(array_keys($word_counts), 0, 5);
if (!empty($top_tags)) {
- wp_set_post_tags($post_id, implode(',', $top_tags), true);
+ wp_set_post_tags($post_id, $top_tags, true);
}
}
-// Menüeintrag für Automatische Tags
+/**
+ * Extrahiert relevante Wörter aus dem Inhalt.
+ *
+ * @param string $content Der Inhalt des Beitrags.
+ * @param array $stopwords Liste der Stopwörter.
+ * @return array Liste der extrahierten Wörter.
+ */
+function wp_multi_extract_words($content, $stopwords) {
+ preg_match_all('/\b[a-zäöüß]{4,}\b/u', $content, $matches);
+ return array_unique(array_diff($matches[0], $stopwords));
+}
+
+/**
+ * Lädt die kombinierten Stopwörter (Standard + benutzerdefiniert).
+ *
+ * @return array Liste der Stopwörter.
+ */
+function wp_multi_get_stopwords() {
+ $cache_key = 'wp_multi_stopwords';
+ $stopwords = get_transient($cache_key);
+
+ if ($stopwords !== false) {
+ return $stopwords;
+ }
+
+ $custom_stopwords = get_option(WP_MULTI_AUTO_TAGS_OPTION, '');
+ $custom_stopwords = array_filter(array_map('trim', explode(',', sanitize_text_field($custom_stopwords))));
+
+ $default_stopwords = [
+ 'und', 'oder', 'ein', 'eine', 'der', 'die', 'das', 'in', 'mit', 'auf', 'zu', 'von',
+ 'für', 'ist', 'es', 'im', 'an', 'am', 'bei', 'auch', 'aber', 'so', 'dass', 'kann',
+ 'wenn', 'wie', 'wir', 'man', 'nur', 'nicht', 'mehr', 'als', 'sein', 'wurde', 'werden',
+ 'hat', 'haben', 'schon', 'doch', 'denn', 'diese', 'dieser', 'dieses', 'nach', 'sehr', 'allgemein'
+ ];
+
+ $stopwords = array_merge($default_stopwords, $custom_stopwords);
+ set_transient($cache_key, $stopwords, DAY_IN_SECONDS);
+ return $stopwords;
+}
+
+/**
+ * Fügt das Admin-Menü für automatische Tags hinzu.
+ */
function wp_multi_admin_menu() {
add_submenu_page(
'edit.php',
@@ -491,45 +520,47 @@ function wp_multi_admin_menu() {
}
add_action('admin_menu', 'wp_multi_admin_menu');
-// Menüseite mit Banner & schöner Progress Bar
+/**
+ * Rendert die Admin-Seite für automatische Tags.
+ */
function wp_multi_auto_tags_page() {
+ if (!current_user_can('manage_options')) {
+ wp_die(__('Zugriff verweigert.', 'wp-multi'));
+ }
+
?>
admin_url('admin-ajax.php'),
- 'nonce' => wp_create_nonce('wp_multi_auto_tags_nonce')
+ 'nonce' => wp_create_nonce(WP_MULTI_AUTO_TAGS_NONCE),
+ 'messages' => [
+ 'processing' => __('Wird verarbeitet...', 'wp-multi'),
+ 'run' => __('Jetzt ausführen', 'wp-multi'),
+ 'loading' => __('Lade...', 'wp-multi'),
+ 'no_posts' => __('Keine Beiträge gefunden.', 'wp-multi'),
+ 'success' => __('Automatische Tags erfolgreich hinzugefügt!', 'wp-multi'),
+ 'error' => __('Fehler bei der Verarbeitung.', 'wp-multi'),
+ 'start_error' => __('Fehler beim Starten der Verarbeitung.', 'wp-multi'),
+ ],
]);
?>
-
-
-
-
-
- |
- |
- |
- |
- |
-
-
-
-
- $row) : ?>
-
- user_id); ?> |
- action); ?> |
-
- post_id) {
- $post_title = get_the_title($row->post_id);
- echo esc_html($post_title ? $post_title : 'Kein Titel verfügbar');
- } else {
- echo 'Kein Beitrag';
- }
- ?>
- |
- post_id); ?> |
- timestamp); ?> |
-
-
-
-
- |
-
-
-
-
-
- get_results(
+ $wpdb->prepare(
+ "SELECT DATE(timestamp) AS date, action, post_id, COUNT(*) AS count, user_id, timestamp
+ FROM " . WP_MULTI_ANALYTICS_TABLE . "
+ WHERE timestamp >= %s
+ GROUP BY date, action, post_id, user_id, timestamp
+ ORDER BY date ASC",
+ date('Y-m-d H:i:s', strtotime($date_query))
+ )
+ );
}
-// Funktion, um die Analytics-Daten zu holen (Datum und Anzahl der Aktivitäten)
-function wp_multi_get_analytics_data() {
- global $wpdb;
- $table_name = $wpdb->prefix . 'wp_multi_user_analytics';
-
- // Die letzten 7 Tage abrufen
- $results = $wpdb->get_results("
- SELECT DATE(timestamp) AS date, action, post_id, COUNT(*) AS count, user_id, timestamp
- FROM $table_name
- WHERE timestamp >= CURDATE() - INTERVAL 7 DAY
- GROUP BY date, action, post_id, user_id, timestamp
- ORDER BY date ASC
- ");
-
- // Daten für das Diagramm und die Tabelle organisieren
- $dates = array();
- $comment_counts = array();
- $view_counts = array();
- $post_titles = array();
+/**
+ * Verarbeitet rohe Analytics-Daten für Diagramm und Tabelle.
+ *
+ * @param array $results Rohe Analytics-Daten.
+ * @return array Verarbeitete Daten.
+ */
+function wp_multi_process_analytics_data($results) {
+ $dates = [];
+ $comment_counts = [];
+ $view_counts = [];
foreach ($results as $result) {
- $dates[] = $result->date;
- if ($result->action == 'comment') {
- $comment_counts[$result->date] = $result->count;
- } elseif ($result->action == 'view') {
- $view_counts[$result->date] = $result->count;
+ $date = $result->date;
+ if (!in_array($date, $dates)) {
+ $dates[] = $date;
}
-
- // Hinzufügen der Post-Titel für die Anzeige
- if (!empty($result->post_id)) {
- $post_titles[$result->post_id] = get_the_title($result->post_id);
+ if ($result->action === 'comment') {
+ $comment_counts[$date] = ($comment_counts[$date] ?? 0) + $result->count;
+ } elseif ($result->action === 'view') {
+ $view_counts[$date] = ($view_counts[$date] ?? 0) + $result->count;
}
}
- // Sicherstellen, dass alle Daten für die letzten 7 Tage vorhanden sind
- $unique_dates = array_unique($dates);
- $all_dates = array();
- $datasets = array(
- 'comments' => [],
- 'views' => []
- );
+ $all_dates = [];
+ $datasets = ['comments' => [], 'views' => []];
for ($i = 6; $i >= 0; $i--) {
$date = date('Y-m-d', strtotime("-$i day"));
$all_dates[] = $date;
- $datasets['comments'][] = isset($comment_counts[$date]) ? $comment_counts[$date] : 0;
- $datasets['views'][] = isset($view_counts[$date]) ? $view_counts[$date] : 0;
+ $datasets['comments'][] = $comment_counts[$date] ?? 0;
+ $datasets['views'][] = $view_counts[$date] ?? 0;
}
- // Rückgabe der Daten für das Diagramm und die Tabelle
return [
'dates' => array_reverse($all_dates),
'datasets' => [
[
- 'label' => 'Kommentare',
+ 'label' => __('Kommentare', 'wp-multi'),
'data' => array_reverse($datasets['comments']),
'borderColor' => 'rgba(75, 192, 192, 1)',
'borderWidth' => 1,
'fill' => false,
],
[
- 'label' => 'Beitragsaufrufe',
+ 'label' => __('Beitragsaufrufe', 'wp-multi'),
'data' => array_reverse($datasets['views']),
'borderColor' => 'rgba(153, 102, 255, 1)',
'borderWidth' => 1,
@@ -1796,66 +1859,211 @@ function wp_multi_get_analytics_data() {
];
}
-// Hinzufügen der Analytics-Seite unter "Benutzer" im Admin-Menü
+/**
+ * Ruft Analytics-Daten mit Caching ab.
+ *
+ * @param string $date_query Datum für die Abfrage.
+ * @return array Analytics-Daten.
+ */
+function wp_multi_get_analytics_data($date_query = 'CURDATE() - INTERVAL 7 DAY') {
+ $cache_key = 'wp_multi_analytics_data_' . md5($date_query);
+ $cached_data = get_transient($cache_key);
+
+ if ($cached_data !== false) {
+ return $cached_data;
+ }
+
+ $results = wp_multi_fetch_raw_analytics($date_query);
+ $data = wp_multi_process_analytics_data($results);
+
+ set_transient($cache_key, $data, HOUR_IN_SECONDS);
+ return $data;
+}
+
+/**
+ * Zeigt die Benutzer-Analytics-Seite im Admin-Bereich an.
+ */
+function wp_multi_display_user_analytics() {
+ global $wpdb;
+
+ if (!$wpdb->get_var("SHOW TABLES LIKE '" . WP_MULTI_ANALYTICS_TABLE . "'")) {
+ echo '' . esc_html__('Die Analytics-Tabelle existiert nicht. Bitte aktiviere das Plugin erneut.', 'wp-multi') . '
';
+ return;
+ }
+
+ $time_range = isset($_GET['time_range']) ? sanitize_text_field($_GET['time_range']) : '7days';
+ $date_query = 'CURDATE() - INTERVAL 7 DAY';
+ if ($time_range === '30days') {
+ $date_query = 'CURDATE() - INTERVAL 30 DAY';
+ } elseif ($time_range === 'custom' && isset($_GET['start_date'], $_GET['end_date'])) {
+ $start_date = sanitize_text_field($_GET['start_date']);
+ $end_date = sanitize_text_field($_GET['end_date']);
+ $date_query = "$start_date AND $end_date";
+ }
+
+ $results = wp_multi_get_analytics_data($date_query);
+
+ ?>
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+
+
+
+ $row) : ?>
+
+ user_id); ?> |
+ action); ?> |
+
+ post_id) {
+ $post_title = get_the_title($row->post_id);
+ echo esc_html($post_title ?: __('Kein Titel verfügbar', 'wp-multi'));
+ } else {
+ echo esc_html__('Kein Beitrag', 'wp-multi');
+ }
+ ?>
+ |
+ post_id ?: '-'); ?> |
+ timestamp); ?> |
+
+
+
+
+
+
+ '1',
+ 'email' => '1',
+ 'url' => '1',
+ 'swear' => '1',
+ 'ip' => '1',
+ 'allowed_urls' => '',
+ 'allowed_words' => '', // Neue Option für erlaubte Wörter
+ 'filter_strength' => 'moderate', // Neue Option für Filterstärke
+ ];
- register_setting('wp_multi_filter_options_group', 'wp_multi_filter_phone');
- register_setting('wp_multi_filter_options_group', 'wp_multi_filter_email');
- register_setting('wp_multi_filter_options_group', 'wp_multi_filter_url');
- register_setting('wp_multi_filter_options_group', 'wp_multi_filter_swear');
- register_setting('wp_multi_filter_options_group', 'wp_multi_filter_ip');
- register_setting('wp_multi_filter_options_group', 'wp_multi_allowed_urls'); // NEU
+ foreach ($options as $key => $default) {
+ add_option(WP_MULTI_FILTER_OPTION_PREFIX . $key, $default);
+ register_setting('wp_multi_filter_options_group', WP_MULTI_FILTER_OPTION_PREFIX . $key, [
+ 'sanitize_callback' => $key === 'allowed_urls' || $key === 'allowed_words' ? 'sanitize_textarea_field' : 'sanitize_text_field',
+ ]);
+ }
}
add_action('admin_init', 'wp_multi_register_comment_filter_settings');
-// Admin-Menü & Untermenü hinzufügen
+/**
+ * Fügt das Admin-Menü für den Kommentar-Filter hinzu.
+ */
function wp_multi_create_menu() {
add_submenu_page(
'users.php',
- 'Benutzer sperren',
- 'Benutzer sperren',
- 'manage_options',
- 'wp-multi-blocked-users',
+ __('Benutzer sperren', 'wp-multi'),
+ __('Benutzer sperren', 'wp-multi'),
+ 'manage_options',
+ 'wp-multi-blocked-users',
'wp_multi_blocked_users_page'
);
add_submenu_page(
'edit-comments.php',
- 'Kommentar-Filter Einstellungen',
- 'Kommentar-Filter',
- 'manage_options',
- 'wp-multi-comment-filter-settings',
+ __('Kommentar-Filter Einstellungen', 'wp-multi'),
+ __('Kommentar-Filter', 'wp-multi'),
+ 'manage_options',
+ 'wp-multi-comment-filter-settings',
'wp_multi_comment_filter_settings_page'
);
}
add_action('admin_menu', 'wp_multi_create_menu');
-// Admin-Seite für Kommentar-Filter
+/**
+ * Rendert die Admin-Seite für Kommentar-Filter-Einstellungen.
+ */
function wp_multi_comment_filter_settings_page() {
?>
@@ -1863,38 +2071,61 @@ function wp_multi_comment_filter_settings_page() {
- Kommentar-Filter Einstellungen
-
+
+
-
+
5]);
+ if (!is_wp_error($response)) {
+ $json_content = wp_remote_retrieve_body($response);
+ $decoded_data = json_decode($json_content, true);
+ if (json_last_error() === JSON_ERROR_NONE && isset($decoded_data['words']) && is_array($decoded_data['words'])) {
+ $swear_words = array_map('strtolower', $decoded_data['words']);
+ set_transient(WP_MULTI_SWEAR_WORDS_CACHE_KEY, $swear_words, DAY_IN_SECONDS);
+ } else {
+ error_log('WP Multi Filter: Fehler beim Dekodieren der Schimpfwort-JSON-Datei.');
+ }
+ } else {
+ error_log('WP Multi Filter: Fehler beim Abrufen der Schimpfwort-Liste: ' . $response->get_error_message());
+ }
+
+ // Fallback: Standard-Schimpfwörter, falls die externe Liste nicht verfügbar ist
+ if (empty($swear_words)) {
+ $swear_words = ['beispielwort1', 'beispielwort2']; // Ersetze durch echte Fallback-Wörter
+ }
+
+ return $swear_words;
+}
+
+/**
+ * Filtert Schimpfwörter basierend auf der Filterstärke.
+ *
+ * @param string $content Kommentarinhalt.
+ * @param array $swear_words Schimpfwörter.
+ * @param array $allowed_words Erlaubte Wörter.
+ * @param string $strength Filterstärke.
+ * @return string Gefilterter Inhalt.
+ */
+function wp_multi_filter_swear_words($content, $swear_words, $allowed_words, $strength) {
+ if (empty($swear_words)) {
+ return $content;
+ }
+
+ foreach ($swear_words as $word) {
+ if (in_array(strtolower($word), $allowed_words)) {
+ continue;
+ }
+
+ $pattern = ($strength === 'loose')
+ ? '/\b' . preg_quote($word, '/') . '\b/iu'
+ : '/\b' . preg_quote($word, '/') . '[a-z0-9]*\b/iu';
+
+ if ($strength === 'moderate') {
$pattern = '/\b' . preg_quote($word, '/') . '\b/iu';
- $replacement = str_repeat('*', mb_strlen($word));
- $comment_content = preg_replace($pattern, $replacement, $comment_content);
}
+
+ $replacement = str_repeat('*', mb_strlen($word));
+ $content = preg_replace($pattern, $replacement, $content);
}
- if (get_option('wp_multi_filter_phone') == 1) {
+ return $content;
+}
+
+/**
+ * Filtert Kommentarinhalte basierend auf den Einstellungen.
+ *
+ * @param string $comment_content Kommentarinhalt.
+ * @return string Gefilterter Inhalt.
+ */
+function wp_multi_filter_comment_content($comment_content) {
+ if (get_option(WP_MULTI_FILTER_OPTION_PREFIX . 'swear') == 1) {
+ $swear_words = wp_multi_load_swear_words();
+ $allowed_words = array_map('strtolower', array_map('trim', explode(',', get_option(WP_MULTI_FILTER_OPTION_PREFIX . 'allowed_words', ''))));
+ $filter_strength = get_option(WP_MULTI_FILTER_OPTION_PREFIX . 'filter_strength', 'moderate');
+ $comment_content = wp_multi_filter_swear_words($comment_content, $swear_words, $allowed_words, $filter_strength);
+ }
+
+ if (get_option(WP_MULTI_FILTER_OPTION_PREFIX . 'phone') == 1) {
$comment_content = preg_replace('/\b(\+?[0-9]{1,3}[-.\s]?)?(\(?\d{2,4}\)?[-.\s]?\d{2,4}[-.\s]?\d{2,4})\b/i', '**********', $comment_content);
}
- if (get_option('wp_multi_filter_email') == 1) {
+ if (get_option(WP_MULTI_FILTER_OPTION_PREFIX . 'email') == 1) {
$comment_content = preg_replace('/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/i', '**********', $comment_content);
}
- if (get_option('wp_multi_filter_url') == 1) {
- $allowed_urls = array_map('trim', explode(',', get_option('wp_multi_allowed_urls', '')));
- $comment_content = preg_replace_callback('/\b((https?:\/\/)?(www\.)?[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})(\/\S*)?\b/i', function($matches) use ($allowed_urls) {
- // Entfernt "http://", "https://" und "www."
- $url = strtolower(preg_replace(['/^https?:\/\//', '/^www\./'], '', $matches[0]));
- return in_array($url, $allowed_urls) ? $matches[0] : '**************';
- }, $comment_content);
+ if (get_option(WP_MULTI_FILTER_OPTION_PREFIX . 'url') == 1) {
+ $allowed_urls = array_map('strtolower', array_map('trim', explode(',', get_option(WP_MULTI_FILTER_OPTION_PREFIX . 'allowed_urls', ''))));
+ $comment_content = preg_replace_callback(
+ '/\b((https?:\/\/)?(www\.)?[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})(\/\S*)?\b/i',
+ function ($matches) use ($allowed_urls) {
+ $url = strtolower(preg_replace(['/^https?:\/\//', '/^www\./'], '', $matches[0]));
+ return in_array($url, $allowed_urls) ? $matches[0] : '**************';
+ },
+ $comment_content
+ );
}
- if (get_option('wp_multi_filter_ip') == 1) {
+ if (get_option(WP_MULTI_FILTER_OPTION_PREFIX . 'ip') == 1) {
$comment_content = preg_replace('/\b(?:\d{1,3}\.){3}\d{1,3}\b/', '**********', $comment_content);
}
@@ -4220,185 +4512,332 @@ add_action('admin_menu', 'wp_stat_notice_add_reported_posts_menu');
/*
-* Gast Lesezeichen
-*/
+ * Verbessertes Gast-Lesezeichen-Plugin mit erhöhter Sicherheit und Benutzerfreundlichkeit
+ */
-// Funktion zum Erstellen des benutzerdefinierten Post-Typs für Lesezeichen
+define('STATISTIK_MANAGER_BOOKMARK_POST_TYPE', 'bookmark');
+define('STATISTIK_MANAGER_COOKIE_NAME', 'guest_token');
+define('STATISTIK_MANAGER_COOKIE_DURATION', 30 * DAY_IN_SECONDS);
+define('STATISTIK_MANAGER_BOOKMARKS_CACHE_KEY', 'statistik_manager_bookmarks_');
+
+/**
+ * Erstellt den benutzerdefinierten Post-Typ für Lesezeichen.
+ */
function statistik_manager_create_bookmark_post_type() {
- register_post_type('bookmark',
- array(
- 'labels' => array(
- 'name' => __('Lesezeichen', 'statistik-manager'),
- 'singular_name' => __('Lesezeichen', 'statistik-manager')
- ),
- 'public' => false, // Privat, nur für Backend
- 'show_ui' => false, // Nicht im Backend anzeigen
- 'show_in_menu' => false, // Nicht im Menü anzeigen
- 'supports' => array('title', 'custom-fields')
- )
- );
+ register_post_type(STATISTIK_MANAGER_BOOKMARK_POST_TYPE, [
+ 'labels' => [
+ 'name' => __('Lesezeichen', 'statistik-manager'),
+ 'singular_name' => __('Lesezeichen', 'statistik-manager'),
+ ],
+ 'public' => false,
+ 'show_ui' => false,
+ 'show_in_menu' => false,
+ 'supports' => ['title', 'custom-fields'],
+ ]);
}
add_action('init', 'statistik_manager_create_bookmark_post_type');
-// Funktion zum Speichern eines Lesezeichens für Gäste
-function statistik_manager_save_bookmark($post_id) {
- if (isset($_COOKIE['guest_token'])) {
- update_post_meta($post_id, '_guest_token', $_COOKIE['guest_token']);
- }
-}
-
-// Funktion zum Abrufen der Lesezeichen eines Gastes
-function statistik_manager_get_guest_bookmarks() {
- $guest_token = isset($_COOKIE['guest_token']) ? $_COOKIE['guest_token'] : null;
+/**
+ * Generiert oder holt den Gast-Token.
+ *
+ * @return string Der Gast-Token.
+ */
+function statistik_manager_get_guest_token() {
+ $guest_token = isset($_COOKIE[STATISTIK_MANAGER_COOKIE_NAME]) ? sanitize_text_field($_COOKIE[STATISTIK_MANAGER_COOKIE_NAME]) : null;
if (!$guest_token) {
- // Wenn der Gast noch kein Token hat, erstellen und speichern
- $guest_token = wp_generate_uuid4(); // Ein zufälliger UUID-Token
- setcookie('guest_token', $guest_token, time() + 3600 * 24 * 30, COOKIEPATH, COOKIE_DOMAIN); // Cookie für 30 Tage setzen
+ $guest_token = wp_generate_uuid4();
+ setcookie(
+ STATISTIK_MANAGER_COOKIE_NAME,
+ $guest_token,
+ time() + STATISTIK_MANAGER_COOKIE_DURATION,
+ COOKIEPATH,
+ COOKIE_DOMAIN,
+ is_ssl(), // Secure
+ true // HttpOnly
+ );
}
- // Abfrage der Lesezeichen für den aktuellen Gast
- $args = array(
- 'post_type' => 'bookmark',
- 'meta_key' => '_guest_token',
- 'meta_value' => $guest_token,
- 'posts_per_page' => -1,
- 'post_status' => 'publish'
- );
- $bookmarks_query = new WP_Query($args);
-
- return $bookmarks_query->posts;
+ return $guest_token;
}
-// Funktion zum Löschen eines Lesezeichens (nur für den aktuellen Gast)
-function statistik_manager_delete_bookmark() {
- if (isset($_POST['bookmark_id']) && isset($_COOKIE['guest_token'])) {
- $bookmark_id = intval($_POST['bookmark_id']);
- $guest_token = $_COOKIE['guest_token'];
+/**
+ * Speichert ein Lesezeichen für einen Gast.
+ *
+ * @param int $post_id Post-ID des Lesezeichens.
+ */
+function statistik_manager_save_bookmark($post_id) {
+ $guest_token = statistik_manager_get_guest_token();
+ update_post_meta($post_id, '_guest_token', $guest_token);
+}
- // Überprüfen, ob das Lesezeichen diesem Gast gehört
- $stored_token = get_post_meta($bookmark_id, '_guest_token', true);
- if ($stored_token === $guest_token) {
- wp_delete_post($bookmark_id, true);
- echo 'Lesezeichen erfolgreich gelöscht!';
- } else {
- echo 'Du kannst nur deine eigenen Lesezeichen löschen!';
- }
+/**
+ * Ruft die Lesezeichen eines Gastes ab.
+ *
+ * @return array Liste der Lesezeichen.
+ */
+function statistik_manager_get_guest_bookmarks() {
+ $guest_token = statistik_manager_get_guest_token();
+ $cache_key = STATISTIK_MANAGER_BOOKMARKS_CACHE_KEY . md5($guest_token);
+ $bookmarks = get_transient($cache_key);
+
+ if ($bookmarks !== false) {
+ return $bookmarks;
}
- wp_die(); // Beende die Anfrage
+
+ $args = [
+ 'post_type' => STATISTIK_MANAGER_BOOKMARK_POST_TYPE,
+ 'meta_query' => [
+ [
+ 'key' => '_guest_token',
+ 'value' => $guest_token,
+ ],
+ ],
+ 'posts_per_page' => -1,
+ 'post_status' => 'publish',
+ 'orderby' => 'date',
+ 'order' => 'DESC',
+ ];
+
+ $bookmarks_query = new WP_Query($args);
+ $bookmarks = $bookmarks_query->posts;
+
+ set_transient($cache_key, $bookmarks, HOUR_IN_SECONDS);
+ return $bookmarks;
+}
+
+/**
+ * Löscht ein Lesezeichen via AJAX.
+ */
+function statistik_manager_delete_bookmark() {
+ check_ajax_referer('statistik_manager_bookmark_nonce', 'nonce');
+
+ if (!isset($_POST['bookmark_id']) || !isset($_COOKIE[STATISTIK_MANAGER_COOKIE_NAME])) {
+ wp_send_json_error(['message' => __('Ungültige Anfrage.', 'statistik-manager')]);
+ }
+
+ $bookmark_id = absint($_POST['bookmark_id']);
+ $guest_token = sanitize_text_field($_COOKIE[STATISTIK_MANAGER_COOKIE_NAME]);
+ $stored_token = get_post_meta($bookmark_id, '_guest_token', true);
+
+ if ($stored_token !== $guest_token) {
+ wp_send_json_error(['message' => __('Du kannst nur deine eigenen Lesezeichen löschen.', 'statistik-manager')]);
+ }
+
+ wp_delete_post($bookmark_id, true);
+ delete_transient(STATISTIK_MANAGER_BOOKMARKS_CACHE_KEY . md5($guest_token));
+ wp_send_json_success(['message' => __('Lesezeichen erfolgreich gelöscht.', 'statistik-manager')]);
}
add_action('wp_ajax_delete_bookmark', 'statistik_manager_delete_bookmark');
add_action('wp_ajax_nopriv_delete_bookmark', 'statistik_manager_delete_bookmark');
-// Funktion zum Anzeigen der Lesezeichen mit Löschen-Option
-function statistik_manager_display_bookmarks() {
- $bookmarks = statistik_manager_get_guest_bookmarks();
-
- if (!empty($bookmarks)) {
- $output = '';
- $output .= '
' . __('Gespeicherte Lesezeichen', 'statistik-manager') . '
';
- $output .= '
';
-
- foreach ($bookmarks as $bookmark) {
- $bookmark_url = get_post_meta($bookmark->ID, '_bookmark_url', true);
- $bookmark_id = $bookmark->ID;
- $bookmark_name = get_the_title($bookmark); // Benutzerdefinierter Name des Lesezeichens
-
- // Ausgabe des Lesezeichens mit getauschtem Button und Titel
- $output .= '- ';
- // Button kommt nun vor dem Titel
- $output .= ' ';
- $output .= '' . esc_html($bookmark_name) . '';
- $output .= '
';
- }
-
- $output .= '
';
- $output .= '
';
- return $output;
- } else {
- return '' . __('Keine Lesezeichen gefunden.', 'statistik-manager') . '
';
- }
-}
-
-// Funktion zum Hinzufügen eines Lesezeichens via AJAX
+/**
+ * Fügt ein Lesezeichen via AJAX hinzu.
+ */
function statistik_manager_add_bookmark_ajax() {
- if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['bookmark_url']) && isset($_POST['bookmark_name'])) {
- $bookmark_url = sanitize_text_field($_POST['bookmark_url']);
- $bookmark_name = sanitize_text_field($_POST['bookmark_name']); // Name des Lesezeichens
+ check_ajax_referer('statistik_manager_bookmark_nonce', 'nonce');
- // Neues Lesezeichen erstellen
- $post_id = wp_insert_post(array(
- 'post_type' => 'bookmark',
- 'post_title' => $bookmark_name, // Benutzerdefinierter Name für das Lesezeichen
- 'post_status' => 'publish',
- 'meta_input' => array(
- '_bookmark_url' => $bookmark_url
- )
- ));
-
- // Speichern des Gast-Token
- if (isset($_COOKIE['guest_token'])) {
- update_post_meta($post_id, '_guest_token', $_COOKIE['guest_token']);
- }
-
- // Rückgabe des neuen Lesezeichens als HTML
- $bookmark_html = '';
- $bookmark_html .= '';
- $bookmark_html .= '' . esc_html($bookmark_name) . '';
- $bookmark_html .= '';
-
- echo $bookmark_html;
+ if (!isset($_POST['bookmark_url']) || !isset($_POST['bookmark_name'])) {
+ wp_send_json_error(['message' => __('Bitte alle Felder ausfüllen.', 'statistik-manager')]);
}
- wp_die(); // Beende die Anfrage
+ $bookmark_url = esc_url_raw($_POST['bookmark_url']);
+ $bookmark_name = sanitize_text_field($_POST['bookmark_name']);
+
+ if (empty($bookmark_url) || empty($bookmark_name)) {
+ wp_send_json_error(['message' => __('Ungültige URL oder Name.', 'statistik-manager')]);
+ }
+
+ // Prüfen, ob die URL bereits existiert
+ $guest_token = statistik_manager_get_guest_token();
+ $args = [
+ 'post_type' => STATISTIK_MANAGER_BOOKMARK_POST_TYPE,
+ 'meta_query' => [
+ 'relation' => 'AND',
+ [
+ 'key' => '_guest_token',
+ 'value' => $guest_token,
+ ],
+ [
+ 'key' => '_bookmark_url',
+ 'value' => $bookmark_url,
+ ],
+ ],
+ 'posts_per_page' => 1,
+ ];
+
+ $existing = new WP_Query($args);
+ if ($existing->have_posts()) {
+ wp_send_json_error(['message' => __('Diese URL ist bereits ein Lesezeichen.', 'statistik-manager')]);
+ }
+
+ // Neues Lesezeichen erstellen
+ $post_id = wp_insert_post([
+ 'post_type' => STATISTIK_MANAGER_BOOKMARK_POST_TYPE,
+ 'post_title' => $bookmark_name,
+ 'post_status' => 'publish',
+ 'meta_input' => [
+ '_bookmark_url' => $bookmark_url,
+ '_guest_token' => $guest_token,
+ ],
+ ]);
+
+ if (is_wp_error($post_id)) {
+ wp_send_json_error(['message' => __('Fehler beim Hinzufügen des Lesezeichens.', 'statistik-manager')]);
+ }
+
+ delete_transient(STATISTIK_MANAGER_BOOKMARKS_CACHE_KEY . md5($guest_token));
+ wp_send_json_success([
+ 'message' => __('Lesezeichen erfolgreich hinzugefügt.', 'statistik-manager'),
+ 'html' => '' . esc_html($bookmark_name) . '',
+ ]);
}
add_action('wp_ajax_add_bookmark', 'statistik_manager_add_bookmark_ajax');
add_action('wp_ajax_nopriv_add_bookmark', 'statistik_manager_add_bookmark_ajax');
-// JavaScript zum Hinzufügen des Lesezeichens ohne Seitenaktualisierung
+/**
+ * Zeigt die Lesezeichen eines Gastes an.
+ *
+ * @return string HTML-Ausgabe der Lesezeichen.
+ */
+function statistik_manager_display_bookmarks() {
+ $bookmarks = statistik_manager_get_guest_bookmarks();
+
+ ob_start();
+ ?>
+
+
+
+
+