1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
|
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OC\Mail\Provider;
use OC\AppFramework\Bootstrap\Coordinator;
use OCP\Mail\Provider\IManager;
use OCP\Mail\Provider\IProvider;
use OCP\Mail\Provider\IService;
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class Manager implements IManager {
protected ?array $providersCollection = null;
public function __construct(
private Coordinator $coordinator,
private ContainerInterface $container,
private LoggerInterface $logger,
) {
}
/**
* Determine if any mail providers are registered
*
* @since 30.0.0
*
* @return bool
*/
public function has(): bool {
// return true if collection has any providers
return !empty($this->providers());
}
/**
* Retrieve a count of how many mail providers are registered
*
* @since 30.0.0
*
* @return int
*/
public function count(): int {
// return count of providers in collection
return count($this->providers());
}
/**
* Retrieve which mail providers are registered
*
* @since 30.0.0
*
* @return array<string,string> collection of provider id and label ['jmap' => 'JMap Connector']
*/
public function types(): array {
// construct types collection
$types = [];
// extract id and name from providers collection
foreach ($this->providers() as $entry) {
$types[$entry->id()] = $entry->label();
}
// return types collection
return $types;
}
/**
* Retrieve all registered mail providers
*
* @since 30.0.0
*
* @return array<string,IProvider> collection of provider id and object ['jmap' => IProviderObject]
*/
public function providers(): array {
// evaluate if we already have a cached collection of providers and return the collection if we do
if (is_array($this->providersCollection)) {
return $this->providersCollection;
}
// retrieve server registration context
$context = $this->coordinator->getRegistrationContext();
// evaluate if registration context was returned
if ($context === null) {
return [];
}
// initilize cached collection
$this->providersCollection = [];
// iterate through all registered mail providers
foreach ($context->getMailProviders() as $entry) {
try {
/** @var IProvider $provider */
// object provider
$provider = $this->container->get($entry->getService());
// add provider to cache collection
$this->providersCollection[$provider->id()] = $provider;
} catch (Throwable $e) {
$this->logger->error(
'Could not load mail provider ' . $entry->getService() . ': ' . $e->getMessage(),
['exception' => $e]
);
}
}
// return mail provider collection
return $this->providersCollection;
}
/**
* Retrieve a provider with a specific id
*
* @since 30.0.0
*
* @param string $providerId provider id
*
* @return IProvider|null
*/
public function findProviderById(string $providerId): IProvider | null {
// evaluate if we already have a cached collection of providers
if (!is_array($this->providersCollection)) {
$this->providers();
}
if (isset($this->providersCollection[$providerId])) {
return $this->providersCollection[$providerId];
}
// return null if provider was not found
return null;
}
/**
* Retrieve all services for all registered mail providers
*
* @since 30.0.0
*
* @param string $userId user id
*
* @return array<string,array<string,IService>> collection of provider id, service id and object ['jmap' => ['Service1' => IServiceObject]]
*/
public function services(string $userId): array {
// initilize collection
$services = [];
// retrieve and iterate through mail providers
foreach ($this->providers() as $entry) {
// retrieve collection of services
$mailServices = $entry->listServices($userId);
// evaluate if mail services collection is not empty and add results to services collection
if (!empty($mailServices)) {
$services[$entry->id()] = $mailServices;
}
}
// return collection
return $services;
}
/**
* Retrieve a service with a specific id
*
* @since 30.0.0
*
* @param string $userId user id
* @param string $serviceId service id
* @param string $providerId provider id
*
* @return IService|null returns service object or null if none found
*/
public function findServiceById(string $userId, string $serviceId, ?string $providerId = null): IService | null {
// evaluate if provider id was specified
if ($providerId !== null) {
// find provider
$provider = $this->findProviderById($providerId);
// evaluate if provider was found
if ($provider instanceof IProvider) {
// find service with specific id
$service = $provider->findServiceById($userId, $serviceId);
// evaluate if mail service was found
if ($service instanceof IService) {
return $service;
}
}
} else {
// retrieve and iterate through mail providers
foreach ($this->providers() as $provider) {
// find service with specific id
$service = $provider->findServiceById($userId, $serviceId);
// evaluate if mail service was found
if ($service instanceof IService) {
return $service;
}
}
}
// return null if no match was found
return null;
}
/**
* Retrieve a service for a specific mail address
* returns first service with specific primary address
*
* @since 30.0.0
*
* @param string $userId user id
* @param string $address mail address (e.g. test@example.com)
* @param string $providerId provider id
*
* @return IService|null returns service object or null if none found
*/
public function findServiceByAddress(string $userId, string $address, ?string $providerId = null): IService | null {
// evaluate if provider id was specified
if ($providerId !== null) {
// find provider
$provider = $this->findProviderById($providerId);
// evaluate if provider was found
if ($provider instanceof IProvider) {
// find service with specific mail address
$service = $provider->findServiceByAddress($userId, $address);
// evaluate if mail service was found
if ($service instanceof IService) {
return $service;
}
}
} else {
// retrieve and iterate through mail providers
foreach ($this->providers() as $provider) {
// find service with specific mail address
$service = $provider->findServiceByAddress($userId, $address);
// evaluate if mail service was found
if ($service instanceof IService) {
return $service;
}
}
}
// return null if no match was found
return null;
}
}
|