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