ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
class.ilBadgeHandler.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
13 {
17  protected $db;
18 
22  protected $tree;
23 
27  protected $lng;
28 
29  protected $settings; // [ilSetting]
30 
31  protected static $instance; // [ilBadgeHandler]
32 
38  protected function __construct()
39  {
40  global $DIC;
41 
42  $this->db = $DIC->database();
43  if (isset($DIC["tree"])) {
44  $this->tree = $DIC->repositoryTree();
45  }
46  $this->settings = new ilSetting("bdga");
47  }
48 
54  public static function getInstance()
55  {
56  if (!self::$instance) {
57  self::$instance = new self();
58  }
59  return self::$instance;
60  }
61 
62 
63  //
64  // setter/getter
65  //
66 
67  public function isActive()
68  {
69  return $this->settings->get("active", false);
70  }
71 
72  public function setActive($a_value)
73  {
74  $this->settings->set("active", (bool) $a_value);
75  }
76 
77  public function isObiActive()
78  {
79  // see bug #20124
80  return false;
81 
82  return $this->settings->get("obi_active", false);
83  }
84 
85  public function setObiActive($a_value)
86  {
87  $this->settings->set("obi_active", (bool) $a_value);
88  }
89 
90  public function getObiOrganistation()
91  {
92  return $this->settings->get("obi_organisation", null);
93  }
94 
95  public function setObiOrganisation($a_value)
96  {
97  $this->settings->set("obi_organisation", trim($a_value));
98  }
99 
100  public function getObiContact()
101  {
102  return $this->settings->get("obi_contact", null);
103  }
104 
105  public function setObiContact($a_value)
106  {
107  $this->settings->set("obi_contact", trim($a_value));
108  }
109 
110  public function getObiSalt()
111  {
112  return $this->settings->get("obi_salt", null);
113  }
114 
115  public function setObiSalt($a_value)
116  {
117  $this->settings->set("obi_salt", trim($a_value));
118  }
119 
120  public function getComponents()
121  {
122  $components = $this->settings->get("components", null);
123  if ($components) {
124  return unserialize($components);
125  }
126  return array();
127  }
128 
129  public function setComponents(array $a_components = null)
130  {
131  if (is_array($a_components) &&
132  !sizeof($a_components)) {
133  $a_components = null;
134  }
135  $this->settings->set("components", $a_components !== null
136  ? serialize(array_unique($a_components))
137  : null);
138  }
139 
140 
141  //
142  // component handling
143  //
144 
145  protected function getComponent($a_id)
146  {
147  $ilDB = $this->db;
148 
149  // see ilCtrl
150  $set = $ilDB->query("SELECT * FROM il_component" .
151  " WHERE id = " . $ilDB->quote($a_id, "text"));
152  $rec = $ilDB->fetchAssoc($set);
153  if ($rec["type"]) {
154  return $rec;
155  }
156  }
157 
164  public function getProviderInstance($a_component_id)
165  {
166  $comp = $this->getComponent($a_component_id);
167  if ($comp) {
168  $class = "il" . $comp["name"] . "BadgeProvider";
169  $file = $comp["type"] . "/" . $comp["name"] . "/classes/class." . $class . ".php";
170  if (file_exists($file)) {
171  include_once $file;
172  $obj = new $class;
173  if ($obj instanceof ilBadgeProvider) {
174  return $obj;
175  }
176  }
177  }
178  }
179 
180  public function getComponentCaption($a_component_id)
181  {
182  $comp = $this->getComponent($a_component_id);
183  if ($comp) {
184  return $comp["type"] . "/" . $comp["name"];
185  }
186  }
187 
188  //
189  // types
190  //
191 
192  public function getUniqueTypeId($a_component_id, ilBadgeType $a_badge)
193  {
194  return $a_component_id . "/" . $a_badge->getId();
195  }
196 
202  public function getTypeInstanceByUniqueId($a_id)
203  {
204  $parts = explode("/", $a_id);
205  $comp_id = $parts[0];
206  $type_id = $parts[1];
207  $provider = $this->getProviderInstance($comp_id);
208  if ($provider) {
209  foreach ($provider->getBadgeTypes() as $type) {
210  if ($type->getId() == $type_id) {
211  return $type;
212  }
213  }
214  }
215  }
216 
217  public function getInactiveTypes()
218  {
219  $types = $this->settings->get("inactive_types", null);
220  if ($types) {
221  return unserialize($types);
222  }
223  return array();
224  }
225 
226  public function setInactiveTypes(array $a_types = null)
227  {
228  if (is_array($a_types) &&
229  !sizeof($a_types)) {
230  $a_types = null;
231  }
232  $this->settings->set("inactive_types", $a_types !== null
233  ? serialize(array_unique($a_types))
234  : null);
235  }
236 
242  public function getAvailableTypes()
243  {
244  $res = array();
245 
246  $inactive = $this->getInactiveTypes();
247  foreach ($this->getComponents() as $component_id) {
248  $provider = $this->getProviderInstance($component_id);
249  if ($provider) {
250  foreach ($provider->getBadgeTypes() as $type) {
251  $id = $this->getUniqueTypeId($component_id, $type);
252  if (!in_array($id, $inactive)) {
253  $res[$id] = $type;
254  }
255  }
256  }
257  }
258 
259  return $res;
260  }
261 
268  public function getAvailableTypesForObjType($a_object_type)
269  {
270  $res = array();
271 
272  foreach ($this->getAvailableTypes() as $id => $type) {
273  if (in_array($a_object_type, $type->getValidObjectTypes())) {
274  $res[$id] = $type;
275  }
276  }
277 
278  return $res;
279  }
280 
288  public function getAvailableManualBadges($a_parent_obj_id, $a_parent_obj_type = null)
289  {
290  $res = array();
291 
292  if (!$a_parent_obj_type) {
293  $a_parent_obj_type = ilObject::_lookupType($a_parent_obj_id);
294  }
295 
296  include_once "./Services/Badge/classes/class.ilBadge.php";
297  $badges = ilBadge::getInstancesByParentId($a_parent_obj_id);
298  foreach (ilBadgeHandler::getInstance()->getAvailableTypesForObjType($a_parent_obj_type) as $type_id => $type) {
299  if (!$type instanceof ilBadgeAuto) {
300  foreach ($badges as $badge) {
301  if ($badge->getTypeId() == $type_id &&
302  $badge->isActive()) {
303  $res[$badge->getId()] = $badge->getTitle();
304  }
305  }
306  }
307  }
308 
309  asort($res);
310  return $res;
311  }
312 
313 
314 
315  //
316  // service/module definition
317  //
318 
324  public static function updateFromXML($a_component_id)
325  {
326  $handler = self::getInstance();
327  $components = $handler->getComponents();
328  $components[] = $a_component_id;
329  $handler->setComponents($components);
330  }
331 
337  public static function clearFromXML($a_component_id)
338  {
339  $handler = self::getInstance();
340  $components = $handler->getComponents();
341  foreach ($components as $idx => $component) {
342  if ($component == $a_component_id) {
343  unset($components[$idx]);
344  }
345  }
346  $handler->setComponents($components);
347  }
348 
349 
350  //
351  // helper
352  //
353 
354  public function isObjectActive($a_obj_id, $a_obj_type = null)
355  {
356  if (!$this->isActive()) {
357  return false;
358  }
359 
360  if (!$a_obj_type) {
361  $a_obj_type = ilObject::_lookupType($a_obj_id);
362  }
363 
364  if ($a_obj_type != "bdga") {
365  include_once 'Services/Container/classes/class.ilContainer.php';
366  include_once 'Services/Object/classes/class.ilObjectServiceSettingsGUI.php';
368  $a_obj_id,
370  false
371  )) {
372  return false;
373  }
374  }
375 
376  return true;
377  }
378 
379  public function triggerEvaluation($a_type_id, $a_user_id, array $a_params = null)
380  {
381  if (!$this->isActive() ||
382  in_array($a_type_id, $this->getInactiveTypes())) {
383  return;
384  }
385 
386  $type = $this->getTypeInstanceByUniqueId($a_type_id);
387  if (!$type ||
388  !$type instanceof ilBadgeAuto) {
389  return;
390  }
391 
392  include_once "Services/Badge/classes/class.ilBadge.php";
393  include_once "Services/Badge/classes/class.ilBadgeAssignment.php";
394  $new_badges = array();
395  foreach (ilBadge::getInstancesByType($a_type_id) as $badge) {
396  if ($badge->isActive()) {
397  // already assigned?
398  if (!ilBadgeAssignment::exists($badge->getId(), $a_user_id)) {
399  if ((bool) $type->evaluate($a_user_id, (array) $a_params, (array) $badge->getConfiguration())) {
400  $ass = new ilBadgeAssignment($badge->getId(), $a_user_id);
401  $ass->store();
402 
403  $new_badges[$a_user_id][] = $badge->getId();
404  }
405  }
406  }
407  }
408 
409  $this->sendNotification($new_badges);
410  }
411 
412  public function getUserIds($a_parent_ref_id, $a_parent_obj_id = null, $a_parent_type = null)
413  {
414  $tree = $this->tree;
415 
416  if (!$a_parent_obj_id) {
417  $a_parent_obj_id = ilObject::_lookupObjectId($a_parent_ref_id);
418  }
419  if (!$a_parent_type) {
420  $a_parent_type = ilObject::_lookupType($a_parent_obj_id);
421  }
422 
423  // try to get participants from (parent) course/group
424  switch ($a_parent_type) {
425  case "crs":
426  include_once "Modules/Course/classes/class.ilCourseParticipants.php";
427  $member_obj = ilCourseParticipants::_getInstanceByObjId($a_parent_obj_id);
428  return $member_obj->getMembers();
429 
430  case "grp":
431  include_once "Modules/Group/classes/class.ilGroupParticipants.php";
432  $member_obj = ilGroupParticipants::_getInstanceByObjId($a_parent_obj_id);
433  return $member_obj->getMembers();
434 
435  default:
436  // walk path to find course or group object and use members of that object
437  $path = $tree->getPathId($a_parent_ref_id);
438  array_pop($path);
439  foreach (array_reverse($path) as $path_ref_id) {
440  $type = ilObject::_lookupType($path_ref_id, true);
441  if ($type == "crs" || $type == "grp") {
442  return $this->getParticipantsForObject($path_ref_id, null, $type);
443  }
444  }
445  break;
446  }
447  }
448 
449 
450  //
451  // PATH HANDLING (PUBLISHING)
452  //
453 
454  protected function getBasePath()
455  {
456  return ilUtil::getWebspaceDir() . "/pub_badges/";
457  }
458 
459  public function getInstancePath(ilBadgeAssignment $a_ass)
460  {
461  $hash = md5($a_ass->getBadgeId() . "_" . $a_ass->getUserId());
462 
463  $path = $this->getBasePath() . "instances/" .
464  $a_ass->getBadgeId() . "/" .
465  floor($a_ass->getUserId()/1000) . "/";
466 
467  ilUtil::makeDirParents($path);
468 
469  $path .= $hash . ".json";
470 
471  return $path;
472  }
473 
474  public function countStaticBadgeInstances(ilBadge $a_badge)
475  {
476  $path = $this->getBasePath() . "instances/" . $a_badge->getId();
477  $cnt = 0;
478  if (is_dir($path)) {
480  }
481  return $cnt;
482  }
483 
484  protected function countStaticBadgeInstancesHelper(&$a_cnt, $a_path)
485  {
486  foreach (glob($a_path . "/*") as $item) {
487  if (is_dir($item)) {
488  $this->countStaticBadgeInstancesHelper($a_cnt, $item);
489  } elseif (substr($item, -5) == ".json") {
490  $a_cnt++;
491  }
492  }
493  }
494 
495  public function getBadgePath(ilBadge $a_badge)
496  {
497  $hash = md5($a_badge->getId());
498 
499  $path = $this->getBasePath() . "badges/" .
500  floor($a_badge->getId()/100) . "/" .
501  $hash . "/";
502 
503  ilUtil::makeDirParents($path);
504 
505  return $path;
506  }
507 
508  protected function prepareIssuerJson($a_url)
509  {
510  $json = new stdClass();
511  $json->{"@context"} = "https://w3id.org/openbadges/v1";
512  $json->type = "Issuer";
513  $json->id = $a_url;
514  $json->name = $this->getObiOrganistation();
515  $json->url = ILIAS_HTTP_PATH . "/";
516  $json->email = $this->getObiContact();
517 
518  return $json;
519  }
520 
521  public function getIssuerStaticUrl()
522  {
523  $path = $this->getBasePath() . "issuer/";
525  $path .= "issuer.json";
526 
527  $url = ILIAS_HTTP_PATH . substr($path, 1);
528 
529  if (!file_exists($path)) {
530  $json = json_encode($this->prepareIssuerJson($url));
531  file_put_contents($path, $json);
532  }
533 
534  return $url;
535  }
536 
537  public function rebuildIssuerStaticUrl()
538  {
539  $path = $this->getBasePath() . "issuer/issuer.json";
540  if (file_exists($path)) {
541  unlink($path);
542  }
543  $this->getIssuerStaticUrl();
544  }
545 
546 
547  //
548  // notification
549  //
550 
551  public function sendNotification(array $a_user_map, $a_parent_ref_id = null)
552  {
553  $badges = array();
554 
555  include_once "Services/Badge/classes/class.ilBadge.php";
556  include_once "Services/Badge/classes/class.ilBadgeAssignment.php";
557  include_once "Services/Notification/classes/class.ilSystemNotification.php";
558  include_once "Services/Link/classes/class.ilLink.php";
559 
560  foreach ($a_user_map as $user_id => $badge_ids) {
561  $user_badges = array();
562 
563  foreach ($badge_ids as $badge_id) {
564  // making extra sure
565  if (!ilBadgeAssignment::exists($badge_id, $user_id)) {
566  continue;
567  }
568 
569  if (!array_key_exists($badge_id, $badges)) {
570  $badges[$badge_id] = new ilBadge($badge_id);
571  }
572 
573  $badge = $badges[$badge_id];
574 
575  $user_badges[] = $badge->getTitle();
576  }
577 
578  if (sizeof($user_badges)) {
579  // compose and send mail
580 
581  $ntf = new ilSystemNotification(false);
582  $ntf->setLangModules(array("badge"));
583 
584  $ntf->setRefId($a_parent_ref_id);
585  $ntf->setGotoLangId("badge_notification_parent_goto");
586 
587  // user specific language
588  $lng = $ntf->getUserLanguage($user_id);
589 
590  $ntf->setIntroductionLangId("badge_notification_body");
591 
592  $ntf->addAdditionalInfo("badge_notification_badges", implode("\n", $user_badges), true);
593 
594  $url = ilLink::_getLink($user_id, "usr", array(), "_bdg");
595  $ntf->addAdditionalInfo("badge_notification_badges_goto", $url);
596 
597  $ntf->setReasonLangId("badge_notification_reason");
598 
599  // force email
600  $mail = new ilMail(ANONYMOUS_USER_ID);
601  $mail->enableSOAP(false);
602  $mail->sendMail(
603  ilObjUser::_lookupEmail($user_id),
604  null,
605  null,
606  $lng->txt("badge_notification_subject"),
607  $ntf->composeAndGetMessage($user_id, null, "read", true),
608  null,
609  array("system")
610  );
611 
612 
613  // osd
614  // bug #24562
615  if (ilContext::hasHTML()) {
616  $osd_params = array("badge_list" => "<br />" . implode("<br />", $user_badges));
617 
618  require_once "Services/Notifications/classes/class.ilNotificationConfig.php";
619  $notification = new ilNotificationConfig("osd_main");
620  $notification->setTitleVar("badge_notification_subject", array(), "badge");
621  $notification->setShortDescriptionVar("badge_notification_osd", $osd_params, "badge");
622  $notification->setLongDescriptionVar("", $osd_params, "");
623  $notification->setAutoDisable(false);
624  $notification->setLink($url);
625  $notification->setIconPath(ilUtil::getImagePath('icon_bdga.svg'));
626  $notification->setValidForSeconds(ilNotificationConfig::TTL_SHORT);
627  $notification->setVisibleForSeconds(ilNotificationConfig::DEFAULT_TTS);
628  $notification->notifyByUsers(array($user_id));
629  }
630  }
631  }
632  }
633 }
Badge Provider interface.
static makeDirParents($a_dir)
Create a new directory and all parent directories.
getAvailableTypesForObjType($a_object_type)
Get valid badges types for object type.
isObjectActive($a_obj_id, $a_obj_type=null)
static exists($a_badge_id, $a_user_id)
$type
global $DIC
Definition: saml.php:7
getAvailableTypes()
Get badges types.
Badge type interface.
getTypeInstanceByUniqueId($a_id)
Get type instance by unique id (component, type)
static _getInstanceByObjId($a_obj_id)
Get singleton instance.
static updateFromXML($a_component_id)
Import component definition.
if(!array_key_exists('StateId', $_REQUEST)) $id
getProviderInstance($a_component_id)
Get provider instance.
sendNotification(array $a_user_map, $a_parent_ref_id=null)
getInstancePath(ilBadgeAssignment $a_ass)
static _lookupObjectId($a_ref_id)
lookup object id
Describes a notification and provides methods for publishing this notification.
Manual Badge Auto.
static clearFromXML($a_component_id)
Remove component definition.
static getInstancesByParentId($a_parent_id, array $a_filter=null)
foreach($_POST as $key=> $value) $res
triggerEvaluation($a_type_id, $a_user_id, array $a_params=null)
getId()
Get typ id (unique for component)
setComponents(array $a_components=null)
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
static hasHTML()
Has HTML output.
This class handles base functions for mail handling.
__construct()
Constructor.
setInactiveTypes(array $a_types=null)
static _getInstanceByObjId($a_obj_id)
Get singleton instance.
Create styles array
The data for the language used.
static _lookupType($a_id, $a_reference=false)
lookup object type
getUniqueTypeId($a_component_id, ilBadgeType $a_badge)
settings()
Definition: settings.php:2
getComponentCaption($a_component_id)
static _lookupEmail($a_user_id)
Lookup email.
getBadgePath(ilBadge $a_badge)
global $ilDB
getAvailableManualBadges($a_parent_obj_id, $a_parent_obj_type=null)
Get available manual badges for object id.
countStaticBadgeInstancesHelper(&$a_cnt, $a_path)
setObiOrganisation($a_value)
$url
if(!file_exists("$old.txt")) if($old===$new) if(file_exists("$new.txt")) $file
countStaticBadgeInstances(ilBadge $a_badge)
$handler
getUserIds($a_parent_ref_id, $a_parent_obj_id=null, $a_parent_type=null)
static getWebspaceDir($mode="filesystem")
get webspace directory
Wrapper classes for system notifications.
static getInstancesByType($a_type_id)
static _lookupContainerSetting($a_id, $a_keyword, $a_default_value=null)
Lookup a container setting.
static getInstance()
Constructor.