Update from Git Manager GUI

This commit is contained in:
2026-03-22 00:40:18 +01:00
parent ead2f3a62a
commit 65d2371239
5 changed files with 1912 additions and 173 deletions

View File

@@ -279,6 +279,18 @@ class WBF_DB {
) $charset;";
dbDelta( $sql_bookmarks );
// ── Ignore-Liste ──────────────────────────────────────────────────────
$sql_ignore = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}forum_ignore_list (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
user_id BIGINT UNSIGNED NOT NULL,
ignored_id BIGINT UNSIGNED NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY user_ignored (user_id, ignored_id),
KEY ignored_id (ignored_id)
) $charset;";
dbDelta( $sql_ignore );
// ── prefix_id zu threads ──────────────────────────────────────────────
self::maybe_add_column( "{$wpdb->prefix}forum_threads", 'prefix_id',
"ALTER TABLE {$wpdb->prefix}forum_threads ADD COLUMN prefix_id BIGINT UNSIGNED DEFAULT NULL" );
@@ -623,7 +635,8 @@ class WBF_DB {
FROM {$wpdb->prefix}forum_threads t
JOIN {$wpdb->prefix}forum_users u ON u.id = t.user_id
JOIN {$wpdb->prefix}forum_categories c ON c.id = t.category_id
AND t.status != 'archived' ORDER BY t.created_at DESC LIMIT %d", $limit
WHERE t.status != 'archived' AND t.deleted_at IS NULL
ORDER BY t.created_at DESC LIMIT %d", $limit
));
}
@@ -1207,13 +1220,18 @@ class WBF_DB {
global $wpdb;
$token = bin2hex( random_bytes(32) );
$hash = hash( 'sha256', $token );
// Alte Tokens löschen
$wpdb->delete( "{$wpdb->prefix}forum_users", [] ); // nur placeholder
// Altes Token dieses Users zurücksetzen bevor ein neues gesetzt wird
$wpdb->query( $wpdb->prepare(
"UPDATE {$wpdb->prefix}forum_users
SET reset_token=NULL, reset_token_expires=NULL
WHERE id=%d",
(int) $user_id
) );
$wpdb->query( $wpdb->prepare(
"UPDATE {$wpdb->prefix}forum_users
SET reset_token=%s, reset_token_expires=DATE_ADD(NOW(), INTERVAL 1 HOUR)
WHERE id=%d",
$hash, $user_id
$hash, (int) $user_id
) );
return $token; // Klartext-Token → per E-Mail senden
}
@@ -1689,6 +1707,128 @@ class WBF_DB {
));
}
// ── Ignore-Liste ──────────────────────────────────────────────────────────
public static function toggle_ignore( $user_id, $ignored_id ) {
global $wpdb;
$user_id = (int) $user_id;
$ignored_id = (int) $ignored_id;
if ( self::is_ignored( $user_id, $ignored_id ) ) {
$wpdb->delete( "{$wpdb->prefix}forum_ignore_list", [
'user_id' => $user_id,
'ignored_id' => $ignored_id,
] );
return false;
}
$wpdb->replace( "{$wpdb->prefix}forum_ignore_list", [
'user_id' => $user_id,
'ignored_id' => $ignored_id,
] );
return true;
}
public static function is_ignored( $user_id, $ignored_id ) {
global $wpdb;
$table = "{$wpdb->prefix}forum_ignore_list";
if ( $wpdb->get_var( "SHOW TABLES LIKE '$table'" ) !== $table ) return false;
return (bool) $wpdb->get_var( $wpdb->prepare(
"SELECT id FROM {$wpdb->prefix}forum_ignore_list WHERE user_id=%d AND ignored_id=%d",
(int) $user_id, (int) $ignored_id
) );
}
/** Gibt alle ignorierten User-IDs als int-Array zurück */
public static function get_ignored_ids( $user_id ) {
global $wpdb;
$table = "{$wpdb->prefix}forum_ignore_list";
if ( $wpdb->get_var( "SHOW TABLES LIKE '$table'" ) !== $table ) return [];
$ids = $wpdb->get_col( $wpdb->prepare(
"SELECT ignored_id FROM {$wpdb->prefix}forum_ignore_list WHERE user_id=%d",
(int) $user_id
) );
return array_map( 'intval', $ids );
}
/** Vollständige Ignore-Liste mit User-Daten */
public static function get_ignore_list( $user_id ) {
global $wpdb;
$table = "{$wpdb->prefix}forum_ignore_list";
if ( $wpdb->get_var( "SHOW TABLES LIKE '$table'" ) !== $table ) return [];
return $wpdb->get_results( $wpdb->prepare(
"SELECT u.id, u.username, u.display_name, u.avatar_url, u.role,
il.created_at AS ignored_since
FROM {$wpdb->prefix}forum_ignore_list il
JOIN {$wpdb->prefix}forum_users u ON u.id = il.ignored_id
WHERE il.user_id = %d
ORDER BY il.created_at DESC",
(int) $user_id
) );
}
// ── DSGVO Art. 17: Konto vollständig löschen ──────────────────────────────
public static function delete_user_gdpr( $user_id ) {
global $wpdb;
$user_id = (int) $user_id;
$user = self::get_user( $user_id );
if ( ! $user ) return false;
if ( $user->role === 'superadmin' ) return false;
$wpdb->delete( "{$wpdb->prefix}forum_messages", [ 'from_id' => $user_id ] );
$wpdb->delete( "{$wpdb->prefix}forum_messages", [ 'to_id' => $user_id ] );
$wpdb->delete( "{$wpdb->prefix}forum_remember_tokens", [ 'user_id' => $user_id ] );
$wpdb->delete( "{$wpdb->prefix}forum_notifications", [ 'user_id' => $user_id ] );
$wpdb->delete( "{$wpdb->prefix}forum_notifications", [ 'actor_id' => $user_id ] );
$wpdb->delete( "{$wpdb->prefix}forum_subscriptions", [ 'user_id' => $user_id ] );
$table_bm = "{$wpdb->prefix}forum_bookmarks";
if ( $wpdb->get_var( "SHOW TABLES LIKE '$table_bm'" ) === $table_bm ) {
$wpdb->delete( $table_bm, [ 'user_id' => $user_id ] );
}
$wpdb->delete( "{$wpdb->prefix}forum_likes", [ 'user_id' => $user_id ] );
$wpdb->delete( "{$wpdb->prefix}forum_reactions", [ 'user_id' => $user_id ] );
$wpdb->delete( "{$wpdb->prefix}forum_reports", [ 'reporter_id' => $user_id ] );
$table_pv = "{$wpdb->prefix}forum_poll_votes";
if ( $wpdb->get_var( "SHOW TABLES LIKE '$table_pv'" ) === $table_pv ) {
$wpdb->delete( $table_pv, [ 'user_id' => $user_id ] );
}
// Ignore-Liste beidseitig bereinigen
$table_il = "{$wpdb->prefix}forum_ignore_list";
if ( $wpdb->get_var( "SHOW TABLES LIKE '$table_il'" ) === $table_il ) {
$wpdb->delete( $table_il, [ 'user_id' => $user_id ] );
$wpdb->delete( $table_il, [ 'ignored_id' => $user_id ] );
}
delete_transient( 'wbf_flood_' . $user_id );
delete_transient( 'wbf_flood_ts_' . $user_id );
self::delete_user_meta_all( $user_id );
$anon_hash = substr( hash( 'sha256', $user_id . wp_salt() . microtime( true ) ), 0, 12 );
$wpdb->update(
"{$wpdb->prefix}forum_users",
[
'username' => 'deleted_' . $anon_hash,
'email' => 'deleted_' . $anon_hash . '@deleted.invalid',
'password' => '',
'display_name' => 'Gelöschter Nutzer',
'avatar_url' => '',
'bio' => '',
'signature' => '',
'ban_reason' => '',
'reset_token' => null,
'reset_token_expires' => null,
'pre_ban_role' => '',
'ban_until' => null,
'role' => 'banned',
],
[ 'id' => $user_id ]
);
return true;
}
// ── Wortfilter ────────────────────────────────────────────────────────────
public static function get_word_filter() {
@@ -1711,25 +1851,29 @@ class WBF_DB {
// ── Flood Control ─────────────────────────────────────────────────────────
public static function check_flood( $user_id ) {
$user_id = (int) $user_id;
if ( $user_id <= 0 ) return true; // kein eingeloggter User — kein Flood-Check
$interval = (int)( wbf_get_settings()['flood_interval'] ?? 0 );
if ( $interval <= 0 ) return true; // deaktiviert
$key = 'wbf_flood_' . (int)$user_id;
$key = 'wbf_flood_' . (int)$user_id;
$ts_key = 'wbf_flood_ts_' . (int)$user_id;
$last = get_transient( $key );
if ( $last !== false ) {
return false; // noch gesperrt
}
set_transient( $key, time(), $interval );
set_transient( $key, 1, $interval );
set_transient( $ts_key, time(), $interval + 5 );
return true;
}
public static function flood_remaining( $user_id ) {
$interval = (int)( wbf_get_settings()['flood_interval'] ?? 0 );
if ( $interval <= 0 ) return 0;
$key = 'wbf_flood_' . (int)$user_id;
$last = get_transient( $key );
if ( $last === false ) return 0;
// Transients speichern keine genaue Restzeit — wir schätzen über $interval
return $interval;
$ts_key = 'wbf_flood_ts_' . (int)$user_id;
$sent = get_transient( $ts_key );
if ( $sent === false ) return 0;
$remaining = $interval - ( time() - (int)$sent );
return max( 0, $remaining );
}
}