Merge pull request 'refactor(ip-geo): drop dual-read gates; keep single meta and four surfaces' (#299) from worktree-ip-location-display into main

Reviewed-on: CYL/wordpress-theme-aksrt#299
This commit is contained in:
kate522 committed 2026-07-25 15:21:01 +08:00
commit 3ea1be02ed
4 files changed
+87 -177

No files matched your search

+63 -111
View File
@@ -1,11 +1,16 @@
<?php <?php
/** /**
* IP 归属地 — shared storage, format, and display helpers. * IP 归属地 — storage, format, and display (no dual-read / no legacy keys).
*
* Gates:
* master: ip_geo_enabled
* surface: ip_geo_display ∈ {comment, user_home, user_center, post}
* users: user_city_s (+ user_city_type)
* comments: comment_city_s (+ comment_city_type) via comments/geo.php
* *
* Display positions (ip_geo_display): comment | user_home | user_center | post
* Meta: * Meta:
* comment → aksrt_comment_addr (array) * comment → aksrt_comment_addr {country,province,city}
* user → aksrt_user_addr (array), aksrt_register_ip (string) * user → aksrt_user_addr, aksrt_register_ip
* *
* @package AKSRT * @package AKSRT
*/ */
@@ -22,7 +27,7 @@ if (!function_exists('aksrt_get_ip_geo_config')) :
} }
return [ return [
'ip_geo_enabled' => false, 'ip_geo_enabled' => false,
'ip_geo_display' => ['comment'], 'ip_geo_display' => ['comment', 'user_home', 'user_center', 'post'],
'ip_geo_format' => 'province_city', 'ip_geo_format' => 'province_city',
'ip_geo_fallback_text' => '', 'ip_geo_fallback_text' => '',
]; ];
@@ -31,15 +36,34 @@ endif;
if (!function_exists('aksrt_ip_geo_master_enabled')) : if (!function_exists('aksrt_ip_geo_master_enabled')) :
function aksrt_ip_geo_master_enabled(): bool { function aksrt_ip_geo_master_enabled(): bool {
return !empty(aksrt_get_ip_geo_config()['ip_geo_enabled']);
}
endif;
if (!function_exists('aksrt_ip_geo_display_list')) :
/**
* @return list<string>
*/
function aksrt_ip_geo_display_list(): array {
$c = aksrt_get_ip_geo_config(); $c = aksrt_get_ip_geo_config();
return !empty($c['ip_geo_enabled']); $display = $c['ip_geo_display'] ?? [];
if (!is_array($display)) {
$display = [];
}
$allowed = ['comment', 'user_home', 'user_center', 'post'];
$out = [];
foreach ($display as $item) {
$key = sanitize_key((string) $item);
if (in_array($key, $allowed, true) && !in_array($key, $out, true)) {
$out[] = $key;
}
}
return $out;
} }
endif; endif;
if (!function_exists('aksrt_ip_geo_display_enabled')) : if (!function_exists('aksrt_ip_geo_display_enabled')) :
/** /**
* Whether a surface may show IP 归属地 badges.
*
* @param string $location comment|user_home|user_center|post * @param string $location comment|user_home|user_center|post
*/ */
function aksrt_ip_geo_display_enabled(string $location): bool { function aksrt_ip_geo_display_enabled(string $location): bool {
@@ -47,41 +71,19 @@ if (!function_exists('aksrt_ip_geo_display_enabled')) :
return false; return false;
} }
$location = sanitize_key($location); $location = sanitize_key($location);
$c = aksrt_get_ip_geo_config(); if (!in_array($location, aksrt_ip_geo_display_list(), true)) {
$display = $c['ip_geo_display'] ?? []; return false;
if (!is_array($display)) {
$display = [$display];
} }
$display = array_values(array_unique(array_filter(array_map('sanitize_key', $display)))); if (in_array($location, ['user_home', 'user_center'], true) && !aksrt_user_city_enabled()) {
return false;
// Legacy saves only had "comment". When master is on, expand so user/post
// surfaces work without forcing a re-save of the checkbox group.
if ($display === [] || $display === ['comment']) {
$display = ['comment', 'user_home', 'user_center', 'post'];
} }
return true;
// Zibll: user home/center are gated by user_city_s, not a separate surface list.
// Still honour an explicit opt-out if the admin removed them from the list after upgrade.
if (in_array($location, ['user_home', 'user_center'], true)) {
if (!aksrt_user_city_enabled()) {
return false;
}
// If list explicitly includes any user surface, require membership; else allow.
$has_user_keys = (bool) array_intersect($display, ['user_home', 'user_center']);
if ($has_user_keys) {
return in_array($location, $display, true);
}
return true;
}
return in_array($location, $display, true);
} }
endif; endif;
if (!function_exists('aksrt_ip_geo_format_key')) : if (!function_exists('aksrt_ip_geo_format_key')) :
function aksrt_ip_geo_format_key(): string { function aksrt_ip_geo_format_key(): string {
$c = aksrt_get_ip_geo_config(); $format = sanitize_key((string) (aksrt_get_ip_geo_config()['ip_geo_format'] ?? 'province_city'));
$format = sanitize_key((string) ($c['ip_geo_format'] ?? 'province_city'));
return in_array($format, ['province_city', 'province', 'country_province'], true) return in_array($format, ['province_city', 'province', 'country_province'], true)
? $format ? $format
: 'province_city'; : 'province_city';
@@ -90,14 +92,14 @@ endif;
if (!function_exists('aksrt_user_city_enabled')) : if (!function_exists('aksrt_user_city_enabled')) :
/** /**
* Users feature switch (user home / user center), independent of comment city_s. * Users feature: show city on user home / user center.
* Default true when key absent (zibll parity for new installs).
*/ */
function aksrt_user_city_enabled(): bool { function aksrt_user_city_enabled(): bool {
if (!class_exists('\AKSRT\Settings\Settings')) { if (!class_exists('\AKSRT\Settings\Settings')) {
return true; // zibll default on return true;
} }
$all = \AKSRT\Settings\Settings::get_all(); $all = \AKSRT\Settings\Settings::get_all();
// Unset → on (zibll _pz default true). Explicit false turns off.
if (!array_key_exists('user_city_s', $all)) { if (!array_key_exists('user_city_s', $all)) {
return true; return true;
} }
@@ -106,24 +108,14 @@ if (!function_exists('aksrt_user_city_enabled')) :
endif; endif;
if (!function_exists('aksrt_user_city_type')) : if (!function_exists('aksrt_user_city_type')) :
/**
* User-facing precision (maps to shared format keys).
*/
function aksrt_user_city_type(): string { function aksrt_user_city_type(): string {
if (!class_exists('\AKSRT\Settings\Settings')) { if (!class_exists('\AKSRT\Settings\Settings')) {
return aksrt_ip_geo_format_key(); return aksrt_ip_geo_format_key();
} }
$all = \AKSRT\Settings\Settings::get_all(); $all = \AKSRT\Settings\Settings::get_all();
$type = sanitize_key((string) ($all['user_city_type'] ?? '')); $type = sanitize_key((string) ($all['user_city_type'] ?? ''));
// zibll: pro / city if (in_array($type, ['province_city', 'province', 'country_province'], true)) {
if ($type === 'pro' || $type === 'province') { return $type;
return 'province';
}
if ($type === 'city' || $type === 'province_city') {
return 'province_city';
}
if ($type === 'country_province') {
return 'country_province';
} }
return aksrt_ip_geo_format_key(); return aksrt_ip_geo_format_key();
} }
@@ -138,10 +130,8 @@ if (!function_exists('aksrt_normalize_geo_addr')) :
if (!is_array($raw)) { if (!is_array($raw)) {
return ['country' => '', 'province' => '', 'city' => '']; return ['country' => '', 'province' => '', 'city' => ''];
} }
// Accept zibll-shaped nation → country.
$country = trim((string) ($raw['country'] ?? $raw['nation'] ?? ''));
return [ return [
'country' => $country, 'country' => trim((string) ($raw['country'] ?? '')),
'province' => trim((string) ($raw['province'] ?? '')), 'province' => trim((string) ($raw['province'] ?? '')),
'city' => trim((string) ($raw['city'] ?? '')), 'city' => trim((string) ($raw['city'] ?? '')),
]; ];
@@ -161,7 +151,6 @@ if (!function_exists('aksrt_format_geo_label')) :
return $label; return $label;
} }
} }
// Local fallback (mirrors IPGeo::format).
switch ($type) { switch ($type) {
case 'province': case 'province':
return $addr['province'] !== '' ? $addr['province'] : $addr['city']; return $addr['province'] !== '' ? $addr['province'] : $addr['city'];
@@ -180,10 +169,10 @@ endif;
if (!function_exists('aksrt_get_geo_badge_html')) : if (!function_exists('aksrt_get_geo_badge_html')) :
/** /**
* @param array<string,string>|mixed $addr Addr meta. * @param array<string,string>|mixed $addr Addr meta.
* @param string $type Format. * @param string $type Format.
* @param string $class CSS classes. * @param string $class CSS classes.
* @param string $title Title attr. * @param string $title Title attr.
*/ */
function aksrt_get_geo_badge_html($addr, string $type = 'province_city', string $class = 'badg badg-sm', string $title = ''): string { function aksrt_get_geo_badge_html($addr, string $type = 'province_city', string $class = 'badg badg-sm', string $title = ''): string {
$label = aksrt_format_geo_label(is_array($addr) ? $addr : [], $type); $label = aksrt_format_geo_label(is_array($addr) ? $addr : [], $type);
@@ -218,18 +207,16 @@ endif;
if (!function_exists('aksrt_store_user_addr')) : if (!function_exists('aksrt_store_user_addr')) :
/** /**
* Resolve current client IP and persist user meta. * Resolve IP and write aksrt_user_addr (login / register / own-page refresh).
* Zibll: refresh on every login when user_city_s is on.
* Also refresh when article (post) display needs author addr.
*/ */
function aksrt_store_user_addr(int $user_id, ?string $ip = null): void { function aksrt_store_user_addr(int $user_id, ?string $ip = null): void {
if ($user_id <= 0 || !aksrt_ip_geo_master_enabled()) { if ($user_id <= 0 || !aksrt_ip_geo_master_enabled()) {
return; return;
} }
$need = aksrt_user_city_enabled() $need = aksrt_user_city_enabled()
|| aksrt_ip_geo_display_enabled('post') || in_array('post', aksrt_ip_geo_display_list(), true)
|| aksrt_ip_geo_display_enabled('user_home') || in_array('user_home', aksrt_ip_geo_display_list(), true)
|| aksrt_ip_geo_display_enabled('user_center'); || in_array('user_center', aksrt_ip_geo_display_list(), true);
if (!$need) { if (!$need) {
return; return;
} }
@@ -252,46 +239,22 @@ endif;
if (!function_exists('aksrt_get_user_addr')) : if (!function_exists('aksrt_get_user_addr')) :
/** /**
* @param int $user_id User ID. * Read aksrt_user_addr; if empty and viewing self, resolve current client IP once.
*
* @return array{country:string,province:string,city:string} * @return array{country:string,province:string,city:string}
*/ */
function aksrt_get_user_addr(int $user_id): array { function aksrt_get_user_addr(int $user_id): array {
if ($user_id <= 0) { if ($user_id <= 0) {
return ['country' => '', 'province' => '', 'city' => '']; return ['country' => '', 'province' => '', 'city' => ''];
} }
$raw = get_user_meta($user_id, 'aksrt_user_addr', true); $addr = aksrt_normalize_geo_addr(get_user_meta($user_id, 'aksrt_user_addr', true));
// Legacy / accidental zibll key.
if ((!is_array($raw) || empty($raw)) && metadata_exists('user', $user_id, 'user_addr')) {
$raw = get_user_meta($user_id, 'user_addr', true);
}
$addr = aksrt_normalize_geo_addr($raw);
if ($addr['country'] !== '' || $addr['province'] !== '' || $addr['city'] !== '') { if ($addr['country'] !== '' || $addr['province'] !== '' || $addr['city'] !== '') {
return $addr; return $addr;
} }
// Self view: write-on-read from current IP (same outcome as next login).
// Lazy backfill from stored IPs so pages work before next login. if ((int) get_current_user_id() === $user_id && aksrt_ip_geo_master_enabled()) {
$ips = []; aksrt_store_user_addr($user_id);
foreach (['aksrt_register_ip', 'register_ip'] as $k) { return aksrt_normalize_geo_addr(get_user_meta($user_id, 'aksrt_user_addr', true));
$v = trim((string) get_user_meta($user_id, $k, true));
if ($v !== '') {
$ips[] = $v;
}
}
// Own profile: refresh from current client IP (zibll updates on login; this covers open sessions).
if ((int) get_current_user_id() === $user_id) {
$cur = function_exists('aksrt_get_client_ip') ? (string) aksrt_get_client_ip() : (string) ($_SERVER['REMOTE_ADDR'] ?? '');
$cur = trim($cur);
if ($cur !== '') {
array_unshift($ips, $cur);
}
}
$ips = array_values(array_unique(array_filter($ips)));
foreach ($ips as $ip) {
$looked = aksrt_lookup_geo_for_ip($ip);
if ($looked['country'] !== '' || $looked['province'] !== '' || $looked['city'] !== '') {
update_user_meta($user_id, 'aksrt_user_addr', $looked);
return $looked;
}
} }
return $addr; return $addr;
} }
@@ -299,18 +262,12 @@ endif;
if (!function_exists('aksrt_get_user_city_badge_html')) : if (!function_exists('aksrt_get_user_city_badge_html')) :
/** /**
* Badge for user home / user center (requires user_city_s + display location).
*
* @param int $user_id User. * @param int $user_id User.
* @param string $location user_home|user_center * @param string $location user_home|user_center
* @param string $class CSS. * @param string $class CSS.
*/ */
function aksrt_get_user_city_badge_html(int $user_id, string $location = 'user_home', string $class = 'badg'): string { function aksrt_get_user_city_badge_html(int $user_id, string $location = 'user_home', string $class = 'badg'): string {
if ($user_id <= 0) { if ($user_id <= 0 || !aksrt_ip_geo_display_enabled($location)) {
return '';
}
// aksrt_ip_geo_display_enabled already enforces master + user_city for user surfaces.
if (!aksrt_ip_geo_display_enabled($location)) {
return ''; return '';
} }
return aksrt_get_geo_badge_html(aksrt_get_user_addr($user_id), aksrt_user_city_type(), $class); return aksrt_get_geo_badge_html(aksrt_get_user_addr($user_id), aksrt_user_city_type(), $class);
@@ -319,7 +276,7 @@ endif;
if (!function_exists('aksrt_get_post_author_city_badge_html')) : if (!function_exists('aksrt_get_post_author_city_badge_html')) :
/** /**
* Article detail author IP 属地 (uses author last-login addr). * Article author IP 属地 (author aksrt_user_addr).
*/ */
function aksrt_get_post_author_city_badge_html(int $author_id = 0, string $class = 'badg badg-sm'): string { function aksrt_get_post_author_city_badge_html(int $author_id = 0, string $class = 'badg badg-sm'): string {
if (!aksrt_ip_geo_display_enabled('post')) { if (!aksrt_ip_geo_display_enabled('post')) {
@@ -331,14 +288,11 @@ if (!function_exists('aksrt_get_post_author_city_badge_html')) :
if ($author_id <= 0) { if ($author_id <= 0) {
return ''; return '';
} }
// Prefer user_city type when feature on; else global format.
$type = aksrt_user_city_enabled() ? aksrt_user_city_type() : aksrt_ip_geo_format_key(); $type = aksrt_user_city_enabled() ? aksrt_user_city_type() : aksrt_ip_geo_format_key();
return aksrt_get_geo_badge_html(aksrt_get_user_addr($author_id), $type, $class); return aksrt_get_geo_badge_html(aksrt_get_user_addr($author_id), $type, $class);
} }
endif; endif;
// ── Hooks: persist on login / register ──────────────────────────────────────
add_action('wp_login', static function ($user_login, $user = null): void { add_action('wp_login', static function ($user_login, $user = null): void {
$user_id = 0; $user_id = 0;
if ($user instanceof WP_User) { if ($user instanceof WP_User) {
@@ -347,7 +301,7 @@ add_action('wp_login', static function ($user_login, $user = null): void {
$u = get_user_by('login', $user_login); $u = get_user_by('login', $user_login);
$user_id = $u instanceof WP_User ? (int) $u->ID : 0; $user_id = $u instanceof WP_User ? (int) $u->ID : 0;
} }
if ($user_id > 0 && function_exists('aksrt_store_user_addr')) { if ($user_id > 0) {
aksrt_store_user_addr($user_id); aksrt_store_user_addr($user_id);
} }
}, 20, 2); }, 20, 2);
@@ -362,7 +316,5 @@ add_action('user_register', static function ($user_id): void {
if ($ip !== '') { if ($ip !== '') {
update_user_meta($user_id, 'aksrt_register_ip', $ip); update_user_meta($user_id, 'aksrt_register_ip', $ip);
} }
if (function_exists('aksrt_store_user_addr')) { aksrt_store_user_addr($user_id, $ip !== '' ? $ip : null);
aksrt_store_user_addr($user_id, $ip !== '' ? $ip : null);
}
}, 20, 1); }, 20, 1);
+8 -55
View File
@@ -2,8 +2,8 @@
/** /**
* Comment city / IP geo helpers. * Comment city / IP geo helpers.
* *
* Meta key: aksrt_comment_addr (array from IPGeo). * Meta: aksrt_comment_addr {country,province,city}
* Gates: extensions.ip_geo_enabled + ip_geo_display includes comment + comment_city_s. * Gates: ip_geo_enabled + ip_geo_display has comment + comment_city_s
* *
* @package AKSRT * @package AKSRT
*/ */
@@ -11,25 +11,10 @@
defined('ABSPATH') || exit; defined('ABSPATH') || exit;
if (!function_exists('aksrt_comment_city_enabled')) : if (!function_exists('aksrt_comment_city_enabled')) :
/**
* Whether comment city badges are enabled.
*/
function aksrt_comment_city_enabled(): bool { function aksrt_comment_city_enabled(): bool {
// Prefer shared display gate when available. if (function_exists('aksrt_ip_geo_display_enabled') && !aksrt_ip_geo_display_enabled('comment')) {
if (function_exists('aksrt_ip_geo_display_enabled')) {
if (!aksrt_ip_geo_display_enabled('comment')) {
// Allow legacy path: comment_city_s alone still works if master is on
// but display list empty — require master + city_s at minimum.
if (!function_exists('aksrt_ip_geo_master_enabled') || !aksrt_ip_geo_master_enabled()) {
return false;
}
// Master on but location not selected → off.
return false;
}
} elseif (function_exists('aksrt_ip_geo_master_enabled') && !aksrt_ip_geo_master_enabled()) {
return false; return false;
} }
if (!class_exists('\AKSRT\Settings\Settings')) { if (!class_exists('\AKSRT\Settings\Settings')) {
return false; return false;
} }
@@ -39,9 +24,6 @@ if (!function_exists('aksrt_comment_city_enabled')) :
endif; endif;
if (!function_exists('aksrt_comment_city_type')) : if (!function_exists('aksrt_comment_city_type')) :
/**
* Display format key for city badge.
*/
function aksrt_comment_city_type(): string { function aksrt_comment_city_type(): string {
if (!class_exists('\AKSRT\Settings\Settings')) { if (!class_exists('\AKSRT\Settings\Settings')) {
return function_exists('aksrt_ip_geo_format_key') ? aksrt_ip_geo_format_key() : 'province_city'; return function_exists('aksrt_ip_geo_format_key') ? aksrt_ip_geo_format_key() : 'province_city';
@@ -56,8 +38,6 @@ endif;
if (!function_exists('aksrt_store_comment_addr')) : if (!function_exists('aksrt_store_comment_addr')) :
/** /**
* Resolve IP geo and persist on comment.
*
* @param int $comment_id Comment ID. * @param int $comment_id Comment ID.
* @param string|null $ip Optional IP override. * @param string|null $ip Optional IP override.
*/ */
@@ -95,25 +75,23 @@ endif;
if (!function_exists('aksrt_get_comment_addr')) : if (!function_exists('aksrt_get_comment_addr')) :
/** /**
* @param int|WP_Comment $comment Comment. * @param int|WP_Comment $comment Comment.
* @return array{country?:string,province?:string,city?:string} * @return array{country:string,province:string,city:string}
*/ */
function aksrt_get_comment_addr($comment): array { function aksrt_get_comment_addr($comment): array {
$comment_id = $comment instanceof WP_Comment ? (int) $comment->comment_ID : (int) $comment; $comment_id = $comment instanceof WP_Comment ? (int) $comment->comment_ID : (int) $comment;
if ($comment_id <= 0) { if ($comment_id <= 0) {
return []; return ['country' => '', 'province' => '', 'city' => ''];
} }
$raw = get_comment_meta($comment_id, 'aksrt_comment_addr', true); $raw = get_comment_meta($comment_id, 'aksrt_comment_addr', true);
if (function_exists('aksrt_normalize_geo_addr')) { if (function_exists('aksrt_normalize_geo_addr')) {
return aksrt_normalize_geo_addr($raw); return aksrt_normalize_geo_addr($raw);
} }
return is_array($raw) ? $raw : []; return is_array($raw) ? $raw : ['country' => '', 'province' => '', 'city' => ''];
} }
endif; endif;
if (!function_exists('aksrt_format_comment_city_label')) : if (!function_exists('aksrt_format_comment_city_label')) :
/** /**
* Format addr array into display string.
*
* @param array<string,string> $addr Addr. * @param array<string,string> $addr Addr.
* @param string $type Format. * @param string $type Format.
*/ */
@@ -121,30 +99,11 @@ if (!function_exists('aksrt_format_comment_city_label')) :
if (function_exists('aksrt_format_geo_label')) { if (function_exists('aksrt_format_geo_label')) {
return aksrt_format_geo_label($addr, $type); return aksrt_format_geo_label($addr, $type);
} }
$country = trim((string) ($addr['country'] ?? '')); return '';
$province = trim((string) ($addr['province'] ?? ''));
$city = trim((string) ($addr['city'] ?? ''));
switch ($type) {
case 'province':
return $province !== '' ? $province : $city;
case 'country_province':
$parts = array_filter([$country, $province]);
return implode(' ', $parts);
case 'province_city':
default:
$parts = array_filter([$province, $city]);
if (empty($parts) && $country !== '') {
return $country;
}
return implode(' ', $parts);
}
} }
endif; endif;
if (!function_exists('aksrt_get_comment_city_badge_html')) : if (!function_exists('aksrt_get_comment_city_badge_html')) :
/**
* HTML badge for comment city (empty string if disabled/missing).
*/
function aksrt_get_comment_city_badge_html($comment): string { function aksrt_get_comment_city_badge_html($comment): string {
if (!aksrt_comment_city_enabled()) { if (!aksrt_comment_city_enabled()) {
return ''; return '';
@@ -156,16 +115,10 @@ if (!function_exists('aksrt_get_comment_city_badge_html')) :
'badg badg-sm comment-city-badge' 'badg badg-sm comment-city-badge'
); );
} }
$addr = aksrt_get_comment_addr($comment); return '';
$label = aksrt_format_comment_city_label($addr, aksrt_comment_city_type());
if ($label === '') {
return '';
}
return '<span class="badg badg-sm comment-city-badge" title="' . esc_attr__('IP 属地', 'aksrt') . '">' . esc_html($label) . '</span>';
} }
endif; endif;
// Persist geo after any successful insert (covers REST + core).
add_action('comment_post', static function ($comment_id): void { add_action('comment_post', static function ($comment_id): void {
if (function_exists('aksrt_store_comment_addr')) { if (function_exists('aksrt_store_comment_addr')) {
aksrt_store_comment_addr((int) $comment_id); aksrt_store_comment_addr((int) $comment_id);
+3 -3
View File
@@ -44,7 +44,7 @@ class IPGeo {
} }
} }
$provider = sanitize_key((string) ($config['ip_addr_sdk'] ?? ($config['ip_geo_provider'] ?? 'null'))); $provider = sanitize_key((string) ($config['ip_addr_sdk'] ?? 'null'));
$result = $this->query_provider($provider, $ip, $config); $result = $this->query_provider($provider, $ip, $config);
if (!empty($result['province']) || !empty($result['city']) || !empty($result['country'])) { if (!empty($result['province']) || !empty($result['city']) || !empty($result['country'])) {
@@ -66,7 +66,7 @@ class IPGeo {
*/ */
public function get_status(): array { public function get_status(): array {
$config = $this->get_config(); $config = $this->get_config();
$provider = sanitize_key((string) ($config['ip_addr_sdk'] ?? ($config['ip_geo_provider'] ?? 'null'))); $provider = sanitize_key((string) ($config['ip_addr_sdk'] ?? 'null'));
$enabled = !empty($config['ip_geo_enabled']); $enabled = !empty($config['ip_geo_enabled']);
$missing = []; $missing = [];
@@ -88,7 +88,7 @@ class IPGeo {
'transport' => 'http_api', 'transport' => 'http_api',
'missing_fields' => $missing, 'missing_fields' => $missing,
'cache_ttl' => (int) ($config['ip_geo_cache_ttl'] ?? 86400), 'cache_ttl' => (int) ($config['ip_geo_cache_ttl'] ?? 86400),
'display' => (array) ($config['ip_geo_display'] ?? ['comment']), 'display' => (array) ($config['ip_geo_display'] ?? ['comment', 'user_home', 'user_center', 'post']),
'format' => (string) ($config['ip_geo_format'] ?? 'province_city'), 'format' => (string) ($config['ip_geo_format'] ?? 'province_city'),
]; ];
} }
+13 -8
View File
@@ -47,19 +47,25 @@ class ExtensionRuntime {
public static function get_ip_geo_settings(): array { public static function get_ip_geo_settings(): array {
$settings = Settings::get_all(); $settings = Settings::get_all();
$provider = sanitize_key((string) ($settings['ip_addr_sdk'] ?? ($settings['ip_geo_provider'] ?? 'null'))); $provider = sanitize_key((string) ($settings['ip_addr_sdk'] ?? 'null'));
$allowed = ['polling', 'qq', 'amap', 'null']; $allowed = ['polling', 'qq', 'amap', 'null'];
if (!in_array($provider, $allowed, true)) { if (!in_array($provider, $allowed, true)) {
$provider = 'null'; $provider = 'null';
} }
$display_raw = $settings['ip_geo_display'] ?? ['comment', 'user_home', 'user_center', 'post']; $display_raw = $settings['ip_geo_display'] ?? ['comment', 'user_home', 'user_center', 'post'];
$display = is_array($display_raw) ? $display_raw : [$display_raw]; $display = is_array($display_raw) ? $display_raw : [];
$display = array_values(array_unique(array_filter(array_map('sanitize_key', $display))));
$allowed_display = ['comment', 'user_home', 'user_center', 'post']; $allowed_display = ['comment', 'user_home', 'user_center', 'post'];
$display = array_values(array_filter($display, static fn($v) => in_array($v, $allowed_display, true))); $display_norm = [];
if ($display === []) { foreach ($display as $item) {
$display = ['comment', 'user_home', 'user_center', 'post']; $key = sanitize_key((string) $item);
if (in_array($key, $allowed_display, true) && !in_array($key, $display_norm, true)) {
$display_norm[] = $key;
}
}
// Empty / missing → full four surfaces (canonical default).
if ($display_norm === []) {
$display_norm = $allowed_display;
} }
$format = sanitize_key((string) ($settings['ip_geo_format'] ?? 'province_city')); $format = sanitize_key((string) ($settings['ip_geo_format'] ?? 'province_city'));
@@ -70,9 +76,8 @@ class ExtensionRuntime {
return [ return [
'ip_geo_enabled' => !empty($settings['ip_geo_enabled']), 'ip_geo_enabled' => !empty($settings['ip_geo_enabled']),
'ip_addr_sdk' => $provider, 'ip_addr_sdk' => $provider,
'ip_geo_provider' => $provider,
'ip_geo_cache_ttl' => max(3600, (int) ($settings['ip_geo_cache_ttl'] ?? 86400)), 'ip_geo_cache_ttl' => max(3600, (int) ($settings['ip_geo_cache_ttl'] ?? 86400)),
'ip_geo_display' => $display, 'ip_geo_display' => $display_norm,
'ip_geo_format' => $format, 'ip_geo_format' => $format,
'ip_geo_fallback_text' => (string) ($settings['ip_geo_fallback_text'] ?? ''), 'ip_geo_fallback_text' => (string) ($settings['ip_geo_fallback_text'] ?? ''),
'ip_addr_sdk_qq_appkey' => (string) ($settings['ip_addr_sdk_qq_appkey'] ?? ''), 'ip_addr_sdk_qq_appkey' => (string) ($settings['ip_addr_sdk_qq_appkey'] ?? ''),