域名管理
This commit is contained in:
Executable
+189
@@ -0,0 +1,189 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* 域名管理模型
|
||||
*/
|
||||
class Domain extends Model
|
||||
{
|
||||
/** @var string 中国域名后缀黑名单 */
|
||||
public const CHINA_SUFFIX_BLACKLIST = [
|
||||
'cn', 'com.cn', 'net.cn', 'org.cn', 'gov.cn', 'edu.cn', 'ac.cn', 'mil.cn',
|
||||
];
|
||||
|
||||
protected $name = 'domain';
|
||||
protected $autoWriteTimestamp = 'integer';
|
||||
protected $createTime = 'createtime';
|
||||
protected $updateTime = 'updatetime';
|
||||
protected $deleteTime = false;
|
||||
|
||||
protected $append = [
|
||||
'zone_status_text',
|
||||
'ns_status_text',
|
||||
'dns_status_text',
|
||||
];
|
||||
|
||||
public function getZoneStatusList(): array
|
||||
{
|
||||
return [
|
||||
'pending' => __('Zone pending'),
|
||||
'active' => __('Zone active'),
|
||||
'failed' => __('Zone failed'),
|
||||
];
|
||||
}
|
||||
|
||||
public function getNsStatusList(): array
|
||||
{
|
||||
return [
|
||||
'pending' => __('NS pending'),
|
||||
'verified' => __('NS verified'),
|
||||
'failed' => __('NS failed'),
|
||||
];
|
||||
}
|
||||
|
||||
public function getDnsStatusList(): array
|
||||
{
|
||||
return [
|
||||
'pending' => __('DNS pending'),
|
||||
'created' => __('DNS created'),
|
||||
'failed' => __('DNS failed'),
|
||||
];
|
||||
}
|
||||
|
||||
public function getZoneStatusTextAttr($value, $data): string
|
||||
{
|
||||
$value = $value ?: ($data['zone_status'] ?? '');
|
||||
$list = $this->getZoneStatusList();
|
||||
return $list[$value] ?? '';
|
||||
}
|
||||
|
||||
public function getNsStatusTextAttr($value, $data): string
|
||||
{
|
||||
$value = $value ?: ($data['ns_status'] ?? '');
|
||||
$list = $this->getNsStatusList();
|
||||
return $list[$value] ?? '';
|
||||
}
|
||||
|
||||
public function getDnsStatusTextAttr($value, $data): string
|
||||
{
|
||||
$value = $value ?: ($data['dns_status'] ?? '');
|
||||
$list = $this->getDnsStatusList();
|
||||
return $list[$value] ?? '';
|
||||
}
|
||||
|
||||
public function setNameserversAttr($value): string
|
||||
{
|
||||
if (is_array($value)) {
|
||||
return json_encode(array_values($value), JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
return (string)$value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, string>
|
||||
*/
|
||||
public function getNameserversArray(): array
|
||||
{
|
||||
$value = $this->getAttr('nameservers');
|
||||
if (is_array($value)) {
|
||||
return $value;
|
||||
}
|
||||
if (is_string($value) && $value !== '') {
|
||||
$decoded = json_decode($value, true);
|
||||
return is_array($decoded) ? $decoded : [];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
public static function normalizeDomain(string $domain): string
|
||||
{
|
||||
return strtolower(trim($domain));
|
||||
}
|
||||
|
||||
public static function isValidRootDomain(string $domain): bool
|
||||
{
|
||||
$domain = self::normalizeDomain($domain);
|
||||
if ($domain === '' || strlen($domain) > 253) {
|
||||
return false;
|
||||
}
|
||||
if (strpos($domain, 'www.') === 0) {
|
||||
return false;
|
||||
}
|
||||
if (!preg_match('/^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}$/i', $domain)) {
|
||||
return false;
|
||||
}
|
||||
if (self::isChinaSuffix($domain)) {
|
||||
return false;
|
||||
}
|
||||
$label = self::getDomainLabelWithoutSuffix($domain);
|
||||
if ($label === '' || strpos($label, '.') !== false) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function isChinaSuffix(string $domain): bool
|
||||
{
|
||||
$domain = self::normalizeDomain($domain);
|
||||
foreach (self::CHINA_SUFFIX_BLACKLIST as $suffix) {
|
||||
if ($domain === $suffix || self::endsWith($domain, '.' . $suffix)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function getMatchedSuffix(string $domain): string
|
||||
{
|
||||
$domain = self::normalizeDomain($domain);
|
||||
$suffixes = array_merge(self::CHINA_SUFFIX_BLACKLIST, ['co.uk', 'com', 'net', 'org', 'io', 'co', 'me', 'info', 'biz']);
|
||||
usort($suffixes, function ($a, $b) {
|
||||
return strlen($b) - strlen($a);
|
||||
});
|
||||
foreach ($suffixes as $suffix) {
|
||||
if ($domain === $suffix || self::endsWith($domain, '.' . $suffix)) {
|
||||
return $suffix;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
public static function getDomainLabelWithoutSuffix(string $domain): string
|
||||
{
|
||||
$domain = self::normalizeDomain($domain);
|
||||
$suffix = self::getMatchedSuffix($domain);
|
||||
if ($suffix === '') {
|
||||
$pos = strrpos($domain, '.');
|
||||
return $pos === false ? $domain : substr($domain, 0, $pos);
|
||||
}
|
||||
$suffixWithDot = '.' . $suffix;
|
||||
if (self::endsWith($domain, $suffixWithDot)) {
|
||||
return substr($domain, 0, -strlen($suffixWithDot));
|
||||
}
|
||||
return $domain;
|
||||
}
|
||||
|
||||
public static function mapCloudflareZoneStatus(string $status): string
|
||||
{
|
||||
if ($status === 'active') {
|
||||
return 'active';
|
||||
}
|
||||
if (in_array($status, ['pending', 'initializing'], true)) {
|
||||
return 'pending';
|
||||
}
|
||||
return 'failed';
|
||||
}
|
||||
|
||||
private static function endsWith(string $haystack, string $needle): bool
|
||||
{
|
||||
if ($needle === '') {
|
||||
return true;
|
||||
}
|
||||
return substr($haystack, -strlen($needle)) === $needle;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user