ILIAS  trunk Revision v11.0_alpha-1723-g8e69f309bab
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
class.ilForumNotificationDataProvider.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
26 {
27  protected int $obj_id = 0;
28  protected ?string $post_user_name = null;
29  protected ?string $update_user_name = null;
30  public int $pos_author_id = 0;
31  protected int $forum_id = 0;
34  protected string $forum_title = '';
35  protected string $thread_title = '';
37  protected array $attachments = [];
38  private readonly ilDBInterface $db;
39  private readonly ilAccessHandler $access;
40  private readonly ilObjUser $user;
41  private readonly ilTree $tree;
42  protected bool $is_anonymized = false;
43 
44  public function __construct(
45  public ilForumPost $objPost,
46  protected int $ref_id,
47  private readonly ilForumNotificationCache $notificationCache
48  ) {
49  global $DIC;
50  $this->db = $DIC->database();
51  $this->access = $DIC->access();
52  $this->user = $DIC->user();
53  $this->tree = $DIC->repositoryTree();
54  $this->obj_id = ilObject::_lookupObjId($ref_id);
55  $this->read();
56  }
57 
58  public function getRefId(): int
59  {
60  return $this->ref_id;
61  }
62 
63  public function getObjId(): int
64  {
65  return $this->obj_id;
66  }
67 
68  public function getThreadId(): int
69  {
70  return $this->objPost->getThreadId();
71  }
72 
73  public function getPostId(): int
74  {
75  return $this->objPost->getId();
76  }
77 
78  public function getForumId(): int
79  {
80  return $this->forum_id;
81  }
82 
83  public function closestContainer(): ?ilObject
84  {
86  }
87 
88  public function providesClosestContainer(): bool
89  {
90  return $this->closest_container !== null;
91  }
92 
93  public function getForumTitle(): string
94  {
95  return $this->forum_title;
96  }
97 
98  public function getThreadTitle(): string
99  {
100  return $this->thread_title;
101  }
102 
103  public function getPostTitle(): string
104  {
105  return $this->objPost->getSubject();
106  }
107 
108  public function getPostMessage(): string
109  {
110  return $this->objPost->getMessage();
111  }
112 
113  public function getPosDisplayUserId(): int
114  {
115  return $this->objPost->getDisplayUserId();
116  }
117 
118  public function getPostDate(): string
119  {
120  return $this->objPost->getCreateDate();
121  }
122 
123  public function getPostUpdate(): string
124  {
125  return $this->objPost->getChangeDate();
126  }
127 
128  public function isPostCensored(): bool
129  {
130  return $this->objPost->isCensored();
131  }
132 
133  public function getPostCensoredDate(): string
134  {
135  return $this->objPost->getCensoredDate();
136  }
137 
138  public function getCensorshipComment(): string
139  {
140  return $this->objPost->getCensorshipComment();
141  }
142 
146  public function getAttachments(): array
147  {
148  return $this->attachments;
149  }
150 
151  public function getPosUserAlias(): string
152  {
153  return $this->objPost->getUserAlias();
154  }
155 
156  public function isAnonymized(): bool
157  {
158  return $this->is_anonymized;
159  }
160 
161  public function getImportName(): string
162  {
163  return $this->objPost->getImportName();
164  }
165 
166  public function getPostUpdateUserId(): int
167  {
168  return $this->objPost->getUpdateUserId();
169  }
170 
171  public function getPostUserName(ilLanguage $user_lang): string
172  {
173  if ($this->post_user_name === null) {
174  $authorinfo = new ilForumAuthorInformation(
175  $this->getPosAuthorId(),
176  $this->getPosDisplayUserId(),
177  $this->getPosUserAlias(),
178  $this->getImportName(),
179  [],
180  $user_lang
181  );
182  $this->post_user_name = $this->getPublicUserInformation($authorinfo);
183  }
184 
185  return $this->post_user_name;
186  }
187 
188  public function getPostUpdateUserName(ilLanguage $user_lang): string
189  {
190  if ($this->update_user_name === null) {
191  $authorinfo = new ilForumAuthorInformation(
192  $this->getPosAuthorId(),
193  $this->getPostUpdateUserId(),
194  $this->getPosUserAlias(),
195  $this->getImportName(),
196  [],
197  $user_lang
198  );
199  $this->update_user_name = $this->getPublicUserInformation($authorinfo);
200  }
201 
202  // Possible Fix for #25432
203  if ($this->objPost->getUserAlias() && $this->objPost->getDisplayUserId() === 0
204  && $this->objPost->getPosAuthorId() === $this->objPost->getUpdateUserId()) {
205  return $this->objPost->getUserAlias();
206  }
207 
209  }
210 
211  public function getPublicUserInformation(ilForumAuthorInformation $authorinfo): string
212  {
213  if ($authorinfo->hasSuffix()) {
214  $public_name = $authorinfo->getAuthorName();
215  } else {
216  $public_name = $authorinfo->getAuthorShortName();
217 
218  if ($authorinfo->getAuthorName() && !$this->isAnonymized()) {
219  $public_name = $authorinfo->getAuthorName();
220  }
221  }
222 
223  return $public_name;
224  }
225 
226  protected function read(): void
227  {
228  $this->readForumData();
229  $this->readThreadTitle();
230  $this->readAttachments();
231  }
232 
233  private function readThreadTitle(): void
234  {
235  $cacheKey = $this->notificationCache->createKeyByValues([
236  'thread_title',
237  $this->getObjId()
238  ]);
239 
240  if (!$this->notificationCache->exists($cacheKey)) {
241  $result = $this->db->queryF(
242  '
243  SELECT thr_subject FROM frm_threads
244  WHERE thr_pk = %s',
245  ['integer'],
246  [$this->objPost->getThreadId()]
247  );
248 
249  $row = $this->db->fetchAssoc($result);
250  $this->notificationCache->store($cacheKey, $row);
251  }
252 
253  $row = $this->notificationCache->fetch($cacheKey);
254  $this->thread_title = $row['thr_subject'];
255  }
256 
257  private function readForumData(): void
258  {
259  $cacheKey = $this->notificationCache->createKeyByValues([
260  'forum_data',
261  $this->getObjId()
262  ]);
263 
264  if (!$this->notificationCache->exists($cacheKey)) {
265  $result = $this->db->queryF(
266  '
267  SELECT top_pk, top_name, frm_settings.anonymized FROM frm_data
268  INNER JOIN frm_settings ON top_frm_fk = frm_settings.obj_id
269  WHERE top_frm_fk = %s',
270  ['integer'],
271  [$this->getObjId()]
272  );
273 
274  $row = $this->db->fetchAssoc($result);
275 
276  $container = $this->determineClosestContainer($this->getRefId());
277  if ($container instanceof ilObjCourse || $container instanceof ilObjGroup) {
278  $row['closest_container'] = $container;
279  }
280 
281  $this->notificationCache->store($cacheKey, $row);
282  }
283 
284  $row ??= $this->notificationCache->fetch($cacheKey);
285  $this->forum_id = (int) $row['top_pk'];
286  $this->forum_title = (string) $row['top_name'];
287  $this->closest_container = $row['closest_container'] ?? null;
288 
289  $this->is_anonymized = (bool) $row['anonymized'];
290  }
291 
292  public function determineClosestContainer(int $frm_ref_id): ?ilObject
293  {
294  $cacheKey = $this->notificationCache->createKeyByValues([
295  'forum_container',
296  $frm_ref_id
297  ]);
298 
299  if (!$this->notificationCache->exists($cacheKey)) {
300  $ref_id = $this->tree->checkForParentType($frm_ref_id, 'crs');
301  if ($ref_id <= 0) {
302  $ref_id = $this->tree->checkForParentType($frm_ref_id, 'grp');
303  }
304 
305  if ($ref_id > 0) {
307  $this->notificationCache->store($cacheKey, $container);
308  return $container;
309  }
310  }
311 
312  return null;
313  }
314 
315  private function readAttachments(): void
316  {
318  $fileDataForum = new ilFileDataForum($this->getObjId(), $this->objPost->getId());
319  $filesOfPost = $fileDataForum->getFilesOfPost();
320 
321  $fileDataMail = new ilFileDataMail(ANONYMOUS_USER_ID);
322 
323  foreach ($filesOfPost as $attachment) {
324  $this->attachments[$attachment['path']] = $attachment['name'];
325  $fileDataMail->copyAttachmentFile($attachment['path'], $attachment['name']);
326  }
327  }
328  }
329 
333  public function getForumNotificationRecipients(int $notification_type): array
334  {
335  $event_type = $this->getEventType($notification_type);
336  $cacheKey = $this->notificationCache->createKeyByValues([
337  'forum',
338  $notification_type,
339  $this->getForumId(),
340  $this->user->getId()
341  ]);
342 
343  if (!$this->notificationCache->exists($cacheKey)) {
344  $condition = ' ';
345  if ($event_type === 0) {
346  $condition = ' OR frm_notification.interested_events >= ' . $this->db->quote(0, 'integer');
347  }
348 
349  $res = $this->db->queryF(
350  '
351  SELECT frm_notification.user_id FROM frm_notification, frm_data
352  WHERE frm_data.top_pk = %s
353  AND frm_notification.frm_id = frm_data.top_frm_fk
354  AND frm_notification.user_id != %s
355  AND (frm_notification.interested_events & %s ' . $condition . ')
356  GROUP BY frm_notification.user_id ',
357  ['integer', 'integer', 'integer'],
358  [$this->getForumId(), $this->user->getId(), $event_type]
359  );
360 
361  $rcps = $this->createRecipientArray($res);
362  $this->notificationCache->store($cacheKey, $rcps);
363  }
364 
365  $rcps = $this->notificationCache->fetch($cacheKey);
366 
367  return array_unique($rcps);
368  }
369 
373  public function getThreadNotificationRecipients(int $notification_type): array
374  {
375  if ($this->getThreadId() === 0) {
376  return [];
377  }
378 
379  $event_type = $this->getEventType($notification_type);
380  $cacheKey = $this->notificationCache->createKeyByValues([
381  'thread',
382  $notification_type,
383  $this->getThreadId(),
384  $this->user->getId()
385  ]);
386 
387  if (!$this->notificationCache->exists($cacheKey)) {
388  $condition = ' ';
389  if ($event_type === 0) {
390  $condition = ' OR interested_events >= ' . $this->db->quote(0, 'integer');
391  }
392 
393  $res = $this->db->queryF(
394  '
395  SELECT frm_notification.user_id
396  FROM frm_notification
397  INNER JOIN frm_threads ON frm_threads.thr_pk = frm_notification.thread_id
398  WHERE frm_notification.thread_id = %s
399  AND frm_notification.user_id != %s
400  AND (frm_notification.interested_events & %s ' . $condition . ')',
401  ['integer', 'integer', 'integer'],
402  [$this->getThreadId(), $this->user->getId(), $event_type]
403  );
404 
405  $usrIds = $this->createRecipientArray($res);
406  $this->notificationCache->store($cacheKey, $usrIds);
407  }
408 
409  return (array) $this->notificationCache->fetch($cacheKey);
410  }
411 
415  public function getPostAnsweredRecipients(): array
416  {
417  $cacheKey = $this->notificationCache->createKeyByValues([
418  'post_answered',
419  $this->objPost->getParentId()
420  ]);
421 
422  if (!$this->notificationCache->exists($cacheKey)) {
423  $parent_objPost = new ilForumPost($this->objPost->getParentId());
424 
425  $this->notificationCache->store($cacheKey, $parent_objPost);
426  }
427 
429  $parent_objPost = $this->notificationCache->fetch($cacheKey);
430  $rcps = [];
431  $rcps[] = $parent_objPost->getPosAuthorId();
432 
433  return $rcps;
434  }
435 
439  public function getPostActivationRecipients(): array
440  {
441  $cacheKey = $this->notificationCache->createKeyByValues([
442  'post_activation',
443  $this->getRefId()
444  ]);
445 
446  if (!$this->notificationCache->exists($cacheKey)) {
447  // get moderators to notify about needed activation
448  $rcps = ilForum::_getModerators($this->getRefId());
449  $this->notificationCache->store($cacheKey, $rcps);
450  }
451 
452  $rcps = $this->notificationCache->fetch($cacheKey);
453 
454  return (array) $rcps;
455  }
456 
457  public function getPosAuthorId(): int
458  {
459  return $this->pos_author_id;
460  }
461 
465  private function getRefIdsByObjId(int $objId): array
466  {
467  $cacheKey = $this->notificationCache->createKeyByValues([
468  'refs_by_obj_id',
469  $objId
470  ]);
471 
472  if (!$this->notificationCache->exists($cacheKey)) {
473  $this->notificationCache->store($cacheKey, ilObject::_getAllReferences($objId));
474  }
475 
476  return $this->notificationCache->fetch($cacheKey);
477  }
478 
482  private function createRecipientArray(ilDBStatement $statement): array
483  {
484  $refIds = $this->getRefIdsByObjId($this->getObjId());
485 
486  $usrIds = [];
487  while ($row = $this->db->fetchAssoc($statement)) {
488  foreach ($refIds as $refId) {
489  if ($this->access->checkAccessOfUser((int) $row['user_id'], 'read', '', $refId)) {
490  $usrIds[] = (int) $row['user_id'];
491  }
492  }
493  }
494 
495  return $usrIds;
496  }
497 
498  public function getDeletedBy(): string
499  {
500  if ($this->objPost->getUserAlias() && $this->objPost->getDisplayUserId() === 0
501  && $this->objPost->getPosAuthorId() === $this->user->getId()) {
502  return $this->objPost->getUserAlias();
503  }
504 
505  return $this->user->getLogin();
506  }
507 
508  private function getEventType(int $notification_type): int
509  {
510  return match ($notification_type) {
516  default => 0,
517  };
518  }
519 }
$res
Definition: ltiservices.php:66
getPublicUserInformation(ilForumAuthorInformation $authorinfo)
const ANONYMOUS_USER_ID
Definition: constants.php:27
This class handles all operations on files (attachments) in directory ilias_data/mail.
__construct(public ilForumPost $objPost, protected int $ref_id, private readonly ilForumNotificationCache $notificationCache)
static _getAllReferences(int $id)
get all reference ids for object ID
$objId
Definition: xapitoken.php:57
$refId
Definition: xapitoken.php:58
Class ilForumNotificationDataProvider.
$container
Definition: wac.php:36
static _lookupObjId(int $ref_id)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
$ref_id
Definition: ltiauth.php:65
static getInstanceByRefId(int $ref_id, bool $stop_on_error=true)
get an instance of an Ilias object by reference id
global $DIC
Definition: shib_login.php:22
Class ilForumNotificationCache.
Interface ilForumNotificationMailData.
static _getModerators(int $a_ref_id)
Class ilObjGroup.
getAuthorName(bool $without_short_name=false)