prefix . 'aksrt_user_restriction'; } /** * Add a restriction to a user. */ public function restrict(int $user_id, string $type, string $reason, string $scope = self::SCOPE_GLOBAL, string $expires_at = '', int $created_by = 0): array { global $wpdb; if (!in_array($type, self::TYPES, true)) { return ['success' => false, 'message' => 'Invalid restriction type.']; } if (!in_array($scope, self::SCOPES, true)) { return ['success' => false, 'message' => 'Invalid scope.']; } if ($created_by <= 0) { $created_by = get_current_user_id(); } $data = [ 'user_id' => $user_id, 'type' => $type, 'reason' => sanitize_textarea_field($reason), 'scope' => $scope, 'expires_at' => $expires_at ? gmdate('Y-m-d H:i:s', strtotime($expires_at)) : null, 'created_by' => $created_by, 'created_at' => current_time('mysql', true), ]; $result = $wpdb->insert($this->table(), $data); if ($result === false) { return ['success' => false, 'message' => 'Database error.']; } // Update user meta for quick lookup $this->sync_user_restriction_meta($user_id); return ['success' => true, 'id' => $wpdb->insert_id]; } /** * Remove a restriction by ID. */ public function remove_restriction(int $restriction_id): bool { global $wpdb; $restriction = $this->get_restriction($restriction_id); if (!$restriction) return false; $result = $wpdb->delete($this->table(), ['id' => $restriction_id]); if ($result) { $this->sync_user_restriction_meta((int) $restriction['user_id']); } return (bool) $result; } /** * Get a single restriction by ID. */ public function get_restriction(int $restriction_id): ?array { global $wpdb; $row = $wpdb->get_row($wpdb->prepare( "SELECT * FROM {$this->table()} WHERE id = %d", $restriction_id ), ARRAY_A); return $row ?: null; } /** * Get all active restrictions for a user. */ public function get_user_restrictions(int $user_id, bool $active_only = true): array { global $wpdb; $now = current_time('mysql', true); if ($active_only) { $rows = $wpdb->get_results($wpdb->prepare( "SELECT * FROM {$this->table()} WHERE user_id = %d AND (expires_at IS NULL OR expires_at > %s) ORDER BY created_at DESC", $user_id, $now ), ARRAY_A); } else { $rows = $wpdb->get_results($wpdb->prepare( "SELECT * FROM {$this->table()} WHERE user_id = %d ORDER BY created_at DESC", $user_id ), ARRAY_A); } return $rows ?: []; } /** * Check if a user has an active restriction of a given type and scope. */ public function is_restricted(int $user_id, string $type = '', string $scope = ''): bool { $restrictions = $this->get_user_restrictions($user_id, true); foreach ($restrictions as $r) { if ($type && $r['type'] !== $type) continue; if ($scope && $r['scope'] !== $scope && $r['scope'] !== self::SCOPE_GLOBAL) continue; return true; } return false; } /** * Check if a user is banned (global). */ public function is_banned(int $user_id): bool { return $this->is_restricted($user_id, self::TYPE_BAN, self::SCOPE_GLOBAL); } /** * Get the active ban restriction for a user (if any). */ public function get_active_ban(int $user_id): ?array { $restrictions = $this->get_user_restrictions($user_id, true); foreach ($restrictions as $r) { if ($r['type'] === self::TYPE_BAN && $r['scope'] === self::SCOPE_GLOBAL) { return $r; } } return null; } /** * Enforce ban on login. */ public function enforce_login_ban($user, string $username, string $password) { if (is_wp_error($user) || !$user instanceof \WP_User) { return $user; } if ($this->is_banned($user->ID)) { $ban = $this->get_active_ban($user->ID); $message = '您的账号已被封禁。'; if (!empty($ban['reason'])) { $message .= '原因:' . $ban['reason']; } return new \WP_Error('user_banned', $message); } return $user; } /** * Enforce comment mute. */ public function enforce_comment_mute($post_id) { $user_id = get_current_user_id(); if ($user_id > 0 && $this->is_restricted($user_id, self::TYPE_MUTE, self::SCOPE_COMMENT)) { wp_die('您已被限制评论。', '评论限制', ['response' => 403]); } return $post_id; } /** * Sync restriction meta for quick lookup. */ private function sync_user_restriction_meta(int $user_id): void { $active = $this->get_user_restrictions($user_id, true); $types = array_unique(array_column($active, 'type')); update_user_meta($user_id, '_aksrt_active_restrictions', $types); update_user_meta($user_id, '_aksrt_is_banned', in_array(self::TYPE_BAN, $types, true) ? 1 : 0); } /** * Get restriction stats for admin overview. */ public function get_stats(): array { global $wpdb; $now = current_time('mysql', true); $table = $this->table(); $total = (int) $wpdb->get_var("SELECT COUNT(*) FROM {$table}"); $active = (int) $wpdb->get_var($wpdb->prepare( "SELECT COUNT(*) FROM {$table} WHERE expires_at IS NULL OR expires_at > %s", $now )); $banned = (int) $wpdb->get_var($wpdb->prepare( "SELECT COUNT(*) FROM {$table} WHERE type = %s AND (expires_at IS NULL OR expires_at > %s)", self::TYPE_BAN, $now )); return ['total' => $total, 'active' => $active, 'banned' => $banned]; } }