diff --git a/wp-multi-toolkit.php b/wp-multi-toolkit.php index 61b234c..c074eb4 100644 --- a/wp-multi-toolkit.php +++ b/wp-multi-toolkit.php @@ -3,7 +3,7 @@ * Plugin Name: WP Multi Toolkit * Plugin URI: https://git.viper.ipv64.net/M_Viper/wp-multi-toolkit * Description: Ein umfassendes Toolkit inklusive WP Multi Funktionen und Update-Management für zugehörige Plugins. - * Version: 1.0.4 + * Version: 1.0.7 * Author: M_Viper * Author URI: https://m-viper.de * Requires at least: 6.7.2 @@ -18,6 +18,541 @@ defined('ABSPATH') or die('No direct access allowed.'); + +/* + * DB Backup + */ + +// Funktion zum Erstellen des Backups +function wpmt_create_database_backup() { + global $wpdb; + + // Definiere den Dateinamen für das Backup + $backup_filename = 'wp-database-backup-' . date('Y-m-d_H-i-s') . '.sql'; + + // Spezifizieren des Speicherorts des Backups (im Uploads-Verzeichnis) + $upload_dir = wp_upload_dir(); + $backup_file_path = $upload_dir['basedir'] . '/wpmt_backups/' . $backup_filename; + + // Sicherstellen, dass der Backup-Ordner existiert + if (!file_exists($upload_dir['basedir'] . '/wpmt_backups')) { + wp_mkdir_p($upload_dir['basedir'] . '/wpmt_backups'); + } + + // Hole alle Tabellen der Datenbank + $tables = $wpdb->get_results('SHOW TABLES', ARRAY_N); + if (empty($tables)) { + return new WP_Error('backup_error', 'Keine Tabellen in der Datenbank gefunden.'); + } + + // Öffne die Backup-Datei + $backup_file = fopen($backup_file_path, 'w'); + if (!$backup_file) { + return new WP_Error('backup_error', 'Fehler beim Öffnen der Backup-Datei.'); + } + + // Schreibe die SQL-Dumps für jede Tabelle + foreach ($tables as $table) { + $table_name = $table[0]; + + // SQL-Dump für die Tabelle hinzufügen + fwrite($backup_file, "DROP TABLE IF EXISTS `$table_name`;\n"); + + // Struktur der Tabelle + $create_table_query = $wpdb->get_row("SHOW CREATE TABLE $table_name", ARRAY_N); + fwrite($backup_file, $create_table_query[1] . ";\n\n"); + + // Daten der Tabelle + $rows = $wpdb->get_results("SELECT * FROM $table_name", ARRAY_A); + foreach ($rows as $row) { + $columns = array_map(function ($col) use ($wpdb) { + return $wpdb->prepare('%s', $col); + }, array_values($row)); + + $columns_str = implode(", ", $columns); + fwrite($backup_file, "INSERT INTO `$table_name` VALUES ($columns_str);\n"); + } + + fwrite($backup_file, "\n\n"); + } + + // Datei schließen + fclose($backup_file); + + // Gebe den Pfad zur herunterladbaren Datei zurück + return $backup_file_path; +} + +// Neue Funktion zum Löschen von Backups +function wpmt_delete_backup() { + if (isset($_POST['wpmt_action']) && $_POST['wpmt_action'] == 'delete_backup' && isset($_POST['backup_file'])) { + $upload_dir = wp_upload_dir(); + $backup_file = $upload_dir['basedir'] . '/wpmt_backups/' . sanitize_file_name($_POST['backup_file']); + + if (file_exists($backup_file)) { + unlink($backup_file); + echo '

' . __('Backup erfolgreich gelöscht!', 'wp-multi-toolkit') . '

'; + } else { + echo '

' . __('Backup-Datei nicht gefunden.', 'wp-multi-toolkit') . '

