ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
class.ilGroupXMLParser.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
27 {
28  public static int $CREATE = 1;
29  public static int $UPDATE = 2;
30 
32 
36  private ilLogger $log;
38  protected ilObjUser $user;
40  protected ilSetting $settings;
41 
43 
45 
47  private string $current_container_setting = '';
48  private ?array $sort = null;
49 
50  private array $group_data = [];
51  private bool $group_imported = false;
52  private bool $in_period = false;
53  private string $cdata = '';
54 
55 
56  protected array $parent = [];
57  protected int $counter = 0;
58 
59  protected int $mode;
60 
61 
62  public function __construct(ilObjGroup $group, string $a_xml, int $a_parent_id)
63  {
64  global $DIC;
65 
67  $this->user = $DIC->user();
68  $this->rbacreview = $DIC->rbac()->review();
69  $this->settings = $DIC->settings();
70  $this->sax_controller = new ilSaxController();
71  $this->mode = ilGroupXMLParser::$CREATE;
72  $this->group_obj = $group;
73  $this->log = $DIC->logger()->grp();
74  $this->setXMLContent($a_xml);
75 
76  // SET MEMBER VARIABLES
77  $this->pushParentId($a_parent_id);
78  }
79 
80  public function pushParentId(int $a_id): void
81  {
82  $this->parent[] = $a_id;
83  }
84  public function popParentId(): void
85  {
86  array_pop($this->parent);
87  }
88 
89  public function getParentId(): int
90  {
91  return $this->parent[count($this->parent) - 1];
92  }
93 
94 
98  public function setHandlers($a_xml_parser): void
99  {
100  $this->sax_controller->setHandlers($a_xml_parser);
101  $this->sax_controller->setDefaultElementHandler($this);
102 
103  $this->advanced_md_value_parser = new ilAdvancedMDValueParser(
104  $this->group_obj->getId()
105  );
106 
107  $this->sax_controller->setElementHandler(
108  $this->advanced_md_value_parser,
109  'AdvancedMetaData'
110  );
111  }
112 
113 
114 
118  public function startParsing(): void
119  {
120  parent::startParsing();
121 
122  if ($this->mode == ilGroupXMLParser::$CREATE) {
123  $status = is_object($this->group_obj) ? $this->group_obj->getRefId() : false;
124  } else {
125  $status = is_object($this->group_obj) ? $this->group_obj->update() : false;
126  }
127  $this->after_parsing_status = $status;
128  }
129 
130  public function getObjectRefId()
131  {
133  }
134 
135 
140  public function handlerBeginTag($a_xml_parser, string $a_name, array $a_attribs): void
141  {
142  global $DIC;
143 
144  $a_attribs = $this->trimAndStripAttribs($a_attribs);
145 
146  $ilErr = $DIC['ilErr'];
147 
148  switch ($a_name) {
149  case "group":
150  $this->group_data["admin"] = array();
151  $this->group_data["member"] = array();
152 
153  $this->group_data["type"] = $a_attribs["type"];
154  $this->group_data["id"] = $a_attribs["id"];
155 
156  break;
157 
158  case 'title':
159  break;
160 
161  case "owner":
162  $this->group_data["owner"] = $a_attribs["id"];
163  break;
164 
165  case 'registration':
166  $this->group_data['registration_type'] = $a_attribs['type'];
167  $this->group_data['waiting_list_enabled'] = $a_attribs['waitingList'] == 'Yes' ? true : false;
168  break;
169 
170  case 'period':
171  $this->in_period = true;
172  $this->group_data['period_with_time'] = $a_attribs['withTime'];
173  break;
174 
175  case 'maxMembers':
176  $this->group_data['max_members_enabled'] = $a_attribs['enabled'] == 'Yes' ? true : false;
177  break;
178 
179  case "admin":
180  if (!isset($a_attribs['action']) || $a_attribs['action'] == "Attach") {
181  $this->group_data["admin"]["attach"][] = $a_attribs["id"];
182  } elseif (isset($a_attribs['action']) || $a_attribs['action'] == "Detach") {
183  $this->group_data["admin"]["detach"][] = $a_attribs["id"];
184  }
185 
186  if (isset($a_attribs['notification']) and $a_attribs['notification'] == 'Yes') {
187  $this->group_data['notifications'][] = $a_attribs['id'];
188  }
189 
190  break;
191 
192  case "member":
193  if (!isset($a_attribs['action']) || $a_attribs['action'] == "Attach") {
194  $GLOBALS['DIC']->logger()->grp()->debug('New member with id ' . $a_attribs['id']);
195  $this->group_data["member"]["attach"][] = $a_attribs["id"];
196  } elseif (isset($a_attribs['action']) || $a_attribs['action'] == "Detach") {
197  $GLOBALS['DIC']->logger()->grp()->debug('Deprecated member with id ' . $a_attribs['id']);
198  $this->group_data["member"]["detach"][] = $a_attribs["id"];
199  }
200 
201  break;
202 
203  case 'ContainerSetting':
204  $this->current_container_setting = $a_attribs['id'];
205  break;
206 
207  case 'Sort':
208 
209  if ($this->group_imported) {
210  $this->initContainerSorting($a_attribs, $this->group_obj->getId());
211  } else {
212  $this->sort = $a_attribs;
213  }
214  break;
215 
216 
217  case 'SessionLimit':
218  if (isset($a_attribs['active'])) {
219  $this->group_data['session_limit'] = (bool) $a_attribs['active'];
220  }
221  if (isset($a_attribs['previous'])) {
222  $this->group_data['session_previous'] = (int) $a_attribs['previous'];
223  }
224  if (isset($a_attribs['next'])) {
225  $this->group_data['session_next'] = (int) $a_attribs['next'];
226  }
227  break;
228 
229  case 'GroupMap':
230  $this->group_data['map_enabled'] = (bool) $a_attribs['enabled'] ?? false;
231  $this->group_data['map_latitude'] = (string) $a_attribs['latitude'] ?? '';
232  $this->group_data['map_longitude'] = (string) $a_attribs['longitude'] ?? '';
233  $this->group_data['map_location_zoom'] = (int) $a_attribs['location_zoom'] ?? 0;
234  break;
235 
236  case 'RegistrationAccessCode':
237  $this->group_data['registration_code_enabled'] = (bool) $a_attribs['enabled'] ?? false;
238  $this->group_data['registration_code'] = (string) $a_attribs['code'] ?? '';
239  break;
240 
241  case 'WaitingListAutoFill':
242  case 'CancellationEnd':
243  case 'minMembers':
244  case 'mailMembersType':
245  break;
246  }
247  }
248 
249  public function handlerEndTag($a_xml_parser, string $a_name): void
250  {
251  $this->cdata = $this->trimAndStrip($this->cdata);
252 
253  switch ($a_name) {
254  case "title":
255  $this->group_data["title"] = trim($this->cdata);
256  break;
257 
258  case "description":
259  $this->group_data["description"] = trim($this->cdata);
260  break;
261 
262  case 'information':
263  $this->group_data['information'] = trim($this->cdata);
264  break;
265 
266  case 'password':
267  $this->group_data['password'] = trim($this->cdata);
268  break;
269 
270  case 'maxMembers':
271  $this->group_data['max_members'] = trim($this->cdata);
272  break;
273 
274  case 'expiration':
275  $this->group_data['expiration_end'] = trim($this->cdata);
276  break;
277 
278  case 'start':
279  if ($this->in_period) {
280  $this->group_data['period_start'] = trim($this->cdata);
281  } else {
282  $this->group_data['expiration_start'] = trim($this->cdata);
283  }
284  break;
285 
286  case 'end':
287  if ($this->in_period) {
288  $this->group_data['period_end'] = trim($this->cdata);
289  } else {
290  $this->group_data['expiration_end'] = trim($this->cdata);
291  }
292  break;
293 
294  case 'period':
295  $this->in_period = false;
296  break;
297 
298  case "group":
299  $this->save();
300  break;
301 
302  case 'ContainerSetting':
303  if ($this->current_container_setting) {
305  $this->group_obj->getId(),
307  trim($this->cdata)
308  );
309  }
310  break;
311 
312  case 'WaitingListAutoFill':
313  $this->group_data['auto_wait'] = trim($this->cdata);
314  break;
315 
316  case 'CancellationEnd':
317  if ((int) $this->cdata) {
318  $this->group_data['cancel_end'] = new ilDate((int) $this->cdata, IL_CAL_UNIX);
319  }
320  break;
321 
322  case 'minMembers':
323  if ((int) $this->cdata) {
324  $this->group_data['min_members'] = (int) $this->cdata;
325  }
326  break;
327 
328  case 'showMembers':
329  if ((int) $this->cdata) {
330  $this->group_data['show_members'] = (int) $this->cdata;
331  }
332  break;
333 
334  case 'admissionNotification':
335  if ((int) $this->cdata) {
336  $this->group_data['auto_notification'] = (bool) $this->cdata;
337  }
338  break;
339 
340  case 'mailMembersType':
341  $this->group_data['mail_members_type'] = (int) $this->cdata;
342  break;
343 
344  case 'ViewMode':
345  $this->group_data['view_mode'] = (int) $this->cdata;
346  break;
347  }
348  $this->cdata = '';
349  }
350 
351 
355  public function handlerCharacterData($a_xml_parser, string $a_name): void
356  {
357  $a_name = str_replace("<", "&lt;", $a_name);
358  $a_name = str_replace(">", "&gt;", $a_name);
359 
360  if (!empty($a_name)) {
361  $this->cdata .= $a_name;
362  }
363  }
364 
365  public function save(): bool
366  {
367  if ($this->group_imported) {
368  return true;
369  }
370 
371  $this->group_obj->setImportId($this->group_data["id"] ?? '');
372  $this->group_obj->setTitle($this->group_data["title"] ?? '');
373  $this->group_obj->setDescription($this->group_data["description"] ?? '');
374  $this->group_obj->setInformation((string) $this->group_data['information']);
375 
376  if (isset($this->group_data['period_start']) && isset($this->group_data['period_end'])) {
377  try {
378  if ($this->group_data['period_with_time'] ?? false) {
379  $this->group_obj->setPeriod(
380  new \ilDateTime($this->group_data['period_start'], IL_CAL_UNIX),
381  new \ilDateTime($this->group_data['period_end'], IL_CAL_UNIX)
382  );
383  } else {
384  $this->group_obj->setPeriod(
385  new \ilDateTime($this->group_data['period_start'], IL_CAL_UNIX),
386  new \ilDateTime($this->group_data['period_end'], IL_CAL_UNIX)
387  );
388  }
389  } catch (Exception $e) {
390  $this->log->warning('Ignoring invalid group period settings: ');
391  $this->log->warning('Period start: ' . $this->group_data['period_start']);
392  $this->log->warning('Period end: ' . $this->group_data['period_end']);
393  }
394  }
395 
396  $ownerChanged = false;
397  if (isset($this->group_data["owner"])) {
398  $owner = $this->group_data["owner"];
399  if (!is_numeric($owner)) {
400  $owner = ilUtil::__extractId($owner, (int) IL_INST_ID);
401  }
402  if (is_numeric($owner) && $owner > 0) {
403  $this->group_obj->setOwner((int) $owner);
404  $ownerChanged = true;
405  }
406  }
407 
411  if ($this->mode == ilGroupXMLParser::$CREATE) {
412  $this->group_obj->createReference();
413  $this->group_obj->putInTree($this->getParentId());
414  $this->group_obj->setPermissions($this->getParentId());
415  if (
416  array_key_exists('type', $this->group_data) &&
417  $this->group_data['type'] == 'closed'
418  ) {
419  $this->group_obj->updateGroupType(
421  );
422  }
423  } else {
424  if (
425  array_key_exists('type', $this->group_data) &&
426  $this->group_data['type'] == 'closed'
427  ) {
428  $this->group_obj->updateGroupType(
430  );
431  } elseif (
432  array_key_exists('type', $this->group_data) &&
433  $this->group_data['type'] == 'open'
434  ) {
435  $this->group_obj->updateGroupType(
437  );
438  }
439  }
440  // SET GROUP SPECIFIC DATA
441  switch ($this->group_data['registration_type'] ?? '') {
442  case 'direct':
443  case 'enabled':
445  break;
446 
447  case 'disabled':
449  break;
450 
451  case 'confirmation':
453  break;
454 
455  case 'password':
457  break;
458 
459  default:
461  }
462  $this->group_obj->setRegistrationType($flag);
463 
464 
465  $registration_end = null;
466  if ($this->group_data['expiration_end'] ?? false) {
467  $registration_end = new ilDateTime($this->group_data['expiration_end'], IL_CAL_UNIX);
468  }
469 
470  $registration_start = null;
471  if ($this->group_data['expiration_start'] ?? false) {
472  $registration_start = new ilDateTime($this->group_data['expiration_start'], IL_CAL_UNIX);
473  }
474  if (
475  $registration_start instanceof ilDateTime &&
476  $registration_end instanceof ilDateTime
477  ) {
478  $this->group_obj->enableUnlimitedRegistration(false);
479  $this->group_obj->setRegistrationStart($registration_start);
480  $this->group_obj->setRegistrationEnd($registration_end);
481  } else {
482  $this->group_obj->enableUnlimitedRegistration(true);
483  }
484  $this->group_obj->setPassword($this->group_data['password'] ?? '');
485  $this->group_obj->enableMembershipLimitation((bool) ($this->group_data['max_members_enabled'] ?? false));
486  $this->group_obj->setMaxMembers((int) ($this->group_data['max_members'] ?? 0));
487  $this->group_obj->enableWaitingList((bool) ($this->group_data['waiting_list_enabled'] ?? false));
488  $this->group_obj->setWaitingListAutoFill((bool) ($this->group_data['auto_wait'] ?? false));
489  $this->group_obj->setCancellationEnd($this->group_data['cancel_end'] ?? null);
490  $this->group_obj->setMinMembers((int) ($this->group_data['min_members'] ?? 0));
491  $this->group_obj->setShowMembers((bool) ($this->group_data['show_members'] ?? false));
492  $this->group_obj->setAutoNotification((bool) (($this->group_data['auto_notification'] ?? false)));
493  $this->group_obj->setMailToMembersType((int) ($this->group_data['mail_members_type'] ?? 0));
494  $this->group_obj->enableRegistrationAccessCode((bool) ($this->group_data['registration_code_enabled'] ?? false));
495  $this->group_obj->setRegistrationAccessCode((string) ($this->group_data['registration_code'] ?? ''));
496  if (isset($this->group_data['view_mode'])) {
497  $this->group_obj->setViewMode((int) $this->group_data['view_mode']);
498  }
499  if (isset($this->group_data['session_limit'])) {
500  $this->group_obj->enableSessionLimit((bool) $this->group_data['session_limit']);
501  }
502  if (isset($this->group_data['session_previous'])) {
503  $this->group_obj->setNumberOfPreviousSessions((int) $this->group_data['session_previous']);
504  }
505  if (isset($this->group_data['session_next'])) {
506  $this->group_obj->setNumberOfNextSessions((int) $this->group_data['session_next']);
507  }
508 
509  $this->group_obj->setEnableGroupMap((bool) ($this->group_data['map_enabled'] ?? false));
510  $this->group_obj->setLatitude((string) ($this->group_data['map_latitude'] ?? ''));
511  $this->group_obj->setLongitude((string) ($this->group_data['map_longitude'] ?? ''));
512  $this->group_obj->setLocationZoom((int) ($this->group_data['map_location_zoom'] ?? 0));
513 
514  /*
515  * readContainerSettings needs to be called before update, otherwise container
516  * settings are overwritten by the default, see #24742.
517  */
518  $this->group_obj->readContainerSettings();
519  $this->group_obj->update();
520 
521  // ASSIGN ADMINS/MEMBERS
522  $this->assignMembers();
523 
524  $this->pushParentId($this->group_obj->getRefId());
525 
526  if ($this->sort) {
527  $this->initContainerSorting($this->sort, $this->group_obj->getId());
528  }
529 
530  $this->group_imported = true;
531 
532  return true;
533  }
534 
535  public function assignMembers(): void
536  {
537  $this->participants = new ilGroupParticipants($this->group_obj->getId());
538  $this->participants->add($this->user->getId(), ilParticipants::IL_GRP_ADMIN);
539  $this->participants->updateNotification($this->user->getId(), (bool) $this->settings->get('mail_grp_admin_notification', "1"));
540 
541  // attach ADMINs
542  if (isset($this->group_data["admin"]["attach"]) && count($this->group_data["admin"]["attach"])) {
543  foreach ($this->group_data["admin"]["attach"] as $user) {
544  if ($id_data = $this->parseId($user)) {
545  if ($id_data['local'] or $id_data['imported']) {
546  $this->participants->add($id_data['usr_id'], ilParticipants::IL_GRP_ADMIN);
547  if (isset($this->group_data['notifications']) && in_array($user, (array) $this->group_data['notifications'])) {
548  $this->participants->updateNotification($id_data['usr_id'], true);
549  }
550  }
551  }
552  }
553  }
554  // detach ADMINs
555  if (isset($this->group_data["admin"]["detach"]) && count($this->group_data["admin"]["detach"])) {
556  foreach ($this->group_data["admin"]["detach"] as $user) {
557  if ($id_data = $this->parseId($user)) {
558  if ($id_data['local'] or $id_data['imported']) {
559  if ($this->participants->isAssigned($id_data['usr_id'])) {
560  $this->participants->delete($id_data['usr_id']);
561  }
562  }
563  }
564  }
565  }
566  // MEMBER
567  if (isset($this->group_data["member"]["attach"]) && count($this->group_data["member"]["attach"])) {
568  foreach ($this->group_data["member"]["attach"] as $user) {
569  if ($id_data = $this->parseId($user)) {
570  if ($id_data['local'] or $id_data['imported']) {
571  $this->participants->add($id_data['usr_id'], ilParticipants::IL_GRP_MEMBER);
572  }
573  }
574  }
575  }
576 
577  if (isset($this->group_data["member"]["detach"]) && count($this->group_data["member"]["detach"])) {
578  foreach ($this->group_data["member"]["detach"] as $user) {
579  if ($id_data = $this->parseId($user)) {
580  if ($id_data['local'] or $id_data['imported']) {
581  if ($this->participants->isAssigned($id_data['usr_id'])) {
582  $this->participants->delete($id_data['usr_id']);
583  }
584  }
585  }
586  }
587  }
588  }
589 
590  public function parseId(string $a_id): array
591  {
592  $fields = explode('_', $a_id);
593  $usr_id = (int) $fields[3];
594 
595  if (!is_array($fields) or
596  $fields[0] != 'il' or
597  !is_numeric($fields[1]) or
598  $fields[2] != 'usr' or
599  !is_numeric($usr_id)) {
600  return [];
601  }
602  if ($id = ilObjUser::_getImportedUserId($a_id)) {
603  return array('imported' => true,
604  'local' => false,
605  'usr_id' => $id);
606  }
607  if (($fields[1] == $this->settings->get('inst_id', "0")) and ($user = ilObjUser::_lookupName($usr_id))) {
608  if (strlen($user['login'])) {
609  return array('imported' => false,
610  'local' => true,
611  'usr_id' => $usr_id);
612  }
613  }
614  $this->log->warning('Parsing id failed: ' . $a_id);
615  return [];
616  }
617 
618 
619  public function setMode(int $mode): void
620  {
621  $this->mode = $mode;
622  }
623 
624  public function initContainerSorting(array $a_attribs, int $a_group_id): void
625  {
627  }
628 
629  protected function trimAndStripAttribs(array $attribs): array
630  {
631  $ret = [];
632  foreach ($attribs as $k => $v) {
633  $ret[$k] = $this->trimAndStrip((string) $v);
634  }
635  return $ret;
636  }
637 
638  protected function trimAndStrip(string $input): string
639  {
640  return ilUtil::stripSlashes(trim($input));
641  }
642 }
const IL_INST_ID
Definition: constants.php:40
handlerCharacterData($a_xml_parser, string $a_name)
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
static _lookupName(int $a_user_id)
lookup user name
static _importContainerSortingSettings(array $attibs, int $obj_id)
sorting import for all container objects
const IL_CAL_UNIX
sort()
description: > Example for rendering a Sort Glyph.
Definition: sort.php:41
$ilErr
Definition: raiseError.php:33
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
$GLOBALS["DIC"]
Definition: wac.php:53
global $DIC
Definition: shib_login.php:26
handlerEndTag($a_xml_parser, string $a_name)
End element handler.
ilGroupParticipants $participants
ilAdvancedMDValueParser $advanced_md_value_parser
static _writeContainerSetting(int $a_id, string $a_keyword, string $a_value)
add(int $a_usr_id, int $a_role)
__construct(ilObjGroup $group, string $a_xml, int $a_parent_id)
handlerBeginTag($a_xml_parser, string $a_name, array $a_attribs)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _getImportedUserId(string $i2_id)
Group Import Parser.
ilSaxController $sax_controller
static __extractId(string $ilias_id, int $inst_id)
extract ref id from role title, e.g.
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
__construct(Container $dic, ilPlugin $plugin)
trimAndStripAttribs(array $attribs)
Class ilObjGroup.
setHandlers($a_xml_parser)
initContainerSorting(array $a_attribs, int $a_group_id)
setXMLContent(string $a_xml_content)