getDnsMocks()[$domain])) { return DnsHelper::parseTxt(Configuration::getInstanceConfiguration()->getDnsMocks()[$domain]); } // Check the database if enabled if ($useDatabase) { // Return from the database cache if one exists // TODO: Implement renewal here $resolvedServer = ResolvedDnsRecordsManager::getDnsRecord($domain); if ($resolvedServer !== null) { return $resolvedServer; } } // Resolve DNS & Records $txtRecords = self::dnsGetTxtRecords($domain); if ($txtRecords === false) { throw new ResolutionException(sprintf("Failed to resolve DNS TXT records for %s", $domain)); } $fullRecord = self::concatenateTxtRecords($txtRecords); try { // Parse the TXT record using DnsHelper $record = DnsHelper::parseTxt($fullRecord); // Cache the resolved server record in the database if($useDatabase) { ResolvedDnsRecordsManager::addResolvedServer($domain, $record); } return $record; } catch (InvalidArgumentException $e) { throw new ResolutionException(sprintf("Failed to find valid SocialBox record for %s: %s", $domain, $e->getMessage())); } } /** * Retrieves the TXT records for a given domain using the dns_get_record function. * * @param string $domain The domain name to fetch TXT records for. * @return array|false An array of DNS TXT records on success, or false on failure. */ private static function dnsGetTxtRecords(string $domain): array|false { return @dns_get_record($domain, DNS_TXT); } /** * Concatenates an array of TXT records into a single string, filtering for SocialBox records. * * @param array $txtRecords An array of TXT records, where each record is expected to have a 'txt' key. * @return string A concatenated string of all relevant TXT records. */ private static function concatenateTxtRecords(array $txtRecords): string { $fullRecordBuilder = ''; foreach ($txtRecords as $txt) { if (isset($txt['txt'])) { $record = trim($txt['txt'], '" '); // Only include records that start with v=socialbox if (stripos($record, 'v=socialbox') === 0) { $fullRecordBuilder .= $record; } } } return $fullRecordBuilder; } /** * Retrieves the mocked records. * * @return array The list of mocked records. */ public static function getMockedRecords(): array { return self::$mockedRecords; } /** * Adds a mock DNS record for a specific domain. * * @param string $domain The domain name for which the DNS record is being mocked. * @param DnsRecord $record The DNS record to be associated with the specified domain. * @return void */ public static function addMock(string $domain, DnsRecord|string $record): void { if(isset(self::$mockedRecords[$domain])) { return; } if(is_string($record)) { $record = DnsHelper::parseTxt($record); } self::$mockedRecords[$domain] = $record; } /** * Clears all mocked records by resetting the mocked records array. * * @return void */ public static function clearMockedRecords(): void { self::$mockedRecords = []; } }