serverId !== null) { $server = DnsServer::find($this->serverId); $pleskDomains = $server ? $pleskDomainService->listDomains($server) : false; if ($pleskDomains === false) { Log::error('DNS sync: không lấy được danh sách domain từ Plesk', [ 'server_id' => $this->serverId, 'error' => $pleskDomainService->getLastError(), ]); event(new DnsSyncCompleted(0, ['server #' . $this->serverId], 0)); return; } $imported = $this->importDomains($pleskDomains); } $domains = $domainRepository->model ->notCancelled() ->when( $this->serverId !== null, fn ($query) => $query->where('dns_manager_server_id', $this->serverId), fn ($query) => $query->whereNotNull('dns_manager_server_id'), ) ->get(); foreach ($domains as $domain) { if (!$serverService->addServerById($domain->dns_manager_server_id)) { $failedDomains[] = $domain->domain_name; continue; } $result = $serverService->listRecords($domain->domain_name); if ($result['error']) { $failedDomains[] = $domain->domain_name; continue; } foreach ($result['data'] as $item) { $type = strtoupper($item['type'] ?? ''); if (!in_array($type, self::PLESK_RECORD_TYPES, true) || empty($item['id'])) { continue; } $recordRepository->model->updateOrCreate( [ 'dns_manager_domain_id' => $domain->id, 'plesk_id' => $item['id'], ], $this->mapPleskRecord($item, $type, $domain->domain_name) ); $synced++; } } Log::info('DNS sync from Plesk finished', [ 'server_id' => $this->serverId, 'imported' => $imported, 'synced' => $synced, 'failed_domains' => $failedDomains, ]); event(new DnsSyncCompleted($synced, $failedDomains, $imported)); } /** * @param array> $pleskDomains */ private function importDomains(array $pleskDomains): int { $imported = 0; foreach ($pleskDomains as $item) { $name = strtolower(trim((string) ($item['name'] ?? ''))); if ($name === '' || empty($item['id']) || !empty($item['base_domain_id'])) { continue; } $domain = DnsDomain::whereRaw('LOWER(domain_name) = ?', [$name])->first(); if (!$domain) { DnsDomain::create([ 'domain_name' => $name, 'dns_manager_server_id' => $this->serverId, 'plesk_id' => $item['id'], 'is_created' => DnsDomain::STATUS_CREATED, ]); $imported++; continue; } $sameServer = in_array((int) $domain->dns_manager_server_id, [0, $this->serverId], true); if ($domain->plesk_id || !$sameServer || (int) $domain->is_created === DnsDomain::STATUS_CANCELLED) { continue; } $domain->update([ 'dns_manager_server_id' => $this->serverId, 'plesk_id' => $item['id'], 'is_created' => (int) $domain->is_created === DnsDomain::STATUS_PENDING ? DnsDomain::STATUS_CREATED : $domain->is_created, ]); $imported++; } return $imported; } private function mapPleskRecord(array $item, string $type, string $domainName): array { $host = rtrim($item['host'] ?? '', '.'); $domainName = rtrim($domainName, '.'); $name = $host === $domainName ? '@' : preg_replace('/\.' . preg_quote($domainName, '/') . '$/', '', $host); $opt = trim((string) ($item['opt'] ?? '')); $priority = null; $weight = null; $port = null; $serviceName = null; $protocol = null; if ($type === 'SRV') { [$priority, $weight, $port] = array_pad(preg_split('/\s+/', $opt), 3, null); if (preg_match('/^_([^.]+)\._([^.]+)\./', $name, $m)) { $serviceName = '_' . $m[1]; $protocol = '_' . $m[2]; } } elseif ($type === 'MX') { $priority = is_numeric($opt) ? $opt : null; } return [ 'type' => $type, 'type_valid' => $type, 'name' => $name, 'value' => $item['value'] ?? '', 'ttl' => $item['ttl'] ?? 300, 'priority' => $priority, 'weight' => $weight, 'port' => $port, 'service_name' => $serviceName, 'protocol' => $protocol, ]; } }