ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilMembershipNotifications.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
11 {
12  protected $ref_id; // [int]
13  protected $mode; // [int]
14  protected $custom; // [array]
15  protected $participants; // [ilParticipants]
16 
17  const VALUE_OFF = 0;
18  const VALUE_ON = 1;
19  const VALUE_BLOCKED = 2;
20 
21  const MODE_SELF = 1;
22  const MODE_ALL = 2;
23  const MODE_ALL_BLOCKED = 3;
24  const MODE_CUSTOM = 4;
25 
32  public function __construct($a_ref_id)
33  {
34  $this->ref_id = (int) $a_ref_id;
35  $this->custom = array();
36  $this->setMode(self::MODE_SELF);
37 
38  if ($this->ref_id) {
39  $this->read();
40  }
41  }
42 
48  public static function isActive()
49  {
50  global $DIC;
51 
52  $ilSetting = $DIC['ilSetting'];
53 
54  if (!$ilSetting->get("block_activated_news") || !$ilSetting->get("crsgrp_ntf")) {
55  return false;
56  }
57  return true;
58  }
59 
60  public static function isActiveForRefId(int $ref_id)
61  {
62  if (!self::isActive()) {
63  return false;
64  }
65  // see #31471, #30687, and ilNewsItem::getNewsForRefId
66  $obj_id = ilObject::_lookupObjId($ref_id);
68  $obj_id,
69  'cont_use_news',
70  true
71  ) || (
73  $obj_id,
74  'cont_show_news',
75  true
77  $obj_id,
78  'news_timeline'
79  )
80  )) {
81  return false;
82  }
83  return true;
84  }
85 
89  protected function read()
90  {
91  global $DIC;
92 
93  $ilDB = $DIC['ilDB'];
94 
95  $set = $ilDB->query("SELECT nmode mode" .
96  " FROM member_noti" .
97  " WHERE ref_id = " . $ilDB->quote($this->ref_id, "integer"));
98  if ($ilDB->numRows($set)) {
99  $row = $ilDB->fetchAssoc($set);
100  $this->setMode($row["mode"]);
101 
102  if ($row["mode"] == self::MODE_CUSTOM) {
103  $set = $ilDB->query("SELECT *" .
104  " FROM member_noti_user" .
105  " WHERE ref_id = " . $ilDB->quote($this->ref_id, "integer"));
106  while ($row = $ilDB->fetchAssoc($set)) {
107  $this->custom[$row["user_id"]] = $row["status"];
108  }
109  }
110  }
111  }
112 
113 
114  //
115  // MODE
116  //
117 
123  public function getMode()
124  {
125  return $this->mode;
126  }
127 
133  protected function setMode($a_value)
134  {
135  if ($this->isValidMode($a_value)) {
136  $this->mode = $a_value;
137  }
138  }
139 
146  protected function isValidMode($a_value)
147  {
148  $valid = array(
149  self::MODE_SELF
150  ,self::MODE_ALL
151  ,self::MODE_ALL_BLOCKED
152  // ,self::MODE_CUSTOM currently used in forum
153  );
154  return in_array($a_value, $valid);
155  }
156 
163  public function switchMode($a_new_mode)
164  {
165  global $DIC;
166 
167  $ilDB = $DIC['ilDB'];
168 
169  if (!$this->ref_id) {
170  return;
171  }
172 
173  if ($this->mode &&
174  $this->mode != $a_new_mode &&
175  $this->isValidMode($a_new_mode)) {
176  $ilDB->manipulate("DELETE FROM member_noti" .
177  " WHERE ref_id = " . $ilDB->quote($this->ref_id, "integer"));
178 
179  // no custom data
180  if ($a_new_mode != self::MODE_CUSTOM) {
181  $ilDB->manipulate("DELETE FROM member_noti_user" .
182  " WHERE ref_id = " . $ilDB->quote($this->ref_id, "integer"));
183  }
184 
185  // mode self is default
186  if ($a_new_mode != self::MODE_SELF) {
187  $ilDB->insert("member_noti", array(
188  "ref_id" => array("integer", $this->ref_id),
189  "nmode" => array("integer", $a_new_mode)
190  ));
191  }
192 
193  // remove all user settings (all active is preset, optional opt out)
194  if ($a_new_mode == self::MODE_ALL) {
195  $ilDB->manipulate("DELETE FROM usr_pref" .
196  " WHERE " . $ilDB->like("keyword", "text", "grpcrs_ntf_" . $this->ref_id));
197  }
198  }
199 
200  $this->setMode($a_new_mode);
201  }
202 
203 
204  //
205  // ACTIVE USERS
206  //
207 
213  protected function getParticipants()
214  {
215  global $DIC;
216 
217  $tree = $DIC['tree'];
218 
219  if ($this->participants === null) {
220  $this->participants = false;
221 
222  $grp_ref_id = $tree->checkForParentType($this->ref_id, "grp");
223  if ($grp_ref_id) {
224  include_once "Modules/Group/classes/class.ilGroupParticipants.php";
225  $this->participants = ilGroupParticipants::_getInstanceByObjId(ilObject::_lookupObjId($grp_ref_id));
226  }
227 
228  if (!$this->participants) {
229  $crs_ref_id = $tree->checkForParentType($this->ref_id, "crs");
230  if ($crs_ref_id) {
231  include_once "Modules/Course/classes/class.ilCourseParticipants.php";
232  $this->participants = ilCourseParticipants::_getInstanceByObjId(ilObject::_lookupObjId($crs_ref_id));
233  }
234  }
235  }
236 
237  return $this->participants;
238  }
239 
245  public function getActiveUsers()
246  {
247  global $DIC;
248 
249  $ilDB = $DIC->database();
250 
251  $users = $all = array();
252 
253  $part_obj = $this->getParticipants();
254  if ($part_obj) {
255  $all = $part_obj->getParticipants();
256  }
257  if (!sizeof($all)) {
258  return array();
259  }
260 
261  switch ($this->getMode()) {
262  // users decide themselves
263  case self::MODE_SELF:
264  $set = $ilDB->query("SELECT usr_id" .
265  " FROM usr_pref" .
266  " WHERE keyword = " . $ilDB->quote("grpcrs_ntf_".$this->ref_id, "text") .
267  " AND value = " . $ilDB->quote(self::VALUE_ON, "text"));
268  while ($row = $ilDB->fetchAssoc($set)) {
269  $users[] = $row["usr_id"];
270  }
271  break;
272 
273  // all members, mind opt-out
274  case self::MODE_ALL:
275  // users who did opt-out
276  $inactive = array();
277  $set = $ilDB->query("SELECT usr_id" .
278  " FROM usr_pref" .
279  " WHERE keyword = " . $ilDB->quote("grpcrs_ntf_".$this->ref_id, "text") .
280  " AND value = " . $ilDB->quote(self::VALUE_OFF, "text"));
281  while ($row = $ilDB->fetchAssoc($set)) {
282  $inactive[] = $row["usr_id"];
283  }
284  $users = array_diff($all, $inactive);
285  break;
286 
287  // all members, no opt-out
288  case self::MODE_ALL_BLOCKED:
289  $users = $all;
290  break;
291 
292  // custom settings
293  case self::MODE_CUSTOM:
294  foreach ($this->custom as $user_id => $status) {
295  if ($status != self::VALUE_OFF) {
296  $users[] = $user_id;
297  }
298  }
299  break;
300  }
301 
302  // only valid participants
303  return array_intersect($all, $users);
304  }
305 
306 
307  //
308  // USER STATUS
309  //
310 
317  public function activateUser($a_user_id = null)
318  {
319  return $this->toggleUser(true, $a_user_id);
320  }
321 
328  public function deactivateUser($a_user_id = null)
329  {
330  return $this->toggleUser(false, $a_user_id);
331  }
332 
339  protected function getUser($a_user_id = null)
340  {
341  global $DIC;
342 
343  $ilUser = $DIC['ilUser'];
344 
345  if ($a_user_id === null ||
346  $a_user_id == $ilUser->getId()) {
347  $user = $ilUser;
348  } else {
349  $user = new ilUser($a_user_id);
350  }
351 
352  if ($user->getId() &&
353  $user->getId() != ANONYMOUS_USER_ID) {
354  return $user;
355  }
356  }
357 
365  protected function toggleUser($a_status, $a_user_id = null)
366  {
367  global $DIC;
368 
369  $ilDB = $DIC['ilDB'];
370 
371  if (!self::isActive()) {
372  return;
373  }
374 
375  switch ($this->getMode()) {
376  case self::MODE_ALL:
377  case self::MODE_SELF:
378  // current user!
379  $user = $this->getUser();
380  if ($user) {
381  // blocked value not supported in user pref!
382  $user->setPref("grpcrs_ntf_" . $this->ref_id, (int) (bool) $a_status);
383  $user->writePrefs();
384  return true;
385  }
386  break;
387 
388  case self::MODE_CUSTOM:
389  $user = $this->getUser($a_user_id);
390  if ($user) {
391  $user_id = $user->getId();
392 
393  // did status change at all?
394  if (!array_key_exists($user_id, $this->custom) ||
395  $this->custom[$user_id != $a_status]) {
396  $this->custom[$user_id] = $a_status;
397 
398  $ilDB->replace(
399  "member_noti_user",
400  array(
401  "ref_id" => array("integer", $this->ref_id),
402  "user_id" => array("integer", $user_id),
403  ),
404  array(
405  "status" => array("integer", $a_status)
406  )
407  );
408  }
409  return true;
410  }
411  break;
412 
413  case self::MODE_ALL_BLOCKED:
414  // no individual settings
415  break;
416  }
417 
418  return false;
419  }
420 
421 
422  //
423  // CURRENT USER
424  //
425 
431  public function isCurrentUserActive()
432  {
433  global $DIC;
434 
435  $ilUser = $DIC['ilUser'];
436 
437  return in_array($ilUser->getId(), $this->getActiveUsers());
438  }
439 
445  public function canCurrentUserEdit()
446  {
447  global $DIC;
448 
449  $ilUser = $DIC['ilUser'];
450 
451  $user_id = $ilUser->getId();
452  if ($user_id == ANONYMOUS_USER_ID) {
453  return false;
454  }
455 
456  switch ($this->getMode()) {
457  case self::MODE_SELF:
458  case self::MODE_ALL:
459  return true;
460 
461  case self::MODE_ALL_BLOCKED:
462  return false;
463 
464  case self::MODE_CUSTOM:
465  return !(array_key_exists($user_id, $this->custom) &&
466  $this->custom[$user_id] == self::VALUE_BLOCKED);
467  }
468  }
469 
470 
471  //
472  // CRON
473  //
474 
480  public static function getActiveUsersforAllObjects()
481  {
482  global $DIC;
483 
484  $ilDB = $DIC['ilDB'];
485  $tree = $DIC['tree'];
486 
488 
489 
490  $res = array();
491 
492  if (self::isActive()) {
493  $objects = array();
494 
495  // user-preference data (MODE_SELF)
496  $log->debug("read usr_pref");
497  $set = $ilDB->query("SELECT DISTINCT(keyword) keyword" .
498  " FROM usr_pref" .
499  " WHERE " . $ilDB->like("keyword", "text", "grpcrs_ntf_%") .
500  " AND value = " . $ilDB->quote("1", "text"));
501  while ($row = $ilDB->fetchAssoc($set)) {
502  $ref_id = substr($row["keyword"], 11);
503  $objects[(int) $ref_id] = (int) $ref_id;
504  }
505 
506  // all other modes
507  $log->debug("read member_noti");
508  $set = $ilDB->query("SELECT ref_id" .
509  " FROM member_noti");
510  while ($row = $ilDB->fetchAssoc($set)) {
511  $objects[(int) $row["ref_id"]] = (int) $row["ref_id"];
512  }
513 
514  // this might be slow but it is to be used in CRON JOB ONLY!
515  foreach (array_unique($objects) as $ref_id) {
516  // :TODO: enough checking?
517  if (!$tree->isDeleted($ref_id)) {
518  $log->debug("get active users");
519  $noti = new self($ref_id);
520  $active = $noti->getActiveUsers();
521  if (sizeof($active)) {
522  $res[$ref_id] = $active;
523  }
524  }
525  }
526  }
527 
528  return $res;
529  }
530 
531 
532  //
533  // (OBJECT SETTINGS) FORM
534  //
535 
543  public static function addToSettingsForm($a_ref_id, ilPropertyFormGUI $a_form = null, ilFormPropertyGUI $a_input = null)
544  {
545  global $DIC;
546 
547  $lng = $DIC['lng'];
548 
549  if (self::isActive() &&
550  $a_ref_id) {
551  $lng->loadLanguageModule("membership");
552  $noti = new self($a_ref_id);
553 
554  $force_noti = new ilRadioGroupInputGUI($lng->txt("mem_force_notification"), "force_noti");
555  $force_noti->setRequired(true);
556  if ($a_form) {
557  $a_form->addItem($force_noti);
558  } else {
559  $a_input->addSubItem($force_noti);
560  }
561 
562  if ($noti->isValidMode(self::MODE_SELF)) {
563  $option = new ilRadioOption($lng->txt("mem_force_notification_mode_self"), self::MODE_SELF);
564  $force_noti->addOption($option);
565  }
566  if ($noti->isValidMode(self::MODE_ALL_BLOCKED)) {
567  $option = new ilRadioOption($lng->txt("mem_force_notification_mode_blocked"), self::MODE_ALL_BLOCKED);
568  $force_noti->addOption($option);
569 
570  if ($noti->isValidMode(self::MODE_ALL)) {
571  $changeable = new ilCheckboxInputGUI($lng->txt("mem_force_notification_mode_all_sub_blocked"), "force_noti_allblk");
572  $option->addSubItem($changeable);
573  }
574  } elseif ($noti->isValidMode(self::MODE_ALL)) {
575  $option = new ilRadioOption($lng->txt("mem_force_notification_mode_all"), self::MODE_ALL);
576  $force_noti->addOption($option);
577  }
578  /* not supported in GUI
579  if($noti->isValidMode(self::MODE_CUSTOM))
580  {
581  $option = new ilRadioOption($lng->txt("mem_force_notification_mode_custom"), self::MODE_CUSTOM);
582  $option->setInfo($lng->txt("mem_force_notification_mode_custom_info"));
583  $force_noti->addOption($option);
584  }
585  */
586 
587  // set current mode
588  $current_mode = $noti->getMode();
589  $has_changeable_cb = ($noti->isValidMode(self::MODE_ALL_BLOCKED) &&
590  $noti->isValidMode(self::MODE_ALL));
591  if (!$has_changeable_cb) {
592  $force_noti->setValue($current_mode);
593  } else {
594  switch ($current_mode) {
595  case self::MODE_SELF:
596  $force_noti->setValue($current_mode);
597  $changeable->setChecked(true); // checked as "default" on selection of parent
598  break;
599 
600  case self::MODE_ALL_BLOCKED:
601  $force_noti->setValue($current_mode);
602  break;
603 
604  case self::MODE_ALL:
605  $force_noti->setValue(self::MODE_ALL_BLOCKED);
606  $changeable->setChecked(true);
607  break;
608  }
609  }
610  }
611  }
612 
619  public static function importFromForm($a_ref_id, ilPropertyFormGUI $a_form = null)
620  {
621  if (self::isActive() &&
622  $a_ref_id) {
623  $noti = new self($a_ref_id);
624  $has_changeable_cb = ($noti->isValidMode(self::MODE_ALL_BLOCKED) &&
625  $noti->isValidMode(self::MODE_ALL));
626  $changeable = null;
627  if (!$a_form) {
628  $mode = (int) $_POST["force_noti"];
629  if ($has_changeable_cb) {
630  $changeable = (int) $_POST["force_noti_allblk"];
631  }
632  } else {
633  $mode = $a_form->getInput("force_noti");
634  if ($has_changeable_cb) {
635  $changeable = $a_form->getInput("force_noti_allblk");
636  }
637  }
638  // checkbox (all) is subitem of all_blocked
639  if ($changeable &&
640  $mode == self::MODE_ALL_BLOCKED) {
641  $mode = self::MODE_ALL;
642  }
643  $noti->switchMode($mode);
644  }
645  }
646 
652  public function cloneSettings($new_ref_id)
653  {
654  global $ilDB;
655 
656  $set = $ilDB->queryF(
657  "SELECT * FROM member_noti " .
658  " WHERE ref_id = %s ",
659  array("integer"),
660  array($this->ref_id)
661  );
662  while ($rec = $ilDB->fetchAssoc($set)) {
663  $ilDB->insert("member_noti", array(
664  "ref_id" => array("integer", $new_ref_id),
665  "nmode" => array("integer", $rec["nmode"])
666  ));
667  }
668  }
669 }
This class represents an option in a radio group.
static isActive()
Is feature active?
This class represents a property form user interface.
getUser($a_user_id=null)
Init user instance.
$valid
static _getInstanceByObjId($a_obj_id)
Get singleton instance.
This class represents a checkbox property in a property form.
deactivateUser($a_user_id=null)
Deactivate notification for user.
isCurrentUserActive()
Get user notification status.
static addToSettingsForm($a_ref_id, ilPropertyFormGUI $a_form=null, ilFormPropertyGUI $a_input=null)
Add notification settings to form.
This class represents a property in a property form.
setValue($a_value)
Set Value.
foreach($_POST as $key=> $value) $res
$lng
$log
Definition: result.php:15
static _lookupObjId($a_id)
isValidMode($a_value)
Is given mode valid?
switchMode($a_new_mode)
Switch mode for object.
$ilUser
Definition: imgupload.php:18
static _getInstanceByObjId($a_obj_id)
Get singleton instance.
This class represents a property in a property form.
global $ilSetting
Definition: privfeed.php:17
getActiveUsers()
Get active notifications for current object.
global $ilDB
getParticipants()
Init participants for current object.
$DIC
Definition: xapitoken.php:46
static getLogger($a_component_id)
Get component logger.
static getActiveUsersforAllObjects()
Get active notifications for all objects.
toggleUser($a_status, $a_user_id=null)
Toggle user notification status.
Membership notification settings.
canCurrentUserEdit()
Can user change notification status?
static importFromForm($a_ref_id, ilPropertyFormGUI $a_form=null)
Import notification settings from form.
$_POST["username"]
setRequired($a_required)
Set Required.
static _lookupContainerSetting($a_id, $a_keyword, $a_default_value=null)
Lookup a container setting.
cloneSettings($new_ref_id)
Clone notification object settings.
activateUser($a_user_id=null)
Activate notification for user.