diff --git a/assets/admin.css b/assets/admin.css new file mode 100644 index 0000000..0897d49 --- /dev/null +++ b/assets/admin.css @@ -0,0 +1,594 @@ +/** + * WP Multi Suite - Gemeinsames Admin-Design-System + * + * Alle Regeln sind unter .wpm-admin gescoped, damit keine fremden + * Admin-Seiten beeinflusst werden. Wird nur auf den eigenen Seiten + * geladen (Hook-Registry in wp-multi-toolkit.php). + */ + +.wpm-admin { + --wpm-primary: #0073aa; + --wpm-primary-dark: #005f8a; + --wpm-primary-light: #e8f4fa; + --wpm-success: #2ecc71; + --wpm-success-bg: #e9f7ef; + --wpm-warning: #f39c12; + --wpm-warning-bg: #fef5e7; + --wpm-danger: #e74c3c; + --wpm-danger-bg: #fdecea; + --wpm-info-bg: #e8f4fa; + --wpm-text: #2d3436; + --wpm-text-soft: #4a5568; + --wpm-text-muted: #718096; + --wpm-border: #e2e8f0; + --wpm-bg-soft: #f5f7fa; + --wpm-radius: 12px; + --wpm-radius-sm: 8px; + --wpm-shadow: 0 4px 20px rgba(0, 0, 0, 0.08); + --wpm-shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.05); + + max-width: 1200px; + margin: 20px 20px 20px 0; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; + color: var(--wpm-text); +} + +/* ---------- Marken-Header ---------- */ + +.wpm-admin .wpm-header { + display: flex; + align-items: center; + gap: 20px; + background: linear-gradient(135deg, var(--wpm-primary) 0%, var(--wpm-primary-dark) 100%); + border-radius: var(--wpm-radius); + padding: 22px 28px; + margin-bottom: 24px; + box-shadow: var(--wpm-shadow); + color: #fff; +} + +.wpm-admin .wpm-header__logo { + height: 52px; + width: auto; + flex-shrink: 0; + border-radius: var(--wpm-radius-sm); + background: rgba(255, 255, 255, 0.12); + padding: 6px; +} + +.wpm-admin .wpm-header__text { + min-width: 0; +} + +.wpm-admin .wpm-header__title { + margin: 0; + padding: 0; + font-size: 24px; + font-weight: 600; + line-height: 1.25; + color: #fff; +} + +.wpm-admin .wpm-header__sub { + margin: 4px 0 0; + font-size: 14px; + color: rgba(255, 255, 255, 0.85); +} + +/* ---------- Karten & Grid ---------- */ + +.wpm-admin .wpm-card { + background: #fff; + border-radius: var(--wpm-radius); + box-shadow: var(--wpm-shadow); + padding: 24px; + margin-bottom: 24px; + transition: transform 0.25s ease, box-shadow 0.25s ease; +} + +.wpm-admin .wpm-card:hover { + transform: translateY(-2px); +} + +.wpm-admin .wpm-card__title { + margin: 0 0 16px; + padding: 0 0 12px; + font-size: 18px; + font-weight: 600; + color: var(--wpm-text); + border-bottom: 1px solid var(--wpm-border); +} + +.wpm-admin .wpm-grid { + display: grid; + grid-template-columns: 1fr; + gap: 24px; + margin-bottom: 24px; +} + +.wpm-admin .wpm-grid--2 { + grid-template-columns: 1fr 1fr; +} + +.wpm-admin .wpm-grid--3 { + grid-template-columns: repeat(3, 1fr); +} + +.wpm-admin .wpm-grid > .wpm-card { + margin-bottom: 0; +} + +/* ---------- Formulare ---------- */ + +.wpm-admin .wpm-field { + display: grid; + grid-template-columns: 220px 1fr; + gap: 8px 24px; + align-items: start; + padding: 14px 0; + border-bottom: 1px solid var(--wpm-border); +} + +.wpm-admin .wpm-field:last-of-type { + border-bottom: none; +} + +.wpm-admin .wpm-field__label { + font-weight: 600; + font-size: 14px; + color: var(--wpm-text); + padding-top: 6px; +} + +.wpm-admin .wpm-field__hint { + display: block; + font-size: 12px; + color: var(--wpm-text-muted); + margin-top: 4px; + font-weight: 400; +} + +.wpm-admin .wpm-card input[type="text"], +.wpm-admin .wpm-card input[type="url"], +.wpm-admin .wpm-card input[type="email"], +.wpm-admin .wpm-card input[type="number"], +.wpm-admin .wpm-card input[type="date"], +.wpm-admin .wpm-card select, +.wpm-admin .wpm-card textarea { + width: 100%; + max-width: 640px; + padding: 10px 12px; + border: 1px solid var(--wpm-border); + border-radius: var(--wpm-radius-sm); + font-size: 14px; + line-height: 1.5; + background: #fff; + color: var(--wpm-text); + box-shadow: none; + transition: border-color 0.2s, box-shadow 0.2s; +} + +.wpm-admin .wpm-card input:focus, +.wpm-admin .wpm-card select:focus, +.wpm-admin .wpm-card textarea:focus { + border-color: var(--wpm-primary); + box-shadow: 0 0 0 3px rgba(0, 115, 170, 0.12); + outline: none; +} + +/* Auswahl-Menüs klar als Dropdown erkennbar machen (eigener Pfeil) */ +.wpm-admin .wpm-card select { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + padding-right: 36px; + cursor: pointer; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath fill='%23718096' d='M0 0l5 6 5-6z'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: right 14px center; + background-size: 10px 6px; +} + +.wpm-admin .wpm-card textarea { + resize: vertical; +} + +/* Settings-API-Markup (form-table) innerhalb Karten harmonisieren */ + +.wpm-admin .wpm-card .form-table { + margin-top: 0; + background: transparent; + border-radius: 0; + padding: 0; + box-shadow: none; +} + +.wpm-admin .wpm-card .form-table th { + font-weight: 600; + font-size: 14px; + color: var(--wpm-text); + width: 220px; + padding: 14px 24px 14px 0; +} + +.wpm-admin .wpm-card .form-table td { + padding: 14px 0; +} + +.wpm-admin .wpm-card .form-table tr { + border-bottom: 1px solid var(--wpm-border); +} + +.wpm-admin .wpm-card .description, +.wpm-admin .wpm-card small { + font-size: 12px; + color: var(--wpm-text-muted); + font-style: normal; +} + +/* ---------- Buttons ---------- */ + +.wpm-admin .wpm-btn, +.wpm-admin .button, +.wpm-admin .button-primary, +.wpm-admin .button-secondary { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 9px 18px; + border-radius: var(--wpm-radius-sm); + font-size: 14px; + font-weight: 500; + line-height: 1.4; + text-decoration: none; + cursor: pointer; + border: 1px solid var(--wpm-border); + background: var(--wpm-bg-soft); + color: var(--wpm-text); + transition: all 0.2s ease; + height: auto; + min-height: 0; +} + +.wpm-admin .wpm-btn--primary, +.wpm-admin .button-primary { + background: var(--wpm-primary); + border-color: var(--wpm-primary); + color: #fff; + text-shadow: none; + box-shadow: none; +} + +.wpm-admin .wpm-btn--primary:hover, +.wpm-admin .button-primary:hover { + background: var(--wpm-primary-dark); + border-color: var(--wpm-primary-dark); + color: #fff; + transform: translateY(-1px); + box-shadow: 0 2px 8px rgba(0, 115, 170, 0.3); +} + +.wpm-admin .wpm-btn:hover, +.wpm-admin .button:hover, +.wpm-admin .button-secondary:hover { + background: var(--wpm-border); + color: var(--wpm-text); + transform: translateY(-1px); +} + +.wpm-admin .wpm-btn--danger { + background: var(--wpm-danger); + border-color: var(--wpm-danger); + color: #fff; +} + +.wpm-admin .wpm-btn--danger:hover { + background: #c0392b; + border-color: #c0392b; + color: #fff; + box-shadow: 0 2px 8px rgba(231, 76, 60, 0.3); +} + +.wpm-admin .wpm-btn--ghost { + background: transparent; + border-color: transparent; + color: var(--wpm-primary); +} + +.wpm-admin .wpm-btn--ghost:hover { + background: var(--wpm-primary-light); + color: var(--wpm-primary-dark); +} + +/* ---------- Tabellen ---------- */ + +.wpm-admin .wpm-table-wrap { + border-radius: var(--wpm-radius-sm); + overflow: hidden; + box-shadow: var(--wpm-shadow-sm); + border: 1px solid var(--wpm-border); +} + +.wpm-admin table.wpm-table { + width: 100%; + border-collapse: collapse; + background: #fff; + border: none; + box-shadow: none; +} + +.wpm-admin table.wpm-table th { + background: var(--wpm-bg-soft); + font-weight: 600; + font-size: 13px; + text-transform: uppercase; + letter-spacing: 0.04em; + color: var(--wpm-text); + padding: 14px 16px; + text-align: left; + border-bottom: 2px solid var(--wpm-border); +} + +.wpm-admin table.wpm-table td { + padding: 13px 16px; + font-size: 14px; + color: var(--wpm-text-soft); + border-bottom: 1px solid var(--wpm-border); +} + +.wpm-admin table.wpm-table tbody tr:last-child td { + border-bottom: none; +} + +.wpm-admin table.wpm-table tbody tr:nth-child(even) { + background: #fafbfc; +} + +.wpm-admin table.wpm-table tbody tr:hover { + background: var(--wpm-primary-light); +} + +.wpm-admin table.wpm-table th a { + color: var(--wpm-primary); + text-decoration: none; +} + +/* ---------- Notices ---------- */ + +.wpm-admin .wpm-notice { + display: flex; + align-items: center; + gap: 10px; + padding: 12px 16px; + border-radius: var(--wpm-radius-sm); + margin-bottom: 20px; + font-size: 14px; + animation: wpmFadeIn 0.4s ease; +} + +.wpm-admin .wpm-notice--success { + background: var(--wpm-success-bg); + border-left: 4px solid var(--wpm-success); +} + +.wpm-admin .wpm-notice--warning { + background: var(--wpm-warning-bg); + border-left: 4px solid var(--wpm-warning); +} + +.wpm-admin .wpm-notice--error { + background: var(--wpm-danger-bg); + border-left: 4px solid var(--wpm-danger); +} + +.wpm-admin .wpm-notice--info { + background: var(--wpm-info-bg); + border-left: 4px solid var(--wpm-primary); +} + +@keyframes wpmFadeIn { + from { opacity: 0; transform: translateY(8px); } + to { opacity: 1; transform: translateY(0); } +} + +/* ---------- Badges / Status-Pills ---------- */ + +.wpm-admin .wpm-badge { + display: inline-block; + padding: 3px 10px; + border-radius: 999px; + font-size: 12px; + font-weight: 600; + line-height: 1.6; + background: var(--wpm-bg-soft); + color: var(--wpm-text-soft); +} + +.wpm-admin .wpm-badge--success { + background: var(--wpm-success-bg); + color: #1e8449; +} + +.wpm-admin .wpm-badge--warning { + background: var(--wpm-warning-bg); + color: #b9770e; +} + +.wpm-admin .wpm-badge--danger { + background: var(--wpm-danger-bg); + color: #b03a2e; +} + +/* ---------- Statistik-Kacheln ---------- */ + +.wpm-admin .wpm-stats { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); + gap: 16px; + margin-bottom: 24px; +} + +.wpm-admin .wpm-stat-card { + background: #fff; + border-radius: var(--wpm-radius); + box-shadow: var(--wpm-shadow-sm); + border: 1px solid var(--wpm-border); + padding: 20px; + display: flex; + align-items: center; + gap: 14px; +} + +.wpm-admin .wpm-stat-card .dashicons { + font-size: 28px; + width: 28px; + height: 28px; + color: var(--wpm-primary); + flex-shrink: 0; +} + +.wpm-admin .wpm-stat-card__value { + font-size: 26px; + font-weight: 700; + color: var(--wpm-text); + line-height: 1.1; +} + +.wpm-admin .wpm-stat-card__label { + font-size: 12px; + color: var(--wpm-text-muted); + text-transform: uppercase; + letter-spacing: 0.04em; + margin-top: 2px; +} + +/* ---------- Tabs ---------- */ + +.wpm-admin .wpm-tabs { + display: flex; + gap: 4px; + margin-bottom: 24px; + border-bottom: 2px solid var(--wpm-border); +} + +.wpm-admin .wpm-tab { + padding: 10px 20px; + font-size: 14px; + font-weight: 500; + color: var(--wpm-text-soft); + text-decoration: none; + border-radius: var(--wpm-radius-sm) var(--wpm-radius-sm) 0 0; + border-bottom: 2px solid transparent; + margin-bottom: -2px; + transition: all 0.2s; +} + +.wpm-admin .wpm-tab:hover { + background: var(--wpm-bg-soft); + color: var(--wpm-text); +} + +.wpm-admin .wpm-tab--active { + color: var(--wpm-primary); + border-bottom-color: var(--wpm-primary); + font-weight: 600; +} + +/* ---------- Modul-Übersicht (Landing-Page) ---------- */ + +.wpm-admin .wpm-modules { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); + gap: 16px; +} + +.wpm-admin .wpm-module { + display: flex; + align-items: flex-start; + gap: 14px; + background: #fff; + border: 1px solid var(--wpm-border); + border-radius: var(--wpm-radius); + padding: 18px; + text-decoration: none; + color: var(--wpm-text); + box-shadow: var(--wpm-shadow-sm); + transition: all 0.2s ease; +} + +.wpm-admin .wpm-module:hover { + transform: translateY(-2px); + box-shadow: var(--wpm-shadow); + border-color: var(--wpm-primary); +} + +.wpm-admin .wpm-module .dashicons { + font-size: 26px; + width: 26px; + height: 26px; + color: var(--wpm-primary); + flex-shrink: 0; + margin-top: 2px; +} + +.wpm-admin .wpm-module__title { + font-size: 15px; + font-weight: 600; + margin: 0 0 4px; + color: var(--wpm-text); +} + +.wpm-admin .wpm-module__desc { + font-size: 12.5px; + color: var(--wpm-text-muted); + margin: 0; + line-height: 1.5; +} + +/* ---------- Footer ---------- */ + +.wpm-admin .wpm-footer { + text-align: center; + font-size: 12px; + color: var(--wpm-text-muted); + padding: 8px 0 20px; +} + +.wpm-admin .wpm-footer a { + color: var(--wpm-primary); + text-decoration: none; +} + +/* ---------- Responsive ---------- */ + +@media (max-width: 1024px) { + .wpm-admin .wpm-grid--2, + .wpm-admin .wpm-grid--3 { + grid-template-columns: 1fr; + } + + .wpm-admin .wpm-field { + grid-template-columns: 1fr; + } +} + +@media (max-width: 768px) { + .wpm-admin { + margin: 10px 10px 10px 0; + } + + .wpm-admin .wpm-header { + flex-direction: column; + text-align: center; + gap: 10px; + padding: 18px; + } + + .wpm-admin .wpm-card { + padding: 16px; + } + + .wpm-admin .wpm-table-wrap { + overflow-x: auto; + } +} diff --git a/wp-multi-toolkit.php b/wp-multi-toolkit.php index 10d552d..2b8b040 100644 --- a/wp-multi-toolkit.php +++ b/wp-multi-toolkit.php @@ -1,3405 +1,3459 @@ -get_results('SHOW TABLES', ARRAY_N); - if (empty($tables)) { - return new WP_Error('backup_error', __('Keine Tabellen in der Datenbank gefunden.', 'wp-multi-toolkit')); - } - - // Öffne die Backup-Datei - $backup_file = fopen($backup_file_path, 'w'); - if (!$backup_file) { - return new WP_Error('backup_error', __('Backup-Datei konnte nicht geöffnet werden.', 'wp-multi-toolkit')); - } - - // 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 (mit SQL-Injection-Schutz) - $create_table_query = $wpdb->get_row($wpdb->prepare('SHOW CREATE TABLE %s', $table_name), ARRAY_N); - if ($create_table_query) { - fwrite($backup_file, $create_table_query[1] . ";\n\n"); - } - - // Daten der Tabelle in Batches holen (Performance-Optimierung) - $offset = 0; - $batch_size = 1000; - while ($rows = $wpdb->get_results($wpdb->prepare("SELECT * FROM `$table_name` LIMIT %d, %d", $offset, $batch_size), 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"); - } - $offset += $batch_size; - } - - fwrite($backup_file, "\n\n"); - } - - // Datei schließen - fclose($backup_file); - - return $backup_file_path; - } - - /** - * Löscht ein Backup aus dem Backup-Verzeichnis. - */ - function wpmt_delete_backup() { - if (!current_user_can('manage_options')) { - wp_die(__('Du hast nicht die Berechtigung, diese Aktion auszuführen.', 'wp-multi-toolkit')); - } - if (isset($_POST['wpmt_action']) && $_POST['wpmt_action'] === 'delete_backup' && isset($_POST['backup_file']) && check_admin_referer('wpmt_delete_backup_nonce')) { - $backup_file = WPMT_BACKUP_DIR . 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') . '

'; - } - } -} - - /** - * Plant automatische Backups via Cron-Job. - */ - function wpmt_schedule_backup() { - $schedule = get_option('wpmt_backup_schedule', 'none'); - $hook = 'wpmt_scheduled_backup'; - - // Entferne bestehende Cron-Jobs, um Duplikate zu vermeiden - wp_clear_scheduled_hook($hook); - - // Plane neuen Cron-Job, wenn aktiviert - if ($schedule !== 'none' && !wp_next_scheduled($hook)) { - wp_schedule_event(time(), $schedule, $hook); - } - } - add_action('wp', 'wpmt_schedule_backup'); - - /** - * Führt das geplante Backup aus und sendet optional eine E-Mail-Benachrichtigung. - */ - function wpmt_create_scheduled_backup() { - $backup_path = wpmt_create_database_backup(); - if (!is_wp_error($backup_path)) { - // Sende E-Mail-Benachrichtigung, wenn aktiviert - $send_email = get_option('wpmt_backup_email_notification', 0); - if ($send_email) { - $admin_email = get_option('admin_email'); - $subject = __('Datenbank-Backup erstellt', 'wp-multi-toolkit'); - $message = __('Ein neues Backup wurde erstellt: ', 'wp-multi-toolkit') . $backup_path; - wp_mail($admin_email, $subject, $message); - } - } else { - // Optional: Fehler in Log schreiben - error_log('WP Multi Toolkit: Geplantes Backup fehlgeschlagen: ' . $backup_path->get_error_message()); - } - } - add_action('wpmt_scheduled_backup', 'wpmt_create_scheduled_backup'); - - /** - * Exportiert die Backup-Einstellungen als JSON-Datei. - */ - function wpmt_export_backup_settings() { - if (isset($_POST['wpmt_export_backup_settings']) && check_admin_referer('wpmt_export_backup_settings')) { - $settings = array( - 'wpmt_backup_schedule' => get_option('wpmt_backup_schedule', 'none'), - 'wpmt_backup_email_notification' => get_option('wpmt_backup_email_notification', 0), - ); - header('Content-Type: application/json'); - header('Content-Disposition: attachment; filename="wpmt_backup_settings.json"'); - echo json_encode($settings, JSON_PRETTY_PRINT); - exit; - } - } - add_action('admin_init', 'wpmt_export_backup_settings'); - - /** - * Importiert Backup-Einstellungen aus einer JSON-Datei. - */ - function wpmt_import_backup_settings() { - if (isset($_POST['wpmt_import_backup_settings']) && check_admin_referer('wpmt_import_backup_settings') && isset($_FILES['wpmt_backup_settings_file'])) { - $file = $_FILES['wpmt_backup_settings_file']['tmp_name']; - $settings = json_decode(file_get_contents($file), true); - - if (is_array($settings)) { - $valid_schedules = array('none', 'hourly', 'twicedaily', 'daily', 'weekly'); - update_option('wpmt_backup_schedule', in_array($settings['wpmt_backup_schedule'], $valid_schedules) ? $settings['wpmt_backup_schedule'] : 'none'); - update_option('wpmt_backup_email_notification', isset($settings['wpmt_backup_email_notification']) ? (int) $settings['wpmt_backup_email_notification'] : 0); - echo '

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

'; - - // Cron-Job aktualisieren - wpmt_schedule_backup(); - } else { - echo '

' . __('Ungültige Datei.', 'wp-multi-toolkit') . '

'; - } - } - } - add_action('admin_init', 'wpmt_import_backup_settings'); - - /** - * Anzeige der Backup-Seite mit Liste der Backups und Verlinkung zur Einstellungsseite. - */ - function wpmt_display_backup_page() { - $backup_dir = WPMT_BACKUP_DIR; - $backups = glob($backup_dir . '/*.sql'); - - ?> -
-

-

- -
- - -

-
- - -

- - - - - - - - - - - - - - - -
- -
- - - - -
-
- -

- -
- -
-

-
- -
- -

-
- - -

-
-
- - -

-

-
-
- function($value) { - $valid_schedules = array('none', 'hourly', 'twicedaily', 'daily', 'weekly'); - return in_array($value, $valid_schedules) ? $value : 'none'; - } - )); - register_setting('wpmt_backup_settings', 'wpmt_backup_email_notification', array( - 'sanitize_callback' => 'absint' - )); - - add_settings_section( - 'wpmt_backup_main_section', - __('Automatische Backup-Einstellungen', 'wp-multi-toolkit'), - function() { - echo '

' . __('Konfigurieren Sie automatische Backups und Benachrichtigungen.', 'wp-multi-toolkit') . '

'; - }, - 'wpmt_backup_settings' - ); - - add_settings_field( - 'wpmt_backup_schedule', - __('Backup-Zeitplan', 'wp-multi-toolkit'), - function() { - $schedule = get_option('wpmt_backup_schedule', 'none'); - ?> - - - > - -

' . esc_html($backup_path->get_error_message()) . '

'; - } else { - echo '

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

'; - } - } - } - add_action('admin_init', 'wpmt_handle_backup_request'); - - /** - * Fügt die Backup-Menüpunkte zum Admin-Menü hinzu. - */ - function wpmt_add_backup_menu() { - add_submenu_page( - 'tools.php', - __('WP-Multi DB-Backup', 'wp-multi-toolkit'), - __('WP-Multi DB-Backup', 'wp-multi-toolkit'), - 'manage_options', - 'wpmt-database-backup', - 'wpmt_display_backup_page' - ); - - add_submenu_page( - 'tools.php', - __('WP-Multi Backup-Einstellungen', 'wp-multi-toolkit'), - __('Backup-Einstellungen', 'wp-multi-toolkit'), - 'manage_options', - 'wpmt-backup-settings', - 'wpmt_display_backup_settings_page' - ); - } - add_action('admin_menu', 'wpmt_add_backup_menu'); - - -/* - * 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 - ?> -
-

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/>
-
-
-
-
-
- - -
-
- - - - - insert( - $wpdb->prefix . 'wpmt_cookie_consent', - array( - 'user_ip' => anonymize_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()) { - global $wpdb; - $now = gmdate('Y-m-d H:i:00'); - - // Überprüfe, ob benutzerdefinierte Beitragstypen vorhanden sind - $args = array( - 'public' => true, - '_builtin' => false, - ); - - $output = 'names'; // names oder objects, names ist der Standard - $operator = 'and'; // 'and' oder 'or' - $post_types = get_post_types($args, $output, $operator); - - if (count($post_types) === 0) { - $sql = "SELECT ID FROM $wpdb->posts WHERE post_type IN ('post', 'page') AND post_status = 'future' AND post_date_gmt < '$now'"; - } else { - $str = implode('\',\'', $post_types); - $sql = "SELECT ID FROM $wpdb->posts WHERE post_type IN ('page', 'post', '$str') AND post_status = 'future' AND post_date_gmt < '$now'"; - } - - $resulto = $wpdb->get_results($sql); - if ($resulto) { - foreach ($resulto as $thisarr) { - wp_publish_post($thisarr->ID); - } - } - } -} - -// Die Funktion beim Laden der Seite aufrufen -add_action('wp_head', 'pubMissedPosts'); - - -/* - * Gitea - Ticket - BUG - Report - */ - -/** - * Sendet ein Support-Ticket an den Server und leitet es an das entsprechende Gitea-Repository weiter. - * - * @param string $plugin_name Der Name des Plugins (z. B. wp-multi, wp-multi-teamcard). - * @param string $title Der Titel des Tickets. - * @param string $description Die Beschreibung des Tickets. - * @param string $label Die Kategorie des Tickets (z. B. bug, enhancement). - * @return string Die Rückmeldung (Erfolg oder Fehler). - */ -function send_support_ticket_to_server($plugin_name, $title, $description, $label = 'bug') { - $server_url = 'https://m-viper.de/gitea-issue-creator.php'; - - // Daten für die Anfrage vorbereiten - $data = [ - 'plugin' => $plugin_name, - 'title' => $title, - 'description' => $description, - 'label' => $label - ]; - - $args = [ - 'method' => 'POST', - 'body' => json_encode($data), - 'headers' => [ - 'Content-Type' => 'application/json', - ], - 'timeout' => 45, - ]; - - $response = wp_remote_post($server_url, $args); - - if (is_wp_error($response)) { - $error_message = $response->get_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', 'wp-multi-toolkit') . ''; - } else { - return '' . sprintf(__('Es gab einen Fehler: %s', 'wp-multi-toolkit'), esc_html($response_body)) . ''; - } -} - -/** - * Rendert das Support-Ticket-Formular im Admin-Bereich. - */ -function support_ticket_form() { - ?> -
-

-
-
-
- - -
- -
- - -
- -
- - -
- -
- - -
- - -
- - ' . $result . '
'; - } - ?> -
- - - - - display_name ?: __('Freund', 'wp-multi-toolkit'); - - $assistant_responses = apply_filters('wpmt_assistant_responses', array( - 'default' => sprintf( - __('Ups, das habe ich nicht ganz verstanden, %s! 😅 Versuche es mit einer anderen Formulierung oder schau in die Dokumentation. Alternativ kannst du ein Support-Ticket erstellen, und wir helfen dir weiter!', 'wp-multi-toolkit'), - esc_html($user_name), - admin_url('admin.php?page=wpmt_docs'), - admin_url('admin.php?page=wp_multi_support') - ) - )); - - // Stichwörter für Autovervollständigung und Anzeige - $keywords = array_keys($assistant_responses); - unset($keywords[array_search('default', $keywords)]); - $keywords_list = implode(', ', array_map(function($key) { - return ucfirst(str_replace('-', ' ', $key)); - }, $keywords)); - - ?> -
-

-
-
- <?php _e('Virtueller Assistent', 'wp-multi-toolkit'); ?> -

-

-
-
-
-
-
- - - -
-
-
-

-

-
-
- - - - - $synonyms) { - foreach ($synonyms as $synonym) { - $distance = levenshtein($input, wpmt_normalize_text($synonym)); - if ($distance < $min_distance && $distance <= $max_distance) { - $min_distance = $distance; - $best_match = $key; - } - } - } - return $best_match; -} - -/** - * AJAX-Handler für Assistenten-Anfragen - */ -function wpmt_assistant_query() { - check_ajax_referer('wpmt_assistant_nonce', 'nonce'); - - $question = isset($_POST['question']) ? sanitize_text_field($_POST['question']) : ''; - $last_question = isset($_POST['last_question']) ? sanitize_text_field($_POST['last_question']) : ''; - $selected_keyword = isset($_POST['selected_keyword']) ? sanitize_text_field($_POST['selected_keyword']) : ''; - - if (empty($question)) { - wp_send_json_error(__('Bitte gib eine Frage ein, um weiterzumachen!', 'wp-multi-toolkit')); - } - - $current_user = wp_get_current_user(); - $user_name = $current_user->display_name ?: __('Freund', 'wp-multi-toolkit'); - - $responses = apply_filters('wpmt_assistant_responses', array( - 'default' => sprintf( - __('Ups, das habe ich nicht ganz verstanden, %s! 😅 Versuche es mit einer anderen Formulierung oder schau in die Dokumentation. Alternativ kannst du ein Support-Ticket erstellen, und wir helfen dir weiter!', 'wp-multi-toolkit'), - esc_html($user_name), - admin_url('admin.php?page=wpmt_docs'), - admin_url('admin.php?page=wp_multi_support') - ) - )); - - $keyword_synonyms = apply_filters('wpmt_assistant_keyword_synonyms', array( - 'statistik' => ['statistik', 'statistiken', 'stats', 'daten', 'bericht'], - 'telegram' => ['telegram', 'telegarm', 'tg', 'tele', 'benachrichtigung telegram'], - 'discord' => ['discord', 'discrod', 'dc', 'discord benachrichtigung'], - 'admin links' => ['admin links', 'admin-links', 'adminlinks', 'links', 'menü links'], - 'gast-autor' => ['gast-autor', 'gastautor', 'guest author', 'gast', 'autor'], - 'beitrag report' => ['beitrag report', 'beitrag-report', 'report', 'melden', 'gemeldete beiträge'], - 'textbox' => ['textbox', 'text-box', 'textfeld', 'text am beitrag'], - 'banner' => ['banner', 'werbung', 'anzeige', 'header banner', 'footer banner'], - 'inhaltsverzeichnis' => ['inhaltsverzeichnis', 'inhalt', 'index', 'verzeichnis', 'alphabetische liste'], - 'lesezeichen' => ['lesezeichen', 'bookmark', 'favoriten', 'speichern', 'merken'], - 'custom shortcode' => ['custom shortcode', 'shortcode', 'eigener shortcode', 'shortcodes'], - 'kommentar sperren' => ['kommentar sperren', 'kommentarsperre', 'blockieren', 'sperren', 'nutzer blockieren'], - 'filter' => ['filter', 'kommentarfilter', 'filtern', 'kommentare filtern'], - 'analytics' => ['analytics', 'analyse', 'benutzer analytics', 'datenanalyse'], - 'pinwand' => ['pinwand', 'notiz', 'pinnwand', 'team notizen'], - 'brute force' => ['brute force', 'bruteforce', 'sicherheit', 'login schutz'], - 'anti spam' => ['anti spam', 'antispam', 'spam', 'spam schutz'], - 'auto tag' => ['auto tag', 'autotag', 'tags', 'automatische tags'], - 'login deaktivieren' => ['login deaktivieren', 'login-deaktivieren', 'login', 'zugang sperren'], - 'text copy' => ['text copy', 'text-copy', 'kopierschutz', 'rechtsklick sperre'], - 'trash mail' => ['trash mail', 'trash-mail', 'spam mail', 'wegwerf email'], - 'kommentar benachrichtigung' => ['kommentar benachrichtigung', 'kommentar-benachrichtigung', 'benachrichtigung', 'comment', 'kommentar alarm'], - 'kategorien ausblenden' => ['kategorien ausblenden', 'kategorie-ausblenden', 'kategorien', 'ausblenden', 'kategorie filter'], - 'suchfunktion' => ['suchfunktion', 'suche', 'search', 'wp multi search'], - 'teamcard' => ['teamcard', 'team-card', 'teamkarte', 'team', 'teamkarten'], - 'teammitglied hinzufügen' => ['teammitglied hinzufügen', 'teammitglied-hinzufügen', 'mitglied', 'hinzufügen', 'teammitglied'], - 'teamcard shortcode' => ['teamcard shortcode', 'teamcard-shortcode', 'shortcode', 'teamkarten shortcode'], - 'teamcard kategorie' => ['teamcard kategorie', 'teamcard-kategorie', 'kategorie', 'team kategorie'], - 'teamcard bild' => ['teamcard bild', 'teamcard-bild', 'bild', 'team foto'], - 'teamcard löschen' => ['teamcard löschen', 'teamcard-löschen', 'löschen', 'teammitglied entfernen'], - 'teamcard reihenfolge' => ['teamcard reihenfolge', 'teamcard-reihenfolge', 'reihenfolge', 'team sortieren'], - 'teamcard deinstallation' => ['teamcard deinstallation', 'teamcard-deinstallation', 'deinstallieren', 'teamcard entfernen'], - 'teamcard updates' => ['teamcard updates', 'teamcard-updates', 'updates', 'teamcard aktualisierung'], - 'update management' => ['update management', 'update-management', 'updates', 'plugin updates'], - 'support issues' => ['support issues', 'support-issues', 'support', 'ticket', 'hilfe'], - 'dokumentation' => ['dokumentation', 'doku', 'docs', 'anleitung', 'dokumentaton'], - 'virtueller assistent' => ['virtueller assistent', 'assistent', 'virtuell', 'chatbot'], - 'toolbar' => ['toolbar', 'werkzeugleiste', 'schnellstart', 'quickbar'], - 'wp multi plugins' => ['wp multi plugins', 'wp-multi-plugins', 'plugins', 'wp multi'], - 'was sind wp multi plugins' => ['was sind wp multi plugins', 'wp multi plugins', 'plugins', 'wp multi erklärung'], - 'wie installiere ich ein plugin' => ['wie installiere ich ein plugin', 'plugin installieren', 'installation', 'plugin setup', 'install plugin'], - 'wo finde ich updates' => ['wo finde ich updates', 'updates finden', 'aktualisierungen', 'plugin updates', 'update suchen'], - 'wie erstelle ich ein support ticket' => ['wie erstelle ich ein support ticket', 'support ticket', 'ticket', 'support anfrage', 'ticket erstellen'], - 'welche voraussetzungen gibt es' => ['welche voraussetzungen gibt es', 'voraussetzungen', 'anforderungen', 'systemanforderungen', 'plugin voraussetzungen'], - 'sind die plugins kostenlos' => ['sind die plugins kostenlos', 'kostenlos', 'gratis', 'plugin kosten', 'free plugins'], - 'wie deaktiviere ich ein plugin' => ['wie deaktiviere ich ein plugin', 'plugin deaktivieren', 'deaktivieren', 'plugin ausschalten', 'disable plugin'], - 'wo finde ich die dokumentation' => ['wo finde ich die dokumentation', 'dokumentation finden', 'doku', 'anleitung finden', 'doku suchen'], - 'wer entwickelt die plugins' => ['wer entwickelt die plugins', 'entwickler', 'm_viper', 'plugin entwickler', 'wer macht plugins'], - 'kann ich eigene funktionen hinzufügen' => ['kann ich eigene funktionen hinzufügen', 'eigene funktionen', 'anpassen', 'erweitern', 'custom functions'], - 'wie richte ich wp multi ein' => ['wie richte ich wp multi ein', 'wp multi einrichten', 'setup wp multi', 'installation wp multi', 'wp multi installieren'], - 'was ist wordpress' => ['was ist wordpress', 'wordpress', 'wordpress erklärung', 'cms wordpress', 'wordpress info'], - 'wie sichere ich meine website' => ['wie sichere ich meine website', 'website sichern', 'sicherheit', 'backup', 'sichere website'], - 'wie verbessere ich die performance' => ['wie verbessere ich die performance', 'performance', 'geschwindigkeit', 'optimierung', 'website schneller'], - 'wie kontaktiere ich den support' => ['wie kontaktiere ich den support', 'support kontakt', 'hilfe kontakt', 'support team', 'support anfragen'], - 'welche plugins sind kompatibel' => ['welche plugins sind kompatibel', 'kompatibilität', 'plugin kompatibel', 'kompatible plugins', 'plugin kompatibilität'], - 'wie teste ich ein plugin' => ['wie teste ich ein plugin', 'plugin testen', 'test plugin', 'plugin ausprobieren', 'plugin prüfen'] - )); - - $normalized_question = wpmt_normalize_text($question); - $response = $responses['default']; - $matched_keywords = []; - - // Wenn ein spezifisches Stichwort ausgewählt wurde - if ($selected_keyword && isset($responses[$selected_keyword])) { - $response = $responses[$selected_keyword]; - } else { - // Suche nach allen passenden Stichwörtern - foreach ($keyword_synonyms as $key => $synonyms) { - if ($key === 'default') continue; - foreach ($synonyms as $synonym) { - if (strpos($normalized_question, wpmt_normalize_text($synonym)) !== false) { - $matched_keywords[] = $key; - break; - } - } - } - - // Falls kein Treffer, suche nach Tippfehlern - if (empty($matched_keywords)) { - $matched_keyword = wpmt_levenshtein_match($normalized_question, $keyword_synonyms); - if ($matched_keyword && isset($responses[$matched_keyword])) { - $matched_keywords[] = $matched_keyword; - } - } - - // Wenn genau ein Stichwort gefunden wurde - if (count($matched_keywords) === 1) { - $response = $responses[$matched_keywords[0]]; - if ($matched_keywords[0] === $matched_keyword) { - $response = sprintf( - __('Meintest du vielleicht „%s“, %s? Hier ist die Antwort: ', 'wp-multi-toolkit'), - esc_html(str_replace('-', ' ', $matched_keywords[0])), - esc_html($user_name) - ) . $response; - } - } - // Wenn mehrere Stichwörter gefunden wurden - elseif (count($matched_keywords) > 1) { - $response = sprintf( - __('Mehrere Themen passen zu deiner Frage, %s! 😊 Wähle eines aus: ', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $response .= '
'; - foreach ($matched_keywords as $key) { - $response .= sprintf( - '%s', - esc_attr($key), - esc_html(ucfirst(str_replace('-', ' ', $key))) - ); - } - $response .= '
'; - } - // Wenn kein Treffer, Vorschläge machen - else { - $suggestions = []; - $words = explode(' ', $normalized_question); - foreach ($words as $word) { - foreach ($keyword_synonyms as $key => $synonyms) { - foreach ($synonyms as $synonym) { - if (levenshtein($word, wpmt_normalize_text($synonym)) <= 4 && !in_array($key, $suggestions)) { - $suggestions[] = $key; - } - } - } - } - if (!empty($suggestions)) { - $response .= sprintf( - __('Keine direkte Antwort gefunden, %s. 🙁 Vielleicht passen diese Themen: %s.', 'wp-multi-toolkit'), - esc_html($user_name), - implode(', ', array_map(function($key) { return ucfirst(str_replace('-', ' ', $key)); }, $suggestions)) - ); - } - } - } - - // Antwort mit Bewertungsoptionen - $allowed_html = array( - 'a' => array('href' => true, 'class' => true, 'data-keyword' => true), - 'code' => array(), - 'strong' => array(), - 'div' => array('class' => true), - 'ul' => array(), - 'li' => array() - ); - $formatted_response = wp_kses($response, $allowed_html) . '
'; - $formatted_response .= '' . __('Hilfreich', 'wp-multi-toolkit') . ''; - $formatted_response .= '' . __('Nicht hilfreich', 'wp-multi-toolkit') . ''; - $formatted_response .= '
'; - - wp_send_json_success(array('response' => $formatted_response)); -} -add_action('wp_ajax_wpmt_assistant_query', 'wpmt_assistant_query'); - -/** - * AJAX-Handler für Feedback - */ -function wpmt_assistant_feedback() { - check_ajax_referer('wpmt_assistant_nonce', 'nonce'); - - $message = isset($_POST['message']) ? wp_kses_post($_POST['message']) : ''; - $rating = isset($_POST['rating']) ? sanitize_text_field($_POST['rating']) : ''; - - $feedback_log = get_option('wpmt_assistant_feedback', array()); - $feedback_log[] = array( - 'message' => $message, - 'rating' => $rating, - 'timestamp' => current_time('mysql') - ); - update_option('wpmt_assistant_feedback', $feedback_log); - - wp_send_json_success(); -} -add_action('wp_ajax_wpmt_assistant_feedback', 'wpmt_assistant_feedback'); - -/** - * Registriert die Assistenten-Seite im Admin-Menü - */ -function wpmt_add_assistant_page() { - add_submenu_page( - 'wp_multi_support', - __('Virtueller Assistent', 'wp-multi-toolkit'), - __('Virtueller Assistent', 'wp-multi-toolkit'), - 'manage_options', - 'wpmt_assistant', - 'wpmt_virtual_assistant_page' - ); -} -add_action('admin_menu', 'wpmt_add_assistant_page'); - - /** - * Antworten vordefinieren - */ - add_filter('wpmt_assistant_responses', function($responses) { - $current_user = wp_get_current_user(); - $user_name = $current_user->display_name ?: __('Freund', 'wp-multi-toolkit'); - - // WP Multi - $responses['statistik'] = sprintf( - __('Hey %s, willst du die Statistiken deiner Website im Blick haben? 📊 Füge den Shortcode [statistik_manager] in einen Beitrag oder eine Seite ein, um sie anzuzeigen. Oder gehe zu WP Stat & Notice, um Details wie Beitragsanzahl, Kommentare oder Kategorien zu sehen. Tipp: Aktiviere Benachrichtigungen für wichtige Updates! Bereit, deine Daten zu checken? 😎', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['telegram'] = sprintf( - __('Telegram-Benachrichtigungen einrichten, %s? Super einfach! 🔔 Gehe zu Notify > TG-Notify, erstelle einen Bot über BotFather und folge den Schritten, um ihn zu konfigurieren. Neue Beiträge oder Kommentare landen direkt in deinem Chat. Jetzt einrichten. Tipp: Teste den Bot mit einer Probemitteilung! Alles klar? 🚀', 'wp-multi-toolkit'), - esc_html($user_name), - admin_url('admin.php?page=tg-notify') - ); - $responses['discord'] = sprintf( - __('Discord-Benachrichtigungen für deine Community, %s? 😄 Gehe zu Notify > DC-Notify, erstelle einen Webhook in deinem Discord-Server und füge ihn in den Einstellungen ein. Neue Beiträge werden automatisch gepostet. Los geht’s! Tipp: Nutze einen separaten Kanal für Benachrichtigungen! Bereit? 🌟', 'wp-multi-toolkit'), - esc_html($user_name), - admin_url('admin.php?page=wp-multi') - ); - $responses['admin links'] = sprintf( - __('Eigene Admin-Links hinzufügen, %s? Perfekt für schnellen Zugriff! 🔧 Gehe zu Werkzeuge > Admin-Link hinzufügen, gib Namen und URL ein (z. B. für externe Tools) und speichere. Deine Links erscheinen im Admin-Menü. Tipp: Gruppiere Links für bessere Übersicht! Alles organisiert? 😊', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['gast-autor'] = sprintf( - __('Gastautoren auf deiner Seite, %s? 😊 Gehe zu Benutzer > Gastautor (Übersicht), füge Autoren hinzu und weise ihnen Beiträge zu. Ihre Namen erscheinen automatisch im Frontend. Tipp: Füge eine kurze Bio hinzu, um sie vorzustellen! Einfach, oder? ✨', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['beitrag report'] = sprintf( - __('Probleme mit Beiträgen, %s? 🧹 Unter Gemeldete Beiträge kannst du unangemessene Inhalte prüfen, bearbeiten oder löschen. So bleibt deine Seite sauber! Brauchst du Hilfe? Erstelle ein Support-Ticket. Alles unter Kontrolle? 🚀', 'wp-multi-toolkit'), - esc_html($user_name), - admin_url('admin.php?page=wp_multi_support') - ); - $responses['textbox'] = sprintf( - __('Eine Textbox am Beitragsende, %s? Ideal für Hinweise oder Werbung! ✨ Gehe zu WP Multi > Textbox, füge deinen Text ein und passe das Design an. Die Box erscheint automatisch unter Beiträgen. Tipp: Nutze auffällige Farben für mehr Aufmerksamkeit! Bereit? 😄', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['banner'] = sprintf( - __('Ein schickes Banner, %s? 🎨 Gehe zu WP Stat & Notice, lade ein Bild hoch und wähle Header oder Footer. Perfekt, um Neuigkeiten zu präsentieren! Tipp: Verwende Bilder mit hohem Kontrast für bessere Sichtbarkeit. Los geht’s! 🚀', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['inhaltsverzeichnis'] = sprintf( - __('Ein Inhaltsverzeichnis für deine Beiträge, %s? 🚀 Nutze den Shortcode [alphabetical_index], um alle Beiträge übersichtlich aufzulisten. Ideal für Blogs mit vielen Inhalten! Tipp: Kombiniere es mit Kategoriefiltern für mehr Struktur. Alles klar? 😎', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['lesezeichen'] = sprintf( - __('Lesezeichen für deine Besucher, %s? 😎 Mit [add_bookmark] können Nutzer Beiträge speichern, und [display_bookmarks] zeigt ihre Liste. Alles per Cookie – keine Datenbank nötig! Tipp: Füge die Shortcodes in eine Sidebar für schnellen Zugriff! Cool, oder? 🚀', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['custom shortcode'] = sprintf( - __('Eigene Shortcodes erstellen, %s? Super flexibel! 😉 Gehe zu WP Multi > Shortcodes, lege deinen Shortcode an und füge ihn im Editor ein. Ideal für wiederkehrende Inhalte! Tipp: Dokumentiere deine Shortcodes für spätere Änderungen. Bereit zum Codieren? 🚀', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['kommentar sperren'] = sprintf( - __('Bestimmte Nutzer blockieren, %s? 🛡️ Gehe zu Benutzer sperren, gib Benutzername, IP oder E-Mail ein und speichere. So bleibt die Kommentarspalte sauber! Tipp: Überprüfe die Sperrliste regelmäßig, um sie aktuell zu halten. Alles sicher? 😊', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['filter'] = sprintf( - __('Kommentare filtern, %s? 😊 Gehe zu Kommentare > Kommentar Filter und verbiete URLs, Schimpfwörter oder Telefonnummern. Verstöße werden mit * ersetzt. Tipp: Teste die Filter mit einem Probekommentar, um sicherzugehen! Deine Community wird’s lieben! 🌟', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['analytics'] = sprintf( - __('Datenanalyse für deine Beiträge, %s? 📊 Unter Benutzer > Benutzer Analytics siehst du Views, Kommentare, Top-Beiträge und mehr. Perfekt, um Inhalte zu optimieren! Tipp: Exportiere die Daten für langfristige Analysen. Bereit, ein Profi zu werden? 😎', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['pinwand'] = sprintf( - __('Nachrichten für dein Team, %s? 📌 Unter Pinnwand kannst du Notizen für Admins oder Redakteure hinterlegen. Erstelle, bearbeite oder lösche sie jederzeit. Tipp: Nutze die Pinnwand für wichtige To-Dos! Alles organisiert? 😄', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['brute force'] = sprintf( - __('Sicherheit zuerst, %s! 🛡️ Der Brute-Force-Schutz protokolliert Fehlversuche und sperrt nach 5 Versuchen. Einstellungen findest du unter Sicherheit. Tipp: Aktiviere Benachrichtigungen, um verdächtige Aktivitäten zu überwachen! Alles sicher? 🚀', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['anti spam'] = sprintf( - __('Spam loswerden, %s? 😒 Aktiviere den Anti-Spam-Schutz unter Sicherheit, um Bots zu blockieren. Spam-Kommentare werden automatisch gefiltert. Tipp: Kombiniere es mit Kommentarfiltern für doppelten Schutz! Bereit? 😊', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['auto tag'] = sprintf( - __('Automatische Tags, %s? ⏳ Gehe zu Beiträge > Automatische Tags, füge fehlende Tags hinzu oder verbiete Wörter. Spart Zeit! Tipp: Überprüfe die Tags regelmäßig, um sie an deine Inhalte anzupassen. Alles klar? 🚀', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['login deaktivieren'] = sprintf( - __('Logins deaktivieren, %s? 🔒 Gehe zu Benutzer > Alle Benutzer, wähle einen Benutzer und schalte den Login ab. Ideal für temporäre Sperren. Tipp: Notiere dir, wen du deaktiviert hast! Alles unter Kontrolle? 😎', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['text copy'] = sprintf( - __('Inhalte schützen, %s? 🛡️ Aktiviere die Rechtsklick-Sperre unter WP Multi-Einstellungen, um Texte vor Kopieren zu sichern. Perfekt für Blogs! Tipp: Füge einen Hinweis hinzu, warum Kopieren deaktiviert ist. Bereit? 😊', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['trash mail'] = sprintf( - __('Kein Bock auf Spam-Mails, %s? 😊 Wir blockieren Trash-Mails in Kommentaren automatisch. Die Liste wird vom Entwickler gepflegt – du musst nichts tun! Tipp: Aktiviere Anti-Spam für extra Schutz! Alles sauber? 🌟', 'wp-multi-toolkit'), - esc_html($user_name) - ); - - // WP Multi Comment Notifications - $responses['kommentar benachrichtigung'] = sprintf( - __('Immer über neue Kommentare informiert, %s? 🔔 Gehe zu Kommentare > Kommentar Benachrichtigung und richte E-Mail, Telegram oder Discord ein. Tipp: Filtere Benachrichtigungen, um nur wichtige zu erhalten! Nie wieder etwas verpassen! 😄', 'wp-multi-toolkit'), - esc_html($user_name) - ); - - // WP Multi Kategorie - $responses['kategorien ausblenden'] = sprintf( - __('Kategorien ausblenden, %s? 🗂️ Gehe zu Beiträge > Kategorie Filter und wähle, was im Frontend nicht angezeigt werden soll. Ideal für eine saubere Seite! Tipp: Teste Änderungen in der Vorschau! Alles organisiert? 🚀', 'wp-multi-toolkit'), - esc_html($user_name) - ); - - // WP Multi Search - $responses['suchfunktion'] = sprintf( - __('Eine starke Suche, %s? 🔍 Füge WP Multi Search über Shortcode, Widget oder Menü hinzu. Einstellungen findest du unter Einstellung > WP-Multi Search. Tipp: Aktiviere Autovervollständigung für bessere Ergebnisse! Bereit, alles zu finden? 😎', 'wp-multi-toolkit'), - esc_html($user_name) - ); - - // WP Multi Team-Card - $responses['teamcard'] = sprintf( - __('Dein Team präsentieren, %s? 🌟 Mit WP Multi Team-Card erstellst du professionelle Teamkarten mit Namen, Funktionen und Bildern. Nutze [teamcards] im Frontend. Jetzt ausprobieren und dein Team ins Rampenlicht stellen! 🚀', 'wp-multi-toolkit'), - esc_html($user_name), - admin_url('admin.php?page=teamcard_management') - ); - $responses['teammitglied hinzufügen'] = sprintf( - __('Ein neues Teammitglied, %s? 😄 Gehe zu Team-Cards, gib Name, Funktion, Zuständigkeit und Bild ein und klicke auf Hinzufügen. Tipp: Wähle hochauflösende Bilder für beste Darstellung! Bereit fürs Update? ✨', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['teamcard shortcode'] = sprintf( - __('Teamkarten anzeigen, %s? 🚀 Nutze [teamcards] für alle Mitglieder oder [teamcards kategorie="slug"] für eine Kategorie. Füge den Shortcode in Beiträge ein. Tipp: Teste verschiedene Layouts! Alles klar? 😊', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['teamcard kategorie'] = sprintf( - __('Kategorien für Teamkarten, %s? 🗂️ Erstelle sie unter Beiträge > Kategorien und weise sie Mitgliedern zu. Zeige sie mit [teamcards kategorie="slug"]. Tipp: Sortiere Teams nach Abteilungen! Alles organisiert? 😎', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['teamcard bild'] = sprintf( - __('Ein Bild für ein Teammitglied, %s? 😊 In Team-Cards klickst du auf Bild auswählen und lädst ein Foto hoch. Es erscheint in der Teamkarte. Tipp: Nutze quadratische Bilder für einheitliches Design! Bereit? 🚀', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['teamcard löschen'] = sprintf( - __('Ein Teammitglied entfernen, %s? 🗑️ Gehe zu Team-Cards, finde das Mitglied und klicke auf Löschen. Tipp: Sichere Daten vor dem Löschen! Schnell erledigt? 😄', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['teamcard reihenfolge'] = sprintf( - __('Reihenfolge der Teamkarten ändern, %s? 😎 In Team-Cards verschiebst du Mitglieder per Drag-and-Drop. Tipp: Speichere nach dem Sortieren, um Änderungen zu sichern! Alles sortiert? 🚀', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['teamcard deinstallation'] = sprintf( - __('Team-Card deinstallieren, %s? ⚠️ Achtung: Alle Teammitglieder und Bilder werden gelöscht. Sichere Daten mit einem Backup! Mehr Infos: Mehr Infos. Alles klar? 😊', 'wp-multi-toolkit'), - esc_html($user_name), - 'https://git.viper.ipv64.net/M_Viper/wp-multi-teamcard' - ); - $responses['teamcard updates'] = sprintf( - __('Updates für Team-Card, %s? 🚀 Schau auf git.viper.ipv64.net für die neueste Version. Updates werden auch im Admin-Bereich angezeigt. Tipp: Lies die Changelogs für neue Features! Bleib up to date! 😎', 'wp-multi-toolkit'), - esc_html($user_name), - 'https://git.viper.ipv64.net/M_Viper/wp-multi-teamcard' - ); - - // WP Multi Toolkit - $responses['update management'] = sprintf( - __('Updates im Griff, %s? 🌟 Im Dashboard-Widget Verfügbare Updates für WP Multi Toolkit siehst du den Status aller Plugins. Lade neue Versionen herunter und installiere sie. Jetzt prüfen. Tipp: Sichere deine Seite vor Updates! Bereit? 🚀', 'wp-multi-toolkit'), - esc_html($user_name), - admin_url('index.php') - ); - $responses['support issues'] = sprintf( - __('Hilfe nötig, %s? 😊 Erstelle ein Support-Ticket unter WP-Multi Support. Beschreibe dein Problem genau, und wir melden uns schnell! Ticket erstellen. Tipp: Screenshots helfen uns, schneller zu reagieren! Bereit? 🌟', 'wp-multi-toolkit'), - esc_html($user_name), - admin_url('admin.php?page=wp_multi_support') - ); - $responses['dokumentation'] = sprintf( - __('Alles über WP Multi erfahren, %s? 📚 Die Dokumentation findest du unter WP-Multi Support > Dokumentation. Dort gibt’s Anleitungen und FAQs. Dokumentation ansehen. Tipp: Nutze die Suche in der Doku! Bereit? 😄', 'wp-multi-toolkit'), - esc_html($user_name), - admin_url('admin.php?page=wpmt_docs') - ); - $responses['virtueller assistent'] = sprintf( - __('Das bin ich, %s! 😄 Dein virtueller Assistent für alle WP Multi Fragen. Stelle mir deine Fragen unter WP-Multi Support > Virtueller Assistent. Tipp: Frag nach spezifischen Features, ich kenne sie alle! Wie kann ich dir helfen? 🚀', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['toolbar'] = sprintf( - __('Die Schnellstart-Toolbar, %s? 🚀 Unten rechts findest du Support, Updates, Dokumentation und mich – alles in einem Klick! Tipp: Halte die Toolbar aktiviert für schnellen Zugriff! Praktisch, oder? 😊', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['wp multi plugins'] = sprintf( - __('Neugierig auf WP Multi Plugins, %s? 🌟 Hier die Übersicht:Mehr in der Dokumentation! 😎', 'wp-multi-toolkit'), - esc_html($user_name), - admin_url('admin.php?page=wpmt_docs') - ); - - // Allgemeine Fragen und Antworten - $responses['was sind wp multi plugins'] = sprintf( - __('WP Multi Plugins, %s? 🚀 Eine Sammlung cooler Tools für deine Website! Von Statistiken über Sicherheit bis Benachrichtigungen – alles dabei. Schau unter wp multi plugins oder auf git.viper.ipv64.net. Bereit, deine Seite zu boosten? 😄', 'wp-multi-toolkit'), - esc_html($user_name), - 'https://git.viper.ipv64.net/M_Viper' - ); - $responses['wie installiere ich ein plugin'] = sprintf( - __('Ein Plugin installieren, %s? 😊 Gehe zu Plugins > Neu hinzufügen, lade die Datei von git.viper.ipv64.net hoch und aktiviere es. Oder per FTP in /wp-content/plugins/. Tipp: Lies die Doku für Details! Los geht’s! 🚀', 'wp-multi-toolkit'), - esc_html($user_name), - 'https://git.viper.ipv64.net/M_Viper' - ); - $responses['wo finde ich updates'] = sprintf( - __('Updates, %s? 🌟 Im Dashboard-Widget Verfügbare Updates für WP Multi Toolkit oder auf git.viper.ipv64.net. Lade die neue Version hoch! Tipp: Sichere deine Seite vor Updates! Bleib frisch! 😎', 'wp-multi-toolkit'), - esc_html($user_name), - 'https://git.viper.ipv64.net/M_Viper' - ); - $responses['wie erstelle ich ein support ticket'] = sprintf( - __('Ein Support-Ticket, %s? 😊 Gehe zu WP-Multi Support, wähle das Plugin, gib Titel und Beschreibung ein und sende es ab. Jetzt erstellen. Tipp: Füge Screenshots hinzu! Wir helfen schnell! 🚀', 'wp-multi-toolkit'), - esc_html($user_name), - admin_url('admin.php?page=wp_multi_support') - ); - $responses['welche voraussetzungen gibt es'] = sprintf( - __('Voraussetzungen, %s? 📋 Mindestens WordPress 6.7.2 und PHP 7.4. Für Telegram/Discord brauchst du API-Keys. Details in der Dokumentation. Tipp: Prüfe deine Server-Einstellungen! Bereit? 😄', 'wp-multi-toolkit'), - esc_html($user_name), - admin_url('admin.php?page=wpmt_docs') - ); - $responses['sind die plugins kostenlos'] = sprintf( - __('Kostenlos, %s? 😄 Ja, alle WP Multi Plugins sind gratis auf git.viper.ipv64.net! Tipp: Spende dem Entwickler einen Kaffee, wenn sie dir gefallen! Bereit? 🚀', 'wp-multi-toolkit'), - esc_html($user_name), - 'https://git.viper.ipv64.net/M_Viper' - ); - $responses['wie deaktiviere ich ein plugin'] = sprintf( - __('Plugin deaktivieren, %s? 😎 Gehe zu Plugins > Installierte Plugins, klicke auf Deaktivieren oder Löschen. Tipp: Deaktiviere vor Updates, um Konflikte zu vermeiden! Alles klar? 🌟', 'wp-multi-toolkit'), - esc_html($user_name) - ); - $responses['wo finde ich die dokumentation'] = sprintf( - __('Dokumentation, %s? 📚 Unter WP-Multi Support > Dokumentation findest du Anleitungen und FAQs. Jetzt ansehen. Tipp: Nutze die Suche in der Doku! Bereit? 😊', 'wp-multi-toolkit'), - esc_html($user_name), - admin_url('admin.php?page=wpmt_docs') - ); - $responses['wer entwickelt die plugins'] = sprintf( - __('Wer entwickelt sie, %s? 😊 M_Viper, ein WordPress-Fan! Besuche m-viper.de oder git.viper.ipv64.net. Tipp: Folge M_Viper für News! Cool, oder? 🚀', 'wp-multi-toolkit'), - esc_html($user_name), - 'https://m-viper.de', - 'https://git.viper.ipv64.net/M_Viper' - ); - $responses['kann ich eigene funktionen hinzufügen'] = sprintf( - __('Eigene Funktionen, %s? 🌟 Die Plugins sind Open Source! Schau den Code auf git.viper.ipv64.net an. Ideen? Erstelle ein Ticket mit Verbesserung! Tipp: Teste in einer Staging-Umgebung! Bereit? 😎', 'wp-multi-toolkit'), - esc_html($user_name), - 'https://git.viper.ipv64.net/M_Viper' - ); - - // Neue allgemeine Antworten - $responses['wie richte ich wp multi ein'] = sprintf( - __('WP Multi einrichten, %s? 🚀 Nach der Installation gehe zu WP-Multi Support und aktiviere die Plugins. Folge der Anleitung in der Dokumentation. Tipp: Prüfe, ob deine WordPress-Version aktuell ist! Bereit? 😄', 'wp-multi-toolkit'), - esc_html($user_name), - admin_url('admin.php?page=wpmt_docs') - ); - $responses['was ist wordpress'] = sprintf( - __('WordPress, %s? 📝 Ein kostenloses CMS für Websites, Blogs oder Shops – ohne Programmierkenntnisse! WP Multi Plugins machen es noch besser. Mehr in der Dokumentation. Neugierig? 😊', 'wp-multi-toolkit'), - esc_html($user_name), - admin_url('admin.php?page=wpmt_docs') - ); - $responses['wie sichere ich meine website'] = sprintf( - __('Website sichern, %s? 🛡️ Nutze WP Multi Features wie Brute-Force-Schutz und Anti-Spam unter Sicherheit. Erstelle Backups (z. B. mit UpdraftPlus) und aktiviere die Rechtsklick-Sperre. Mehr in der Dokumentation. Alles sicher? 🚀', 'wp-multi-toolkit'), - esc_html($user_name), - admin_url('admin.php?page=wpmt_docs') - ); - $responses['wie verbessere ich die performance'] = sprintf( - __('Performance boosten, %s? ⚡ Nutze WP Multi Search für schnelle Suchen und Caching-Plugins wie WP Super Cache. Optimiere Bilder und prüfe Ladezeiten unter Benutzer > Benutzer Analytics. Mehr in der Dokumentation. Bereit für Speed? 😎', 'wp-multi-toolkit'), - esc_html($user_name), - admin_url('admin.php?page=wpmt_docs') - ); - $responses['wie kontaktiere ich den support'] = sprintf( - __('Support kontaktieren, %s? 😊 Erstelle ein Ticket unter WP-Multi Support (Ticket erstellen) oder besuche m-viper.de. Tipp: Beschreibe dein Problem genau! Bereit? 🌟', 'wp-multi-toolkit'), - esc_html($user_name), - admin_url('admin.php?page=wp_multi_support'), - 'https://m-viper.de' - ); - $responses['welche plugins sind kompatibel'] = sprintf( - __('Kompatible Plugins, %s? 🌟 WP Multi Plugins passen zu den meisten WordPress-Plugins, wenn sie die Standards einhalten. Teste in einer Staging-Umgebung. Probleme? Schau in die Dokumentation oder erstelle ein Support-Ticket! Alles klar? 😄', 'wp-multi-toolkit'), - esc_html($user_name), - admin_url('admin.php?page=wpmt_docs'), - admin_url('admin.php?page=wp_multi_support') - ); - $responses['wie teste ich ein plugin'] = sprintf( - __('Plugin testen, %s? 😊 Installiere es in einer Staging-Umgebung oder lokal. Aktiviere es, teste Funktionen und prüfe Kompatibilität. Probleme? Schau in die Dokumentation oder kontaktiere den Support. Tipp: Deaktiviere andere Plugins, um Konflikte zu finden! Bereit? 🚀', 'wp-multi-toolkit'), - esc_html($user_name), - admin_url('admin.php?page=wpmt_docs'), - admin_url('admin.php?page=wp_multi_support') - ); - - return $responses; - }); - - /** - * Sicherstellen, dass jQuery geladen wird - */ - function wpmt_enqueue_scripts() { - wp_enqueue_script('jquery'); - } - add_action('admin_enqueue_scripts', 'wpmt_enqueue_scripts'); - - -/* - * Schnellzugriff-Menü (Floating Toolbar) - */ - - - function wpmt_add_floating_toolbar() { - if (!current_user_can('manage_options') || !is_admin()) { - return; - } - ?> -
- - -
- - 'wpmt_sanitize_settings' - )); - add_settings_section('wpmt_main_section', __('WP Multi Einstellungen', 'wp-multi-toolkit'), null, 'wpmt_settings'); - add_settings_field('wpmt_enable_multi', __('Multi-Funktion aktivieren', 'wp-multi-toolkit'), 'wpmt_enable_multi_callback', 'wpmt_settings', 'wpmt_main_section'); -} -add_action('admin_init', 'wpmt_register_settings'); - -function wpmt_sanitize_settings($input) { - $new_input = array(); - $new_input['enable_multi'] = isset($input['enable_multi']) ? 1 : 0; - return $new_input; -} - -function wpmt_enable_multi_callback() { - $options = get_option('wpmt_multi_settings', array('enable_multi' => 0)); - echo ''; -} - -function wpmt_settings_page() { - ?> -
-

-
- -
-
- 0)); - if ($options['enable_multi']) { - return '

' . __('Multi-Funktion ist aktiviert!', 'wp-multi-toolkit') . '

'; - } - return '

' . __('Multi-Funktion ist deaktiviert.', 'wp-multi-toolkit') . '

'; -} -add_shortcode('wpmt_multi', 'wpmt_multi_shortcode'); - -// ### Automatisierte Plugin-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'; - - $installed_plugins = get_plugins(); - $wp_multi_plugins = array( - 'wp-multi-toolkit' => array( - 'file' => 'wp-multi-toolkit/wp-multi-toolkit.php', - 'name' => 'WP Multi Toolkit', - 'description' => __('Zentrales Toolkit für die WP Multi Plugin-Reihe mit Update-Management und Support-Funktionen.', 'wp-multi-toolkit'), - 'repo' => 'wp-multi-toolkit' - ), - 'wp-multi' => array( - 'file' => 'WP-Multi/wp-multi.php', - 'name' => 'WP Multi', - 'description' => __('Hauptplugin für Multi-Funktionen mit Shortcode-Unterstützung.', 'wp-multi-toolkit'), - 'repo' => 'wp-multi' - ), - 'wp-multi-search' => array( - 'file' => 'wp-multi-search/wp-multi-search.php', - 'name' => 'WP Multi Search', - 'description' => __('Erweiterte Suchfunktionen für WordPress.', 'wp-multi-toolkit'), - 'repo' => 'WP-Multi-Search' - ), - 'wp-multi-comment-notifications' => array( - 'file' => 'wp-multi-comment-notifications/wp-multi-comment-notifications.php', - 'name' => 'WP Multi Comment Notifications', - 'description' => __('Automatische Benachrichtigungen für neue Kommentare.', 'wp-multi-toolkit'), - 'repo' => 'wp-multi-comment-notifications' - ), - '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', - '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' - ) - ); - - ?> -
-

