'', 'type' => 'A', 'value' => '', 'opt' => '', 'ttl' => 300, ]; protected string $domain = ''; protected array $entry_points = [ 'auth' => ':8443/api/v2/auth/keys', 'server' => ':8443/api/v2/server', 'domain' => ':8443/api/v2/domains', 'record' => ':8443/api/v2/dns/records', ]; public function __construct( public DnsServerRepositoryInterface $serverRepository ) { $this->server = $this->getServer(); } public function findServerByID(int $id): ?DnsServer { return $this->server = $this->serverRepository->find($id); } public function handlePayload(array $data = []): static { $this->domain = $data['domain'] ?? ''; $name = $data['name'] ?? ''; $this->payload = [ 'type' => $data['type'] ?? 'A', 'host' => $name === '@' ? $this->domain : ($name . '.' . $this->domain), 'value' => str_replace(["\r", "\n"], ' ', $data['value'] ?? ''), 'ttl' => $data['ttl'] ?? 300, ]; switch (strtoupper($this->payload['type'])) { case 'MX': $this->payload['opt'] = $data['priority'] ?? 0; break; case 'SRV': $this->payload['host'] = sprintf('_%s._%s.%s', $data['service_name'], $data['protocol'], $this->domain); $this->payload['opt'] = sprintf('%d %d %d', $data['priority'] ?? 0, $data['weight'] ?? 50, $data['port'] ?? 21); break; } return $this; } public function addRecord(): array { if (empty($this->domain)) { return ['error' => true, 'message' => 'Invalid domain']; } try { $response = Http::withoutVerifying() ->withBasicAuth($this->server->username, Crypt::decryptString($this->server->password)) ->timeout(10) ->post( BaseHelper::url($this->server->ip_address) . $this->entry_points['record'] . '?' . http_build_query(['domain' => $this->domain]), $this->payload )->throw(); $this->resetServer(); return $response->successful() && count($response->json()) ? ['error' => false, 'data' => $response->json()] : ['error' => true]; } catch (RequestException $e) { Log::error($e->getMessage()); return ['error' => true, 'message' => $e->getMessage()]; } } public function listRecords(string $domain): array { if (empty($domain)) { return ['error' => true, 'message' => 'Invalid domain']; } try { $response = Http::withoutVerifying() ->withBasicAuth($this->server->username, Crypt::decryptString($this->server->password)) ->timeout(15) ->get( BaseHelper::url($this->server->ip_address) . $this->entry_points['record'], ['domain' => $domain] )->throw(); $this->resetServer(); return ['error' => false, 'data' => $response->json() ?? []]; } catch (RequestException $e) { Log::error($e->getMessage()); return ['error' => true, 'message' => $e->getMessage()]; } } public function updateRecord(int $record_id = 0): array { if (empty($record_id)) { return ['error' => true, 'message' => 'Invalid request']; } try { $response = Http::withoutVerifying() ->withBasicAuth($this->server->username, Crypt::decryptString($this->server->password)) ->timeout(10) ->put( BaseHelper::url($this->server->ip_address) . $this->entry_points['record'] . "/$record_id", $this->payload )->throw(); $this->resetServer(); return $response->successful() && count($response->json()) ? ['error' => false, 'data' => $response->json()] : ['error' => true]; } catch (RequestException $e) { Log::error($e->getMessage()); return ['error' => true, 'message' => $e->getMessage()]; } } public function deleteRecord(int $record_id = 0): array { if (empty($record_id)) { return ['error' => true, 'message' => 'Invalid request']; } try { $response = Http::withoutVerifying() ->withBasicAuth($this->server->username, Crypt::decryptString($this->server->password)) ->timeout(30) ->delete( BaseHelper::url($this->server->ip_address) . $this->entry_points['record'] . "/$record_id" )->throw(); $this->resetServer(); return $response->successful() && count($response->json()) ? ['error' => false, 'data' => $response->json()] : ['error' => true]; } catch (RequestException $e) { Log::error($e->getMessage()); return ['error' => true, 'message' => $e->getMessage()]; } } public function checkConnection(array $data = []): array|false { if (empty($data['username']) || empty($data['password']) || empty($data['ip_address'])) { return false; } try { $response = Http::withoutVerifying() ->withBasicAuth($data['username'], $data['password']) ->timeout(10) ->get(BaseHelper::url($data['ip_address']) . $this->entry_points['server']); return $response->successful() ? $response->json() : false; } catch (RequestException $e) { Log::error($e->getMessage()); return false; } } public function checkConnectionByServer(DnsServer $server): array|false { try { return $this->checkConnection([ 'username' => $server->username, 'password' => Crypt::decryptString($server->password), 'ip_address' => $server->ip_address, ]); } catch (\Throwable $e) { Log::error($e->getMessage()); return false; } } public function getDomainInfo(string $domain = ''): array|false { if (empty($domain)) { return false; } try { $response = Http::withoutVerifying() ->withBasicAuth($this->server->username, Crypt::decryptString($this->server->password)) ->timeout(10) ->get(BaseHelper::url($this->server->ip_address) . $this->entry_points['domain'], ['name' => $domain]); $this->resetServer(); if ($response->successful()) { $domains = $response->json(); foreach ($domains as $domainInfo) { if (isset($domainInfo['name']) && $domainInfo['name'] === $domain) { return $domainInfo; } } } return false; } catch (RequestException $e) { Log::error($e->getMessage()); return false; } } public function createDomain(array $data = []): array|false { if (empty($data)) { return false; } if (!$this->server) { $this->server = $this->serverRepository->find($data['dns_manager_server_id']); } $param = [ 'name' => $data['domain_name'], 'description' => '', 'hosting_type' => 'virtual', 'hosting_settings' => [ 'ftp_login' => str_replace('.', '_', $data['domain_name']), 'ftp_password' => Str::random(12), ], 'ip_addresses' => ['103.42.58.124'], 'ipv4' => ['103.42.58.124'], 'plan' => ['name' => 'Default Domain'], ]; try { $response = Http::withoutVerifying() ->withBasicAuth($this->server->username, Crypt::decryptString($this->server->password)) ->timeout(30) ->post(BaseHelper::url($this->server->ip_address) . $this->entry_points['domain'], $param); $this->resetServer(); $responseData = $response->json(); Log::info('Response Plesk API Created', ['data' => $responseData]); if ($response->successful() && isset($responseData['id'], $responseData['guid'])) { return $responseData; } } catch (RequestException $e) { Log::error('Plesk domain creation failed', [ 'error' => $e->getMessage(), 'response' => $e->response?->body(), 'data' => $param, ]); } return false; } public function updateDomain(int $pleskDomainId, array $data = []): array|false { if (empty($pleskDomainId) || empty($data)) { return false; } if (!$this->server) { $this->server = $this->serverRepository->find($data['dns_manager_server_id']); } $param = [ 'name' => $data['domain_name'], 'description' => '', 'hosting_type' => 'virtual', 'hosting_settings' => [ 'ftp_login' => str_replace('.', '_', $data['domain_name']), 'ftp_password' => Str::random(12), ], 'ip_addresses' => ['103.42.58.124'], 'ipv4' => ['103.42.58.124'], 'plan' => ['name' => 'Default Domain'], ]; try { $response = Http::withoutVerifying() ->withBasicAuth($this->server->username, Crypt::decryptString($this->server->password)) ->timeout(30) ->put(BaseHelper::url($this->server->ip_address) . $this->entry_points['domain'] . "/{$pleskDomainId}", $param); $this->resetServer(); $responseData = $response->json(); Log::info('Response Plesk API Updated', ['data' => $responseData]); if ($response->successful() && isset($responseData['id'], $responseData['guid'])) { return $responseData; } } catch (RequestException $e) { Log::error('Plesk domain update failed', [ 'error' => $e->getMessage(), 'response' => $e->response?->body(), 'data' => $param, ]); } return false; } public function removeDomain(int $pleskDomainId): bool { if (empty($this->server)) { return false; } try { $response = Http::withoutVerifying() ->withBasicAuth($this->server->username, Crypt::decryptString($this->server->password)) ->timeout(30) ->delete(BaseHelper::url($this->server->ip_address) . $this->entry_points['domain'] . "/{$pleskDomainId}"); $this->resetServer(); if ($response->successful()) { Log::info('Xoá domain thành công', ['plesk_id' => $pleskDomainId, 'status' => $response->status()]); return true; } Log::error('Xoá domain thất bại', [ 'plesk_id' => $pleskDomainId, 'status' => $response->status(), 'response' => $response->body(), ]); return false; } catch (\Exception $e) { Log::error('Exception khi xoá domain', ['plesk_id' => $pleskDomainId, 'error' => $e->getMessage()]); return false; } } public function addServerById(int $serverId): bool { $this->server = $this->serverRepository->find($serverId); return !empty($this->server); } private function getServer(): ?DnsServer { return $this->serverRepository->getActived()->first(); } private function resetServer(): void { $this->server = null; } }