'; + } + } +} + +// Funktion zur Anzeige der Backup-Seite und der Liste der Backups im Admin-Bereich +function wpmt_display_backup_page() { + $upload_dir = wp_upload_dir(); + $backup_dir = $upload_dir['basedir'] . '/wpmt_backups'; + + // Hole eine Liste der Backups + $backups = glob($backup_dir . '/*.sql'); + + ?> +
+

+ + +
+ +

+
+ + +

+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+ +

+ +
+

' . $backup_path->get_error_message() . '

'; + } else { + echo '

' . __('Datenbank-Backup erfolgreich erstellt!', 'wp-multi-toolkit') . '

'; + } + } +} + +// Admin-Menüpunkt unter Tools/Werkzeuge hinzufügen +function wpmt_add_backup_menu() { + add_submenu_page( + 'tools.php', + 'WP-Multi DB-Backup', + 'WP-Multi DB-Backup', + 'manage_options', + 'wpmt-database-backup', + 'wpmt_display_backup_page' + ); +} +add_action('admin_menu', 'wpmt_add_backup_menu'); + +// Sicherstellen, dass die Anfrage bearbeitet wird +add_action('admin_init', 'wpmt_handle_backup_request'); + + +/* + * DB cleaner + */ + + +function wp_multi_db_cleaner_page() { + if (!current_user_can('manage_options')) return; + + global $wpdb; + $db_tables = $wpdb->get_results("SHOW TABLES", ARRAY_N); + + $core_protected_tables = [ + $wpdb->prefix . 'posts', + $wpdb->prefix . 'postmeta', + $wpdb->prefix . 'users', + $wpdb->prefix . 'usermeta', + $wpdb->prefix . 'options', + $wpdb->prefix . 'comments', + $wpdb->prefix . 'commentmeta', + $wpdb->prefix . 'terms', + $wpdb->prefix . 'termmeta', + $wpdb->prefix . 'term_relationships', + $wpdb->prefix . 'term_taxonomy', + $wpdb->prefix . 'links', + ]; + + $allow_system_tables = get_option('wp_multi_allow_system_tables', 'no') === 'yes'; + + if (isset($_POST['wp_multi_clean_submit']) && check_admin_referer('wp_multi_clean_action', 'wp_multi_clean_nonce')) { + // Option für die Systemtabellen sperre speichern + if (isset($_POST['allow_system_tables'])) { + update_option('wp_multi_allow_system_tables', 'yes'); + } else { + update_option('wp_multi_allow_system_tables', 'no'); + } + + $results = wp_multi_clean_database($_POST['clean_options'] ?? [], $_POST['truncate_tables'] ?? [], $core_protected_tables, $allow_system_tables); + echo '

Datenbankbereinigung abgeschlossen:

'; + } + + ?> +
+

🧹 WP Multi Toolkit – Datenbank Cleaner

+

Hier kannst du gezielt Inhalte aus deiner Datenbank löschen oder bereinigen.

+ +
+ + +

⚠️ Systemtabellen (Achtung!)

+ +

Wenn du diese Option aktivierst, können Systemtabellen (z.B. Optionen, Beiträge) ebenfalls geleert werden. Sei vorsichtig und stelle sicher, dass du weißt, was du tust!

+ +
+

🔧 Standardbereinigung

+
+
+
+ +
+

🧱 Tabellen gezielt leeren

+

Hier kannst du benutzerdefinierte oder Plugin-Tabellen auswählen, deren Inhalte gelöscht werden sollen. Systemtabellen sind aus Sicherheitsgründen deaktiviert, es sei denn, die Sperre wurde aufgehoben.

+ + + + + + + + + + + prefix, '', $table_name); + $entry_count = $wpdb->get_var("SELECT COUNT(*) FROM `$table_name`"); + $description = wp_multi_get_table_description($short_name); + $is_core = in_array($table_name, $core_protected_tables) && !$allow_system_tables; + ?> + + + + + + + + +
Leeren?TabellennameEinträgeBeschreibung
+ + + + 🔒 (geschützt) + +
+ +
+ +
+
+ query("DELETE FROM {$wpdb->posts} WHERE post_type = 'revision'"); + $results[] = "$deleted Revision(en) gelöscht."; + } + + if (in_array('transients', $options)) { + $transients = $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_%'"); + $results[] = "$transients Transient(en) gelöscht."; + } + + if (in_array('options', $options)) { + $orphaned = $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_value = '' OR option_value IS NULL"); + $results[] = "$orphaned verwaiste Option(en) gelöscht."; + } + + foreach ($truncate_tables as $table) { + if (!$allow_system_tables && in_array($table, $protected)) { + $results[] = "Tabelle $table ist geschützt und wurde nicht geleert."; + } else { + $wpdb->query("TRUNCATE TABLE `$table`"); + $results[] = "Tabelle $table geleert."; + } + } + + if (empty($results)) { + $results[] = "Keine Aktionen durchgeführt."; + } + + return $results; +} + +function wp_multi_get_table_description($short_name) { + // Hier kannst du für jede Tabelle eine Beschreibung hinzufügen + $descriptions = [ + 'postmeta' => 'Meta-Daten zu Beiträgen', + 'options' => 'Allgemeine Optionen', + // Weitere Tabellenbeschreibungen hier hinzufügen + ]; + + return isset($descriptions[$short_name]) ? $descriptions[$short_name] : 'Keine Beschreibung verfügbar'; +} + +// Menüpunkt unter Werkzeuge hinzufügen +function wp_multi_toolkit_menu() { + add_submenu_page( + 'tools.php', // Untermenü von Werkzeuge + 'WP Multi DB cleaner', // Titel der Seite + 'WP Multi DB cleaner', // Name des Menüpunkts + 'manage_options', // Berechtigung + 'wp-multi-toolkit', // Slug + 'wp_multi_db_cleaner_page' // Funktion zum Anzeigen der Seite + ); +} +add_action('admin_menu', 'wp_multi_toolkit_menu'); + + +/* + * Cookie-Banner + */ + + +// Menü für das Cookie-Banner +function wpmt_cookie_banner_menu() { + add_options_page( + __('Cookie Banner Einstellungen', 'wp-multi-toolkit'), + __('Cookie Banner', 'wp-multi-toolkit'), + 'manage_options', + 'wpmt-cookie-banner', + 'wpmt_cookie_banner_settings_page' + ); +} +add_action('admin_menu', 'wpmt_cookie_banner_menu'); + +// Admin-Bereich für die Cookie-Einstellungen +function wpmt_cookie_banner_settings_page() { + // Speichern der Daten, wenn das Formular übermittelt wird + if(isset($_POST['wpmt_save_cookie_settings'])) { + update_option('wpmt_cookie_banner_text', sanitize_textarea_field($_POST['wpmt_cookie_banner_text'])); + update_option('wpmt_cookie_accept_text', sanitize_text_field($_POST['wpmt_cookie_accept_text'])); + update_option('wpmt_cookie_decline_text', sanitize_text_field($_POST['wpmt_cookie_decline_text'])); + update_option('wpmt_cookie_policy_url', esc_url_raw($_POST['wpmt_cookie_policy_url'])); + update_option('wpmt_cookie_impressum_url', esc_url_raw($_POST['wpmt_cookie_impressum_url'])); + update_option('wpmt_cookie_banner_background_color', sanitize_hex_color($_POST['wpmt_cookie_banner_background_color'])); + update_option('wpmt_cookie_type_necessary', isset($_POST['wpmt_cookie_type_necessary']) ? '1' : '0'); + update_option('wpmt_cookie_type_preferences', isset($_POST['wpmt_cookie_type_preferences']) ? '1' : '0'); + update_option('wpmt_cookie_type_statistics', isset($_POST['wpmt_cookie_type_statistics']) ? '1' : '0'); + update_option('wpmt_cookie_type_marketing', isset($_POST['wpmt_cookie_type_marketing']) ? '1' : '0'); + update_option('wpmt_content_blocking_enabled', isset($_POST['wpmt_content_blocking_enabled']) ? '1' : '0'); + update_option('wpmt_enable_cookie_banner', isset($_POST['wpmt_enable_cookie_banner']) ? '1' : '0'); + echo '

' . __('Einstellungen gespeichert!', 'wp-multi-toolkit') . '

'; + } + + // Optionen aus der Datenbank abrufen + $cookie_banner_text = get_option('wpmt_cookie_banner_text', __('Wir verwenden Cookies, um Ihnen das beste Erlebnis zu bieten.', 'wp-multi-toolkit')); + $cookie_accept_text = get_option('wpmt_cookie_accept_text', __('Akzeptieren', 'wp-multi-toolkit')); + $cookie_decline_text = get_option('wpmt_cookie_decline_text', __('Ablehnen', 'wp-multi-toolkit')); + $cookie_policy_url = get_option('wpmt_cookie_policy_url', ''); + $cookie_impressum_url = get_option('wpmt_cookie_impressum_url', ''); + $cookie_banner_background_color = get_option('wpmt_cookie_banner_background_color', '#f0f0f0'); + $cookie_type_necessary = get_option('wpmt_cookie_type_necessary', '1'); + $cookie_type_preferences = get_option('wpmt_cookie_type_preferences', '0'); + $cookie_type_statistics = get_option('wpmt_cookie_type_statistics', '0'); + $cookie_type_marketing = get_option('wpmt_cookie_type_marketing', '0'); + $content_blocking_enabled = get_option('wpmt_content_blocking_enabled', '0'); + $enable_cookie_banner = get_option('wpmt_enable_cookie_banner', '1'); + + // HTML für Einstellungsseite + ?> +
+

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
/>
+
+
+
+
+
+ + +
+
+ '; + echo '

' . esc_html($banner_text) . ' ' . __('Mehr erfahren', 'wp-multi-toolkit') . ' | ' . __('Impressum', 'wp-multi-toolkit') . '

'; + echo ''; + echo ''; + echo ''; + + // JavaScript zum Setzen des Cookies nach Zustimmung + ?> + + insert( + $wpdb->prefix . 'wpmt_cookie_consent', + array( + 'user_ip' => $_SERVER['REMOTE_ADDR'], + 'consent_given' => 1, + 'timestamp' => current_time('mysql') + ) + ); + } + wp_die(); +} +add_action('wp_ajax_wpmt_save_cookie_consent', 'wpmt_save_cookie_consent'); +add_action('wp_ajax_nopriv_wpmt_save_cookie_consent', 'wpmt_save_cookie_consent'); + +// Tabelle für die Cookie-Zustimmung erstellen (bei Aktivierung des Plugins oder beim Laden des Plugins) +function wpmt_create_cookie_consent_table() { + global $wpdb; + + $table_name = $wpdb->prefix . 'wpmt_cookie_consent'; + + // Prüfen, ob die Tabelle bereits existiert + if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") !== $table_name) { + // Tabelle erstellen + $charset_collate = $wpdb->get_charset_collate(); + + $sql = "CREATE TABLE $table_name ( + id bigint(20) NOT NULL AUTO_INCREMENT, + user_ip varchar(255) NOT NULL, + consent_given tinyint(1) NOT NULL, + timestamp datetime DEFAULT CURRENT_TIMESTAMP NOT NULL, + PRIMARY KEY (id) + ) $charset_collate;"; + + require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); + dbDelta($sql); + } +} + +// Aufruf beim Laden des Plugins +add_action('plugins_loaded', 'wpmt_create_cookie_consent_table'); + +// Aufruf bei der Aktivierung des Plugins +register_activation_hook(__FILE__, 'wpmt_create_cookie_consent_table'); + + +/* + * Backup Autoveröffentlichung + */ + + // Funktion, um zukünftige Posts zu veröffentlichen function pubMissedPosts() { if (is_front_page() || is_single()) { @@ -53,45 +588,24 @@ function pubMissedPosts() { // Die Funktion beim Laden der Seite aufrufen add_action('wp_head', 'pubMissedPosts'); -/* - * Abhängigkeitsprüfung: WP Multi Kategorie - */ -function wp_multi_toolkit_check_kategorie_dependency() { - if (!function_exists('is_plugin_active')) { - include_once(ABSPATH . 'wp-admin/includes/plugin.php'); - } - - // Prüfen, ob WP Multi Kategorie installiert und aktiv ist - if (!is_plugin_active('wp-multi-kategorie/wp-multi-kategorie.php')) { - add_action('admin_notices', 'wp_multi_toolkit_kategorie_dependency_notice'); - return false; - } - return true; -} - -// Admin-Hinweis, falls Abhängigkeit fehlt -function wp_multi_toolkit_kategorie_dependency_notice() { - ?> -
-

- - - - -

-
- $plugin_name, 'title' => $title, @@ -112,20 +626,22 @@ function send_support_ticket_to_server($plugin_name, $title, $description, $labe if (is_wp_error($response)) { $error_message = $response->get_error_message(); - return "Es gab einen Fehler bei der Ticketübertragung: $error_message"; + return '' . sprintf(__('Es gab einen Fehler bei der Ticketübertragung: %s', 'wp-multi-toolkit'), $error_message) . ''; } $response_body = wp_remote_retrieve_body($response); $response_data = json_decode($response_body, true); if (isset($response_data['message']) && $response_data['message'] === 'Issues erfolgreich erstellt') { - return 'Issues erfolgreich erstellt'; + return '' . __('Issues erfolgreich erstellt', 'wp-multi-toolkit') . ''; } else { - return 'Es gab einen Fehler: ' . esc_html($response_body) . ''; + return '' . sprintf(__('Es gab einen Fehler: %s', 'wp-multi-toolkit'), esc_html($response_body)) . ''; } } -// Support-Ticket Formular +/** + * Rendert das Support-Ticket-Formular im Admin-Bereich. + */ function support_ticket_form() { ?>
@@ -140,6 +656,7 @@ function support_ticket_form() { +
@@ -266,7 +783,9 @@ function support_ticket_form() { } } -// Menüseite hinzufügen +/** + * Fügt die Support-Ticket-Seite zum Admin-Menü hinzu. + */ function add_support_ticket_page() { add_menu_page( __('WP-Multi Support', 'wp-multi-toolkit'), @@ -278,9 +797,12 @@ function add_support_ticket_page() { } add_action('admin_menu', 'add_support_ticket_page'); + /* * Virtueller Assistent als Submenü */ + + function wpmt_virtual_assistant_page() { if (!current_user_can('manage_options')) { wp_die(__('Du hast nicht die Berechtigung, auf diese Seite zuzugreifen.', 'wp-multi-toolkit')); @@ -409,9 +931,12 @@ function wpmt_add_assistant_page() { } add_action('admin_menu', 'wpmt_add_assistant_page'); + /* * Antworten vordefinieren */ + + add_filter('wpmt_assistant_responses', function($responses) { // WP Multi $responses['statistik'] = __('Nutze den Shortcode [statistik_manager] oder gehe zu "WP Stat & Notice", um Statistiken wie Beitragsanzahl, Kommentare, Kategorien und Serien anzuzeigen.', 'wp-multi-toolkit'); @@ -445,6 +970,17 @@ add_filter('wpmt_assistant_responses', function($responses) { // WP Multi Search $responses['suchfunktion'] = __('Füge eine Suchfunktion (Allgemein, Gastautor, Titel) als Shortcode, Widget oder Menüeintrag hinzu. Einstellungen unter "Einstellung > WP-Multi Search".', 'wp-multi-toolkit'); + // WP Multi Team-Card + $responses['teamcard'] = __('Mit dem WP Multi Team-Card Plugin kannst du Teammitglieder mit Name, Funktion, Zuständigkeit und Bild erstellen. Nutze den Shortcode [teamcards] für die Anzeige im Frontend.', 'wp-multi-toolkit'); + $responses['teammitglied hinzufügen'] = __('Gehe zu "Team-Cards" im Admin-Menü, fülle die Felder (Name, Funktion, Zuständigkeit, Bild) aus und klicke auf "Teammitglied hinzufügen".', 'wp-multi-toolkit'); + $responses['teamcard shortcode'] = __('Verwende den Shortcode [teamcards] in einem Beitrag oder einer Seite, um alle Teammitglieder anzuzeigen. Für eine bestimmte Kategorie nutze z. B. [teamcards kategorie="slug"].', 'wp-multi-toolkit'); + $responses['teamcard kategorie'] = __('Erstelle Kategorien für Teammitglieder unter "Beiträge > Kategorien". Weise sie den Teammitgliedern zu, um sie mit dem Shortcode [teamcards kategorie="slug"] gefiltert anzuzeigen.', 'wp-multi-toolkit'); + $responses['teamcard bild'] = __('Füge ein Bild für ein Teammitglied hinzu, indem du in der "Team-Cards"-Verwaltung auf "Bild auswählen" klickst. Das Bild wird im Frontend in der Teamkarte angezeigt.', 'wp-multi-toolkit'); + $responses['teamcard löschen'] = __('Um ein Teammitglied zu löschen, gehe zu "Team-Cards", finde das Mitglied in der Liste und klicke auf "Löschen".', 'wp-multi-toolkit'); + $responses['teamcard reihenfolge'] = __('Ändere die Reihenfolge der Teammitglieder, indem du die Zeilen in der "Team-Cards"-Tabelle per Drag-and-Drop verschiebst.', 'wp-multi-toolkit'); + $responses['teamcard deinstallation'] = __('Beim Löschen des WP Multi Team-Card Plugins werden alle Teammitglieder, Kategorien und Bilder aus der Datenbank entfernt. Erstelle ein Backup, wenn du die Daten behalten möchtest.', 'wp-multi-toolkit'); + $responses['teamcard updates'] = __('Prüfe Updates für das WP Multi Team-Card Plugin unter https://git.viper.ipv64.net/M_Viper/wp-multi-teamcard. Eine Benachrichtigung erscheint im Admin-Bereich, wenn eine neue Version verfügbar ist.', 'wp-multi-toolkit'); + // WP Multi Toolkit $responses['update management'] = __('Zeigt den Status der WP Multi Plugins und verfügbare Updates im Dashboard-Widget "Verfügbare Updates für WP Multi Toolkit".', 'wp-multi-toolkit'); $responses['support issues'] = __('Erstelle Support-Tickets unter "WP-Multi Support" für Antworten zu WP Multi Plugins.', 'wp-multi-toolkit'); @@ -468,10 +1004,13 @@ add_filter('wpmt_assistant_responses', function($responses) { return $responses; }); + /* * Schnellzugriff-Menü (Floating Toolbar) */ -function wpmt_add_floating_toolbar() { + + + function wpmt_add_floating_toolbar() { if (!current_user_can('manage_options') || !is_admin()) { return; } @@ -499,9 +1038,12 @@ function wpmt_add_floating_toolbar() { } add_action('admin_footer', 'wpmt_add_floating_toolbar'); + /* * Update Funktion */ + + define('WPMT_PLUGIN_DIR', plugin_dir_path(__FILE__)); // Textdomain laden @@ -560,7 +1102,38 @@ add_shortcode('wpmt_multi', 'wpmt_multi_shortcode'); // ### Automatisierte Plugin-Dokumentation ### -// Funktion zur Generierung der Dokumentation +/** + * Ruft die neueste Version eines Plugins aus der Gitea-API ab. + * + * @param string $repo_name Der Name des Gitea-Repositorys. + * @return string|null Die neueste Version oder null bei Fehlern. + */ +function wpmt_get_latest_plugin_version($repo_name) { + $api_url = "https://git.viper.ipv64.net/api/v1/repos/M_Viper/{$repo_name}/releases"; + $response = wp_remote_get($api_url, array( + 'timeout' => 10, + 'headers' => array('Accept' => 'application/json') + )); + + if (is_wp_error($response)) { + return null; + } + + $body = wp_remote_retrieve_body($response); + $releases = json_decode($body, true); + + if (empty($releases) || !is_array($releases)) { + return null; + } + + // Sortiere Releases nach Erstellungsdatum (neuestes zuerst) + usort($releases, function($a, $b) { + return strtotime($b['created_at']) - strtotime($a['created_at']); + }); + + return !empty($releases[0]['tag_name']) ? ltrim($releases[0]['tag_name'], 'v') : null; +} + function wpmt_generate_plugin_docs() { require_once ABSPATH . 'wp-admin/includes/plugin.php'; @@ -593,7 +1166,14 @@ function wpmt_generate_plugin_docs() { 'wp-multi-kategorie' => array( 'file' => 'wp-multi-kategorie/wp-multi-kategorie.php', 'name' => 'WP Multi Kategorie', + 'description' => __('Filtert und verwaltet Kategorien für Beiträge.', 'wp-multi-toolkit'), 'repo' => 'wp-multi-kategorie' + ), + 'wp-multi-teamcard' => array( + 'file' => 'wp-multi-teamcards/wp-multi-team-card.php', // Korrekter Pfad, wie von dir bestätigt + 'name' => 'WP Multi Team-Card', + 'description' => __('Erstellt Teamkarten mit Name, Funktion, Zuständigkeit und Bild, die über den Shortcode [teamcards] angezeigt werden.', 'wp-multi-toolkit'), + 'repo' => 'wp-multi-teamcard' ) ); @@ -610,9 +1190,18 @@ function wpmt_generate_plugin_docs() { if ($is_installed) { $plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin['file']); $is_active = is_plugin_active($plugin['file']); + $status_class = $is_active ? 'status-active' : 'status-inactive'; + $installed_version = $plugin_data['Version']; + $latest_version = wpmt_get_latest_plugin_version($plugin['repo']); + $update_available = $latest_version && version_compare($latest_version, $installed_version, '>'); ?> -

:

-

:

+

:

+

: + + + + +

:

:

@@ -622,7 +1211,7 @@ function wpmt_generate_plugin_docs() {

:

-

:

+

:

:

:

@@ -645,6 +1234,26 @@ function wpmt_generate_plugin_docs() { .wpmt-docs-section p { margin: 5px 0; } + .status-active { + color: #28a745; /* Grün für Aktiv */ + font-weight: bold; + } + .status-inactive { + color: #dc3545; /* Rot für Inaktiv */ + font-weight: bold; + } + .status-not-installed { + color: #dc3545; /* Rot für Nicht installiert */ + font-weight: bold; + } + .version-outdated { + color: #dc3545; /* Rot für veraltete Version */ + font-weight: bold; + } + .version-latest { + color: #28a745; /* Grün für neueste Version */ + font-weight: bold; + } 0)); + + if (!empty($banned_options['reverse_proxy']) && intval($banned_options['reverse_proxy']) === 1) { + foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key) { + if (!empty($_SERVER[$key])) { + foreach (explode(',', $_SERVER[$key]) as $ip) { + $ip = trim($ip); + if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { + return esc_attr($ip); + } + } + } + } + } elseif (!empty($_SERVER['REMOTE_ADDR'])) { + $ip = $_SERVER['REMOTE_ADDR']; + if (strpos($ip, ',') !== false) { + $ip = explode(',', $ip)[0]; + } + return esc_attr($ip); + } + + return ''; +} + +### Function: Preview Banned Message +add_action('wp_ajax_wp_multi_ban_admin', 'wp_multi_ban_preview_banned_message'); +function wp_multi_ban_preview_banned_message() { + if (!current_user_can('manage_options')) { + wp_send_json_error('Zugriff verweigert'); + } + + $banned_stats = get_option('wp_multi_ban_stats', array('users' => array(), 'count' => 0)); + $banned_message = stripslashes(get_option('wp_multi_ban_message', 'Ihr Zugriff auf %SITE_NAME% (%SITE_URL%) wurde gesperrt.')); + $banned_message = str_replace( + array( + '%SITE_NAME%', + '%SITE_URL%', + '%USER_ATTEMPTS_COUNT%', + '%USER_IP%', + '%USER_HOSTNAME%', + '%TOTAL_ATTEMPTS_COUNT%' + ), + array( + esc_html(get_option('blogname')), + esc_url(get_option('siteurl')), + number_format_i18n($banned_stats['users'][wp_multi_ban_get_ip()] ?? 0), + esc_html(wp_multi_ban_get_ip()), + esc_html(@gethostbyaddr(wp_multi_ban_get_ip())), + number_format_i18n($banned_stats['count'] ?? 0) + ), + $banned_message + ); + + wp_send_json_success(array('message' => $banned_message)); +} + +### Function: Print Out Banned Message +function wp_multi_ban_print_banned_message() { + $banned_ip = wp_multi_ban_get_ip(); + $banned_stats = get_option('wp_multi_ban_stats', array('users' => array(), 'count' => 0)); + $banned_stats['count'] = isset($banned_stats['count']) ? $banned_stats['count'] + 1 : 1; + $banned_stats['users'][$banned_ip] = isset($banned_stats['users'][$banned_ip]) ? $banned_stats['users'][$banned_ip] + 1 : 1; + update_option('wp_multi_ban_stats', $banned_stats); + $banned_message = stripslashes(get_option('wp_multi_ban_message', 'Ihr Zugriff auf %SITE_NAME% (%SITE_URL%) wurde gesperrt.')); + $banned_message = str_replace( + array( + '%SITE_NAME%', + '%SITE_URL%', + '%USER_ATTEMPTS_COUNT%', + '%USER_IP%', + '%USER_HOSTNAME%', + '%TOTAL_ATTEMPTS_COUNT%' + ), + array( + esc_html(get_option('blogname')), + esc_url(get_option('siteurl')), + number_format_i18n($banned_stats['users'][$banned_ip] ?? 0), + esc_html($banned_ip), + esc_html(@gethostbyaddr($banned_ip)), + number_format_i18n($banned_stats['count'] ?? 0) + ), + $banned_message + ); + echo 'Gesperrt' . $banned_message . ''; + exit; +} + +### Function: Process Banning +function wp_multi_ban_process_ban($banarray, $against) { + if (!empty($banarray) && !empty($against) && is_array($banarray)) { + foreach ($banarray as $cban) { + if (wp_multi_ban_preg_match_wildcard($cban, $against)) { + wp_multi_ban_print_banned_message(); + } + } + } +} + +### Function: Process Banned IP Range +function wp_multi_ban_process_ban_ip_range($banned_ips_range) { + if (!empty($banned_ips_range) && is_array($banned_ips_range)) { + foreach ($banned_ips_range as $banned_ip_range) { + $range = explode('-', $banned_ip_range); + if (count($range) === 2) { + $range_start = trim($range[0]); + $range_end = trim($range[1]); + if (wp_multi_ban_check_ip_within_range(wp_multi_ban_get_ip(), $range_start, $range_end)) { + wp_multi_ban_print_banned_message(); + break; + } + } + } + } +} + +### Function: Banned +add_action('init', 'wp_multi_ban_banned', 1); +function wp_multi_ban_banned() { + $ip = wp_multi_ban_get_ip(); + if (empty($ip)) { + return; + } + $banned_ips = get_option('wp_multi_ban_ips', array()); + $banned_ips_range = get_option('wp_multi_ban_ips_range', array()); + $banned_hosts = get_option('wp_multi_ban_hosts', array()); + $banned_referers = get_option('wp_multi_ban_referers', array()); + $banned_user_agents = get_option('wp_multi_ban_user_agents', array()); + $banned_exclude_ips = get_option('wp_multi_ban_exclude_ips', array()); + + if (is_array($banned_exclude_ips) && in_array($ip, $banned_exclude_ips)) { + return; + } + + if (is_array($banned_ips)) { + wp_multi_ban_process_ban($banned_ips, $ip); + } + if (is_array($banned_ips_range)) { + wp_multi_ban_process_ban_ip_range($banned_ips_range); + } + if (is_array($banned_hosts)) { + wp_multi_ban_process_ban($banned_hosts, @gethostbyaddr($ip)); + } + if (is_array($banned_referers) && !empty($_SERVER['HTTP_REFERER'])) { + wp_multi_ban_process_ban($banned_referers, $_SERVER['HTTP_REFERER']); + } + if (is_array($banned_user_agents) && !empty($_SERVER['HTTP_USER_AGENT'])) { + wp_multi_ban_process_ban($banned_user_agents, $_SERVER['HTTP_USER_AGENT']); + } +} + +### Function: Check Whether IP Within A Given IP Range +function wp_multi_ban_check_ip_within_range($ip, $range_start, $range_end) { + $range_start = ip2long($range_start); + $range_end = ip2long($range_end); + $ip = ip2long($ip); + return ($ip !== false && $range_start !== false && $range_end !== false && $ip >= $range_start && $ip <= $range_end); +} + +### Function: Wildcard Check +function wp_multi_ban_preg_match_wildcard($regex, $subject) { + if (empty($regex) || empty($subject)) { + return false; + } + $regex = preg_quote($regex, '#'); + $regex = str_replace('\*', '.*', $regex); + return preg_match("#^$regex$#i", $subject) === 1; +} + +### Function: Activate Ban Module +function wp_multi_ban_activate() { + $default_message = 'Ihr Zugriff auf %SITE_NAME% (%SITE_URL%) wurde gesperrt.' . "\n\n" . + 'Details:' . "\n" . + '- Ihre IP: %USER_IP%' . "\n" . + '- Hostname: %USER_HOSTNAME%' . "\n" . + '- Ihre Versuche: %USER_ATTEMPTS_COUNT%' . "\n" . + '- Gesamtanzahl Sperrversuche: %TOTAL_ATTEMPTS_COUNT%' . "\n\n" . + 'Bitte kontaktieren Sie den Support von %SITE_NAME%, falls Sie Fragen haben.'; + add_option('wp_multi_ban_ips', array()); + add_option('wp_multi_ban_hosts', array()); + add_option('wp_multi_ban_stats', array('users' => array(), 'count' => 0)); + add_option('wp_multi_ban_message', $default_message); + add_option('wp_multi_ban_referers', array()); + add_option('wp_multi_ban_exclude_ips', array()); + add_option('wp_multi_ban_ips_range', array()); + add_option('wp_multi_ban_user_agents', array()); + add_option('wp_multi_ban_options', array('reverse_proxy' => 0)); +} + +### Function: Admin Options Page +function wp_multi_ban_options_page() { + if (!current_user_can('manage_options')) { + wp_die('Zugriff verweigert'); + } + + $text = ''; + if (!empty($_POST['Submit'])) { + check_admin_referer('wp_multi_ban_templates'); + + $banned_options = array('reverse_proxy' => isset($_POST['banned_option_reverse_proxy']) ? 1 : 0); + $banned_ips = array(); + $banned_ips_range = array(); + $banned_hosts = array(); + $banned_referers = array(); + $banned_user_agents = array(); + $banned_exclude_ips = array(); + $admin_ip = wp_multi_ban_get_ip(); + $admin_login = trim(wp_get_current_user()->user_login); + + if (!empty($_POST['banned_ips'])) { + foreach (explode("\n", trim($_POST['banned_ips'])) as $banned_ip) { + $banned_ip = trim($banned_ip); + if ($admin_login === 'admin' && $banned_ip === $admin_ip) { + $text .= '
Diese IP \'' . esc_html($banned_ip) . '\' gehört dem Admin und wird nicht gesperrt.
'; + } else { + $banned_ips[] = esc_html($banned_ip); + } + } + } + + if (!empty($_POST['banned_ips_range'])) { + foreach (explode("\n", trim($_POST['banned_ips_range'])) as $banned_ip_range) { + $range = explode('-', trim($banned_ip_range)); + if (count($range) === 2 && $admin_login === 'admin' && wp_multi_ban_check_ip_within_range($admin_ip, trim($range[0]), trim($range[1]))) { + $text .= '
Die Admin-IP \'' . esc_html($admin_ip) . '\' liegt in diesem Bereich und wird nicht gesperrt.
'; + } else { + $banned_ips_range[] = esc_html(trim($banned_ip_range)); + } + } + } + + if (!empty($_POST['banned_hosts'])) { + foreach (explode("\n", trim($_POST['banned_hosts'])) as $banned_host) { + $banned_hosts[] = esc_html(trim($banned_host)); + } + } + + if (!empty($_POST['banned_referers'])) { + foreach (explode("\n", trim($_POST['banned_referers'])) as $banned_referer) { + $banned_referers[] = esc_html(trim($banned_referer)); + } + } + + if (!empty($_POST['banned_user_agents'])) { + foreach (explode("\n", trim($_POST['banned_user_agents'])) as $banned_user_agent) { + $banned_user_agents[] = esc_html(trim($banned_user_agent)); + } + } + + if (!empty($_POST['banned_exclude_ips'])) { + foreach (explode("\n", trim($_POST['banned_exclude_ips'])) as $banned_exclude_ip) { + $banned_exclude_ips[] = esc_html(trim($banned_exclude_ip)); + } + } + + $allowed_tags = wp_kses_allowed_html('post'); + $allowed_tags['a'] = array('href' => true, 'title' => true); + $banned_message = !empty($_POST['banned_template_message']) ? wp_kses(trim($_POST['banned_template_message']), $allowed_tags) : ''; + + update_option('wp_multi_ban_options', $banned_options); + update_option('wp_multi_ban_ips', $banned_ips); + update_option('wp_multi_ban_ips_range', $banned_ips_range); + update_option('wp_multi_ban_hosts', $banned_hosts); + update_option('wp_multi_ban_referers', $banned_referers); + update_option('wp_multi_ban_user_agents', $banned_user_agents); + update_option('wp_multi_ban_exclude_ips', $banned_exclude_ips); + update_option('wp_multi_ban_message', $banned_message); + + $text .= '
Einstellungen gespeichert.
'; + } + + if (!empty($_POST['do']) && $_POST['do'] === 'Sperrstatistiken zurücksetzen') { + check_admin_referer('wp_multi_ban_stats'); + if (!empty($_POST['reset_ban_stats']) && $_POST['reset_ban_stats'] === 'yes') { + update_option('wp_multi_ban_stats', array('users' => array(), 'count' => 0)); + $text .= '
Alle Sperrstatistiken zurückgesetzt.
'; + } elseif (!empty($_POST['delete_ips'])) { + $banned_stats = get_option('wp_multi_ban_stats', array('users' => array(), 'count' => 0)); + foreach ((array)$_POST['delete_ips'] as $delete_ip) { + unset($banned_stats['users'][$delete_ip]); + } + update_option('wp_multi_ban_stats', $banned_stats); + $text .= '
Ausgewählte IP-Statistiken zurückgesetzt.
'; + } + } + + $banned_ips = get_option('wp_multi_ban_ips', array()); + $banned_ips_range = get_option('wp_multi_ban_ips_range', array()); + $banned_hosts = get_option('wp_multi_ban_hosts', array()); + $banned_referers = get_option('wp_multi_ban_referers', array()); + $banned_user_agents = get_option('wp_multi_ban_user_agents', array()); + $banned_exclude_ips = get_option('wp_multi_ban_exclude_ips', array()); + $banned_stats = get_option('wp_multi_ban_stats', array('users' => array(), 'count' => 0)); + $banned_options = get_option('wp_multi_ban_options', array('reverse_proxy' => 0)); + + $banned_ips_display = implode("\n", $banned_ips); + $banned_ips_range_display = implode("\n", $banned_ips_range); + $banned_hosts_display = implode("\n", $banned_hosts); + $banned_referers_display = implode("\n", $banned_referers); + $banned_user_agents_display = implode("\n", $banned_user_agents); + $banned_exclude_ips_display = implode("\n", $banned_exclude_ips); + ?> + + +
+

WP Multi Ban Optionen

+ +
+ +
+
+

Ihre Details

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DetailWert
IP
Hostname
User Agent
Seiten-URL
Bitte nicht sich selbst sperren.
+
+
+

Sperrstatistiken

+
+ + + + + + + + + + + $count) { + ?> + + + + + + + + + + + + + + + + +
IPVersucheAuswählen
+ + +
Keine Sperrversuche
Gesamtversuche: + + +
+
+ +
+
+
+
+
+ +
+

Einstellungen

+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+ + +
+
+
+
+
+ +
+
+
+
+ blog_id); + wp_multi_ban_activate(); + restore_current_blog(); + } + } else { + wp_multi_ban_activate(); + } +} + +// Uninstall Hook +register_uninstall_hook(__FILE__, 'wp_multi_toolkit_uninstall'); +function wp_multi_toolkit_uninstall() { + $options = array( + 'wp_multi_ban_ips', + 'wp_multi_ban_hosts', + 'wp_multi_ban_stats', + 'wp_multi_ban_message', + 'wp_multi_ban_referers', + 'wp_multi_ban_exclude_ips', + 'wp_multi_ban_ips_range', + 'wp_multi_ban_user_agents', + 'wp_multi_ban_options' + ); + if (is_multisite()) { + foreach (get_sites() as $site) { + switch_to_blog($site->blog_id); + foreach ($options as $option) { + delete_option($option); + } + restore_current_blog(); + } + } else { + foreach ($options as $option) { + delete_option($option); + } + } +} \ No newline at end of file