-

- - $plugin) : ?> -
-

- '); - ?> -

:

-

: - - - - -

-

:

-

:

- -

:

- - -

:

- - -

:

-

:

-

:

- -
- -
- - - $widget) + $wp_meta_boxes['dashboard']['normal']['high']; - } -} -add_action('wp_dashboard_setup', 'wpmt_update_dashboard_widget', 1); -add_action('wp_dashboard_setup', 'wpmt_force_widget_position', 999); - -// Widget nicht ausblendbar machen -function wpmt_prevent_widget_hiding($widgets) { - $widgets['wpmt_update_widget'] = array( - 'id' => 'wpmt_update_widget', - 'title' => __('Verfügbare Updates für WP Multi Toolkit', 'wp-multi-toolkit'), - 'callback' => 'wpmt_update_dashboard_widget_content' - ); - return $widgets; -} -add_filter('dashboard_available_widgets', 'wpmt_prevent_widget_hiding'); - -// Benutzerdefiniertes Cron-Intervall hinzufügen -add_filter('cron_schedules', function ($schedules) { - $schedules['hourly'] = array( - 'interval' => 3600, - 'display' => __('Stündlich', 'wp-multi-toolkit'), - ); - return $schedules; -}); - -// Cron-Job registrieren -function wpmt_update_schedule_check() { - if (!wp_next_scheduled('wpmt_update_check_event')) { - wp_schedule_event(time(), 'hourly', 'wpmt_update_check_event'); - } -} -add_action('wp', 'wpmt_update_schedule_check'); - -// Hilfsfunktion zur Wiederverwendung der Gitea-API-Abfrage -function wpmt_fetch_latest_release($repo, $show_prereleases = false) { - $api_url = "https://git.viper.ipv64.net/api/v1/repos/M_Viper/{$repo}/releases"; - $response = wp_remote_get($api_url, array('timeout' => 10)); - - if (is_wp_error($response)) { - error_log("WP Multi Toolkit Update Fehler für {$repo}: " . $response->get_error_message()); - return false; - } - - $body = wp_remote_retrieve_body($response); - $data = json_decode($body, true); - - if (!is_array($data)) { - error_log("WP Multi Toolkit Update für {$repo}: Ungültige API-Antwort"); - return false; - } - - foreach ($data as $release) { - if (!$show_prereleases && isset($release['prerelease']) && $release['prerelease']) { - continue; - } - if (!empty($release['tag_name'])) { - return $release; - } - } - return null; -} - -// Cron-Job für Update-Überprüfung -function wpmt_update_check() { - require_once ABSPATH . 'wp-admin/includes/plugin.php'; - - $show_prereleases = get_option('wpmt_update_show_prereleases', false); - $installed_plugins = get_plugins(); - $plugins_to_check = array( - 'wp-multi-toolkit' => 'wp-multi-toolkit/wp-multi-toolkit.php', - 'wp-multi' => 'WP-Multi/wp-multi.php', - 'WP-Multi-Search' => 'wp-multi-search/wp-multi-search.php', - 'wp-multi-comment-notifications' => 'wp-multi-comment-notifications/wp-multi-comment-notifications.php' - ); - - foreach ($plugins_to_check as $repo => $file) { - if (array_key_exists($file, $installed_plugins) && is_plugin_active($file)) { - $plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $file); - $installed_version = $plugin_data['Version']; - $valid_release = wpmt_fetch_latest_release($repo, $show_prereleases); - - if ($valid_release) { - $latest_version = $valid_release['tag_name']; - $release_notes = $valid_release['body'] ?? ''; - $is_prerelease = isset($release['prerelease']) && $release['prerelease']; - - update_option("wpmt_update_latest_version_{$repo}", $latest_version); - update_option("wpmt_update_release_notes_{$repo}", $release_notes); - update_option("wpmt_update_is_prerelease_{$repo}", $is_prerelease); - } - } - } -} -add_action('wpmt_update_check_event', 'wpmt_update_check'); - -// Funktion zur Überprüfung des Update-Server-Status -function wpmt_check_update_server_status() { - $update_server_url = 'https://git.viper.ipv64.net'; - $response = wp_remote_head($update_server_url, array('timeout' => 5)); - return !is_wp_error($response) && wp_remote_retrieve_response_code($response) == 200; -} - -// Callback-Funktion für das Widget -function wpmt_update_dashboard_widget_content() { - require_once ABSPATH . 'wp-admin/includes/plugin.php'; - - $installed_plugins = get_plugins(); - $show_prereleases = get_option('wpmt_update_show_prereleases', false); - - // Update-Server-Status nur bei Offline anzeigen - $server_online = wpmt_check_update_server_status(); - if (!$server_online) { - echo '

