2026-06-14 15:29:29 +08:00
|
|
|
|
<?php
|
|
|
|
|
|
/**
|
|
|
|
|
|
* SHOW_SITE_COUNTRY 允许列表解析与比对
|
|
|
|
|
|
*/
|
2026-06-15 16:53:05 +08:00
|
|
|
|
require_once __DIR__ . '/CountryCodeNormalizer.php';
|
|
|
|
|
|
|
2026-06-14 15:29:29 +08:00
|
|
|
|
class CountryAllowlist
|
|
|
|
|
|
{
|
2026-06-20 04:09:37 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* SHOW_SITE_COUNTRY 是否已配置(非空允许列表 = 开启国家条件)
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param string|null $config 默认读取 SHOW_SITE_COUNTRY
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static function isEnabled($config = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
if ($config === null) {
|
|
|
|
|
|
$config = defined('SHOW_SITE_COUNTRY') ? SHOW_SITE_COUNTRY : '';
|
|
|
|
|
|
}
|
|
|
|
|
|
return self::parse($config) !== [];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 保存前规范化用户输入:兼容中文逗号/分号、顿号、全角空格及多余空白。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param string $config
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static function normalizeInput($config)
|
|
|
|
|
|
{
|
|
|
|
|
|
$config = trim((string) $config);
|
|
|
|
|
|
if ($config === '') {
|
|
|
|
|
|
return '';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 全角空格、不间断空格
|
|
|
|
|
|
$config = preg_replace('/[\x{3000}\x{00A0}]/u', ' ', $config);
|
|
|
|
|
|
|
|
|
|
|
|
// 常见误输入分隔符统一为英文逗号
|
|
|
|
|
|
$config = str_replace([',', ';', ';', '、'], ',', $config);
|
|
|
|
|
|
|
|
|
|
|
|
// 去掉分隔符两侧空白,合并连续逗号
|
|
|
|
|
|
$config = preg_replace('/\s*,\s*/', ',', $config);
|
|
|
|
|
|
$config = preg_replace('/,+/', ',', $config);
|
|
|
|
|
|
|
|
|
|
|
|
return trim($config, " \t\n\r,");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-14 15:29:29 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @param string $config 逗号分隔国家码,如 US,GB,CA
|
|
|
|
|
|
* @return string[]
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static function parse($config)
|
|
|
|
|
|
{
|
2026-06-20 04:09:37 +08:00
|
|
|
|
$config = self::normalizeInput($config);
|
2026-06-14 15:29:29 +08:00
|
|
|
|
if ($config === '') {
|
|
|
|
|
|
return [];
|
|
|
|
|
|
}
|
2026-06-20 04:09:37 +08:00
|
|
|
|
|
|
|
|
|
|
$parts = explode(',', $config);
|
2026-06-14 15:29:29 +08:00
|
|
|
|
$out = [];
|
|
|
|
|
|
foreach ($parts as $part) {
|
|
|
|
|
|
$part = trim($part);
|
2026-06-15 22:42:59 +08:00
|
|
|
|
if ($part === '') {
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
$normalized = CountryCodeNormalizer::toAlpha2($part);
|
|
|
|
|
|
if ($normalized !== null && $normalized !== '') {
|
|
|
|
|
|
$out[] = $normalized;
|
2026-06-14 15:29:29 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return array_values(array_unique($out));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-15 22:42:59 +08:00
|
|
|
|
/**
|
2026-06-20 04:09:37 +08:00
|
|
|
|
* 读取并规范化 SHOW_SITE_COUNTRY(大写 ISO2,逗号分隔)
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param string|null $config 默认 SHOW_SITE_COUNTRY
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static function resolvedConfig($config = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
if ($config === null) {
|
|
|
|
|
|
$config = defined('SHOW_SITE_COUNTRY') ? SHOW_SITE_COUNTRY : '';
|
|
|
|
|
|
}
|
|
|
|
|
|
return self::formatForConfig($config);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 保存配置前规范化国家列表字符串(dashboard 写入用,输出大写如 US,GB)
|
2026-06-15 22:42:59 +08:00
|
|
|
|
*
|
|
|
|
|
|
* @param string $config
|
2026-06-20 04:09:37 +08:00
|
|
|
|
* @return string 如 US,GB
|
2026-06-15 22:42:59 +08:00
|
|
|
|
*/
|
|
|
|
|
|
public static function formatForConfig($config)
|
|
|
|
|
|
{
|
|
|
|
|
|
$list = self::parse($config);
|
|
|
|
|
|
return implode(',', $list);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-14 15:29:29 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @param string|null $countryCode
|
|
|
|
|
|
* @param string[] $allowlist
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static function isAllowed($countryCode, array $allowlist)
|
|
|
|
|
|
{
|
|
|
|
|
|
if ($allowlist === []) {
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
2026-06-15 16:53:05 +08:00
|
|
|
|
$normalized = CountryCodeNormalizer::toAlpha2($countryCode);
|
|
|
|
|
|
if ($normalized === null || $normalized === '') {
|
2026-06-14 15:29:29 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2026-06-15 16:53:05 +08:00
|
|
|
|
return in_array($normalized, $allowlist, true);
|
2026-06-14 15:29:29 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|