model ->whereNotNull('dns_manager_server_id') ->get(); $synced = 0; $failedDomains = []; 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', ['synced' => $synced, 'failed_domains' => $failedDomains]); event(new DnsSyncCompleted($synced, $failedDomains)); } 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, ]; } }