* SPDX-License-Identifier: AGPL-3.0-or-later */ namespace KTXM\ProviderImap\Smtp; use KTXM\ProviderImap\Smtp\Protocol\Response\Response; /** * Parsed EHLO capabilities. * * The first line of an EHLO reply is the server greeting/domain; every * subsequent line is a capability keyword optionally followed by parameters * (e.g. "AUTH PLAIN LOGIN", "SIZE 35882577"). */ final class SmtpCapabilities { /** * @param array> $keywords capability keyword => parameters */ private function __construct( private readonly array $keywords, ) {} public static function fromEhlo(Response $reply): self { $keywords = []; $lines = $reply->lines(); // Skip the first line (greeting/domain); the rest are capabilities. foreach (array_slice($lines, 1) as $line) { $parts = preg_split('/\s+/', trim($line)) ?: []; $keyword = strtoupper((string) array_shift($parts)); if ($keyword === '') { continue; } $keywords[$keyword] = array_map('strtoupper', $parts); } return new self($keywords); } public function has(string $keyword): bool { return isset($this->keywords[strtoupper($keyword)]); } public function supportsStartTls(): bool { return $this->has('STARTTLS'); } /** * @return list Advertised AUTH mechanisms (uppercased). */ public function authMechanisms(): array { return $this->keywords['AUTH'] ?? []; } public function maxSize(): ?int { $size = $this->keywords['SIZE'][0] ?? null; return $size !== null && ctype_digit($size) ? (int) $size : null; } }