Files
coolify/app/Traits/HasSmtpServers.php
033f0c84da v4.7 (#12478)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com>
Co-authored-by: Aditya Tripathi <aditya@climactic.co>
2026-11-06 14:25:02 +01:00

118 lines
3.3 KiB
PHP

<?php
namespace App\Traits;
use Illuminate\Support\Str;
/**
* Named SMTP servers for email settings.
*
* The smtp_* columns always hold the server in use, so sending and the API read them as before.
* smtp_server_name is the name of that server. smtp_servers holds the other saved servers;
* switching swaps the server in use with a saved one. The methods change the model but do not save it.
*
* @property ?string $smtp_server_name
* @property ?array<int, array<string, mixed>> $smtp_servers
*/
trait HasSmtpServers
{
public const DEFAULT_SMTP_SERVER_NAME = 'Default';
/**
* The columns that belong to one SMTP server, including its sender, because each server
* usually sends from its own verified domain.
*/
public const SMTP_SERVER_COLUMNS = [
'smtp_from_address',
'smtp_from_name',
'smtp_host',
'smtp_port',
'smtp_encryption',
'smtp_username',
'smtp_password',
'smtp_timeout',
'smtp_ehlo_domain',
];
public function initializeHasSmtpServers(): void
{
$this->mergeCasts(['smtp_servers' => 'encrypted:array']);
$this->makeHidden('smtp_servers');
}
public function smtpServerName(): string
{
return filled($this->smtp_server_name) ? $this->smtp_server_name : self::DEFAULT_SMTP_SERVER_NAME;
}
/**
* @return list<array<string, mixed>>
*/
public function savedSmtpServers(): array
{
return array_values($this->smtp_servers ?? []);
}
/**
* Keep the server in use in the saved list, so that new values can replace it.
* A server without a host has nothing worth keeping.
*/
public function keepActiveSmtpServer(): void
{
if (blank($this->smtp_host)) {
return;
}
$server = ['id' => (string) Str::uuid(), 'name' => $this->smtpServerName()];
foreach (self::SMTP_SERVER_COLUMNS as $column) {
$server[$column] = $this->{$column};
}
$this->smtp_servers = [...$this->savedSmtpServers(), $server];
}
/**
* Use the saved server with the given ID, and keep the server in use in the saved list.
*/
public function switchToSmtpServer(string $id): bool
{
$target = collect($this->savedSmtpServers())->firstWhere('id', $id);
if ($target === null) {
return false;
}
$this->smtp_servers = collect($this->savedSmtpServers())->reject(fn (array $server) => $server['id'] === $id)->values()->all();
$this->keepActiveSmtpServer();
$this->useSmtpServer($target);
return true;
}
/**
* Delete the server in use and use the first saved server instead.
*/
public function deleteActiveSmtpServer(): bool
{
$servers = $this->savedSmtpServers();
if ($servers === []) {
return false;
}
$this->smtp_servers = array_slice($servers, 1);
$this->useSmtpServer($servers[0]);
return true;
}
/**
* @param array<string, mixed> $server
*/
private function useSmtpServer(array $server): void
{
$this->smtp_server_name = $server['name'] ?? null;
foreach (self::SMTP_SERVER_COLUMNS as $column) {
$this->{$column} = $server[$column] ?? null;
}
}
}