feat: lots more improvements

Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
2026-04-25 15:43:56 -04:00
parent 6ab61301dc
commit 7485e4c897
9 changed files with 403 additions and 125 deletions

View File

@@ -22,14 +22,11 @@ use KTXM\ProviderImap\Stores\ServiceStore;
/**
* IMAP Mail Provider
*
* Registers IMAP as a mail provider and handles service lifecycle:
* list / fetch / create / modify / destroy / discover / test.
*/
class Provider implements ProviderServiceMutateInterface, ProviderServiceDiscoverInterface, ProviderServiceTestInterface
{
public const JSON_TYPE = ProviderBaseInterface::JSON_TYPE;
public const JSON_TYPE = ProviderBaseInterface::JSON_TYPE;
protected const PROVIDER_IDENTIFIER = 'imap';
protected const PROVIDER_LABEL = 'IMAP Mail Provider';
protected const PROVIDER_DESCRIPTION = 'Provides mail services via the IMAP protocol';
@@ -49,8 +46,6 @@ class Provider implements ProviderServiceMutateInterface, ProviderServiceDiscove
private readonly ServiceStore $serviceStore,
) {}
// ── ProviderBaseInterface ─────────────────────────────────────────────────
public function jsonSerialize(): array
{
return [
@@ -101,23 +96,24 @@ class Provider implements ProviderServiceMutateInterface, ProviderServiceDiscove
return $this->providerAbilities;
}
// ── ProviderServiceMutateInterface ────────────────────────────────────────
public function serviceList(string $tenantId, string $userId, array $filter = []): array
{
$list = $this->serviceStore->list($tenantId, $userId, $filter);
$result = [];
foreach ($list as $entry) {
$service = new Service();
$service->fromStore($entry);
$result[$service->identifier()] = $service;
foreach ($list as $serviceData) {
$serviceInstance = $this->serviceFresh()->fromStore($serviceData);
$list[$serviceInstance->identifier()] = $serviceInstance;
}
return $result;
return $list;
}
public function serviceFetch(string $tenantId, string $userId, string|int $identifier): ?Service
{
return $this->serviceStore->fetch($tenantId, $userId, $identifier);
$serviceData = $this->serviceStore->fetch($tenantId, $userId, $identifier);
if ($serviceData === null) {
return null;
}
$serviceInstance = $this->serviceFresh()->fromStore($serviceData);
return $serviceInstance;
}
public function serviceFindByAddress(string $tenantId, string $userId, string $address): ?Service
@@ -137,7 +133,7 @@ class Provider implements ProviderServiceMutateInterface, ProviderServiceDiscove
return $this->serviceStore->extant($tenantId, $userId, $identifiers);
}
public function serviceFresh(): ResourceServiceMutateInterface
public function serviceFresh(): Service
{
return new Service();
}
@@ -145,21 +141,21 @@ class Provider implements ProviderServiceMutateInterface, ProviderServiceDiscove
public function serviceCreate(string $tenantId, string $userId, ResourceServiceMutateInterface $service): string
{
if (!($service instanceof Service)) {
throw new \InvalidArgumentException('Service must be an instance of IMAP Service');
throw new \InvalidArgumentException('Service must be instance of IMAP Service');
}
$created = $this->serviceStore->create($tenantId, $userId, $service);
return (string) $created->identifier();
return (string) $created['sid'];
}
public function serviceModify(string $tenantId, string $userId, ResourceServiceMutateInterface $service): string
{
if (!($service instanceof Service)) {
throw new \InvalidArgumentException('Service must be an instance of IMAP Service');
throw new \InvalidArgumentException('Service must be instance of IMAP Service');
}
$updated = $this->serviceStore->modify($tenantId, $userId, $service);
return (string) $updated->identifier();
return (string) $updated['sid'];
}
public function serviceDestroy(string $tenantId, string $userId, ResourceServiceMutateInterface $service): bool
@@ -171,23 +167,19 @@ class Provider implements ProviderServiceMutateInterface, ProviderServiceDiscove
return $this->serviceStore->delete($tenantId, $userId, $service->identifier());
}
// ── ProviderServiceDiscoverInterface ──────────────────────────────────────
public function serviceDiscover(
string $tenantId,
string $userId,
string $identity,
string $tenantId,
string $userId,
string $identity,
?string $location = null,
?string $secret = null,
): ?ResourceServiceLocationInterface {
?string $secret = null
): ResourceServiceLocationInterface|null {
$discovery = new Discovery();
// TODO: Make SSL verification configurable per-tenant
$verifySSL = true;
return $discovery->discover($identity, $location, $secret, $verifySSL);
}
// ── ProviderServiceTestInterface ──────────────────────────────────────────
public function serviceTest(ServiceBaseInterface $service, array $options = []): array
{
$startTime = microtime(true);

View File

@@ -168,7 +168,7 @@ class Service implements ServiceBaseInterface, ServiceMutableInterface, ServiceC
], fn($v) => $v !== null);
}
public function jsonDeserialize(array|string $data): static
public function jsonDeserialize(array|string $data, bool $delta = false): static
{
if (is_string($data)) {
$data = json_decode($data, true, 512, JSON_THROW_ON_ERROR);