🔴 ' . __('Update Server offline', 'wp-multi-toolkit') . '

'; - echo '
'; - } - - $plugins_to_check = array( - 'wp-multi-toolkit' => array( - 'file' => 'wp-multi-toolkit/wp-multi-toolkit.php', - 'name' => 'WP Multi Toolkit', - 'repo' => 'wp-multi-toolkit' - ), - 'wp-multi' => array( - 'file' => 'WP-Multi/wp-multi.php', - 'name' => 'WP Multi', - 'repo' => 'wp-multi' - ), - 'WP-Multi-Search' => array( - 'file' => 'wp-multi-search/wp-multi-search.php', - 'name' => 'WP Multi Search', - 'repo' => 'WP-Multi-Search' - ), - 'wp-multi-comment-notifications' => array( - 'file' => 'wp-multi-comment-notifications/wp-multi-comment-notifications.php', - 'name' => 'WP Multi Comment Notifications', - 'repo' => 'wp-multi-comment-notifications' - ), - 'wp-multi-kategorie' => array( - 'file' => 'wp-multi-kategorie/wp-multi-kategorie.php', - 'name' => 'WP Multi Kategorie', - 'repo' => 'wp-multi-kategorie' - ), - 'wp-multi-teamcard' => array( - 'file' => 'wp-multi-teamcards/wp-multi-team-card.php', - 'name' => 'WP Multi Team-Card', - 'repo' => 'wp-multi-teamcard' - ) - ); - - $has_active_plugins = false; - foreach ($plugins_to_check as $key => $plugin) { - $is_installed = array_key_exists($plugin['file'], $installed_plugins); - $is_active = $is_installed && is_plugin_active($plugin['file']); - - if ($is_installed && $is_active) { - $has_active_plugins = true; - $plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin['file']); - $installed_version = $plugin_data['Version']; - $valid_release = wpmt_fetch_latest_release($plugin['repo'], $show_prereleases); - - echo '

