Files
wordpress-theme-aksrt/inc/helpers/comments/geo.php
T
kate522 59f5d5d98a fix(ip-geo): harden full-chain IP geolocation reliability
Capture real client IPs behind CDN, improve provider fallbacks and
negative cache, fix admin credential dependsOn for polling mode, and
map country labels to ISO codes for moderation GeoIP blocks.
2026-07-27 15:39:16 +08:00

142 lines
4.4 KiB
PHP

<?php
/**
* Comment city / IP geo helpers.
*
* Meta: aksrt_comment_addr {country,province,city}
* Gates: ip_geo_enabled + ip_geo_display has comment + comment_city_s
*
* @package AKSRT
*/
defined('ABSPATH') || exit;
if (!function_exists('aksrt_comment_city_enabled')) :
function aksrt_comment_city_enabled(): bool {
if (function_exists('aksrt_ip_geo_display_enabled') && !aksrt_ip_geo_display_enabled('comment')) {
return false;
}
if (!class_exists('\AKSRT\Settings\Settings')) {
return false;
}
$s = \AKSRT\Settings\Settings::get_comment_display_settings();
return !empty($s['city_s']);
}
endif;
if (!function_exists('aksrt_comment_city_type')) :
function aksrt_comment_city_type(): string {
if (!class_exists('\AKSRT\Settings\Settings')) {
return function_exists('aksrt_ip_geo_format_key') ? aksrt_ip_geo_format_key() : 'province_city';
}
$s = \AKSRT\Settings\Settings::get_comment_display_settings();
$type = sanitize_key((string) ($s['city_type'] ?? 'province_city'));
return in_array($type, ['province_city', 'province', 'country_province'], true)
? $type
: 'province_city';
}
endif;
if (!function_exists('aksrt_store_comment_addr')) :
/**
* @param int $comment_id Comment ID.
* @param string|null $ip Optional IP override.
*/
function aksrt_store_comment_addr(int $comment_id, ?string $ip = null): void {
if ($comment_id <= 0 || !aksrt_comment_city_enabled()) {
return;
}
if ($ip === null || $ip === '') {
$comment = get_comment($comment_id);
$ip = $comment instanceof WP_Comment ? (string) $comment->comment_author_IP : '';
}
$ip = trim((string) $ip);
// Private / empty stored IP (CDN edge without proxy headers): resolve live client IP once.
$needs_live = ($ip === '' || $ip === '0.0.0.0');
if (!$needs_live && function_exists('filter_var')) {
$needs_live = !filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE);
}
if ($needs_live && function_exists('aksrt_get_client_ip')) {
$live = trim((string) aksrt_get_client_ip());
if ($live !== '' && $live !== '0.0.0.0'
&& filter_var($live, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)
) {
$ip = $live;
}
}
if ($ip === '') {
return;
}
if (function_exists('aksrt_lookup_geo_for_ip')) {
$addr = aksrt_lookup_geo_for_ip($ip);
} elseif (class_exists('\AKSRT\Extensions\IPGeo')) {
$geo = \AKSRT\Extensions\IPGeo::get_instance()->lookup($ip);
$addr = [
'country' => (string) ($geo['country'] ?? ''),
'province' => (string) ($geo['province'] ?? ''),
'city' => (string) ($geo['city'] ?? ''),
];
} else {
return;
}
if ($addr['country'] === '' && $addr['province'] === '' && $addr['city'] === '') {
return;
}
update_comment_meta($comment_id, 'aksrt_comment_addr', $addr);
}
endif;
if (!function_exists('aksrt_get_comment_addr')) :
/**
* @param int|WP_Comment $comment Comment.
* @return array{country:string,province:string,city:string}
*/
function aksrt_get_comment_addr($comment): array {
$comment_id = $comment instanceof WP_Comment ? (int) $comment->comment_ID : (int) $comment;
if ($comment_id <= 0) {
return ['country' => '', 'province' => '', 'city' => ''];
}
$raw = get_comment_meta($comment_id, 'aksrt_comment_addr', true);
if (function_exists('aksrt_normalize_geo_addr')) {
return aksrt_normalize_geo_addr($raw);
}
return is_array($raw) ? $raw : ['country' => '', 'province' => '', 'city' => ''];
}
endif;
if (!function_exists('aksrt_format_comment_city_label')) :
/**
* @param array<string,string> $addr Addr.
* @param string $type Format.
*/
function aksrt_format_comment_city_label(array $addr, string $type = 'province_city'): string {
if (function_exists('aksrt_format_geo_label')) {
return aksrt_format_geo_label($addr, $type);
}
return '';
}
endif;
if (!function_exists('aksrt_get_comment_city_badge_html')) :
function aksrt_get_comment_city_badge_html($comment): string {
if (!aksrt_comment_city_enabled()) {
return '';
}
if (function_exists('aksrt_get_geo_badge_html')) {
return aksrt_get_geo_badge_html(
aksrt_get_comment_addr($comment),
aksrt_comment_city_type(),
'badg badg-sm comment-city-badge'
);
}
return '';
}
endif;
add_action('comment_post', static function ($comment_id): void {
if (function_exists('aksrt_store_comment_addr')) {
aksrt_store_comment_addr((int) $comment_id);
}
}, 20, 1);