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