' . esc_html($plugin['name']) . '

'; - if ($valid_release === false) { - printf('

%s

', esc_html__('Fehler beim Abrufen der Versionsinformationen.', 'wp-multi-toolkit')); - } elseif ($valid_release) { - $latest_version = $valid_release['tag_name']; - $release_notes = $valid_release['body'] ?? ''; - $is_prerelease = isset($valid_release['prerelease']) && $valid_release['prerelease']; - - if (version_compare($installed_version, $latest_version, '>=')) { - printf( - '

%s

', - sprintf( - __('Ihre Version ist aktuell. Version %s ist die neueste Version.', 'wp-multi-toolkit'), - esc_html($installed_version) - ) - ); - } else { - printf( - '

%s

', - sprintf( - __('Es ist eine neue Version von %s verfügbar! Version %s ist jetzt verfügbar.', 'wp-multi-toolkit'), - esc_html($plugin['name']), - esc_html($latest_version) - ) - ); - printf( - '

%s: %s

', - __('Aktuell installierte Version', 'wp-multi-toolkit'), - esc_html($installed_version) - ); - printf( - '

%s: %s

', - __('Neue Version auf Gitea', 'wp-multi-toolkit'), - esc_html($latest_version) - ); - - if ($is_prerelease && $show_prereleases) { - printf('

%s

', __('Dieses Update ist ein PreRelease.', 'wp-multi-toolkit')); - } - - if (!empty($release_notes)) { - printf( - '

%s:

%s

', - __('Information zum Update', 'wp-multi-toolkit'), - nl2br(esc_html($release_notes)) - ); - } - - $button_text = $is_prerelease ? __('PreRelease herunterladen', 'wp-multi-toolkit') : __('Update herunterladen', 'wp-multi-toolkit'); - $download_url = $valid_release['assets'][0]['browser_download_url'] ?? '#'; - printf( - '

%s

', - esc_url($download_url), - esc_html($button_text) - ); - } - } else { - printf('

%s

', esc_html__('Keine Versionsinformationen gefunden.', 'wp-multi-toolkit')); - } - } - } - - if (!$has_active_plugins) { - echo '

' . __('Keine aktiven WP Multi Plugins gefunden.', 'wp-multi-toolkit') . '

'; - } - - // Optionale Plugins - $optional_plugins = array( - 'wp-multi-toolkit' => array( - 'file' => 'wp-multi-toolkit/wp-multi-toolkit.php', - 'download_url' => 'https://git.viper.ipv64.net/M_Viper/wp-multi-toolkit/releases', - 'description' => __('Kern-Toolkit für WP Multi Plugins.', 'wp-multi-toolkit') - ), - 'wp-multi' => array( - 'file' => 'WP-Multi/wp-multi.php', - 'download_url' => 'https://git.viper.ipv64.net/M_Viper/wp-multi/releases', - 'description' => __('Hauptplugin für WP Multi Funktionen.', 'wp-multi-toolkit') - ), - 'WP-Multi-Search' => array( - 'file' => 'wp-multi-search/wp-multi-search.php', - 'download_url' => 'https://git.viper.ipv64.net/M_Viper/WP-Multi-Search/releases', - 'description' => __('Erweiterte Suchfunktionen.', 'wp-multi-toolkit') - ), - 'wp-multi-comment-notifications' => array( - 'file' => 'wp-multi-comment-notifications/wp-multi-comment-notifications.php', - 'download_url' => 'https://git.viper.ipv64.net/M_Viper/wp-multi-comment-notifications/releases', - 'description' => __('Kommentar-Benachrichtigungen.', 'wp-multi-toolkit') - ), - 'wp-multi-kategorie' => array( - 'file' => 'wp-multi-kategorie/wp-multi-kategorie.php', - 'download_url' => 'https://git.viper.ipv64.net/M_Viper/wp-multi-kategorie/releases', - 'description' => __('Erweiterte Kategorie-Funktionen für WP Multi.', 'wp-multi-toolkit') - ) - ); - - echo '

' . __('Optionale Plugins', 'wp-multi-toolkit') . '

'; - echo ''; - echo ''; - - foreach ($optional_plugins as $key => $plugin) { - $is_installed = array_key_exists($plugin['file'], $installed_plugins); - $is_active = $is_installed && is_plugin_active($plugin['file']); - - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - } - echo '
' . __('Plugin', 'wp-multi-toolkit') . '' . __('Beschreibung', 'wp-multi-toolkit') . '' . __('Status', 'wp-multi-toolkit') . '' . __('Aktion', 'wp-multi-toolkit') . '
' . esc_html($plugins_to_check[$key]['name']) . '' . esc_html($plugin['description']) . ''; - if ($is_active) { - echo '' . __('Aktiv', 'wp-multi-toolkit') . ''; - } elseif ($is_installed) { - echo '' . __('Inaktiv', 'wp-multi-toolkit') . ''; - } else { - echo '' . __('Nicht installiert', 'wp-multi-toolkit') . ''; - } - echo ''; - if ($is_active) { - echo '—'; - } elseif ($is_installed) { - echo '' . __('Aktivieren', 'wp-multi-toolkit') . ''; - } else { - echo '' . __('Herunterladen', 'wp-multi-toolkit') . ''; - } - echo '
'; -} - -// Update-Einstellungen -function wpmt_update_general_settings() { - add_settings_section( - 'wpmt_update_section', - __('WP Multi Toolkit Update Einstellungen', 'wp-multi-toolkit'), - null, - 'general' - ); - - add_settings_field( - 'wpmt_update_show_prereleases', - __('Pre-Releases anzeigen', 'wp-multi-toolkit'), - 'wpmt_update_show_prereleases_callback', - 'general', - 'wpmt_update_section' - ); - - register_setting('general', 'wpmt_update_show_prereleases', array( - 'type' => 'boolean', - 'description' => __('Aktivieren, um Pre-Releases im Dashboard und in den Versionsinformationen anzuzeigen.', 'wp-multi-toolkit'), - 'default' => 0, - )); -} -add_action('admin_init', 'wpmt_update_general_settings'); - -// Callback-Funktion für das Anzeigen der Checkbox -function wpmt_update_show_prereleases_callback() { - $checked = get_option('wpmt_update_show_prereleases', false); - echo ''; - echo '

' . __('Achtung: Pre-Releases sind Beta-Versionen und können Fehler enthalten. Verwenden Sie sie nur, wenn Sie Fehlerberichterstattung oder Tests durchführen möchten.', 'wp-multi-toolkit') . '

'; -} - -// Deinstallation -function wpmt_uninstall() { - $repos = array('wp-multi-toolkit', 'wp-multi', 'WP-Multi-Search', 'wp-multi-comment-notifications'); - foreach ($repos as $repo) { - delete_option("wpmt_update_latest_version_{$repo}"); - delete_option("wpmt_update_release_notes_{$repo}"); - delete_option("wpmt_update_is_prerelease_{$repo}"); - } - delete_option('wpmt_update_show_prereleases'); - delete_option('wpmt_multi_settings'); - wp_clear_scheduled_hook('wpmt_update_check_event'); -} -register_uninstall_hook(__FILE__, 'wpmt_uninstall'); - - -/* - * Ban Funktion - */ - - -// Add Admin Menu -add_action('admin_menu', 'wp_multi_toolkit_setup_menu'); -function wp_multi_toolkit_setup_menu() { - if (!current_user_can('manage_options')) { - return; - } - add_submenu_page( - 'users.php', - 'WP Multi Ban', - 'WP Multi Ban', - 'manage_options', - 'wp-multi-ban', - 'wp_multi_ban_options_page' - ); -} - -// WP Multi Ban Functions - -### Function: Get IP Address -function wp_multi_ban_get_ip() { - $banned_options = get_option('wp_multi_ban_options', array('reverse_proxy' => 0)); - $ip = ''; - - 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 $potential_ip) { - $potential_ip = trim($potential_ip); - if (filter_var($potential_ip, FILTER_VALIDATE_IP)) { - return $potential_ip; - } - } - } - } - } elseif (!empty($_SERVER['REMOTE_ADDR']) && filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP)) { - $ip = explode(',', $_SERVER['REMOTE_ADDR'])[0]; - return $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); - } - } + +
+
+ +
+

+ +

+ +
+
+
+ +
+ +
+ '; + if ($title) { + echo '

' . esc_html($title) . '

