fc3f4c28db
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
159 lines
4.1 KiB
PHP
159 lines
4.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* SPDX-FileCopyrightText: Sebastian Krupinski <krupinski01@gmail.com>
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
|
|
namespace KTXM\ProviderMailSystem\Stores;
|
|
|
|
use KTXC\Db\DataStore;
|
|
use KTXF\Utile\UUID;
|
|
use KTXM\ProviderMailSystem\Providers\Service;
|
|
|
|
/**
|
|
* System Mail Route Store
|
|
*
|
|
* Persists system mail routes (one MongoDB document per route) in the
|
|
* collection `provider_system_mail_services`. Routes are tenant scoped —
|
|
* they carry no user association and contain no transport credentials,
|
|
* only the mapping from a "@system" address to a backing provider/service.
|
|
*
|
|
* @since 2026.07.01
|
|
*/
|
|
class ServiceStore
|
|
{
|
|
protected const COLLECTION_NAME = 'provider_system_mail_services';
|
|
|
|
public function __construct(
|
|
protected readonly DataStore $dataStore,
|
|
) {}
|
|
|
|
/**
|
|
* List routes for a tenant, optionally filtered by route IDs
|
|
*/
|
|
public function list(string $tenantId, ?array $filter = null): array
|
|
{
|
|
$filterCondition = [
|
|
'tid' => $tenantId,
|
|
];
|
|
|
|
if (!empty($filter)) {
|
|
$filterCondition['sid'] = ['$in' => array_map('strval', $filter)];
|
|
}
|
|
|
|
$cursor = $this->dataStore->selectCollection(self::COLLECTION_NAME)->find($filterCondition);
|
|
|
|
$list = [];
|
|
foreach ($cursor as $entry) {
|
|
$list[$entry['sid']] = $entry;
|
|
}
|
|
return $list;
|
|
}
|
|
|
|
/**
|
|
* Check existence of routes by IDs for a tenant
|
|
*/
|
|
public function extant(string $tenantId, array $identifiers): array
|
|
{
|
|
if (empty($identifiers)) {
|
|
return [];
|
|
}
|
|
|
|
$cursor = $this->dataStore->selectCollection(self::COLLECTION_NAME)->find(
|
|
[
|
|
'tid' => $tenantId,
|
|
'sid' => ['$in' => array_map('strval', $identifiers)]
|
|
],
|
|
['projection' => ['sid' => 1]]
|
|
);
|
|
|
|
$existingIds = [];
|
|
foreach ($cursor as $document) {
|
|
$existingIds[] = $document['sid'];
|
|
}
|
|
|
|
$result = [];
|
|
foreach ($identifiers as $id) {
|
|
$result[(string)$id] = in_array((string)$id, $existingIds, true);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve a single route by ID
|
|
*/
|
|
public function fetch(string $tenantId, string|int $serviceId): ?array
|
|
{
|
|
$document = $this->dataStore->selectCollection(self::COLLECTION_NAME)->findOne([
|
|
'tid' => $tenantId,
|
|
'sid' => (string)$serviceId,
|
|
]);
|
|
|
|
if (!$document) {
|
|
return null;
|
|
}
|
|
|
|
return $document;
|
|
}
|
|
|
|
/**
|
|
* Create a new route
|
|
*/
|
|
public function create(string $tenantId, Service $service): array
|
|
{
|
|
$document = $service->toStore();
|
|
|
|
$document['tid'] = $tenantId;
|
|
$document['sid'] = UUID::v4();
|
|
$document['createdOn'] = new \MongoDB\BSON\UTCDateTime();
|
|
$document['modifiedOn'] = new \MongoDB\BSON\UTCDateTime();
|
|
|
|
$this->dataStore->selectCollection(self::COLLECTION_NAME)->insertOne($document);
|
|
|
|
return $document;
|
|
}
|
|
|
|
/**
|
|
* Modify an existing route
|
|
*/
|
|
public function modify(string $tenantId, Service $service): array
|
|
{
|
|
$serviceId = (string)$service->identifier();
|
|
if ($serviceId === '') {
|
|
throw new \InvalidArgumentException('Service ID is required for update');
|
|
}
|
|
|
|
$document = $service->toStore();
|
|
$document['modifiedOn'] = new \MongoDB\BSON\UTCDateTime();
|
|
unset($document['sid'], $document['tid'], $document['createdOn']);
|
|
|
|
$this->dataStore->selectCollection(self::COLLECTION_NAME)->updateOne(
|
|
[
|
|
'tid' => $tenantId,
|
|
'sid' => $serviceId,
|
|
],
|
|
['$set' => $document]
|
|
);
|
|
|
|
return $document;
|
|
}
|
|
|
|
/**
|
|
* Delete a route
|
|
*/
|
|
public function delete(string $tenantId, string|int $serviceId): bool
|
|
{
|
|
$result = $this->dataStore->selectCollection(self::COLLECTION_NAME)->deleteOne([
|
|
'tid' => $tenantId,
|
|
'sid' => (string)$serviceId,
|
|
]);
|
|
|
|
return $result->getDeletedCount() > 0;
|
|
}
|
|
|
|
}
|