* SPDX-License-Identifier: AGPL-3.0-or-later */ namespace KTXM\ProviderImap\Providers; use KTXM\ProviderImap\Client\ConnectionConfig; use KTXM\ProviderImap\Client\ConnectionSecurity; use KTXF\Resource\Provider\ResourceServiceLocationInterface; /** * IMAP Service Location * * Connection details for an IMAP server (host / port / encryption). */ class ServiceLocation implements ResourceServiceLocationInterface { public function __construct( private string $host = '', private int $port = 993, private string $encryption = 'ssl', // ssl | tls | starttls | none private bool $verifyPeer = true, private bool $verifyPeerName = true, private bool $allowSelfSigned = false, ) {} // ── Serialisation ──────────────────────────────────────────────────────── public function toStore(): array { return $this->jsonSerialize(); } public function fromStore(array $data): static { return $this->jsonDeserialize($data); } public function jsonSerialize(): array { return array_filter([ 'type' => self::TYPE_URI, 'host' => $this->host, 'port' => $this->port, 'encryption' => $this->encryption, 'verifyPeer' => $this->verifyPeer, 'verifyPeerName' => $this->verifyPeerName, 'allowSelfSigned' => $this->allowSelfSigned, ], fn($v) => $v !== null && $v !== ''); } public function jsonDeserialize(array|string $data): static { if (is_string($data)) { $data = json_decode($data, true); } $this->host = $data['host'] ?? ''; $this->port = (int)($data['port'] ?? 993); $this->encryption = $data['encryption'] ?? 'ssl'; $this->verifyPeer = $data['verifyPeer'] ?? true; $this->verifyPeerName = $data['verifyPeerName'] ?? true; $this->allowSelfSigned = $data['allowSelfSigned'] ?? false; return $this; } // ── ResourceServiceLocationInterface ───────────────────────────────────── public function type(): string { return self::TYPE_URI; } public function location(): string { return $this->encryption . '://' . $this->host . ':' . $this->port; } // ── Accessors ──────────────────────────────────────────────────────────── public function getHost(): string { return $this->host; } public function setHost(string $v): void { $this->host = $v; } public function getPort(): int { return $this->port; } public function setPort(int $v): void { $this->port = $v; } public function getEncryption(): string { return $this->encryption; } public function setEncryption(string $v): void { $this->encryption = $v; } public function getVerifyPeer(): bool { return $this->verifyPeer; } public function setVerifyPeer(bool $v): void { $this->verifyPeer = $v; } public function getVerifyPeerName(): bool { return $this->verifyPeerName; } public function setVerifyPeerName(bool $v): void { $this->verifyPeerName = $v; } public function getAllowSelfSigned(): bool { return $this->allowSelfSigned; } public function setAllowSelfSigned(bool $v): void { $this->allowSelfSigned = $v; } // ── Client helpers ─────────────────────────────────────────────────────── /** * Build a standalone IMAP client ConnectionConfig from this location. */ public function toConnectionConfig(?string $username = null, ?string $password = null): ConnectionConfig { $security = match ($this->encryption) { 'ssl', 'tls' => ConnectionSecurity::Tls, 'starttls' => ConnectionSecurity::StartTls, default => ConnectionSecurity::Plain, }; return new ConnectionConfig( host: $this->host, port: $this->port, security: $security, username: $username, password: $password, verifyPeer: $this->verifyPeer, verifyPeerName: $this->verifyPeerName, allowSelfSigned: $this->allowSelfSigned, ); } }