'; + } + } +} + +if (!function_exists('wpmt_admin_card_close')) { + function wpmt_admin_card_close() { + echo ''; + } +} + +if (!function_exists('wpmt_admin_notice')) { + /** + * Einheitliche Inline-Notice. $type: success|warning|error|info. + * $message darf einfache Auszeichnung enthalten (wird per wp_kses gefiltert). + */ + function wpmt_admin_notice($type, $message) { + $allowed = array('success', 'warning', 'error', 'info'); + $type = in_array($type, $allowed, true) ? $type : 'info'; + echo '
' + . wp_kses($message, array('strong' => array(), 'em' => array(), 'code' => array(), 'a' => array('href' => true))) + . '
'; + } +} + +if (!function_exists('wpmt_admin_stat_card')) { + function wpmt_admin_stat_card($label, $value, $dashicon = '') { + echo '
'; + if ($dashicon) { + echo ''; + } + echo '
' . esc_html($value) . '
'; + echo '
' . esc_html($label) . '
'; + echo '
'; + } +} + + +/* + * Zentrales Admin-Menü "WP Multi" + * + * Das Toolkit registriert das gemeinsame Top-Level-Menü (Priorität 9), + * wp-multi.php hängt seine Submenüs mit Priorität 20 an. + */ + +function wpmt_register_admin_menus() { + $hook = add_menu_page( + __('WP Multi', 'wp-multi-toolkit'), + __('WP Multi', 'wp-multi-toolkit'), + 'manage_options', + WPMT_MENU_SLUG, + 'wpmt_render_overview_page', + 'dashicons-screenoptions', + 59 + ); + wpmt_register_admin_hook($hook); + + // Erster Submenu-Eintrag mit identischem Slug, damit das Top-Level nicht doppelt erscheint + wpmt_register_admin_hook(add_submenu_page(WPMT_MENU_SLUG, __('Übersicht', 'wp-multi-toolkit'), __('Übersicht', 'wp-multi-toolkit'), 'manage_options', WPMT_MENU_SLUG, 'wpmt_render_overview_page')); + + wpmt_register_admin_hook(add_submenu_page(WPMT_MENU_SLUG, __('WP Multi Ban', 'wp-multi-toolkit'), __('Ban-System', 'wp-multi-toolkit'), 'manage_options', 'wp-multi-ban', 'wp_multi_ban_options_page')); + wpmt_register_admin_hook(add_submenu_page(WPMT_MENU_SLUG, __('WP-Multi DB-Backup', 'wp-multi-toolkit'), __('DB-Backup', 'wp-multi-toolkit'), 'manage_options', 'wpmt-database-backup', 'wpmt_display_backup_page')); + wpmt_register_admin_hook(add_submenu_page(WPMT_MENU_SLUG, __('Backup-Einstellungen', 'wp-multi-toolkit'), __('Backup-Einstellungen', 'wp-multi-toolkit'), 'manage_options', 'wpmt-backup-settings', 'wpmt_display_backup_settings_page')); + wpmt_register_admin_hook(add_submenu_page(WPMT_MENU_SLUG, __('WP Multi DB-Cleaner', 'wp-multi-toolkit'), __('DB-Cleaner', 'wp-multi-toolkit'), 'manage_options', 'wp-multi-toolkit', 'wp_multi_db_cleaner_page')); + wpmt_register_admin_hook(add_submenu_page(WPMT_MENU_SLUG, __('Cookie Banner Einstellungen', 'wp-multi-toolkit'), __('Cookie-Banner', 'wp-multi-toolkit'), 'manage_options', 'wpmt-cookie-banner', 'wpmt_cookie_banner_settings_page')); + wpmt_register_admin_hook(add_submenu_page(WPMT_MENU_SLUG, __('WP-Multi Support', 'wp-multi-toolkit'), __('Support', 'wp-multi-toolkit'), 'manage_options', 'wp_multi_support', 'support_ticket_form')); + wpmt_register_admin_hook(add_submenu_page(WPMT_MENU_SLUG, __('Virtueller Assistent', 'wp-multi-toolkit'), __('Assistent', 'wp-multi-toolkit'), 'manage_options', 'wpmt_assistant', 'wpmt_virtual_assistant_page')); + wpmt_register_admin_hook(add_submenu_page(WPMT_MENU_SLUG, __('WP Multi Dokumentation', 'wp-multi-toolkit'), __('Dokumentation', 'wp-multi-toolkit'), 'manage_options', 'wpmt_docs', 'wpmt_generate_plugin_docs')); +} +add_action('admin_menu', 'wpmt_register_admin_menus', 9); + +/** + * Übersichtsseite: Karten-Grid mit allen Modulen der Suite. + */ +function wpmt_render_overview_page() { + if (!current_user_can('manage_options')) { + wp_die(__('Du hast nicht die erforderlichen Berechtigungen.', 'wp-multi-toolkit')); + } + + $modules = array( + array('wp-multi-ban', 'dashicons-dismiss', __('Ban-System', 'wp-multi-toolkit'), __('IPs, Hostnamen, Referer und User-Agents sperren.', 'wp-multi-toolkit')), + array('wpmt-database-backup', 'dashicons-database-export', __('DB-Backup', 'wp-multi-toolkit'), __('Datenbank-Backups erstellen, herunterladen und planen.', 'wp-multi-toolkit')), + array('wp-multi-toolkit', 'dashicons-trash', __('DB-Cleaner', 'wp-multi-toolkit'), __('Revisionen, Transienten und Tabellen bereinigen.', 'wp-multi-toolkit')), + array('wpmt-cookie-banner', 'dashicons-privacy', __('Cookie-Banner', 'wp-multi-toolkit'), __('DSGVO-Cookie-Hinweis konfigurieren.', 'wp-multi-toolkit')), + array('wp_multi_support', 'dashicons-sos', __('Support', 'wp-multi-toolkit'), __('Support-Tickets direkt an den Entwickler senden.', 'wp-multi-toolkit')), + array('wpmt_assistant', 'dashicons-format-chat', __('Assistent', 'wp-multi-toolkit'), __('Virtueller Assistent für alle WP-Multi-Fragen.', 'wp-multi-toolkit')), + array('wpmt_docs', 'dashicons-book', __('Dokumentation', 'wp-multi-toolkit'), __('Übersicht aller Plugins und Versionen.', 'wp-multi-toolkit')), + ); + + if (!function_exists('is_plugin_active')) { + include_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + $wp_multi_active = is_plugin_active('WP-Multi/wp-multi.php') || is_plugin_active('wp-multi/wp-multi.php'); + + if ($wp_multi_active) { + $modules = array_merge($modules, array( + array('wp-multi-security', 'dashicons-shield', __('Sicherheit', 'wp-multi-toolkit'), __('Anti-Spam, Honeypot und Kommentarfilter.', 'wp-multi-toolkit')), + array('wp_multi_analytics', 'dashicons-chart-bar', __('Benutzer-Analytics', 'wp-multi-toolkit'), __('Beitragsaufrufe und Kommentar-Aktivität.', 'wp-multi-toolkit')), + array('message-board', 'dashicons-admin-comments', __('Pinwand', 'wp-multi-toolkit'), __('Interne Nachrichten für das Admin-Team.', 'wp-multi-toolkit')), + array('reported-posts', 'dashicons-warning', __('Gemeldete Beiträge', 'wp-multi-toolkit'), __('Von Nutzern gemeldete Inhalte verwalten.', 'wp-multi-toolkit')), + array('statistik_manager', 'dashicons-chart-pie', __('Statistik & Notice', 'wp-multi-toolkit'), __('Statistik-Shortcode und Frontend-Banner.', 'wp-multi-toolkit')), + array('wp-multi-notify', 'dashicons-bell', __('Notify', 'wp-multi-toolkit'), __('Telegram- und Discord-Benachrichtigungen.', 'wp-multi-toolkit')), + )); + } + + wpmt_admin_page_open(__('WP Multi', 'wp-multi-toolkit'), __('Zentrale Übersicht aller Module der WP-Multi-Suite', 'wp-multi-toolkit')); + + wpmt_admin_card_open(__('Module', 'wp-multi-toolkit')); + echo '
'; + foreach ($modules as $m) { + printf( + '%s

%s

', + esc_url(admin_url('admin.php?page=' . $m[0])), + esc_attr($m[1]), + esc_html($m[2]), + esc_html($m[3]) + ); + } + echo '
'; + wpmt_admin_card_close(); + + wpmt_admin_page_close(); +} + + +/* + * DB Backup + */ + + // Konstanten für wiederkehrende Pfade + define('WPMT_BACKUP_DIR', wp_upload_dir()['basedir'] . '/wpmt_backups/'); + define('WPMT_BACKUP_URL', wp_upload_dir()['baseurl'] . '/wpmt_backups/'); + + /** + * Erstellt ein Backup der WordPress-Datenbank und speichert es als SQL-Datei. + * + * @return string|WP_Error Der Pfad zur Backup-Datei oder ein WP_Error-Objekt bei Fehlern. + */ + function wpmt_create_database_backup() { + global $wpdb; + + // Dateinamen für das Backup definieren + $backup_filename = 'wp-database-backup-' . date('Y-m-d_H-i-s') . '.sql'; + $backup_file_path = WPMT_BACKUP_DIR . $backup_filename; + + // Sicherstellen, dass der Backup-Ordner existiert und beschreibbar ist + if (!is_writable(wp_upload_dir()['basedir'])) { + return new WP_Error('backup_error', __('Upload-Verzeichnis ist nicht beschreibbar.', 'wp-multi-toolkit')); + } + + if (!file_exists(WPMT_BACKUP_DIR)) { + if (!wp_mkdir_p(WPMT_BACKUP_DIR)) { + return new WP_Error('backup_error', __('Backup-Ordner konnte nicht erstellt werden.', 'wp-multi-toolkit')); + } + } + + // 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.', 'wp-multi-toolkit')); + } + + // Öffne die Backup-Datei + $backup_file = fopen($backup_file_path, 'w'); + if (!$backup_file) { + return new WP_Error('backup_error', __('Backup-Datei konnte nicht geöffnet werden.', 'wp-multi-toolkit')); + } + + // 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. Der Name stammt aus SHOW TABLES (vertrauenswürdig) + // und wird mit Backticks maskiert - prepare('%s') würde ihn fälschlich in + // einfache Anführungszeichen setzen, was ungültiges SQL ergibt und dazu + // führte, dass Backups keine CREATE-TABLE-Anweisungen enthielten. + $create_table_query = $wpdb->get_row('SHOW CREATE TABLE `' . str_replace('`', '', $table_name) . '`', ARRAY_N); + if ($create_table_query) { + fwrite($backup_file, $create_table_query[1] . ";\n\n"); + } + + // Daten der Tabelle in Batches holen (Performance-Optimierung) + $offset = 0; + $batch_size = 1000; + while ($rows = $wpdb->get_results($wpdb->prepare("SELECT * FROM `$table_name` LIMIT %d, %d", $offset, $batch_size), ARRAY_A)) { + foreach ($rows as $row) { + $columns = array_map(function ($col) use ($wpdb) { + // NULL-Werte müssen als SQL-Schlüsselwort NULL geschrieben werden, + // sonst würde beim Wiederherstellen ein Leerstring gespeichert. + if ($col === null) { + return 'NULL'; + } + return $wpdb->prepare('%s', $col); + }, array_values($row)); + $columns_str = implode(", ", $columns); + fwrite($backup_file, "INSERT INTO `$table_name` VALUES ($columns_str);\n"); + } + $offset += $batch_size; + } + + fwrite($backup_file, "\n\n"); + } + + // Datei schließen + fclose($backup_file); + + return $backup_file_path; + } + + /** + * Löscht ein Backup aus dem Backup-Verzeichnis. + */ + function wpmt_delete_backup() { + if (isset($_POST['wpmt_action']) && $_POST['wpmt_action'] === 'delete_backup' && isset($_POST['backup_file']) && check_admin_referer('wpmt_delete_backup_nonce')) { + if (!current_user_can('manage_options')) { + wp_die(__('Du hast nicht die erforderlichen Berechtigungen.', 'wp-multi-toolkit')); + } + $backup_file = WPMT_BACKUP_DIR . 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') . '

'; + } + } + } + + /** + * Plant automatische Backups via Cron-Job. + */ + function wpmt_schedule_backup() { + $schedule = get_option('wpmt_backup_schedule', 'none'); + $hook = 'wpmt_scheduled_backup'; + + // Entferne bestehende Cron-Jobs, um Duplikate zu vermeiden + wp_clear_scheduled_hook($hook); + + // Plane neuen Cron-Job, wenn aktiviert + if ($schedule !== 'none' && !wp_next_scheduled($hook)) { + wp_schedule_event(time(), $schedule, $hook); + } + } + add_action('wp', 'wpmt_schedule_backup'); + + /** + * Führt das geplante Backup aus und sendet optional eine E-Mail-Benachrichtigung. + */ + function wpmt_create_scheduled_backup() { + $backup_path = wpmt_create_database_backup(); + if (!is_wp_error($backup_path)) { + // Sende E-Mail-Benachrichtigung, wenn aktiviert + $send_email = get_option('wpmt_backup_email_notification', 0); + if ($send_email) { + $admin_email = get_option('admin_email'); + $subject = __('Datenbank-Backup erstellt', 'wp-multi-toolkit'); + $message = __('Ein neues Backup wurde erstellt: ', 'wp-multi-toolkit') . $backup_path; + wp_mail($admin_email, $subject, $message); + } + } else { + // Optional: Fehler in Log schreiben + error_log('WP Multi Toolkit: Geplantes Backup fehlgeschlagen: ' . $backup_path->get_error_message()); + } + } + add_action('wpmt_scheduled_backup', 'wpmt_create_scheduled_backup'); + + /** + * Exportiert die Backup-Einstellungen als JSON-Datei. + */ + function wpmt_export_backup_settings() { + if (isset($_POST['wpmt_export_backup_settings']) && check_admin_referer('wpmt_export_backup_settings')) { + if (!current_user_can('manage_options')) { + wp_die(__('Du hast nicht die erforderlichen Berechtigungen.', 'wp-multi-toolkit')); + } + $settings = array( + 'wpmt_backup_schedule' => get_option('wpmt_backup_schedule', 'none'), + 'wpmt_backup_email_notification' => get_option('wpmt_backup_email_notification', 0), + ); + header('Content-Type: application/json'); + header('Content-Disposition: attachment; filename="wpmt_backup_settings.json"'); + echo json_encode($settings, JSON_PRETTY_PRINT); + exit; + } + } + add_action('admin_init', 'wpmt_export_backup_settings'); + + /** + * Importiert Backup-Einstellungen aus einer JSON-Datei. + */ + function wpmt_import_backup_settings() { + if (isset($_POST['wpmt_import_backup_settings']) && check_admin_referer('wpmt_import_backup_settings') && isset($_FILES['wpmt_backup_settings_file'])) { + if (!current_user_can('manage_options')) { + wp_die(__('Du hast nicht die erforderlichen Berechtigungen.', 'wp-multi-toolkit')); + } + + $file = $_FILES['wpmt_backup_settings_file']['tmp_name']; + + // Einstellungsdateien sind winzige JSON-Dateien - alles über 1 MB wird abgelehnt + if (!is_uploaded_file($file) || filesize($file) > MB_IN_BYTES) { + echo '

' . __('Ungültige Datei.', 'wp-multi-toolkit') . '

'; + return; + } + + $settings = json_decode(file_get_contents($file), true); + + if (is_array($settings)) { + $valid_schedules = array('none', 'hourly', 'twicedaily', 'daily', 'weekly'); + $imported_schedule = isset($settings['wpmt_backup_schedule']) ? $settings['wpmt_backup_schedule'] : 'none'; + update_option('wpmt_backup_schedule', in_array($imported_schedule, $valid_schedules, true) ? $imported_schedule : 'none'); + update_option('wpmt_backup_email_notification', isset($settings['wpmt_backup_email_notification']) ? (int) $settings['wpmt_backup_email_notification'] : 0); + echo '

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

'; + + // Cron-Job aktualisieren + wpmt_schedule_backup(); + } else { + echo '

' . __('Ungültige Datei.', 'wp-multi-toolkit') . '

