ILIAS  trunk Revision v12.0_alpha-1227-g7ff6d300864
class.ilMailSearchObjectGUI.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22use ILIAS\Refinery\Factory as Refinery;
23
25{
27 protected Refinery $refinery;
28 protected ?string $view = null;
31 protected ilLanguage $lng;
32 protected ilObjUser $user;
36 protected ilTree $tree;
39 protected bool $mailing_allowed;
40 protected \ILIAS\UI\Factory $ui_factory;
41 protected \ILIAS\UI\Renderer $ui_renderer;
42
47 public function __construct(protected $wsp_access_handler = null, protected ?int $wsp_node_id = null)
48 {
49 global $DIC;
50
51 $this->tpl = $DIC['tpl'];
52 $this->ctrl = $DIC['ilCtrl'];
53 $this->lng = $DIC['lng'];
54 $this->user = $DIC['ilUser'];
55 $this->error = $DIC['ilErr'];
56 $this->rbacsystem = $DIC['rbacsystem'];
57 $this->rbacreview = $DIC['rbacreview'];
58 $this->tree = $DIC['tree'];
59 $this->cache = $DIC['ilObjDataCache'];
60 $this->http = $DIC->http();
61 $this->refinery = $DIC->refinery();
62 $this->ui_factory = $DIC->ui()->factory();
63 $this->ui_renderer = $DIC->ui()->renderer();
64
65 $this->ctrl->saveParameter($this, 'mobj_id');
66 $this->ctrl->saveParameter($this, 'ref');
67
68 $mail = new ilMail($this->user->getId());
69 $this->mailing_allowed = $this->rbacsystem->checkAccess('internal_mail', $mail->getMailObjectReferenceId());
70
71 $this->umail = new ilFormatMail($this->user->getId());
72
73 $this->lng->loadLanguageModule('mail');
74 }
75
76 private function isDefaultRequestContext(): bool
77 {
78 return (
79 !$this->http->wrapper()->query()->has('ref') ||
80 $this->http->wrapper()->query()->retrieve('ref', $this->refinery->kindlyTo()->string()) !== 'wsp'
81 );
82 }
83
84 private function getContext(): string
85 {
86 $context = 'mail';
87 if ($this->http->wrapper()->query()->has('ref')) {
88 $context = $this->http->wrapper()->query()->retrieve('ref', $this->refinery->kindlyTo()->string());
89 }
90
91 return $context;
92 }
93
94 private function isLocalRoleTitle(string $title): bool
95 {
96 foreach ($this->getLocalDefaultRolePrefixes() as $local_role_prefix) {
97 if (str_starts_with($title, $local_role_prefix)) {
98 return true;
99 }
100 }
101
102 return false;
103 }
104
105 abstract protected function getObjectType(): string;
106
110 abstract protected function getLocalDefaultRolePrefixes(): array;
111
112 protected function getRequestValue(string $key, \ILIAS\Refinery\Transformation $trafo, $default = null)
113 {
114 $value = $default;
115 if ($this->http->wrapper()->query()->has($key)) {
116 $value = $this->http->wrapper()->query()->retrieve($key, $trafo);
117 }
118
119 if ($this->http->wrapper()->post()->has($key)) {
120 $value = $this->http->wrapper()->post()->retrieve($key, $trafo);
121 }
122
123 return $value;
124 }
125
129 protected function addPermission(array $a_obj_ids): void
130 {
131 $added = $this->wsp_access_handler->addMissingPermissionForObjects($this->wsp_node_id, $a_obj_ids);
132
133 if ($added) {
134 $this->tpl->setOnScreenMessage('success', $this->lng->txt('wsp_share_success'), true);
135 }
136 $this->ctrl->redirectByClass(ilWorkspaceAccessGUI::class, 'share');
137 }
138
139 protected function share(): void
140 {
141 $view = '';
142 if ($this->http->wrapper()->query()->has('view')) {
143 $view = $this->http->wrapper()->query()->retrieve('view', $this->refinery->kindlyTo()->string());
144 }
145
146 if ($view === 'myobjects') {
147 $obj_ids = [];
148 if ($this->http->wrapper()->query()->has('search_' . $this->getObjectType())) {
149 $obj_ids = [
150 $this->http->wrapper()->query()->retrieve(
151 'search_' . $this->getObjectType(),
152 $this->refinery->kindlyTo()->int()
153 )
154 ];
155 } elseif ($this->http->wrapper()->post()->has('search_' . $this->getObjectType())) {
156 $obj_ids = $this->http->wrapper()->post()->retrieve(
157 'search_' . $this->getObjectType(),
158 $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int())
159 );
160 }
161
162 if ($obj_ids !== []) {
163 $this->addPermission($obj_ids);
164 } else {
165 $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_select_' . $this->getObjectType()));
166 $this->showMyObjects();
167 }
168 } elseif ($view === $this->getObjectType() . '_members') {
169 $usr_ids = [];
170 if ($this->http->wrapper()->query()->has('search_members')) {
171 $usr_ids = [
172 $this->http->wrapper()->query()->retrieve(
173 'search_members',
174 $this->refinery->kindlyTo()->int()
175 )
176 ];
177 } elseif ($this->http->wrapper()->post()->has('search_members')) {
178 $usr_ids = $this->http->wrapper()->post()->retrieve(
179 'search_members',
180 $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int())
181 );
182 }
183
184 if ($usr_ids !== []) {
185 $this->addPermission($usr_ids);
186 } else {
187 $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_select_one_entry'));
188 $this->showMembers();
189 }
190 } else {
191 $this->showMyObjects();
192 }
193 }
194
195 protected function mail(): void
196 {
197 $view = '';
198 if ($this->http->wrapper()->query()->has('view')) {
199 $view = $this->http->wrapper()->query()->retrieve('view', $this->refinery->kindlyTo()->string());
200 }
201
202 if ($view === 'myobjects') {
203 $obj_ids = [];
204 if ($this->http->wrapper()->query()->has('search_' . $this->getObjectType())) {
205 $obj_ids = [
206 $this->http->wrapper()->query()->retrieve(
207 'search_' . $this->getObjectType(),
208 $this->refinery->kindlyTo()->int()
209 )
210 ];
211 } elseif ($this->http->wrapper()->post()->has('search_' . $this->getObjectType())) {
212 $obj_ids = $this->http->wrapper()->post()->retrieve(
213 'search_' . $this->getObjectType(),
214 $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int())
215 );
216 }
217
218 if ($obj_ids !== []) {
219 $this->mailObjects();
220 } else {
221 $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_select_' . $this->getObjectType()));
222 $this->showMyObjects();
223 }
224 } elseif ($view === $this->getObjectType() . '_members') {
225 $usr_ids = [];
226 if ($this->http->wrapper()->query()->has('search_members')) {
227 $usr_ids = [
228 $this->http->wrapper()->query()->retrieve(
229 'search_members',
230 $this->refinery->kindlyTo()->int()
231 )
232 ];
233 } elseif ($this->http->wrapper()->post()->has('search_members')) {
234 $usr_ids = $this->http->wrapper()->post()->retrieve(
235 'search_members',
236 $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int())
237 );
238 }
239
240 if ($usr_ids !== []) {
241 $this->mailMembers();
242 } else {
243 $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_select_one_entry'));
244 $this->showMembers();
245 }
246 } else {
247 $this->showMyObjects();
248 }
249 }
250
251 protected function mailObjects(): void
252 {
253 $members = [];
254 $mail_data = $this->umail->retrieveFromStage();
255
256 $obj_ids = [];
257 if ($this->http->wrapper()->query()->has('search_' . $this->getObjectType())) {
258 $obj_ids = [
259 $this->http->wrapper()->query()->retrieve(
260 'search_' . $this->getObjectType(),
261 $this->refinery->kindlyTo()->int()
262 )
263 ];
264 } elseif ($this->http->wrapper()->post()->has('search_' . $this->getObjectType())) {
265 $obj_ids = $this->http->wrapper()->post()->retrieve(
266 'search_' . $this->getObjectType(),
267 $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int())
268 );
269 }
270
271 foreach ($obj_ids as $obj_id) {
272 $ref_ids = ilObject::_getAllReferences($obj_id);
273 foreach ($ref_ids as $ref_id) {
274 $can_send_mails = ilParticipants::canSendMailToMembers(
275 $ref_id,
276 $this->user->getId(),
278 );
279 if (!$can_send_mails) {
280 continue;
281 }
282
283 $roles = $this->rbacreview->getAssignableChildRoles($ref_id);
284 foreach ($roles as $role) {
285 if ($this->isLocalRoleTitle($role['title'])) {
286 $recipient = (new ilRoleMailboxAddress($role['obj_id']))->value();
287 if (!$this->umail->existsRecipient($recipient, (string) $mail_data['rcp_to'])) {
288 $members[] = $recipient;
289 }
290 }
291 }
292 }
293 }
294
295 $mail_data = $members !== [] ? $this->umail->appendSearchResult(array_unique($members), 'to') : $this->umail->retrieveFromStage();
296
297 $this->umail->persistToStage(
298 (int) $mail_data['user_id'],
299 $mail_data['rcp_to'],
300 $mail_data['rcp_cc'],
301 $mail_data['rcp_bcc'],
302 $mail_data['m_subject'],
303 $mail_data['m_message'],
304 $mail_data['attachments'],
305 $mail_data['use_placeholders'],
306 $mail_data['tpl_ctx_id'],
307 $mail_data['tpl_ctx_params']
308 );
309
310 $this->ctrl->redirectToURL('ilias.php?baseClass=ilMailGUI&type=search_res');
311 }
312
313 public function mailMembers(): void
314 {
315 $members = [];
316 $usr_ids = [];
317 if ($this->http->wrapper()->query()->has('search_members')) {
318 $usr_ids = [
319 $this->http->wrapper()->query()->retrieve(
320 'search_members',
321 $this->refinery->kindlyTo()->int()
322 )
323 ];
324 } elseif ($this->http->wrapper()->post()->has('search_members')) {
325 $usr_ids = $this->http->wrapper()->post()->retrieve(
326 'search_members',
327 $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int())
328 );
329 }
330
331 $mail_data = $this->umail->retrieveFromStage();
332 foreach ($usr_ids as $usr_id) {
333 $login = ilObjUser::_lookupLogin($usr_id);
334 if (!$this->umail->existsRecipient($login, (string) $mail_data['rcp_to'])) {
335 $members[] = $login;
336 }
337 }
338 $mail_data = $this->umail->appendSearchResult(array_unique($members), 'to');
339
340 $this->umail->persistToStage(
341 (int) $mail_data['user_id'],
342 $mail_data['rcp_to'],
343 $mail_data['rcp_cc'],
344 $mail_data['rcp_bcc'],
345 $mail_data['m_subject'],
346 $mail_data['m_message'],
347 $mail_data['attachments'],
348 $mail_data['use_placeholders'],
349 $mail_data['tpl_ctx_id'],
350 $mail_data['tpl_ctx_params']
351 );
352
353 $this->ctrl->redirectToURL('ilias.php?baseClass=ilMailGUI&type=search_res');
354 }
355
356 public function cancel(): void
357 {
358 $view = '';
359 if ($this->http->wrapper()->query()->has('view')) {
360 $view = $this->http->wrapper()->query()->retrieve('view', $this->refinery->kindlyTo()->string());
361 }
362
363 if ($view === 'myobjects' && $this->isDefaultRequestContext()) {
364 $this->ctrl->returnToParent($this);
365 } else {
366 $this->showMyObjects();
367 }
368 }
369
370 public function showMembers(): void
371 {
372 $obj_ids = [];
373 if ($this->http->wrapper()->query()->has('search_' . $this->getObjectType())) {
374 $obj_ids = $this->refinery->kindlyTo()->listOf(
375 $this->refinery->kindlyTo()->int()
376 )->transform(explode(',', (string) $this->http->wrapper()->query()->retrieve(
377 'search_' . $this->getObjectType(),
378 $this->refinery->kindlyTo()->string()
379 )));
380 } elseif ($this->http->wrapper()->post()->has('search_' . $this->getObjectType())) {
381 $obj_ids = $this->http->wrapper()->post()->retrieve(
382 'search_' . $this->getObjectType(),
383 $this->refinery->kindlyTo()->listOf(
384 $this->refinery->kindlyTo()->int()
385 )
386 );
387 } elseif (ilSession::get('search_' . $this->getObjectType())) {
388 $obj_ids = $this->refinery->kindlyTo()->listOf(
389 $this->refinery->kindlyTo()->int()
390 )->transform(explode(',', (string) ilSession::get('search_' . $this->getObjectType())));
391 ilSession::set('search_' . $this->getObjectType(), '');
392 }
393
394 if ($obj_ids === []) {
395 $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_select_' . $this->getObjectType()));
396 $this->showMyObjects();
397 return;
398 }
399
400 foreach ($obj_ids as $obj_id) {
402 $object = ilObjectFactory::getInstanceByObjId($obj_id);
403
404 $ref_ids = array_keys(ilObject::_getAllReferences($object->getId()));
405 $ref_id = $ref_ids[0];
406 $object->setRefId($ref_id);
407
408 if (!$this->doesExposeMembers($object)) {
409 $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_crs_list_members_not_available_for_at_least_one_crs'));
410 $this->showMyObjects();
411 return;
412 }
413 }
414
415 $this->lng->loadLanguageModule($this->getObjectType());
416
417 $this->tpl->setTitle($this->lng->txt('mail_addressbook'));
418
419 $this->ctrl->setParameter($this, 'view', $this->getObjectType() . '_members');
420 if ($obj_ids !== []) {
421 $this->ctrl->setParameter($this, 'search_' . $this->getObjectType(), implode(',', $obj_ids));
422 }
423
424 $context = $this->getContext();
425
427 $this,
428 $this->getObjectType(),
429 $context,
430 $obj_ids
431 );
432 $tableData = [];
433
434 $searchTpl = new ilTemplate('tpl.mail_search_template.html', true, true, 'components/ILIAS/Contact');
435 foreach ($obj_ids as $obj_id) {
436 $members_obj = ilParticipants::getInstanceByObjId($obj_id);
437 $usr_ids = array_map('\intval', ilUtil::_sortIds($members_obj->getParticipants(), 'usr_data', 'lastname', 'usr_id'));
438 foreach ($usr_ids as $usr_id) {
439 $user = new ilObjUser($usr_id);
440 if (!$user->getActive()) {
441 continue;
442 }
443
444 $fullname = '';
445 if (in_array(ilObjUser::_lookupPref($user->getId(), 'public_profile'), ['g', 'y'])) {
446 $fullname = $user->getLastname() . ', ' . $user->getFirstname();
447 }
448
449 $rowData = [
450 'members_id' => $user->getId(),
451 'members_login' => $user->getLogin(),
452 'members_name' => $fullname,
453 'members_crs_grp' => $this->cache->lookupTitle((int) $obj_id),
454 'search_' . $this->getObjectType() => $obj_id
455 ];
456
457 if ('mail' === $context && ilBuddySystem::getInstance()->isEnabled()) {
458 $relation = ilBuddyList::getInstanceByGlobalUser()->getRelationByUserId($user->getId());
459 $state_name = ilStr::convertUpperCamelCaseToUnderscoreCase($relation->getState()->getName());
460 $rowData['status'] = '';
461 if ($user->getId() !== $this->user->getId()) {
462 if ($relation->isOwnedByActor()) {
463 $rowData['status'] = $this->lng->txt('buddy_bs_state_' . $state_name . '_a');
464 } else {
465 $rowData['status'] = $this->lng->txt('buddy_bs_state_' . $state_name . '_p');
466 }
467 }
468 }
469
470 $tableData[] = $rowData;
471 }
472 }
473 $table->setData($tableData);
474
475 if ($tableData !== []) {
476 $searchTpl->setVariable('TXT_MARKED_ENTRIES', $this->lng->txt('marked_entries'));
477 }
478
479 $searchTpl->setVariable('TABLE', $table->getHTML());
480 $this->tpl->setContent($searchTpl->get());
481
482 if ($this->isDefaultRequestContext()) {
483 $this->tpl->printToStdout();
484 }
485 }
486
487 abstract protected function doesExposeMembers(ilObject $object): bool;
488
489 public function showMyObjects(): void
490 {
491 $this->tpl->setTitle($this->lng->txt('mail_addressbook'));
492
493 $searchTpl = new ilTemplate('tpl.mail_search_template.html', true, true, 'components/ILIAS/Contact');
494
495 $this->lng->loadLanguageModule('crs');
496
497 $table = new ilMailSearchObjectsTableGUI(
498 $this,
499 $this->getObjectType(),
500 $this->getContext()
501 );
502 $table->setId('search_' . $this->getObjectType() . '_tbl');
503
504 $objs_ids = ilParticipants::_getMembershipByType($this->user->getId(), [$this->getObjectType()]);
505 $counter = 0;
506 $tableData = [];
507 if ($objs_ids !== []) {
508 $num_courses_hidden_members = 0;
509 foreach ($objs_ids as $obj_id) {
511 $object = ilObjectFactory::getInstanceByObjId($obj_id);
512
513 $ref_ids = array_keys(ilObject::_getAllReferences($object->getId()));
514 $ref_id = $ref_ids[0];
515 $object->setRefId($ref_id);
516
517 $has_untrashed_references = ilObject::_hasUntrashedReference($object->getId());
518 $can_send_mails = ilParticipants::canSendMailToMembers(
519 $object->getRefId(),
520 $this->user->getId(),
522 );
523
524 $exposes_members = $this->doesExposeMembers($object);
525 ;
526 if ($has_untrashed_references && ($can_send_mails || $exposes_members)) {
527 $participants = ilParticipants::getInstanceByObjId($object->getId());
528 $usr_ids = $participants->getParticipants();
529
530 foreach ($usr_ids as $key => $usr_id) {
531 $is_active = ilObjUser::_lookupActive($usr_id);
532 if (!$is_active) {
533 unset($usr_ids[$key]);
534 }
535 }
536 $usr_ids = array_values($usr_ids);
537
538 if (!$exposes_members) {
539 ++$num_courses_hidden_members;
540 }
541
542 $path_arr = $this->tree->getPathFull($object->getRefId(), $this->tree->getRootId());
543 $path = '';
544 foreach ($path_arr as $data) {
545 if ($path !== '') {
546 $path .= ' -> ';
547 }
548 $path .= $data['title'];
549 }
550
551 $this->ctrl->setParameter($this, 'search_' . $this->getObjectType(), $object->getId());
552 $this->ctrl->setParameter($this, 'view', 'myobjects');
553 $buttons = [];
554
555 if ($this->isDefaultRequestContext()) {
556 if ($this->mailing_allowed && $can_send_mails) {
557 $buttons[] = $this->ui_factory
558 ->button()
559 ->shy(
560 $this->lng->txt('mail_members'),
561 $this->ctrl->getLinkTarget($this, 'mail')
562 );
563 }
564 } else {
565 $buttons[] = $this->ui_factory
566 ->button()
567 ->shy(
568 $this->lng->txt('wsp_share_with_members'),
569 $this->ctrl->getLinkTarget($this, 'share')
570 );
571 }
572
573 if ($exposes_members) {
574 $buttons[] = $this->ui_factory
575 ->button()
576 ->shy(
577 $this->lng->txt('mail_list_members'),
578 $this->ctrl->getLinkTarget($this, 'showMembers')
579 );
580 }
581
582 $this->ctrl->clearParameters($this);
583
584 $drop_down = null;
585 if ($buttons !== []) {
586 $drop_down = $this->ui_factory
587 ->dropdown()
588 ->standard($buttons)
589 ->withLabel($this->lng->txt('actions'));
590 }
591
592 $rowData = [
593 'OBJECT_ID' => $object->getId(),
594 'OBJECT_NAME' => $object->getTitle(),
595 'OBJECT_NO_MEMBERS' => count($usr_ids),
596 'OBJECT_PATH' => $path,
597 'COMMAND_SELECTION_LIST' => $drop_down ? $this->ui_renderer->render($drop_down) : '',
598 'hidden_members' => !$exposes_members,
599 ];
600 $counter++;
601 $tableData[] = $rowData;
602 }
603 }
604
605 if ($num_courses_hidden_members > 0) {
606 $searchTpl->setCurrentBlock('caption_block');
607 $searchTpl->setVariable('TXT_LIST_MEMBERS_NOT_AVAILABLE', $this->lng->txt('mail_crs_list_members_not_available'));
608 $searchTpl->parseCurrentBlock();
609 }
610 }
611
612 $searchTpl->setVariable('TXT_MARKED_ENTRIES', $this->lng->txt('marked_entries'));
613
614 $table->setData($tableData);
615 $searchTpl->setVariable('TABLE', $table->getHTML());
616 $this->tpl->setContent($searchTpl->get());
617
618 if ($this->isDefaultRequestContext()) {
619 $this->tpl->printToStdout();
620 }
621 }
622
623 public function executeCommand(): bool
624 {
625 $forward_class = $this->ctrl->getNextClass($this) ?? '';
626 switch (strtolower($forward_class)) {
627 case strtolower(ilBuddySystemGUI::class):
628 if (!ilBuddySystem::getInstance()->isEnabled()) {
629 $this->error->raiseError($this->lng->txt('msg_no_perm_read'), $this->error->MESSAGE);
630 }
631
632 $this->ctrl->saveParameter($this, 'search_' . $this->getObjectType());
633
634 $this->ctrl->setReturn($this, 'showMembers');
635 $this->ctrl->forwardCommand(new ilBuddySystemGUI());
636 break;
637
638 default:
639 if (!($cmd = $this->ctrl->getCmd())) {
640 $cmd = 'showMyObjects';
641 }
642
643 $this->$cmd();
644 break;
645 }
646
647 return true;
648 }
649}
$relation
Builds data types.
Definition: Factory.php:36
error(string $a_errmsg)
static getInstanceByGlobalUser(?ilObjUser $user=null)
Class ilBuddySystemGUI.
Error Handling & global info handling.
language handling
ilGlobalTemplateInterface $tpl
getRequestValue(string $key, \ILIAS\Refinery\Transformation $trafo, $default=null)
doesExposeMembers(ilObject $object)
__construct(protected $wsp_access_handler=null, protected ?int $wsp_node_id=null)
User class.
static _lookupActive(int $a_usr_id)
static _lookupPref(int $a_usr_id, string $a_keyword)
static _lookupLogin(int $a_user_id)
class ilObjectDataCache
static getInstanceByObjId(?int $obj_id, bool $stop_on_error=true)
get an instance of an Ilias object by object id
Class ilObject Basic functions for all objects.
static _hasUntrashedReference(int $obj_id)
checks whether an object has at least one reference that is not in trash
static _getAllReferences(int $id)
get all reference ids for object ID
setRefId(int $ref_id)
static _getMembershipByType(int $a_usr_id, array $a_type, bool $a_only_member_role=false)
get membership by type Get course or group membership
static getInstanceByObjId(int $a_obj_id)
Get instance by obj type.
static canSendMailToMembers(int|ilObject $ref_id_or_instance, ?int $usr_id=null, ?int $mail_obj_ref_id=null)
This method was introduced as a band-aid fix for #22764.
class ilRbacReview Contains Review functions of core Rbac.
class ilRbacSystem system function like checkAccess, addActiveRole ... Supporting system functions ar...
static get(string $a_var)
static set(string $a_var, $a_val)
Set a value.
static convertUpperCamelCaseToUnderscoreCase(string $value)
Convert a value given in camel case conversion to underscore case conversion (e.g.
special template class to simplify handling of ITX/PEAR
Tree class data representation in hierachical trees using the Nested Set Model with Gaps by Joe Celco...
static _sortIds(array $a_ids, string $a_table, string $a_field, string $a_id_name)
Function that sorts ids by a given table field using WHERE IN E.g: __sort(array(6,...
Interface GlobalHttpState.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$ref_id
Definition: ltiauth.php:66
$path
Definition: ltiservices.php:30
static http()
Fetches the global http state from ILIAS.
Interface Observer \BackgroundTasks Contains several chained tasks and infos about them.
global $DIC
Definition: shib_login.php:26
$counter