settings->get('mailgun.api_key', '') !== '' && $this->settings->get('mailgun.domain', '') !== '' && $this->settings->get('alerts.email', '') !== ''; } public function send(string $recipient, string $subject, string $html): array { if (!$this->configured()) { throw new RuntimeException('Mailgun settings are incomplete.'); } $region = (string) $this->settings->get('mailgun.region', 'us'); $host = $region === 'eu' ? 'api.eu.mailgun.net' : 'api.mailgun.net'; $domain = (string) $this->settings->get('mailgun.domain', ''); $endpoint = sprintf('https://%s/v3/%s/messages', $host, rawurlencode($domain)); $body = http_build_query([ 'from' => (string) $this->settings->get('mailgun.from', ''), 'to' => $recipient, 'subject' => $subject, 'html' => $html, ]); $context = stream_context_create([ 'http' => [ 'method' => 'POST', 'header' => [ 'Authorization: Basic ' . base64_encode('api:' . $this->settings->get('mailgun.api_key', '')), 'Content-Type: application/x-www-form-urlencoded', 'Content-Length: ' . strlen($body), ], 'content' => $body, 'ignore_errors' => true, 'timeout' => 15, ], ]); $response = @file_get_contents($endpoint, false, $context); $statusLine = $http_response_header[0] ?? 'HTTP/1.1 500 Unknown response'; preg_match('/\s(\d{3})\s/', $statusLine, $matches); $status = (int) ($matches[1] ?? 500); if ($response === false || $status >= 400) { throw new RuntimeException('Mailgun rejected the message: ' . ($response ?: $statusLine)); } return ['status' => $status, 'body' => $response]; } }