'; + } + } + } + add_action('admin_init', 'wpmt_import_backup_settings'); + + /** + * Anzeige der Backup-Seite mit Liste der Backups und Verlinkung zur Einstellungsseite. + */ + function wpmt_display_backup_page() { + $backup_dir = WPMT_BACKUP_DIR; + $backups = glob($backup_dir . '/*.sql'); + + wpmt_admin_page_open( + __('DB-Backup', 'wp-multi-toolkit'), + __('Datenbank-Backups erstellen, herunterladen und verwalten', 'wp-multi-toolkit') + ); + + wpmt_admin_card_open(__('Neues Backup', 'wp-multi-toolkit')); + ?> +
+ + +

+ + +

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

+
+
+ + +

+

+
+ function($value) { + $valid_schedules = array('none', 'hourly', 'twicedaily', 'daily', 'weekly'); + return in_array($value, $valid_schedules, true) ? $value : 'none'; + } + )); + register_setting('wpmt_backup_settings', 'wpmt_backup_email_notification', array( + 'sanitize_callback' => 'absint' + )); + + add_settings_section( + 'wpmt_backup_main_section', + __('Automatische Backup-Einstellungen', 'wp-multi-toolkit'), + function() { + echo '

' . __('Konfigurieren Sie automatische Backups und Benachrichtigungen.', 'wp-multi-toolkit') . '

'; + }, + 'wpmt_backup_settings' + ); + + add_settings_field( + 'wpmt_backup_schedule', + __('Backup-Zeitplan', 'wp-multi-toolkit'), + function() { + $schedule = get_option('wpmt_backup_schedule', 'none'); + ?> + + + > + +

' . esc_html($backup_path->get_error_message()) . '

'; + } else { + echo '

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

'; + } + } + } + add_action('admin_init', 'wpmt_handle_backup_request'); + + // Die Backup-Menüpunkte werden zentral in wpmt_register_admin_menus() registriert. + + +/* + * 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'; + + $clean_results = array(); + 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 + update_option('wp_multi_allow_system_tables', isset($_POST['allow_system_tables']) ? 'yes' : 'no'); + $allow_system_tables = isset($_POST['allow_system_tables']); + + $clean_results = wp_multi_clean_database($_POST['clean_options'] ?? [], $_POST['truncate_tables'] ?? [], $core_protected_tables, $allow_system_tables); + } + + wpmt_admin_page_open( + __('DB-Cleaner', 'wp-multi-toolkit'), + __('Revisionen, Transienten und Tabelleninhalte gezielt bereinigen', 'wp-multi-toolkit') + ); + + if (!empty($clean_results)) { + $html = '' . esc_html__('Datenbankbereinigung abgeschlossen:', 'wp-multi-toolkit') . ''; + wpmt_admin_notice('success', $html); + echo '
'; + } + + ?> +
+ + + +

+

+

+ + + + +

+ + + +

+
+ + + + + + + + + + + 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, true) && !$allow_system_tables; + ?> + + + + + + + + +
+ + + + 🔒 + +
+
+

+ +
+ query("DELETE FROM {$wpdb->posts} WHERE post_type = 'revision'"); + $results[] = "$deleted Revision(en) gelöscht."; + } + + if (in_array('transients', $options, true)) { + $transients = $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_%'"); + $results[] = "$transients Transient(en) gelöscht."; + } + + if (in_array('options', $options, true)) { + $orphaned = $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_value = '' OR option_value IS NULL"); + $results[] = "$orphaned verwaiste Option(en) gelöscht."; + } + + // Nur Tabellen leeren, die tatsächlich in der Datenbank existieren - schützt davor, + // dass über einen manipulierten POST-Request beliebige Tabellennamen eingeschleust werden. + $existing_tables = $wpdb->get_col('SHOW TABLES'); + + foreach ($truncate_tables as $table) { + $table = sanitize_text_field($table); + + if (!in_array($table, $existing_tables, true)) { + $results[] = "Tabelle $table existiert nicht und wurde ignoriert."; + continue; + } + + if (!$allow_system_tables && in_array($table, $protected, true)) { + $results[] = "Tabelle $table ist geschützt und wurde nicht geleert."; + } else { + $wpdb->query('TRUNCATE TABLE `' . str_replace('`', '', $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'; +} + +// Der DB-Cleaner-Menüpunkt wird zentral in wpmt_register_admin_menus() registriert. + + +/* + * Cookie-Banner + */ + + +// Der Cookie-Banner-Menüpunkt wird zentral in wpmt_register_admin_menus() registriert. + +// Admin-Bereich für die Cookie-Einstellungen +function wpmt_cookie_banner_settings_page() { + if (!current_user_can('manage_options')) { + wp_die(__('Du hast nicht die erforderlichen Berechtigungen.', 'wp-multi-toolkit')); + } + + // Speichern der Daten, wenn das Formular übermittelt wird + if(isset($_POST['wpmt_save_cookie_settings'])) { + check_admin_referer('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'])); + $background_color = sanitize_hex_color($_POST['wpmt_cookie_banner_background_color']); + update_option('wpmt_cookie_banner_background_color', $background_color ? $background_color : '#f0f0f0'); + 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'); + $settings_saved = true; + } + + // 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 + wpmt_admin_page_open( + __('Cookie-Banner', 'wp-multi-toolkit'), + __('DSGVO-konformer Cookie-Hinweis für das Frontend', 'wp-multi-toolkit') + ); + + if (!empty($settings_saved)) { + wpmt_admin_notice('success', __('Einstellungen gespeichert!', 'wp-multi-toolkit')); + } + + wpmt_admin_card_open(); + ?> +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
/>
+
+
+
+
+
+ + +
+ '; + 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' => $ip ? $ip : '', + 'consent_given' => 1, + 'timestamp' => current_time('mysql') + ), + array('%s', '%d', '%s') + ); + } + 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, deren Termin bereits verstrichen ist +function pubMissedPosts() { + global $wpdb; + $now = gmdate('Y-m-d H:i:00'); + + // Überprüfe, ob benutzerdefinierte Beitragstypen vorhanden sind + $args = array( + 'public' => true, + '_builtin' => false, + ); + + $output = 'names'; // names oder objects, names ist der Standard + $operator = 'and'; // 'and' oder 'or' + $post_types = get_post_types($args, $output, $operator); + $post_types = array_merge(['post', 'page'], array_values($post_types)); + + $placeholders = implode(',', array_fill(0, count($post_types), '%s')); + $sql = $wpdb->prepare( + "SELECT ID FROM $wpdb->posts WHERE post_type IN ($placeholders) AND post_status = 'future' AND post_date_gmt < %s", + array_merge($post_types, [$now]) + ); + + $resulto = $wpdb->get_results($sql); + if ($resulto) { + foreach ($resulto as $thisarr) { + wp_publish_post($thisarr->ID); + } + } +} + +// Läuft alle 5 Minuten per WP-Cron statt bei jedem Seitenaufruf (wp_head), um unnötige +// Datenbankabfragen auf jeder Frontend-Anfrage zu vermeiden. +function wpmt_schedule_pub_missed_posts() { + if (!wp_next_scheduled('wpmt_pub_missed_posts_event')) { + wp_schedule_event(time(), 'wpmt_five_minutes', 'wpmt_pub_missed_posts_event'); + } +} +add_action('wp', 'wpmt_schedule_pub_missed_posts'); +add_action('wpmt_pub_missed_posts_event', 'pubMissedPosts'); + +add_filter('cron_schedules', function ($schedules) { + if (!isset($schedules['wpmt_five_minutes'])) { + $schedules['wpmt_five_minutes'] = array( + 'interval' => 5 * MINUTE_IN_SECONDS, + 'display' => __('Alle 5 Minuten', 'wp-multi-toolkit'), + ); + } + return $schedules; +}); + + +/* + * Gitea - Ticket - BUG - Report + */ + +/** + * Sendet ein Support-Ticket an den Server und leitet es an das entsprechende Gitea-Repository weiter. + * + * @param string $plugin_name Der Name des Plugins (z. B. wp-multi, wp-multi-teamcard). + * @param string $title Der Titel des Tickets. + * @param string $description Die Beschreibung des Tickets. + * @param string $label Die Kategorie des Tickets (z. B. bug, enhancement). + * @return string Die Rückmeldung (Erfolg oder Fehler). + */ +function send_support_ticket_to_server($plugin_name, $title, $description, $label = 'bug') { + $server_url = 'https://m-viper.de/gitea-issue-creator.php'; + + // Daten für die Anfrage vorbereiten + $data = [ + 'plugin' => $plugin_name, + 'title' => $title, + 'description' => $description, + 'label' => $label + ]; + + $args = [ + 'method' => 'POST', + 'body' => json_encode($data), + 'headers' => [ + 'Content-Type' => 'application/json', + ], + 'timeout' => 45, + ]; + + $response = wp_remote_post($server_url, $args); + + if (is_wp_error($response)) { + $error_message = $response->get_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', 'wp-multi-toolkit') . ''; + } else { + return '' . sprintf(__('Es gab einen Fehler: %s', 'wp-multi-toolkit'), esc_html($response_body)) . ''; + } +} + +/** + * Rendert das Support-Ticket-Formular im Admin-Bereich. + */ +function support_ticket_form() { + $result_html = ''; + if (isset($_POST['submit_ticket']) && check_admin_referer('wp_multi_submit_ticket')) { + $plugin_name = sanitize_text_field($_POST['plugin_name']); + $title = sanitize_text_field($_POST['ticket_title']); + $description = sanitize_textarea_field($_POST['ticket_description']); + $label = sanitize_text_field($_POST['ticket_label']); + $result_html = send_support_ticket_to_server($plugin_name, $title, $description, $label); + } + + wpmt_admin_page_open( + __('Support', 'wp-multi-toolkit'), + __('Support-Tickets direkt an den Entwickler senden', 'wp-multi-toolkit') + ); + + if ($result_html) { + // Rückgabe enthält eine .success-message oder .error-message span + $type = strpos($result_html, 'success-message') !== false ? 'success' : 'error'; + wpmt_admin_notice($type, wp_strip_all_tags($result_html)); + } + + wpmt_admin_card_open(__('Neues Ticket', 'wp-multi-toolkit')); + ?> +
+ +
+ + +
+
+ + +
+
+ + +
+
+ + +
+

+
+ display_name ?: __('Freund', 'wp-multi-toolkit'); + + $assistant_responses = apply_filters('wpmt_assistant_responses', array( + 'default' => sprintf( + __('Ups, das habe ich nicht ganz verstanden, %s! 😅 Versuche es mit einer anderen Formulierung oder schau in die Dokumentation. Alternativ kannst du ein Support-Ticket erstellen, und wir helfen dir weiter!', 'wp-multi-toolkit'), + esc_html($user_name), + admin_url('admin.php?page=wpmt_docs'), + admin_url('admin.php?page=wp_multi_support') + ) + )); + + // Stichwörter für Autovervollständigung und Anzeige + $keywords = array_keys($assistant_responses); + unset($keywords[array_search('default', $keywords)]); + $keywords_list = implode(', ', array_map(function($key) { + return ucfirst(str_replace('-', ' ', $key)); + }, $keywords)); + + wpmt_admin_page_open( + __('Virtueller Assistent', 'wp-multi-toolkit'), + __('Fragen zu den WP-Multi-Plugins – Schritt für Schritt erklärt', 'wp-multi-toolkit') + ); + ?> +
+
+ <?php _e('Virtueller Assistent', 'wp-multi-toolkit'); ?> +

+

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

+

+
+ + + + + + $synonyms) { + foreach ($synonyms as $synonym) { + $distance = levenshtein($input, wpmt_normalize_text($synonym)); + if ($distance < $min_distance && $distance <= $max_distance) { + $min_distance = $distance; + $best_match = $key; + } + } + } + return $best_match; +} + +/** + * AJAX-Handler für Assistenten-Anfragen + */ +function wpmt_assistant_query() { + check_ajax_referer('wpmt_assistant_nonce', 'nonce'); + + $question = isset($_POST['question']) ? sanitize_text_field($_POST['question']) : ''; + $last_question = isset($_POST['last_question']) ? sanitize_text_field($_POST['last_question']) : ''; + $selected_keyword = isset($_POST['selected_keyword']) ? sanitize_text_field($_POST['selected_keyword']) : ''; + + if (empty($question)) { + wp_send_json_error(__('Bitte gib eine Frage ein, um weiterzumachen!', 'wp-multi-toolkit')); + } + + $current_user = wp_get_current_user(); + $user_name = $current_user->display_name ?: __('Freund', 'wp-multi-toolkit'); + + $responses = apply_filters('wpmt_assistant_responses', array( + 'default' => sprintf( + __('Ups, das habe ich nicht ganz verstanden, %s! 😅 Versuche es mit einer anderen Formulierung oder schau in die Dokumentation. Alternativ kannst du ein Support-Ticket erstellen, und wir helfen dir weiter!', 'wp-multi-toolkit'), + esc_html($user_name), + admin_url('admin.php?page=wpmt_docs'), + admin_url('admin.php?page=wp_multi_support') + ) + )); + + $keyword_synonyms = apply_filters('wpmt_assistant_keyword_synonyms', array( + 'statistik' => ['statistik', 'statistiken', 'stats', 'daten', 'bericht'], + 'telegram' => ['telegram', 'telegarm', 'tg', 'tele', 'benachrichtigung telegram'], + 'discord' => ['discord', 'discrod', 'dc', 'discord benachrichtigung'], + 'admin links' => ['admin links', 'admin-links', 'adminlinks', 'links', 'menü links'], + 'gast-autor' => ['gast-autor', 'gastautor', 'guest author', 'gast', 'autor'], + 'beitrag report' => ['beitrag report', 'beitrag-report', 'report', 'melden', 'gemeldete beiträge'], + 'textbox' => ['textbox', 'text-box', 'textfeld', 'text am beitrag'], + 'banner' => ['banner', 'werbung', 'anzeige', 'header banner', 'footer banner'], + 'inhaltsverzeichnis' => ['inhaltsverzeichnis', 'inhalt', 'index', 'verzeichnis', 'alphabetische liste'], + 'lesezeichen' => ['lesezeichen', 'bookmark', 'favoriten', 'speichern', 'merken'], + 'custom shortcode' => ['custom shortcode', 'shortcode', 'eigener shortcode', 'shortcodes'], + 'kommentar sperren' => ['kommentar sperren', 'kommentarsperre', 'blockieren', 'sperren', 'nutzer blockieren'], + 'filter' => ['filter', 'kommentarfilter', 'filtern', 'kommentare filtern'], + 'analytics' => ['analytics', 'analyse', 'benutzer analytics', 'datenanalyse'], + 'pinwand' => ['pinwand', 'notiz', 'pinnwand', 'team notizen'], + 'brute force' => ['brute force', 'bruteforce', 'sicherheit', 'login schutz'], + 'anti spam' => ['anti spam', 'antispam', 'spam', 'spam schutz'], + 'auto tag' => ['auto tag', 'autotag', 'tags', 'automatische tags'], + 'login deaktivieren' => ['login deaktivieren', 'login-deaktivieren', 'login', 'zugang sperren'], + 'text copy' => ['text copy', 'text-copy', 'kopierschutz', 'rechtsklick sperre'], + 'trash mail' => ['trash mail', 'trash-mail', 'spam mail', 'wegwerf email'], + 'kommentar benachrichtigung' => ['kommentar benachrichtigung', 'kommentar-benachrichtigung', 'benachrichtigung', 'comment', 'kommentar alarm'], + 'kategorien ausblenden' => ['kategorien ausblenden', 'kategorie-ausblenden', 'kategorien', 'ausblenden', 'kategorie filter'], + 'suchfunktion' => ['suchfunktion', 'suche', 'search', 'wp multi search'], + 'teamcard' => ['teamcard', 'team-card', 'teamkarte', 'team', 'teamkarten'], + 'teammitglied hinzufügen' => ['teammitglied hinzufügen', 'teammitglied-hinzufügen', 'mitglied', 'hinzufügen', 'teammitglied'], + 'teamcard shortcode' => ['teamcard shortcode', 'teamcard-shortcode', 'shortcode', 'teamkarten shortcode'], + 'teamcard kategorie' => ['teamcard kategorie', 'teamcard-kategorie', 'kategorie', 'team kategorie'], + 'teamcard bild' => ['teamcard bild', 'teamcard-bild', 'bild', 'team foto'], + 'teamcard löschen' => ['teamcard löschen', 'teamcard-löschen', 'löschen', 'teammitglied entfernen'], + 'teamcard reihenfolge' => ['teamcard reihenfolge', 'teamcard-reihenfolge', 'reihenfolge', 'team sortieren'], + 'teamcard deinstallation' => ['teamcard deinstallation', 'teamcard-deinstallation', 'deinstallieren', 'teamcard entfernen'], + 'teamcard updates' => ['teamcard updates', 'teamcard-updates', 'updates', 'teamcard aktualisierung'], + 'update management' => ['update management', 'update-management', 'updates', 'plugin updates'], + 'support issues' => ['support issues', 'support-issues', 'support', 'ticket', 'hilfe'], + 'dokumentation' => ['dokumentation', 'doku', 'docs', 'anleitung', 'dokumentaton'], + 'virtueller assistent' => ['virtueller assistent', 'assistent', 'virtuell', 'chatbot'], + 'toolbar' => ['toolbar', 'werkzeugleiste', 'schnellstart', 'quickbar'], + 'wp multi plugins' => ['wp multi plugins', 'wp-multi-plugins', 'plugins', 'wp multi'], + 'was sind wp multi plugins' => ['was sind wp multi plugins', 'wp multi plugins', 'plugins', 'wp multi erklärung'], + 'wie installiere ich ein plugin' => ['wie installiere ich ein plugin', 'plugin installieren', 'installation', 'plugin setup', 'install plugin'], + 'wo finde ich updates' => ['wo finde ich updates', 'updates finden', 'aktualisierungen', 'plugin updates', 'update suchen'], + 'wie erstelle ich ein support ticket' => ['wie erstelle ich ein support ticket', 'support ticket', 'ticket', 'support anfrage', 'ticket erstellen'], + 'welche voraussetzungen gibt es' => ['welche voraussetzungen gibt es', 'voraussetzungen', 'anforderungen', 'systemanforderungen', 'plugin voraussetzungen'], + 'sind die plugins kostenlos' => ['sind die plugins kostenlos', 'kostenlos', 'gratis', 'plugin kosten', 'free plugins'], + 'wie deaktiviere ich ein plugin' => ['wie deaktiviere ich ein plugin', 'plugin deaktivieren', 'deaktivieren', 'plugin ausschalten', 'disable plugin'], + 'wo finde ich die dokumentation' => ['wo finde ich die dokumentation', 'dokumentation finden', 'doku', 'anleitung finden', 'doku suchen'], + 'wer entwickelt die plugins' => ['wer entwickelt die plugins', 'entwickler', 'm_viper', 'plugin entwickler', 'wer macht plugins'], + 'kann ich eigene funktionen hinzufügen' => ['kann ich eigene funktionen hinzufügen', 'eigene funktionen', 'anpassen', 'erweitern', 'custom functions'], + 'wie richte ich wp multi ein' => ['wie richte ich wp multi ein', 'wp multi einrichten', 'setup wp multi', 'installation wp multi', 'wp multi installieren'], + 'was ist wordpress' => ['was ist wordpress', 'wordpress', 'wordpress erklärung', 'cms wordpress', 'wordpress info'], + 'wie sichere ich meine website' => ['wie sichere ich meine website', 'website sichern', 'sicherheit', 'backup', 'sichere website'], + 'wie verbessere ich die performance' => ['wie verbessere ich die performance', 'performance', 'geschwindigkeit', 'optimierung', 'website schneller'], + 'wie kontaktiere ich den support' => ['wie kontaktiere ich den support', 'support kontakt', 'hilfe kontakt', 'support team', 'support anfragen'], + 'welche plugins sind kompatibel' => ['welche plugins sind kompatibel', 'kompatibilität', 'plugin kompatibel', 'kompatible plugins', 'plugin kompatibilität'], + 'wie teste ich ein plugin' => ['wie teste ich ein plugin', 'plugin testen', 'test plugin', 'plugin ausprobieren', 'plugin prüfen'] + )); + + $normalized_question = wpmt_normalize_text($question); + $response = $responses['default']; + $matched_keywords = []; + $matched_keyword = null; + + // Wenn ein spezifisches Stichwort ausgewählt wurde + if ($selected_keyword && isset($responses[$selected_keyword])) { + $response = $responses[$selected_keyword]; + } else { + // Suche nach allen passenden Stichwörtern + foreach ($keyword_synonyms as $key => $synonyms) { + if ($key === 'default') continue; + foreach ($synonyms as $synonym) { + if (strpos($normalized_question, wpmt_normalize_text($synonym)) !== false) { + $matched_keywords[] = $key; + break; + } + } + } + + // Falls kein Treffer, suche nach Tippfehlern + if (empty($matched_keywords)) { + $matched_keyword = wpmt_levenshtein_match($normalized_question, $keyword_synonyms); + if ($matched_keyword && isset($responses[$matched_keyword])) { + $matched_keywords[] = $matched_keyword; + } + } + + // Wenn genau ein Stichwort gefunden wurde + if (count($matched_keywords) === 1) { + $response = $responses[$matched_keywords[0]]; + if ($matched_keywords[0] === $matched_keyword) { + $response = sprintf( + __('Meintest du vielleicht „%s“, %s? Hier ist die Antwort: ', 'wp-multi-toolkit'), + esc_html(str_replace('-', ' ', $matched_keywords[0])), + esc_html($user_name) + ) . $response; + } + } + // Wenn mehrere Stichwörter gefunden wurden + elseif (count($matched_keywords) > 1) { + $response = sprintf( + __('Mehrere Themen passen zu deiner Frage, %s! 😊 Wähle eines aus: ', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $response .= '
'; + foreach ($matched_keywords as $key) { + $response .= sprintf( + '%s', + esc_attr($key), + esc_html(ucfirst(str_replace('-', ' ', $key))) + ); + } + $response .= '
'; + } + // Wenn kein Treffer, Vorschläge machen + else { + $suggestions = []; + $words = explode(' ', $normalized_question); + foreach ($words as $word) { + foreach ($keyword_synonyms as $key => $synonyms) { + foreach ($synonyms as $synonym) { + if (levenshtein($word, wpmt_normalize_text($synonym)) <= 4 && !in_array($key, $suggestions)) { + $suggestions[] = $key; + } + } + } + } + if (!empty($suggestions)) { + $response .= sprintf( + __('Keine direkte Antwort gefunden, %s. 🙁 Vielleicht passen diese Themen: %s.', 'wp-multi-toolkit'), + esc_html($user_name), + implode(', ', array_map(function($key) { return ucfirst(str_replace('-', ' ', $key)); }, $suggestions)) + ); + } + } + } + + // Antwort mit Bewertungsoptionen + $allowed_html = array( + 'a' => array('href' => true, 'class' => true, 'data-keyword' => true), + 'code' => array(), + 'strong' => array(), + 'div' => array('class' => true), + 'ul' => array(), + 'li' => array() + ); + $formatted_response = wp_kses($response, $allowed_html) . '
'; + $formatted_response .= '' . __('Hilfreich', 'wp-multi-toolkit') . ''; + $formatted_response .= '' . __('Nicht hilfreich', 'wp-multi-toolkit') . ''; + $formatted_response .= '
'; + + wp_send_json_success(array('response' => $formatted_response)); +} +add_action('wp_ajax_wpmt_assistant_query', 'wpmt_assistant_query'); + +/** + * AJAX-Handler für Feedback + */ +function wpmt_assistant_feedback() { + check_ajax_referer('wpmt_assistant_nonce', 'nonce'); + + $message = isset($_POST['message']) ? wp_kses_post($_POST['message']) : ''; + $rating = isset($_POST['rating']) ? sanitize_text_field($_POST['rating']) : ''; + + $feedback_log = get_option('wpmt_assistant_feedback', array()); + $feedback_log[] = array( + 'message' => $message, + 'rating' => $rating, + 'timestamp' => current_time('mysql') + ); + // Auf die letzten 200 Einträge begrenzen, damit die Option nicht unbegrenzt wächst + if (count($feedback_log) > 200) { + $feedback_log = array_slice($feedback_log, -200); + } + update_option('wpmt_assistant_feedback', $feedback_log); + + wp_send_json_success(); +} +add_action('wp_ajax_wpmt_assistant_feedback', 'wpmt_assistant_feedback'); + +// Die Assistenten-Seite wird zentral in wpmt_register_admin_menus() registriert. + +/** + * Antworten vordefinieren + */ +add_filter('wpmt_assistant_responses', function($responses) { + $current_user = wp_get_current_user(); + $user_name = $current_user->display_name ?: __('Freund', 'wp-multi-toolkit'); + + // WP Multi + $responses['statistik'] = sprintf( + __('Hey %s, willst du die Statistiken deiner Website im Blick haben? 📊 Füge den Shortcode [statistik_manager] in einen Beitrag oder eine Seite ein, um sie anzuzeigen. Oder gehe zu WP Stat & Notice, um Details wie Beitragsanzahl, Kommentare oder Kategorien zu sehen. Tipp: Aktiviere Benachrichtigungen für wichtige Updates! Bereit, deine Daten zu checken? 😎', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['telegram'] = sprintf( + __('Telegram-Benachrichtigungen einrichten, %s? Super einfach! 🔔 Gehe zu Notify > TG-Notify, erstelle einen Bot über BotFather und folge den Schritten, um ihn zu konfigurieren. Neue Beiträge oder Kommentare landen direkt in deinem Chat. Jetzt einrichten. Tipp: Teste den Bot mit einer Probemitteilung! Alles klar? 🚀', 'wp-multi-toolkit'), + esc_html($user_name), + admin_url('admin.php?page=tg-notify') + ); + $responses['discord'] = sprintf( + __('Discord-Benachrichtigungen für deine Community, %s? 😄 Gehe zu Notify > DC-Notify, erstelle einen Webhook in deinem Discord-Server und füge ihn in den Einstellungen ein. Neue Beiträge werden automatisch gepostet. Los geht’s! Tipp: Nutze einen separaten Kanal für Benachrichtigungen! Bereit? 🌟', 'wp-multi-toolkit'), + esc_html($user_name), + admin_url('admin.php?page=wp-multi-dc-notify') + ); + $responses['admin links'] = sprintf( + __('Eigene Admin-Links hinzufügen, %s? Perfekt für schnellen Zugriff! 🔧 Gehe zu Werkzeuge > Admin-Link hinzufügen, gib Namen und URL ein (z. B. für externe Tools) und speichere. Deine Links erscheinen im Admin-Menü. Tipp: Gruppiere Links für bessere Übersicht! Alles organisiert? 😊', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['gast-autor'] = sprintf( + __('Gastautoren auf deiner Seite, %s? 😊 Gehe zu Benutzer > Gastautor (Übersicht), füge Autoren hinzu und weise ihnen Beiträge zu. Ihre Namen erscheinen automatisch im Frontend. Tipp: Füge eine kurze Bio hinzu, um sie vorzustellen! Einfach, oder? ✨', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['beitrag report'] = sprintf( + __('Probleme mit Beiträgen, %s? 🧹 Unter Gemeldete Beiträge kannst du unangemessene Inhalte prüfen, bearbeiten oder löschen. So bleibt deine Seite sauber! Brauchst du Hilfe? Erstelle ein Support-Ticket. Alles unter Kontrolle? 🚀', 'wp-multi-toolkit'), + esc_html($user_name), + admin_url('admin.php?page=wp_multi_support') + ); + $responses['textbox'] = sprintf( + __('Eine Textbox am Beitragsende, %s? Ideal für Hinweise oder Werbung! ✨ Gehe zu WP Multi > Textbox, füge deinen Text ein und passe das Design an. Die Box erscheint automatisch unter Beiträgen. Tipp: Nutze auffällige Farben für mehr Aufmerksamkeit! Bereit? 😄', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['banner'] = sprintf( + __('Ein schickes Banner, %s? 🎨 Gehe zu WP Stat & Notice, lade ein Bild hoch und wähle Header oder Footer. Perfekt, um Neuigkeiten zu präsentieren! Tipp: Verwende Bilder mit hohem Kontrast für bessere Sichtbarkeit. Los geht’s! 🚀', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['inhaltsverzeichnis'] = sprintf( + __('Ein Inhaltsverzeichnis für deine Beiträge, %s? 🚀 Nutze den Shortcode [alphabetical_index], um alle Beiträge übersichtlich aufzulisten. Ideal für Blogs mit vielen Inhalten! Tipp: Kombiniere es mit Kategoriefiltern für mehr Struktur. Alles klar? 😎', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['lesezeichen'] = sprintf( + __('Lesezeichen für deine Besucher, %s? 😎 Mit [add_bookmark] können Nutzer Beiträge speichern, und [display_bookmarks] zeigt ihre Liste. Alles per Cookie – keine Datenbank nötig! Tipp: Füge die Shortcodes in eine Sidebar für schnellen Zugriff! Cool, oder? 🚀', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['custom shortcode'] = sprintf( + __('Eigene Shortcodes erstellen, %s? Super flexibel! 😉 Gehe zu WP Multi > Shortcodes, lege deinen Shortcode an und füge ihn im Editor ein. Ideal für wiederkehrende Inhalte! Tipp: Dokumentiere deine Shortcodes für spätere Änderungen. Bereit zum Codieren? 🚀', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['kommentar sperren'] = sprintf( + __('Bestimmte Nutzer blockieren, %s? 🛡️ Gehe zu Benutzer sperren, gib Benutzername, IP oder E-Mail ein und speichere. So bleibt die Kommentarspalte sauber! Tipp: Überprüfe die Sperrliste regelmäßig, um sie aktuell zu halten. Alles sicher? 😊', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['filter'] = sprintf( + __('Kommentare filtern, %s? 😊 Gehe zu Kommentare > Kommentar Filter und verbiete URLs, Schimpfwörter oder Telefonnummern. Verstöße werden mit * ersetzt. Tipp: Teste die Filter mit einem Probekommentar, um sicherzugehen! Deine Community wird’s lieben! 🌟', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['analytics'] = sprintf( + __('Datenanalyse für deine Beiträge, %s? 📊 Unter Benutzer > Benutzer Analytics siehst du Views, Kommentare, Top-Beiträge und mehr. Perfekt, um Inhalte zu optimieren! Tipp: Exportiere die Daten für langfristige Analysen. Bereit, ein Profi zu werden? 😎', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['pinwand'] = sprintf( + __('Nachrichten für dein Team, %s? 📌 Unter Pinnwand kannst du Notizen für Admins oder Redakteure hinterlegen. Erstelle, bearbeite oder lösche sie jederzeit. Tipp: Nutze die Pinnwand für wichtige To-Dos! Alles organisiert? 😄', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['brute force'] = sprintf( + __('Sicherheit zuerst, %s! 🛡️ Der Brute-Force-Schutz protokolliert Fehlversuche und sperrt nach 5 Versuchen. Einstellungen findest du unter Sicherheit. Tipp: Aktiviere Benachrichtigungen, um verdächtige Aktivitäten zu überwachen! Alles sicher? 🚀', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['anti spam'] = sprintf( + __('Spam loswerden, %s? 😒 Aktiviere den Anti-Spam-Schutz unter Sicherheit, um Bots zu blockieren. Spam-Kommentare werden automatisch gefiltert. Tipp: Kombiniere es mit Kommentarfiltern für doppelten Schutz! Bereit? 😊', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['auto tag'] = sprintf( + __('Automatische Tags, %s? ⏳ Gehe zu Beiträge > Automatische Tags, füge fehlende Tags hinzu oder verbiete Wörter. Spart Zeit! Tipp: Überprüfe die Tags regelmäßig, um sie an deine Inhalte anzupassen. Alles klar? 🚀', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['login deaktivieren'] = sprintf( + __('Logins deaktivieren, %s? 🔒 Gehe zu Benutzer > Alle Benutzer, wähle einen Benutzer und schalte den Login ab. Ideal für temporäre Sperren. Tipp: Notiere dir, wen du deaktiviert hast! Alles unter Kontrolle? 😎', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['text copy'] = sprintf( + __('Inhalte schützen, %s? 🛡️ Aktiviere die Rechtsklick-Sperre unter WP Multi-Einstellungen, um Texte vor Kopieren zu sichern. Perfekt für Blogs! Tipp: Füge einen Hinweis hinzu, warum Kopieren deaktiviert ist. Bereit? 😊', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['trash mail'] = sprintf( + __('Kein Bock auf Spam-Mails, %s? 😊 Wir blockieren Trash-Mails in Kommentaren automatisch. Die Liste wird vom Entwickler gepflegt – du musst nichts tun! Tipp: Aktiviere Anti-Spam für extra Schutz! Alles sauber? 🌟', 'wp-multi-toolkit'), + esc_html($user_name) + ); + + // WP Multi Comment Notifications + $responses['kommentar benachrichtigung'] = sprintf( + __('Immer über neue Kommentare informiert, %s? 🔔 Gehe zu Kommentare > Kommentar Benachrichtigung und richte E-Mail, Telegram oder Discord ein. Tipp: Filtere Benachrichtigungen, um nur wichtige zu erhalten! Nie wieder etwas verpassen! 😄', 'wp-multi-toolkit'), + esc_html($user_name) + ); + + // WP Multi Kategorie + $responses['kategorien ausblenden'] = sprintf( + __('Kategorien ausblenden, %s? 🗂️ Gehe zu Beiträge > Kategorie Filter und wähle, was im Frontend nicht angezeigt werden soll. Ideal für eine saubere Seite! Tipp: Teste Änderungen in der Vorschau! Alles organisiert? 🚀', 'wp-multi-toolkit'), + esc_html($user_name) + ); + + // WP Multi Search + $responses['suchfunktion'] = sprintf( + __('Eine starke Suche, %s? 🔍 Füge WP Multi Search über Shortcode, Widget oder Menü hinzu. Einstellungen findest du unter Einstellung > WP-Multi Search. Tipp: Aktiviere Autovervollständigung für bessere Ergebnisse! Bereit, alles zu finden? 😎', 'wp-multi-toolkit'), + esc_html($user_name) + ); + + // WP Multi Team-Card + $responses['teamcard'] = sprintf( + __('Dein Team präsentieren, %s? 🌟 Mit WP Multi Team-Card erstellst du professionelle Teamkarten mit Namen, Funktionen und Bildern. Nutze [teamcards] im Frontend. Jetzt ausprobieren und dein Team ins Rampenlicht stellen! 🚀', 'wp-multi-toolkit'), + esc_html($user_name), + admin_url('admin.php?page=teamcard_management') + ); + $responses['teammitglied hinzufügen'] = sprintf( + __('Ein neues Teammitglied, %s? 😄 Gehe zu Team-Cards, gib Name, Funktion, Zuständigkeit und Bild ein und klicke auf Hinzufügen. Tipp: Wähle hochauflösende Bilder für beste Darstellung! Bereit fürs Update? ✨', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['teamcard shortcode'] = sprintf( + __('Teamkarten anzeigen, %s? 🚀 Nutze [teamcards] für alle Mitglieder oder [teamcards kategorie="slug"] für eine Kategorie. Füge den Shortcode in Beiträge ein. Tipp: Teste verschiedene Layouts! Alles klar? 😊', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['teamcard kategorie'] = sprintf( + __('Kategorien für Teamkarten, %s? 🗂️ Erstelle sie unter Beiträge > Kategorien und weise sie Mitgliedern zu. Zeige sie mit [teamcards kategorie="slug"]. Tipp: Sortiere Teams nach Abteilungen! Alles organisiert? 😎', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['teamcard bild'] = sprintf( + __('Ein Bild für ein Teammitglied, %s? 😊 In Team-Cards klickst du auf Bild auswählen und lädst ein Foto hoch. Es erscheint in der Teamkarte. Tipp: Nutze quadratische Bilder für einheitliches Design! Bereit? 🚀', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['teamcard löschen'] = sprintf( + __('Ein Teammitglied entfernen, %s? 🗑️ Gehe zu Team-Cards, finde das Mitglied und klicke auf Löschen. Tipp: Sichere Daten vor dem Löschen! Schnell erledigt? 😄', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['teamcard reihenfolge'] = sprintf( + __('Reihenfolge der Teamkarten ändern, %s? 😎 In Team-Cards verschiebst du Mitglieder per Drag-and-Drop. Tipp: Speichere nach dem Sortieren, um Änderungen zu sichern! Alles sortiert? 🚀', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['teamcard deinstallation'] = sprintf( + __('Team-Card deinstallieren, %s? ⚠️ Achtung: Alle Teammitglieder und Bilder werden gelöscht. Sichere Daten mit einem Backup! Mehr Infos: Mehr Infos. Alles klar? 😊', 'wp-multi-toolkit'), + esc_html($user_name), + 'https://git.viper.ipv64.net/M_Viper/wp-multi-teamcard' + ); + $responses['teamcard updates'] = sprintf( + __('Updates für Team-Card, %s? 🚀 Schau auf git.viper.ipv64.net für die neueste Version. Updates werden auch im Admin-Bereich angezeigt. Tipp: Lies die Changelogs für neue Features! Bleib up to date! 😎', 'wp-multi-toolkit'), + esc_html($user_name), + 'https://git.viper.ipv64.net/M_Viper/wp-multi-teamcard' + ); + + // WP Multi Toolkit + $responses['update management'] = sprintf( + __('Updates im Griff, %s? 🌟 Im Dashboard-Widget Verfügbare Updates für WP Multi Toolkit siehst du den Status aller Plugins. Lade neue Versionen herunter und installiere sie. Jetzt prüfen. Tipp: Sichere deine Seite vor Updates! Bereit? 🚀', 'wp-multi-toolkit'), + esc_html($user_name), + admin_url('index.php') + ); + $responses['support issues'] = sprintf( + __('Hilfe nötig, %s? 😊 Erstelle ein Support-Ticket unter WP-Multi Support. Beschreibe dein Problem genau, und wir melden uns schnell! Ticket erstellen. Tipp: Screenshots helfen uns, schneller zu reagieren! Bereit? 🌟', 'wp-multi-toolkit'), + esc_html($user_name), + admin_url('admin.php?page=wp_multi_support') + ); + $responses['dokumentation'] = sprintf( + __('Alles über WP Multi erfahren, %s? 📚 Die Dokumentation findest du unter WP-Multi Support > Dokumentation. Dort gibt’s Anleitungen und FAQs. Dokumentation ansehen. Tipp: Nutze die Suche in der Doku! Bereit? 😄', 'wp-multi-toolkit'), + esc_html($user_name), + admin_url('admin.php?page=wpmt_docs') + ); + $responses['virtueller assistent'] = sprintf( + __('Das bin ich, %s! 😄 Dein virtueller Assistent für alle WP Multi Fragen. Stelle mir deine Fragen unter WP-Multi Support > Virtueller Assistent. Tipp: Frag nach spezifischen Features, ich kenne sie alle! Wie kann ich dir helfen? 🚀', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['toolbar'] = sprintf( + __('Die Schnellstart-Toolbar, %s? 🚀 Unten rechts findest du Support, Updates, Dokumentation und mich – alles in einem Klick! Tipp: Halte die Toolbar aktiviert für schnellen Zugriff! Praktisch, oder? 😊', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['wp multi plugins'] = sprintf( + __('Neugierig auf WP Multi Plugins, %s? 🌟 Hier die Übersicht:Mehr in der Dokumentation! 😎', 'wp-multi-toolkit'), + esc_html($user_name), + admin_url('admin.php?page=wpmt_docs') + ); + + // Allgemeine Fragen und Antworten + $responses['was sind wp multi plugins'] = sprintf( + __('WP Multi Plugins, %s? 🚀 Eine Sammlung cooler Tools für deine Website! Von Statistiken über Sicherheit bis Benachrichtigungen – alles dabei. Schau unter wp multi plugins oder auf git.viper.ipv64.net. Bereit, deine Seite zu boosten? 😄', 'wp-multi-toolkit'), + esc_html($user_name), + 'https://git.viper.ipv64.net/M_Viper' + ); + $responses['wie installiere ich ein plugin'] = sprintf( + __('Ein Plugin installieren, %s? 😊 Gehe zu Plugins > Neu hinzufügen, lade die Datei von git.viper.ipv64.net hoch und aktiviere es. Oder per FTP in /wp-content/plugins/. Tipp: Lies die Doku für Details! Los geht’s! 🚀', 'wp-multi-toolkit'), + esc_html($user_name), + 'https://git.viper.ipv64.net/M_Viper' + ); + $responses['wo finde ich updates'] = sprintf( + __('Updates, %s? 🌟 Im Dashboard-Widget Verfügbare Updates für WP Multi Toolkit oder auf git.viper.ipv64.net. Lade die neue Version hoch! Tipp: Sichere deine Seite vor Updates! Bleib frisch! 😎', 'wp-multi-toolkit'), + esc_html($user_name), + 'https://git.viper.ipv64.net/M_Viper' + ); + $responses['wie erstelle ich ein support ticket'] = sprintf( + __('Ein Support-Ticket, %s? 😊 Gehe zu WP-Multi Support, wähle das Plugin, gib Titel und Beschreibung ein und sende es ab. Jetzt erstellen. Tipp: Füge Screenshots hinzu! Wir helfen schnell! 🚀', 'wp-multi-toolkit'), + esc_html($user_name), + admin_url('admin.php?page=wp_multi_support') + ); + $responses['welche voraussetzungen gibt es'] = sprintf( + __('Voraussetzungen, %s? 📋 Mindestens WordPress 6.7.2 und PHP 7.4. Für Telegram/Discord brauchst du API-Keys. Details in der Dokumentation. Tipp: Prüfe deine Server-Einstellungen! Bereit? 😄', 'wp-multi-toolkit'), + esc_html($user_name), + admin_url('admin.php?page=wpmt_docs') + ); + $responses['sind die plugins kostenlos'] = sprintf( + __('Kostenlos, %s? 😄 Ja, alle WP Multi Plugins sind gratis auf git.viper.ipv64.net! Tipp: Spende dem Entwickler einen Kaffee, wenn sie dir gefallen! Bereit? 🚀', 'wp-multi-toolkit'), + esc_html($user_name), + 'https://git.viper.ipv64.net/M_Viper' + ); + $responses['wie deaktiviere ich ein plugin'] = sprintf( + __('Plugin deaktivieren, %s? 😎 Gehe zu Plugins > Installierte Plugins, klicke auf Deaktivieren oder Löschen. Tipp: Deaktiviere vor Updates, um Konflikte zu vermeiden! Alles klar? 🌟', 'wp-multi-toolkit'), + esc_html($user_name) + ); + $responses['wo finde ich die dokumentation'] = sprintf( + __('Dokumentation, %s? 📚 Unter WP-Multi Support > Dokumentation findest du Anleitungen und FAQs. Jetzt ansehen. Tipp: Nutze die Suche in der Doku! Bereit? 😊', 'wp-multi-toolkit'), + esc_html($user_name), + admin_url('admin.php?page=wpmt_docs') + ); + $responses['wer entwickelt die plugins'] = sprintf( + __('Wer entwickelt sie, %s? 😊 M_Viper, ein WordPress-Fan! Besuche m-viper.de oder git.viper.ipv64.net. Tipp: Folge M_Viper für News! Cool, oder? 🚀', 'wp-multi-toolkit'), + esc_html($user_name), + 'https://m-viper.de', + 'https://git.viper.ipv64.net/M_Viper' + ); + $responses['kann ich eigene funktionen hinzufügen'] = sprintf( + __('Eigene Funktionen, %s? 🌟 Die Plugins sind Open Source! Schau den Code auf git.viper.ipv64.net an. Ideen? Erstelle ein Ticket mit Verbesserung! Tipp: Teste in einer Staging-Umgebung! Bereit? 😎', 'wp-multi-toolkit'), + esc_html($user_name), + 'https://git.viper.ipv64.net/M_Viper' + ); + + // Neue allgemeine Antworten + $responses['wie richte ich wp multi ein'] = sprintf( + __('WP Multi einrichten, %s? 🚀 Nach der Installation gehe zu WP-Multi Support und aktiviere die Plugins. Folge der Anleitung in der Dokumentation. Tipp: Prüfe, ob deine WordPress-Version aktuell ist! Bereit? 😄', 'wp-multi-toolkit'), + esc_html($user_name), + admin_url('admin.php?page=wpmt_docs') + ); + $responses['was ist wordpress'] = sprintf( + __('WordPress, %s? 📝 Ein kostenloses CMS für Websites, Blogs oder Shops – ohne Programmierkenntnisse! WP Multi Plugins machen es noch besser. Mehr in der Dokumentation. Neugierig? 😊', 'wp-multi-toolkit'), + esc_html($user_name), + admin_url('admin.php?page=wpmt_docs') + ); + $responses['wie sichere ich meine website'] = sprintf( + __('Website sichern, %s? 🛡️ Nutze WP Multi Features wie Brute-Force-Schutz und Anti-Spam unter Sicherheit. Erstelle Backups (z. B. mit UpdraftPlus) und aktiviere die Rechtsklick-Sperre. Mehr in der Dokumentation. Alles sicher? 🚀', 'wp-multi-toolkit'), + esc_html($user_name), + admin_url('admin.php?page=wpmt_docs') + ); + $responses['wie verbessere ich die performance'] = sprintf( + __('Performance boosten, %s? ⚡ Nutze WP Multi Search für schnelle Suchen und Caching-Plugins wie WP Super Cache. Optimiere Bilder und prüfe Ladezeiten unter Benutzer > Benutzer Analytics. Mehr in der Dokumentation. Bereit für Speed? 😎', 'wp-multi-toolkit'), + esc_html($user_name), + admin_url('admin.php?page=wpmt_docs') + ); + $responses['wie kontaktiere ich den support'] = sprintf( + __('Support kontaktieren, %s? 😊 Erstelle ein Ticket unter WP-Multi Support (Ticket erstellen) oder besuche m-viper.de. Tipp: Beschreibe dein Problem genau! Bereit? 🌟', 'wp-multi-toolkit'), + esc_html($user_name), + admin_url('admin.php?page=wp_multi_support'), + 'https://m-viper.de' + ); + $responses['welche plugins sind kompatibel'] = sprintf( + __('Kompatible Plugins, %s? 🌟 WP Multi Plugins passen zu den meisten WordPress-Plugins, wenn sie die Standards einhalten. Teste in einer Staging-Umgebung. Probleme? Schau in die Dokumentation oder erstelle ein Support-Ticket! Alles klar? 😄', 'wp-multi-toolkit'), + esc_html($user_name), + admin_url('admin.php?page=wpmt_docs'), + admin_url('admin.php?page=wp_multi_support') + ); + $responses['wie teste ich ein plugin'] = sprintf( + __('Plugin testen, %s? 😊 Installiere es in einer Staging-Umgebung oder lokal. Aktiviere es, teste Funktionen und prüfe Kompatibilität. Probleme? Schau in die Dokumentation oder kontaktiere den Support. Tipp: Deaktiviere andere Plugins, um Konflikte zu finden! Bereit? 🚀', 'wp-multi-toolkit'), + esc_html($user_name), + admin_url('admin.php?page=wpmt_docs'), + admin_url('admin.php?page=wp_multi_support') + ); + + return $responses; +}); + +/** + * Sicherstellen, dass jQuery geladen wird + */ +function wpmt_enqueue_scripts() { + wp_enqueue_script('jquery'); +} +add_action('admin_enqueue_scripts', 'wpmt_enqueue_scripts'); + + +/* + * Schnellzugriff-Menü (Floating Toolbar) + */ + + + function wpmt_add_floating_toolbar() { + if (!current_user_can('manage_options') || !is_admin()) { + return; + } + ?> +
+ + +
+ + 'wpmt_sanitize_settings' + )); + add_settings_section('wpmt_main_section', __('WP Multi Einstellungen', 'wp-multi-toolkit'), null, 'wpmt_settings'); + add_settings_field('wpmt_enable_multi', __('Multi-Funktion aktivieren', 'wp-multi-toolkit'), 'wpmt_enable_multi_callback', 'wpmt_settings', 'wpmt_main_section'); +} +add_action('admin_init', 'wpmt_register_settings'); + +function wpmt_sanitize_settings($input) { + $new_input = array(); + $new_input['enable_multi'] = isset($input['enable_multi']) ? 1 : 0; + return $new_input; +} + +function wpmt_enable_multi_callback() { + $options = get_option('wpmt_multi_settings', array('enable_multi' => 0)); + echo ''; +} + +// Shortcode für Multi-Funktionalität +function wpmt_multi_shortcode($atts) { + $options = get_option('wpmt_multi_settings', array('enable_multi' => 0)); + if ($options['enable_multi']) { + return '

