refactor(classes): organize inc/classes into domain folders
Move ~94 root class shells and root *-traits into domain directories (core, auth, user, credits, content, payment/gateways, forum, shop, sms, ai, messages, extensions, widgets, settings, admin). Update bootstrap require paths, co-locate traits with owners, fix forum/user relative requires, drop duplicate shop controller requires, and wire home-modules load. Path-only; class names and init order unchanged.
This commit is contained in:
1 parent
2a8fe68048
commit
ce1c13b947
115 files changed
+171
-224
No files matched your search
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
trait AKSRT_Moderation_Part_2 {
|
||||
|
||||
|
||||
private function normalize_text(string $text): string {
|
||||
$text = preg_replace('/[\x{200B}-\x{200D}\x{FEFF}]/u', '', $text);
|
||||
$text = preg_replace('/\s+/u', '', (string) $text);
|
||||
if (function_exists('mb_strtolower')) {
|
||||
return mb_strtolower((string) $text, 'UTF-8');
|
||||
}
|
||||
return strtolower((string) $text);
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 4. Rate limit
|
||||
// ============================================================
|
||||
|
||||
private function check_rate_limit(array $data, array $config, string $ip) {
|
||||
if (empty($config['rate_limit_enabled'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$min_interval = max(1, (int) ($config['rate_limit_min_interval'] ?? 8));
|
||||
$max_per_hour = max(1, (int) ($config['rate_limit_max_per_hour'] ?? 15));
|
||||
$prefix = 'aksrt_rate_';
|
||||
|
||||
$last_key = $prefix . md5($ip . '_last');
|
||||
$hour_key = $prefix . md5($ip . '_hourly');
|
||||
$exp_key = '_' . $prefix . md5($ip . '_hourly_expiry');
|
||||
|
||||
$last_comment_time = get_transient($last_key);
|
||||
if ($last_comment_time !== false) {
|
||||
$elapsed = time() - (int) $last_comment_time;
|
||||
if ($elapsed < $min_interval) {
|
||||
$wait_time = $min_interval - $elapsed;
|
||||
return sprintf(__('You are commenting too fast. Please wait %d seconds.', 'aksrt'), $wait_time);
|
||||
}
|
||||
}
|
||||
|
||||
$hourly_count = get_transient($hour_key);
|
||||
if ($hourly_count !== false && (int) $hourly_count >= $max_per_hour) {
|
||||
$reset_time = (int) (get_transient($exp_key) ?: time());
|
||||
$remaining = max(0, $reset_time - time());
|
||||
$minutes = (int) ceil($remaining / 60);
|
||||
return sprintf(__('You have reached the hourly comment limit. Try again in %d minutes.', 'aksrt'), $minutes);
|
||||
}
|
||||
|
||||
if ($hourly_count === false) {
|
||||
set_transient($hour_key, 1, HOUR_IN_SECONDS);
|
||||
set_transient($exp_key, time() + HOUR_IN_SECONDS, HOUR_IN_SECONDS);
|
||||
} else {
|
||||
set_transient($hour_key, ((int) $hourly_count) + 1, HOUR_IN_SECONDS);
|
||||
}
|
||||
set_transient($last_key, time(), $min_interval);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 5. GeoIP
|
||||
// ============================================================
|
||||
|
||||
private function check_geoip(array $config, string $ip) {
|
||||
if (empty($config['geoip_enabled'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$block_countries = $config['geoip_block_countries'] ?? [];
|
||||
if (!is_array($block_countries) || empty($block_countries)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$country_code = $this->lookup_geoip($ip, $config);
|
||||
if ($country_code === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$country_code = strtoupper($country_code);
|
||||
$block_upper = array_map('strtoupper', $block_countries);
|
||||
if (in_array($country_code, $block_upper, true)) {
|
||||
return sprintf(__('Comments from your region (%s) are currently blocked.', 'aksrt'), esc_html($country_code));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private function lookup_geoip(string $ip, array $config): ?string {
|
||||
// 优先复用 IP 归属地模块的查询能力(含缓存)
|
||||
if (class_exists('AKSRT_IP_Geo')) {
|
||||
$result = AKSRT_IP_Geo::get_instance()->lookup($ip);
|
||||
if (!empty($result['country'])) {
|
||||
return $result['country'];
|
||||
}
|
||||
}
|
||||
|
||||
// 回退到内置查询
|
||||
$ip_geo_config = class_exists('AKSRT_Settings')
|
||||
? AKSRT_Settings::get_ip_geo_settings()
|
||||
: [];
|
||||
$provider = (string) ($ip_geo_config['ip_geo_provider'] ?? $config['geoip_provider'] ?? 'ip-api.com');
|
||||
$api_key = (string) ($ip_geo_config['ip_geo_api_key'] ?? $config['geoip_api_key'] ?? '');
|
||||
|
||||
if ($provider === 'ipinfo' || $provider === 'ipinfo.io') {
|
||||
return $this->geoip_ipinfo($ip, $api_key);
|
||||
}
|
||||
return $this->geoip_ipapi($ip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Free ip-api.com endpoint.
|
||||
*/
|
||||
private function geoip_ipapi(string $ip): ?string {
|
||||
$url = 'http://ip-api.com/json/' . urlencode($ip) . '?fields=status,countryCode,message';
|
||||
$response = wp_remote_get($url, [
|
||||
'timeout' => 5,
|
||||
'headers' => ['Accept' => 'application/json'],
|
||||
]);
|
||||
|
||||
if (is_wp_error($response)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$body = json_decode((string) wp_remote_retrieve_body($response), true);
|
||||
if (($body['status'] ?? '') === 'success') {
|
||||
return $body['countryCode'] ?? null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private function geoip_ipinfo(string $ip, string $api_key): ?string {
|
||||
$url = 'https://ipinfo.io/' . urlencode($ip) . '/json?token=' . urlencode($api_key ?: '');
|
||||
$response = wp_remote_get($url, [
|
||||
'timeout' => 5,
|
||||
'headers' => ['Accept' => 'application/json'],
|
||||
]);
|
||||
|
||||
if (is_wp_error($response)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$body = json_decode((string) wp_remote_retrieve_body($response), true);
|
||||
return $body['country'] ?? null;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Utilities
|
||||
// ============================================================
|
||||
|
||||
private function get_client_ip(): string {
|
||||
$keys = ['HTTP_X_FORWARDED_FOR', 'HTTP_X_REAL_IP', 'HTTP_CLIENT_IP'];
|
||||
foreach ($keys as $key) {
|
||||
if (!empty($_SERVER[$key])) {
|
||||
$parts = explode(',', (string) $_SERVER[$key]);
|
||||
$ip = trim($parts[0]);
|
||||
if (filter_var($ip, FILTER_VALIDATE_IP)) {
|
||||
return $ip;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user