ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
MailBoxQuery.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
21namespace ILIAS\Mail\Message;
22
25use DateTimeImmutable;
26use DateTimeZone;
29
31{
32 private const MailBoxOrderColumn DEFAULT_ORDER_COLUMN = MailBoxOrderColumn::SEND_TIME;
33 private const string DEFAULT_ORDER_DIRECTION = Order::ASC;
34
36 private ?int $folder_id = null;
37 private ?string $sender = null;
38 private ?string $recipients = null;
39 private ?string $subject = null;
40 private ?string $body = null;
41 private ?bool $is_unread = null;
42 private ?bool $is_system = null;
43 private ?bool $has_attachment = null;
44 private ?DateTimeImmutable $period_start = null;
45 private ?DateTimeImmutable $period_end = null;
47 private ?array $filtered_ids = null;
48 private int $limit = 999999;
49 private int $offset = 0;
52
53 public function __construct(
54 private readonly int $user_id,
55 ) {
56 global $DIC;
57 $this->db = $DIC->database();
58 }
59
60 public function withFolderId(?int $folder_id): MailBoxQuery
61 {
62 $clone = clone $this;
63 $clone->folder_id = $folder_id;
64
65 return $clone;
66 }
67
68 public function withSender(?string $sender): MailBoxQuery
69 {
70 $clone = clone $this;
71 $clone->sender = $sender;
72
73 return $clone;
74 }
75
76 public function withRecipients(?string $recipients): MailBoxQuery
77 {
78 $clone = clone $this;
79 $clone->recipients = $recipients;
80
81 return $clone;
82 }
83
84 public function withSubject(?string $subject): MailBoxQuery
85 {
86 $clone = clone $this;
87 $clone->subject = $subject;
88
89 return $clone;
90 }
91
92 public function withBody(?string $body): MailBoxQuery
93 {
94 $clone = clone $this;
95 $clone->body = $body;
96
97 return $clone;
98 }
99
100 public function withIsUnread(?bool $is_unread): MailBoxQuery
101 {
102 $clone = clone $this;
103 $clone->is_unread = $is_unread;
104
105 return $clone;
106 }
107
108 public function withIsSystem(?bool $is_system): MailBoxQuery
109 {
110 $clone = clone $this;
111 $clone->is_system = $is_system;
112
113 return $clone;
114 }
115
117 {
118 $clone = clone $this;
119 $clone->has_attachment = $has_attachment;
120
121 return $clone;
122 }
123
124 public function withPeriodStart(?DateTimeImmutable $period_start): MailBoxQuery
125 {
126 $clone = clone $this;
127 $clone->period_start = $period_start;
128
129 return $clone;
130 }
131
132 public function withPeriodEnd(?DateTimeImmutable $period_end): MailBoxQuery
133 {
134 $clone = clone $this;
135 $clone->period_end = $period_end;
136
137 return $clone;
138 }
139
144 {
145 $clone = clone $this;
146 $clone->filtered_ids = $filtered_ids;
147
148 return $clone;
149 }
150
151 public function withLimit(int $limit): MailBoxQuery
152 {
153 $clone = clone $this;
154 $clone->limit = $limit;
155
156 return $clone;
157 }
158
159 public function withOffset(int $offset): MailBoxQuery
160 {
161 $clone = clone $this;
162 $clone->offset = $offset;
163
164 return $clone;
165 }
166
168 {
169 $clone = clone $this;
170 if ($order_column !== null) {
171 $clone->order_column = $order_column;
172 } else {
173 $clone->order_column = self::DEFAULT_ORDER_COLUMN;
174 }
175
176 return $clone;
177 }
178
180 {
181 $clone = clone $this;
182 if (\in_array($order_direction, [Order::ASC, Order::DESC], true)) {
183 $clone->order_direction = $order_direction;
184 } else {
185 $clone->order_direction = self::DEFAULT_ORDER_DIRECTION;
186 }
187
188 return $clone;
189 }
190
194 public function countUnread(): int
195 {
196 return $this->withIsUnread(true)->count();
197 }
198
202 public function count(): int
203 {
204 if ($this->filtered_ids === []) {
205 return 0;
206 }
207
208 $query = 'SELECT COUNT(m.mail_id) cnt '
209 . $this->getFrom()
210 . $this->getWhere();
211
212 $res = $this->db->query($query);
213 if ($row = $this->db->fetchAssoc($res)) {
214 return (int) $row['cnt'];
215 }
216
217 return 0;
218 }
219
224 public function queryMailIds(): array
225 {
226 if ($this->filtered_ids === []) {
227 return [];
228 }
229
230 $query = 'SELECT m.mail_id '
231 . $this->getFrom()
232 . $this->getWhere();
233
234 $ids = [];
235 $res = $this->db->query($query);
236 while ($row = $this->db->fetchAssoc($res)) {
237 $ids[] = (int) $row['mail_id'];
238 }
239
240 return $ids;
241 }
242
248 public function query($short): array
249 {
250 if ($this->filtered_ids === []) {
251 return [];
252 }
253
254 if ($short) {
255 $query = 'SELECT m.mail_id, m.user_id, m.folder_id, m.sender_id, m.send_time, '
256 . 'm.m_status, m.m_subject, m.import_name, m.rcp_to, m.attachments'
257 . $this->getFrom()
258 . $this->getWhere();
259 } else {
260 $query = 'SELECT m.*'
261 . $this->getFrom()
262 . $this->getWhere();
263 }
264
265 if ($this->order_column === MailBoxOrderColumn::FROM) {
266 $query .= ' ORDER BY '
267 . ' u.firstname ' . $this->order_direction . ', '
268 . ' u.lastname ' . $this->order_direction . ', '
269 . ' u.login ' . $this->order_direction . ', '
270 . ' m.import_name ' . $this->order_direction;
271 } else {
272 $query .= ' ORDER BY ' . $this->order_column->value . ' ' . $this->order_direction;
273 }
274
275 $this->db->setLimit($this->limit, $this->offset);
276 $res = $this->db->query($query);
277
278 $set = [];
279 while ($row = $this->db->fetchAssoc($res)) {
280 $set[] = new MailRecordData(
281 isset($row['mail_id']) ? (int) $row['mail_id'] : 0,
282 isset($row['user_id']) ? (int) $row['user_id'] : 0,
283 isset($row['folder_id']) ? (int) $row['folder_id'] : 0,
284 isset($row['sender_id']) ? (int) $row['sender_id'] : null,
285 isset($row['send_time']) ? new DateTimeImmutable($row['send_time']) : null,
286 isset($row['m_status']) ? (string) $row['m_status'] : null,
287 isset($row['m_subject']) ? (string) $row['m_subject'] : null,
288 isset($row['import_name']) ? (string) $row['import_name'] : null,
289 isset($row['use_placeholders']) ? (bool) $row['use_placeholders'] : false,
290 isset($row['m_message']) ? (string) $row['m_message'] : null,
291 isset($row['rcp_to']) ? (string) $row['rcp_to'] : null,
292 isset($row['rcp_cc']) ? (string) $row['rcp_cc'] : null,
293 isset($row['rcp_bcc']) ? (string) $row['rcp_bcc'] : null,
294 isset($row['attachments']) ? (array) unserialize(
295 stripslashes($row['attachments']),
296 ['allowed_classes' => false]
297 ) : [],
298 isset($row['tpl_ctx_id']) ? (string) $row['tpl_ctx_id'] : null,
299 isset($row['tpl_ctx_params']) ? (string) $row['tpl_ctx_params'] : null
300 );
301 }
302
303 return $set;
304 }
305
306 private function getFrom()
307 {
308 return " FROM mail m
309 LEFT JOIN usr_data u ON u.usr_id = m.sender_id
310 LEFT JOIN usr_pref p ON p.usr_id = m.sender_id AND p.keyword = 'public_profile'";
311 }
312
313 private function getWhere(): string
314 {
315 $parts = [];
316
317 // minimum condition: only mailbox of the given user
318 $parts[] = 'm.user_id = ' . $this->db->quote($this->user_id, ilDBConstants::T_INTEGER);
319
320 // sender conditions have to respect searchability and visibility of profile fields
321 $sender_conditions = [];
322 if (($this->sender ?? '') !== '') {
323 $sender_conditions[] = $this->db->like('u.login', ilDBConstants::T_TEXT, '%%' . $this->sender . '%%');
324
325 if (ilUserSearchOptions::_isEnabled('firstname')) {
326 $sender_conditions[] = '(' .
327 $this->db->like('u.firstname', ilDBConstants::T_TEXT, '%%' . $this->sender . '%%')
328 . " AND p.value = 'y')";
329 }
330
331 if (ilUserSearchOptions::_isEnabled('lastname')) {
332 $sender_conditions[] = '(' .
333 $this->db->like('u.lastname', ilDBConstants::T_TEXT, '%%' . $this->sender . '%%')
334 . " AND p.value = 'y')";
335 }
336 }
337 if (!empty($sender_conditions)) {
338 $parts[] = '(' . implode(' OR ', $sender_conditions) . ')';
339 }
340
341 // other text conditions
342 $text_conditions = [
343 [$this->recipients, 'CONCAT(CONCAT(m.rcp_to, m.rcp_cc), m.rcp_bcc)'],
344 [$this->subject, 'm.m_subject'],
345 [$this->body, 'm.m_message'],
346 ];
347
348 foreach ($text_conditions as $cond) {
349 if (($cond[0] ?? '') !== '') {
350 $parts[] = $this->db->like(
351 $cond[1],
353 '%%' . $cond[0] . '%%',
354 false
355 );
356 }
357 }
358
359 if ($this->folder_id !== null) {
360 $parts[] = 'm.folder_id = ' . $this->db->quote($this->folder_id, ilDBConstants::T_INTEGER);
361 }
362
363 if ($this->is_unread === true) {
364 $parts[] = 'm.m_status = ' . $this->db->quote('unread', 'text');
365 } elseif ($this->is_unread === false) {
366 $parts[] = 'm.m_status != ' . $this->db->quote('unread', 'text');
367 }
368
369 if ($this->is_system === true) {
370 $parts[] = 'm.sender_id = ' . $this->db->quote(ANONYMOUS_USER_ID, ilDBConstants::T_INTEGER);
371 } elseif ($this->is_system === false) {
372 $parts[] = 'm.sender_id != ' . $this->db->quote(ANONYMOUS_USER_ID, ilDBConstants::T_INTEGER);
373 }
374
375 if ($this->has_attachment === true) {
376 $parts[] = '(m.attachments != ' . $this->db->quote(serialize(null), ilDBConstants::T_TEXT)
377 . ' AND m.attachments != ' . $this->db->quote(serialize([]), ilDBConstants::T_TEXT) . ')';
378 } elseif ($this->has_attachment === false) {
379 $parts[] = '(m.attachments = ' . $this->db->quote(serialize(null), ilDBConstants::T_TEXT)
380 . ' OR m.attachments = ' . $this->db->quote(serialize([]), ilDBConstants::T_TEXT) . ')';
381 }
382
383 if ($this->period_start !== null) {
384 $parts[] = 'm.send_time >= ' . $this->db->quote(
385 // convert to server time zone (set by ilias initialisation)
386 $this->period_start
387 ->setTimezone(new DateTimeZone(date_default_timezone_get()))
388 ->format('Y-m-d H:i:s'),
390 );
391 }
392
393 if ($this->period_end !== null) {
394 $parts[] = 'm.send_time <= ' . $this->db->quote(
395 // convert to server time zone (set by ilias initialisation)
396 $this->period_end
397 ->setTimezone(new DateTimeZone(date_default_timezone_get()))
398 ->format('Y-m-d H:i:s'),
400 );
401 }
402
403 if (!empty($this->filtered_ids)) {
404 $parts[] = $this->db->in(
405 'm.mail_id',
406 $this->filtered_ids,
407 false,
409 ) . ' ';
410 }
411
412 if ($parts !== []) {
413 return ' WHERE ' . implode(' AND ', $parts);
414 }
415
416 return '';
417 }
418}
Both the subject and the direction need to be specified when expressing an order.
Definition: Order.php:29
const DESC
Definition: Order.php:31
const MailBoxOrderColumn DEFAULT_ORDER_COLUMN
withOrderColumn(?MailBoxOrderColumn $order_column)
countUnread()
Count the number of unread mails with applied filter.
withFilteredIds(?array $filtered_ids)
withOrderDirection(?string $order_direction)
count()
Count the number of all mails with applied filter.
queryMailIds()
Get a list of mail ids.
withPeriodStart(?DateTimeImmutable $period_start)
DateTimeImmutable $period_start
MailBoxOrderColumn $order_column
__construct(private readonly int $user_id,)
withHasAttachment(?bool $has_attachment)
query($short)
Query for mail data with applied filter.
withRecipients(?string $recipients)
withPeriodEnd(?DateTimeImmutable $period_end)
Class ilDBConstants.
Class ilUserSearchOptions.
const ANONYMOUS_USER_ID
Definition: constants.php:27
Interface ilDBInterface.
$res
Definition: ltiservices.php:69
if($clientAssertionType !='urn:ietf:params:oauth:client-assertion-type:jwt-bearer'|| $grantType !='client_credentials') $parts
Definition: ltitoken.php:61
global $DIC
Definition: shib_login.php:26