' . __('Multi-Funktion ist aktiviert!', 'wp-multi-toolkit') . '

'; + } + return '

' . __('Multi-Funktion ist deaktiviert.', 'wp-multi-toolkit') . '

'; +} +add_shortcode('wpmt_multi', 'wpmt_multi_shortcode'); + +// ### Automatisierte Plugin-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'; + + $installed_plugins = get_plugins(); + $wp_multi_plugins = array( + 'wp-multi-toolkit' => array( + 'file' => 'wp-multi-toolkit/wp-multi-toolkit.php', + 'name' => 'WP Multi Toolkit', + 'description' => __('Zentrales Toolkit für die WP Multi Plugin-Reihe mit Update-Management und Support-Funktionen.', 'wp-multi-toolkit'), + 'repo' => 'wp-multi-toolkit' + ), + 'wp-multi' => array( + 'file' => 'WP-Multi/wp-multi.php', + 'name' => 'WP Multi', + 'description' => __('Hauptplugin für Multi-Funktionen mit Shortcode-Unterstützung.', 'wp-multi-toolkit'), + 'repo' => 'wp-multi' + ), + 'wp-multi-search' => array( + 'file' => 'wp-multi-search/wp-multi-search.php', + 'name' => 'WP Multi Search', + 'description' => __('Erweiterte Suchfunktionen für WordPress.', 'wp-multi-toolkit'), + 'repo' => 'WP-Multi-Search' + ), + 'wp-multi-comment-notifications' => array( + 'file' => 'wp-multi-comment-notifications/wp-multi-comment-notifications.php', + 'name' => 'WP Multi Comment Notifications', + 'description' => __('Automatische Benachrichtigungen für neue Kommentare.', 'wp-multi-toolkit'), + 'repo' => 'wp-multi-comment-notifications' + ), + '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', + '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' + ) + ); + + wpmt_admin_page_open( + __('Plugin-Dokumentation', 'wp-multi-toolkit'), + __('Übersicht aller WP Multi Plugins, Versionen und Update-Status', 'wp-multi-toolkit') + ); + + foreach ($wp_multi_plugins as $key => $plugin) { + wpmt_admin_card_open($plugin['name']); + + $is_installed = array_key_exists($plugin['file'], $installed_plugins); + if ($is_installed) { + $plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin['file']); + $is_active = is_plugin_active($plugin['file']); + $installed_version = $plugin_data['Version']; + $latest_version = wpmt_get_latest_plugin_version($plugin['repo']); + $update_available = $latest_version && version_compare($latest_version, $installed_version, '>'); + ?> +

+ : + +

+

+ : + + + + +

+

:

+

:

+ +

:

+ + +

+ : + +

+

:

+

+ $widget) + $wp_meta_boxes['dashboard']['normal']['high']; + } +} +add_action('wp_dashboard_setup', 'wpmt_update_dashboard_widget', 1); +add_action('wp_dashboard_setup', 'wpmt_force_widget_position', 999); + +// Widget nicht ausblendbar machen +function wpmt_prevent_widget_hiding($widgets) { + $widgets['wpmt_update_widget'] = array( + 'id' => 'wpmt_update_widget', + 'title' => __('Verfügbare Updates für WP Multi Toolkit', 'wp-multi-toolkit'), + 'callback' => 'wpmt_update_dashboard_widget_content' + ); + return $widgets; +} +add_filter('dashboard_available_widgets', 'wpmt_prevent_widget_hiding'); + +// Benutzerdefiniertes Cron-Intervall hinzufügen +add_filter('cron_schedules', function ($schedules) { + $schedules['hourly'] = array( + 'interval' => 3600, + 'display' => __('Stündlich', 'wp-multi-toolkit'), + ); + return $schedules; +}); + +// Cron-Job registrieren +function wpmt_update_schedule_check() { + if (!wp_next_scheduled('wpmt_update_check_event')) { + wp_schedule_event(time(), 'hourly', 'wpmt_update_check_event'); + } +} +add_action('wp', 'wpmt_update_schedule_check'); + +// Hilfsfunktion zur Wiederverwendung der Gitea-API-Abfrage +function wpmt_fetch_latest_release($repo, $show_prereleases = false) { + $api_url = "https://git.viper.ipv64.net/api/v1/repos/M_Viper/{$repo}/releases"; + $response = wp_remote_get($api_url, array('timeout' => 10)); + + if (is_wp_error($response)) { + error_log("WP Multi Toolkit Update Fehler für {$repo}: " . $response->get_error_message()); + return false; + } + + $body = wp_remote_retrieve_body($response); + $data = json_decode($body, true); + + if (!is_array($data)) { + error_log("WP Multi Toolkit Update für {$repo}: Ungültige API-Antwort"); + return false; + } + + foreach ($data as $release) { + if (!$show_prereleases && isset($release['prerelease']) && $release['prerelease']) { + continue; + } + if (!empty($release['tag_name'])) { + return $release; + } + } + return null; +} + +// Cron-Job für Update-Überprüfung +function wpmt_update_check() { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + + $show_prereleases = get_option('wpmt_update_show_prereleases', false); + $installed_plugins = get_plugins(); + $plugins_to_check = array( + 'wp-multi-toolkit' => 'wp-multi-toolkit/wp-multi-toolkit.php', + 'wp-multi' => 'WP-Multi/wp-multi.php', + 'WP-Multi-Search' => 'wp-multi-search/wp-multi-search.php', + 'wp-multi-comment-notifications' => 'wp-multi-comment-notifications/wp-multi-comment-notifications.php' + ); + + foreach ($plugins_to_check as $repo => $file) { + if (array_key_exists($file, $installed_plugins) && is_plugin_active($file)) { + $plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $file); + $installed_version = $plugin_data['Version']; + $valid_release = wpmt_fetch_latest_release($repo, $show_prereleases); + + if ($valid_release) { + $latest_version = $valid_release['tag_name']; + $release_notes = $valid_release['body'] ?? ''; + $is_prerelease = isset($valid_release['prerelease']) && $valid_release['prerelease']; + + update_option("wpmt_update_latest_version_{$repo}", $latest_version); + update_option("wpmt_update_release_notes_{$repo}", $release_notes); + update_option("wpmt_update_is_prerelease_{$repo}", $is_prerelease); + } + } + } +} +add_action('wpmt_update_check_event', 'wpmt_update_check'); + +// Funktion zur Überprüfung des Update-Server-Status +function wpmt_check_update_server_status() { + $update_server_url = 'https://git.viper.ipv64.net'; + $response = wp_remote_head($update_server_url, array('timeout' => 5)); + return !is_wp_error($response) && wp_remote_retrieve_response_code($response) == 200; +} + +// Callback-Funktion für das Widget +function wpmt_update_dashboard_widget_content() { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + + $installed_plugins = get_plugins(); + $show_prereleases = get_option('wpmt_update_show_prereleases', false); + + // Update-Server-Status nur bei Offline anzeigen + $server_online = wpmt_check_update_server_status(); + if (!$server_online) { + echo '

