Files
server/shared/lib/Mail/Service/ServiceLocation.php
2025-12-21 10:09:54 -05:00

212 lines
5.4 KiB
PHP

<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: Sebastian Krupinski <krupinski01@gmail.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace KTXF\Mail\Service;
/**
* Mail Service Location Implementation
*
* Unified implementation supporting URI-based and socket-based connections.
*
* @since 2025.05.01
*/
class ServiceLocation implements IServiceLocation {
/**
* @param string $type Location type (uri, socket-single, socket-split)
* @param string|null $uri URI for API-based services
* @param string|null $inboundHost Inbound/primary host
* @param int|null $inboundPort Inbound/primary port
* @param string|null $inboundSecurity Inbound security (none, ssl, tls, starttls)
* @param string|null $outboundHost Outbound host (for split-socket)
* @param int|null $outboundPort Outbound port (for split-socket)
* @param string|null $outboundSecurity Outbound security (for split-socket)
*/
public function __construct(
private string $type,
private ?string $uri = null,
private ?string $inboundHost = null,
private ?int $inboundPort = null,
private ?string $inboundSecurity = null,
private ?string $outboundHost = null,
private ?int $outboundPort = null,
private ?string $outboundSecurity = null,
) {}
/**
* Creates a URI-based location (for API services)
*
* @since 2025.05.01
*
* @param string $uri
*
* @return self
*/
public static function uri(string $uri): self {
return new self(self::TYPE_URI, $uri);
}
/**
* Creates a single-socket location (e.g., SMTP only)
*
* @since 2025.05.01
*
* @param string $host
* @param int $port
* @param string $security
*
* @return self
*/
public static function socket(string $host, int $port, string $security = self::SECURITY_TLS): self {
return new self(
self::TYPE_SOCKET_SINGLE,
null,
$host,
$port,
$security
);
}
/**
* Creates a split-socket location (IMAP + SMTP)
*
* @since 2025.05.01
*
* @param string $inboundHost IMAP host
* @param int $inboundPort IMAP port
* @param string $inboundSecurity IMAP security
* @param string $outboundHost SMTP host
* @param int $outboundPort SMTP port
* @param string $outboundSecurity SMTP security
*
* @return self
*/
public static function splitSocket(
string $inboundHost,
int $inboundPort,
string $inboundSecurity,
string $outboundHost,
int $outboundPort,
string $outboundSecurity
): self {
return new self(
self::TYPE_SOCKET_SPLIT,
null,
$inboundHost,
$inboundPort,
$inboundSecurity,
$outboundHost,
$outboundPort,
$outboundSecurity
);
}
/**
* Creates from array data
*
* @since 2025.05.01
*
* @param array $data
*
* @return self
*/
public static function fromArray(array $data): self {
return new self(
$data['type'] ?? self::TYPE_SOCKET_SINGLE,
$data['uri'] ?? null,
$data['inboundHost'] ?? $data['host'] ?? null,
$data['inboundPort'] ?? $data['port'] ?? null,
$data['inboundSecurity'] ?? $data['security'] ?? null,
$data['outboundHost'] ?? null,
$data['outboundPort'] ?? null,
$data['outboundSecurity'] ?? null,
);
}
/**
* @inheritDoc
*/
public function getType(): string {
return $this->type;
}
/**
* @inheritDoc
*/
public function getUri(): ?string {
return $this->uri;
}
/**
* @inheritDoc
*/
public function getInboundHost(): ?string {
return $this->inboundHost;
}
/**
* @inheritDoc
*/
public function getInboundPort(): ?int {
return $this->inboundPort;
}
/**
* @inheritDoc
*/
public function getInboundSecurity(): ?string {
return $this->inboundSecurity;
}
/**
* @inheritDoc
*/
public function getOutboundHost(): ?string {
return $this->outboundHost ?? $this->inboundHost;
}
/**
* @inheritDoc
*/
public function getOutboundPort(): ?int {
return $this->outboundPort ?? $this->inboundPort;
}
/**
* @inheritDoc
*/
public function getOutboundSecurity(): ?string {
return $this->outboundSecurity ?? $this->inboundSecurity;
}
/**
* @inheritDoc
*/
public function jsonSerialize(): array {
$data = ['type' => $this->type];
if ($this->type === self::TYPE_URI) {
$data['uri'] = $this->uri;
} else {
$data['inboundHost'] = $this->inboundHost;
$data['inboundPort'] = $this->inboundPort;
$data['inboundSecurity'] = $this->inboundSecurity;
if ($this->type === self::TYPE_SOCKET_SPLIT) {
$data['outboundHost'] = $this->outboundHost;
$data['outboundPort'] = $this->outboundPort;
$data['outboundSecurity'] = $this->outboundSecurity;
}
}
return array_filter($data, fn($v) => $v !== null);
}
}