🔴 ' . __('Update Server offline', 'wp-multi-toolkit') . '

'; + echo '
'; + } + + $plugins_to_check = array( + 'wp-multi-toolkit' => array( + 'file' => 'wp-multi-toolkit/wp-multi-toolkit.php', + 'name' => 'WP Multi Toolkit', + 'repo' => 'wp-multi-toolkit' + ), + 'wp-multi' => array( + 'file' => 'WP-Multi/wp-multi.php', + 'name' => 'WP Multi', + 'repo' => 'wp-multi' + ), + 'WP-Multi-Search' => array( + 'file' => 'wp-multi-search/wp-multi-search.php', + 'name' => 'WP Multi Search', + 'repo' => 'WP-Multi-Search' + ), + 'wp-multi-comment-notifications' => array( + 'file' => 'wp-multi-comment-notifications/wp-multi-comment-notifications.php', + 'name' => 'WP Multi Comment Notifications', + 'repo' => 'wp-multi-comment-notifications' + ), + 'wp-multi-kategorie' => array( + 'file' => 'wp-multi-kategorie/wp-multi-kategorie.php', + 'name' => 'WP Multi Kategorie', + 'repo' => 'wp-multi-kategorie' + ) + ); + + $has_active_plugins = false; + foreach ($plugins_to_check as $key => $plugin) { + $is_installed = array_key_exists($plugin['file'], $installed_plugins); + $is_active = $is_installed && is_plugin_active($plugin['file']); + + if ($is_installed && $is_active) { + $has_active_plugins = true; + $plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin['file']); + $installed_version = $plugin_data['Version']; + $valid_release = wpmt_fetch_latest_release($plugin['repo'], $show_prereleases); + + echo '

' . esc_html($plugin['name']) . '

'; + if ($valid_release === false) { + printf('

%s

', esc_html__('Fehler beim Abrufen der Versionsinformationen.', 'wp-multi-toolkit')); + } elseif ($valid_release) { + $latest_version = $valid_release['tag_name']; + $release_notes = $valid_release['body'] ?? ''; + $is_prerelease = isset($valid_release['prerelease']) && $valid_release['prerelease']; + + if (version_compare($installed_version, $latest_version, '>=')) { + printf( + '

%s

', + sprintf( + __('Ihre Version ist aktuell. Version %s ist die neueste Version.', 'wp-multi-toolkit'), + esc_html($installed_version) + ) + ); + } else { + printf( + '

%s

', + sprintf( + __('Es ist eine neue Version von %s verfügbar! Version %s ist jetzt verfügbar.', 'wp-multi-toolkit'), + esc_html($plugin['name']), + esc_html($latest_version) + ) + ); + printf( + '

%s: %s

', + __('Aktuell installierte Version', 'wp-multi-toolkit'), + esc_html($installed_version) + ); + printf( + '

%s: %s

', + __('Neue Version auf Gitea', 'wp-multi-toolkit'), + esc_html($latest_version) + ); + + if ($is_prerelease && $show_prereleases) { + printf('

%s

', __('Dieses Update ist ein PreRelease.', 'wp-multi-toolkit')); + } + + if (!empty($release_notes)) { + printf( + '

%s:

%s

', + __('Information zum Update', 'wp-multi-toolkit'), + nl2br(esc_html($release_notes)) + ); + } + + $button_text = $is_prerelease ? __('PreRelease herunterladen', 'wp-multi-toolkit') : __('Update herunterladen', 'wp-multi-toolkit'); + $download_url = $valid_release['assets'][0]['browser_download_url'] ?? '#'; + printf( + '

%s

', + esc_url($download_url), + esc_html($button_text) + ); + } + } else { + printf('

%s

', esc_html__('Keine Versionsinformationen gefunden.', 'wp-multi-toolkit')); + } + } + } + + if (!$has_active_plugins) { + echo '

' . __('Keine aktiven WP Multi Plugins gefunden.', 'wp-multi-toolkit') . '

'; + } + + // Optionale Plugins + $optional_plugins = array( + 'wp-multi-toolkit' => array( + 'file' => 'wp-multi-toolkit/wp-multi-toolkit.php', + 'download_url' => 'https://git.viper.ipv64.net/M_Viper/wp-multi-toolkit/releases', + 'description' => __('Kern-Toolkit für WP Multi Plugins.', 'wp-multi-toolkit') + ), + 'wp-multi' => array( + 'file' => 'WP-Multi/wp-multi.php', + 'download_url' => 'https://git.viper.ipv64.net/M_Viper/wp-multi/releases', + 'description' => __('Hauptplugin für WP Multi Funktionen.', 'wp-multi-toolkit') + ), + 'WP-Multi-Search' => array( + 'file' => 'wp-multi-search/wp-multi-search.php', + 'download_url' => 'https://git.viper.ipv64.net/M_Viper/WP-Multi-Search/releases', + 'description' => __('Erweiterte Suchfunktionen.', 'wp-multi-toolkit') + ), + 'wp-multi-comment-notifications' => array( + 'file' => 'wp-multi-comment-notifications/wp-multi-comment-notifications.php', + 'download_url' => 'https://git.viper.ipv64.net/M_Viper/wp-multi-comment-notifications/releases', + 'description' => __('Kommentar-Benachrichtigungen.', 'wp-multi-toolkit') + ), + 'wp-multi-kategorie' => array( + 'file' => 'wp-multi-kategorie/wp-multi-kategorie.php', + 'download_url' => 'https://git.viper.ipv64.net/M_Viper/wp-multi-kategorie/releases', + 'description' => __('Erweiterte Kategorie-Funktionen für WP Multi.', 'wp-multi-toolkit') + ) + ); + + echo '

' . __('Optionale Plugins', 'wp-multi-toolkit') . '

'; + echo ''; + echo ''; + + foreach ($optional_plugins as $key => $plugin) { + $is_installed = array_key_exists($plugin['file'], $installed_plugins); + $is_active = $is_installed && is_plugin_active($plugin['file']); + + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + } + echo '
' . __('Plugin', 'wp-multi-toolkit') . '' . __('Beschreibung', 'wp-multi-toolkit') . '' . __('Status', 'wp-multi-toolkit') . '' . __('Aktion', 'wp-multi-toolkit') . '
' . esc_html($plugins_to_check[$key]['name']) . '' . esc_html($plugin['description']) . ''; + if ($is_active) { + echo '' . __('Aktiv', 'wp-multi-toolkit') . ''; + } elseif ($is_installed) { + echo '' . __('Inaktiv', 'wp-multi-toolkit') . ''; + } else { + echo '' . __('Nicht installiert', 'wp-multi-toolkit') . ''; + } + echo ''; + if ($is_active) { + echo '—'; + } elseif ($is_installed) { + echo '' . __('Aktivieren', 'wp-multi-toolkit') . ''; + } else { + echo '' . __('Herunterladen', 'wp-multi-toolkit') . ''; + } + echo '
'; +} + +// Update-Einstellungen +function wpmt_update_general_settings() { + add_settings_section( + 'wpmt_update_section', + __('WP Multi Toolkit Update Einstellungen', 'wp-multi-toolkit'), + null, + 'general' + ); + + add_settings_field( + 'wpmt_update_show_prereleases', + __('Pre-Releases anzeigen', 'wp-multi-toolkit'), + 'wpmt_update_show_prereleases_callback', + 'general', + 'wpmt_update_section' + ); + + register_setting('general', 'wpmt_update_show_prereleases', array( + 'type' => 'boolean', + 'description' => __('Aktivieren, um Pre-Releases im Dashboard und in den Versionsinformationen anzuzeigen.', 'wp-multi-toolkit'), + 'default' => 0, + )); +} +add_action('admin_init', 'wpmt_update_general_settings'); + +// Callback-Funktion für das Anzeigen der Checkbox +function wpmt_update_show_prereleases_callback() { + $checked = get_option('wpmt_update_show_prereleases', false); + echo ''; + echo '

' . __('Achtung: Pre-Releases sind Beta-Versionen und können Fehler enthalten. Verwenden Sie sie nur, wenn Sie Fehlerberichterstattung oder Tests durchführen möchten.', 'wp-multi-toolkit') . '

'; +} + +// Deinstallation +function wpmt_uninstall() { + $repos = array('wp-multi-toolkit', 'wp-multi', 'WP-Multi-Search', 'wp-multi-comment-notifications'); + foreach ($repos as $repo) { + delete_option("wpmt_update_latest_version_{$repo}"); + delete_option("wpmt_update_release_notes_{$repo}"); + delete_option("wpmt_update_is_prerelease_{$repo}"); + } + delete_option('wpmt_update_show_prereleases'); + delete_option('wpmt_multi_settings'); + wp_clear_scheduled_hook('wpmt_update_check_event'); + wp_clear_scheduled_hook('wpmt_pub_missed_posts_event'); +} +// Hinweis: register_uninstall_hook() erlaubt pro Plugin-Datei nur EINEN registrierten +// Callback (ein zweiter Aufruf würde den ersten überschreiben). Deshalb wird +// wpmt_uninstall() aus wp_multi_toolkit_uninstall() heraus aufgerufen statt hier +// separat registriert. + + +/* + * Ban Funktion + */ + + +// Der Ban-System-Menüpunkt wird zentral in wpmt_register_admin_menus() registriert. + +// WP Multi Ban Functions + +### Function: Get IP Address +function wp_multi_ban_get_ip() { + $banned_options = get_option('wp_multi_ban_options', array('reverse_proxy' => 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'); + } + + check_ajax_referer('wp_multi_ban_preview'); + + $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, true)) { + 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(); + + if (!empty($_POST['banned_ips'])) { + foreach (explode("\n", trim($_POST['banned_ips'])) as $banned_ip) { + $banned_ip = trim($banned_ip); + // Schützt die IP des aktuell handelnden Admins vor versehentlichem Aussperren - + // unabhängig vom Benutzernamen (vorher nur für den Benutzernamen "admin" wirksam). + if ($banned_ip === $admin_ip) { + $text .= '
Diese IP \'' . esc_html($banned_ip) . '\' ist deine eigene 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 && wp_multi_ban_check_ip_within_range($admin_ip, trim($range[0]), trim($range[1]))) { + $text .= '
Deine eigene 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); + ?> + + + +
+ +
+ +
+
+

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() { + // Räumt zusätzlich die Update-Management-Optionen auf (siehe Hinweis bei wpmt_uninstall()). + wpmt_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