ILIAS  release_8 Revision v8.24
class.ilMailSearchGUI.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
23use ILIAS\Refinery\Factory as Refinery;
24
30{
37 private bool $errorDelete = false;
41 private $wsp_access_handler = null;
42 private ?int $wsp_node_id = null;
44 private Refinery $refinery;
45
49 public function __construct($wsp_access_handler = null, ?int $wsp_node_id = null)
50 {
52 global $DIC;
53
54 $this->tpl = $DIC['tpl'];
55 $this->ctrl = $DIC['ilCtrl'];
56 $this->lng = $DIC['lng'];
57 $this->rbacreview = $DIC['rbacreview'];
58 $this->object_data_cache = $DIC['ilObjDataCache'];
59 $this->http = $DIC->http();
60 $this->refinery = $DIC->refinery();
61
62 $this->wsp_access_handler = $wsp_access_handler;
63 $this->wsp_node_id = $wsp_node_id;
64
65 $this->ctrl->saveParameter($this, 'mobj_id');
66 $this->ctrl->saveParameter($this, 'ref');
67
68 $this->umail = new ilFormatMail($DIC->user()->getId());
69 }
70
71 public function executeCommand(): bool
72 {
73 $forward_class = $this->ctrl->getNextClass($this);
74 switch ($forward_class) {
75 default:
76 if (!($cmd = $this->ctrl->getCmd())) {
77 $cmd = "showResults";
78 }
79
80 $this->$cmd();
81 break;
82 }
83
84 return true;
85 }
86
87 private function isDefaultRequestContext(): bool
88 {
89 return (
90 !$this->http->wrapper()->query()->has('ref') ||
91 $this->http->wrapper()->query()->retrieve('ref', $this->refinery->kindlyTo()->string()) !== 'wsp'
92 );
93 }
94
95 public function adopt(): void
96 {
97 $trafo = $this->refinery->kindlyTo()->int();
98 if ($this->isDefaultRequestContext()) {
99 $trafo = $this->refinery->kindlyTo()->string();
100 }
101
102 $recipients_to = [];
103 foreach (['to', 'cc', 'bcc'] as $recipient_type) {
104 $recipients = [];
105 foreach (['addr', 'usr', 'grp'] as $search_type) {
106 if ($this->http->wrapper()->post()->has('search_name_' . $recipient_type . '_' . $search_type)) {
107 $recipients[] = $this->http->wrapper()->post()->retrieve(
108 'search_name_' . $recipient_type . '_' . $search_type,
109 $this->refinery->kindlyTo()->listOf($trafo)
110 );
111 }
112 }
113
114 $recipients = array_unique(array_merge(...$recipients));
115 ilSession::set('mail_search_results_' . $recipient_type, $recipients);
116
117 if ('to' === $recipient_type) {
118 $recipients_to = $recipients;
119 }
120 }
121
122 if ($this->isDefaultRequestContext()) {
123 $this->saveMailData();
124 } else {
125 $this->addPermission($recipients_to);
126 }
127
128 $this->ctrl->returnToParent($this);
129 }
130
131 private function saveMailData(): void
132 {
133 $mail_data = $this->umail->retrieveFromStage();
134 $this->umail->persistToStage(
135 (int) $mail_data['user_id'],
136 $mail_data['attachments'],
137 $mail_data['rcp_to'],
138 $mail_data['rcp_cc'],
139 $mail_data['rcp_bcc'],
140 $mail_data['m_subject'],
141 $mail_data['m_message'],
142 $mail_data['use_placeholders'],
143 $mail_data['tpl_ctx_id'],
144 $mail_data['tpl_ctx_params']
145 );
146 }
147
148 public function cancel(): void
149 {
150 $this->ctrl->returnToParent($this);
151 }
152
153 public function search(): bool
154 {
155 $search = '';
156 if ($this->http->wrapper()->post()->has('search')) {
157 $search = $this->http->wrapper()->post()->retrieve('search', $this->refinery->kindlyTo()->string());
158 }
159
160 ilSession::set('mail_search_search', trim($search));
161
162 if (ilSession::get('mail_search_search') === '') {
163 $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_insert_query'));
164 } elseif (strlen(ilSession::get('mail_search_search')) < 3) {
165 $this->lng->loadLanguageModule('search');
166 $this->tpl->setOnScreenMessage('info', $this->lng->txt('search_minimum_three'));
167 }
168
169 $this->showResults();
170
171 return true;
172 }
173
174 protected function initSearchForm(): ilPropertyFormGUI
175 {
176 if ($this->isDefaultRequestContext()) {
177 $this->saveMailData();
178 $title = $this->lng->txt('search_recipients');
179 } else {
180 $this->lng->loadLanguageModule('wsp');
181 $title = $this->lng->txt('wsp_share_search_users');
182 }
183
184 $form = new ilPropertyFormGUI();
185 $form->setTitle($title);
186 $form->setId('search_rcp');
187 $form->setFormAction($this->ctrl->getFormAction($this, 'search'));
188
189 $inp = new ilTextInputGUI($this->lng->txt('search_for'), 'search');
190 $inp->setSize(30);
191 $dsDataLink = $this->ctrl->getLinkTarget($this, 'lookupRecipientAsync', '', true, false);
192 $inp->setDataSource($dsDataLink);
193
194 if (
195 ilSession::get('mail_search_search') &&
196 is_string(ilSession::get('mail_search_search')) &&
197 ilSession::get('mail_search_search') !== ''
198 ) {
199 $inp->setValue(
200 ilLegacyFormElementsUtil::prepareFormOutput(trim(ilSession::get('mail_search_search')), true)
201 );
202 }
203 $form->addItem($inp);
204
205 $form->addCommandButton('search', $this->lng->txt('search'));
206 $form->addCommandButton('cancel', $this->lng->txt('cancel'));
207
208 return $form;
209 }
210
211 public function lookupRecipientAsync(): void
212 {
213 $search = '';
214 if ($this->http->wrapper()->query()->has('term')) {
215 $search = $this->http->wrapper()->query()->retrieve(
216 'term',
217 $this->refinery->kindlyTo()->string()
218 );
219 }
220 if ($this->http->wrapper()->post()->has('term')) {
221 $search = $this->http->wrapper()->post()->retrieve(
222 'term',
223 $this->refinery->kindlyTo()->string()
224 );
225 }
226
227 $search = trim($search);
228
229 $result = [];
230 if (ilStr::strLen($search) >= 3) {
231 // #14768
232 $quoted = ilUtil::stripSlashes($search);
233 $quoted = str_replace(['%', '_'], ['\%', '\_'], $quoted);
234
235 $mailFormObj = new ilMailForm();
236 $result = $mailFormObj->getRecipientAsync(
237 "%" . $quoted . "%",
238 ilUtil::stripSlashes($search),
240 );
241 }
242
243 $this->http->saveResponse(
244 $this->http->response()
245 ->withHeader(ResponseHeader::CONTENT_TYPE, 'application/json')
246 ->withBody(\ILIAS\Filesystem\Stream\Streams::ofString(json_encode($result, JSON_THROW_ON_ERROR)))
247 );
248 $this->http->sendResponse();
249 $this->http->close();
250 }
251
255 private function appendRecipientSelection(
256 array &$result,
257 int $index,
258 string $search_type,
259 string $recipient_type,
260 string $value
261 ): void {
262 $result[$index]['check_' . $recipient_type] = ilLegacyFormElementsUtil::formCheckbox(
263 false,
264 'search_name_' . $recipient_type . '_' . $search_type . '[' . $index . ']',
265 $value
266 );
267
268 $result[$index]['id_' . $recipient_type] = 'search_name_' . $search_type . '_' . $index;
269 $result[$index]['txt_' . $recipient_type] = $this->lng->txt('mail_' . $recipient_type);
270 }
271
272 public function showResults(): void
273 {
274 $form = $this->initSearchForm();
275
276 $this->tpl->addBlockFile('ADM_CONTENT', 'adm_content', 'tpl.mail_search.html', 'Services/Contact');
277 $this->tpl->setVariable('ACTION', $this->ctrl->getFormAction($this));
278 $this->tpl->setTitle($this->lng->txt('mail'));
279 $this->tpl->setVariable('SEARCHFORM', $form->getHtml());
280
281 // #14109
282 if (
283 !ilSession::get('mail_search_search') ||
284 !is_string(ilSession::get('mail_search_search')) ||
285 strlen(ilSession::get('mail_search_search')) < 3
286 ) {
287 if ($this->isDefaultRequestContext()) {
288 $this->tpl->printToStdout();
289 }
290 return;
291 }
292
293 $relations = ilBuddyList::getInstanceByGlobalUser()->getLinkedRelations();
294 if (count($relations)) {
295 $contacts_search_result = new ilSearchResult();
296
297 $query_parser = new ilQueryParser(addcslashes(ilSession::get('mail_search_search'), '%_'));
298 $query_parser->setCombination(ilQueryParser::QP_COMBINATION_AND);
299 $query_parser->setMinWordLength(3);
300 $query_parser->parse();
301
302 $user_search = ilObjectSearchFactory::_getUserSearchInstance($query_parser);
303 $user_search->enableActiveCheck(true);
304 $user_search->setFields(['login']);
305 $result_obj = $user_search->performSearch();
306 $contacts_search_result->mergeEntries($result_obj);
307
308 $user_search->setFields(['firstname']);
309 $result_obj = $user_search->performSearch();
310 $contacts_search_result->mergeEntries($result_obj);
311
312 $user_search->setFields(['lastname']);
313 $result_obj = $user_search->performSearch();
314 $contacts_search_result->mergeEntries($result_obj);
315
316 $contacts_search_result->setMaxHits(100000);
317 $contacts_search_result->preventOverwritingMaxhits(true);
318 $contacts_search_result->filter(ROOT_FOLDER_ID, true);
319
320 // Filter users (depends on setting in user accounts)
321 $users = ilUserFilter::getInstance()->filter($contacts_search_result->getResultIds());
322 $users = array_intersect($users, $relations->getKeys());
323
324 $tbl_contacts = new ilMailSearchResultsTableGUI($this, 'showResults', 'contacts');
325 $tbl_contacts->setTitle($this->lng->txt('mail_addressbook'));
326 $tbl_contacts->setRowTemplate('tpl.mail_search_addr_row.html', 'Services/Contact');
327
328 $has_mail_addr = false;
329 $result = [];
330 $counter = 0;
331 foreach ($users as $user) {
332 $login = ilObjUser::_lookupLogin($user);
333
334 if ($this->isDefaultRequestContext()) {
335 foreach (['to', 'cc', 'bcc'] as $recipient_type) {
336 $this->appendRecipientSelection($result, $counter, 'usr', $recipient_type, $login);
337 }
338 } else {
339 $this->appendRecipientSelection($result, $counter, 'addr', 'to', (string) $user);
340 }
341
342 $result[$counter]['login'] = $login;
343 if (ilObjUser::_lookupPref($user, 'public_email') === 'y') {
344 $has_mail_addr = true;
345 $result[$counter]['email'] = ilObjUser::_lookupEmail($user);
346 }
347
348 if (in_array(ilObjUser::_lookupPref($user, 'public_profile'), ['y', "g"])) {
350 $result[$counter]['firstname'] = $name['firstname'];
351 $result[$counter]['lastname'] = $name['lastname'];
352 } else {
353 $result[$counter]['firstname'] = '';
354 $result[$counter]['lastname'] = '';
355 }
356
357 ++$counter;
358 }
359
360 if ($this->isDefaultRequestContext()) {
361 $tbl_contacts->addColumn(
362 $this->lng->txt('mail_to') . '/' . $this->lng->txt('mail_cc') . '/' . $this->lng->txt('mail_bcc'),
363 'check',
364 '10%'
365 );
366 } else {
367 $tbl_contacts->addColumn('', '', '1%', true);
368 }
369 $tbl_contacts->addColumn($this->lng->txt('login'), 'login', '15%');
370 $tbl_contacts->addColumn($this->lng->txt('firstname'), 'firstname', '15%');
371 $tbl_contacts->addColumn($this->lng->txt('lastname'), 'lastname', '15%');
372 if ($has_mail_addr) {
373 foreach ($result as $key => $val) {
374 if (!isset($val['email']) || (string) $val['email'] === '') {
375 $result[$key]['email'] = '&nbsp;';
376 }
377 }
378
379 $tbl_contacts->addColumn($this->lng->txt('email'), 'email', "15%");
380 }
381 $tbl_contacts->setData($result);
382
383 $tbl_contacts->setDefaultOrderField('login');
384 $tbl_contacts->enable('select_all');
385 $tbl_contacts->setSelectAllCheckbox('search_name_to_addr');
386 $tbl_contacts->setFormName('recipients');
387
388 $this->tpl->setVariable('TABLE_ADDR', $tbl_contacts->getHTML());
389 }
390
391 $all_results = new ilSearchResult();
392
393 $query_parser = new ilQueryParser(addcslashes(ilSession::get('mail_search_search'), '%_'));
394 $query_parser->setCombination(ilQueryParser::QP_COMBINATION_AND);
395 $query_parser->setMinWordLength(3);
396 $query_parser->parse();
397
398 $user_search = ilObjectSearchFactory::_getUserSearchInstance($query_parser);
399 $user_search->enableActiveCheck(true);
400 $user_search->setFields(['login']);
401 $result_obj = $user_search->performSearch();
402 $all_results->mergeEntries($result_obj);
403
404 $user_search->setFields(['firstname']);
405 $result_obj = $user_search->performSearch();
406 $all_results->mergeEntries($result_obj);
407
408 $user_search->setFields(['lastname']);
409 $result_obj = $user_search->performSearch();
410 $all_results->mergeEntries($result_obj);
411
412 $all_results->setMaxHits(100000);
413 $all_results->preventOverwritingMaxhits(true);
414 $all_results->filter(ROOT_FOLDER_ID, true);
415
416 // Filter users (depends on setting in user accounts)
417 $has_mail_usr = false;
418 $users = ilUserFilter::getInstance()->filter($all_results->getResultIds());
419 if ($users !== []) {
420 $tbl_users = new ilMailSearchResultsTableGUI($this, 'showResults', 'usr');
421 $tbl_users->setTitle($this->lng->txt('system') . ': ' . $this->lng->txt('persons'));
422 $tbl_users->setRowTemplate('tpl.mail_search_users_row.html', 'Services/Contact');
423
424 $result = [];
425 $counter = 0;
426 foreach ($users as $user) {
427 $login = ilObjUser::_lookupLogin($user);
428
429 if ($this->isDefaultRequestContext()) {
430 foreach (['to', 'cc', 'bcc'] as $recipient_type) {
431 $this->appendRecipientSelection($result, $counter, 'usr', $recipient_type, $login);
432 }
433 } else {
434 $this->appendRecipientSelection($result, $counter, 'usr', 'to', (string) $user);
435 }
436 $result[$counter]['login'] = $login;
437
438 if (in_array(ilObjUser::_lookupPref($user, 'public_profile'), ['y', "g"])) {
440 $result[$counter]['firstname'] = $name['firstname'];
441 $result[$counter]['lastname'] = $name['lastname'];
442 } else {
443 $result[$counter]['firstname'] = '';
444 $result[$counter]['lastname'] = '';
445 }
446
447 if (ilObjUser::_lookupPref($user, 'public_email') === 'y') {
448 $has_mail_usr = true;
449 $result[$counter]['email'] = ilObjUser::_lookupEmail($user);
450 }
451
452 ++$counter;
453 }
454
455 if ($this->isDefaultRequestContext()) {
456 $tbl_users->addColumn(
457 $this->lng->txt('mail_to') . '/' . $this->lng->txt('mail_cc') . '/' . $this->lng->txt('mail_bcc'),
458 'check',
459 '10%'
460 );
461 } else {
462 $tbl_users->addColumn('', '', '1%');
463 }
464 $tbl_users->addColumn($this->lng->txt('login'), 'login', '15%');
465 $tbl_users->addColumn($this->lng->txt('firstname'), 'firstname', '15%');
466 $tbl_users->addColumn($this->lng->txt('lastname'), 'lastname', '15%');
467 if ($has_mail_usr === true) {
468 foreach ($result as $key => $val) {
469 if (!isset($val['email']) || (string) $val['email'] === '') {
470 $result[$key]['email'] = '&nbsp;';
471 }
472 }
473
474 $tbl_users->addColumn($this->lng->txt('email'), 'email', '15%');
475 }
476 $tbl_users->setData($result);
477
478 $tbl_users->setDefaultOrderField('login');
479 $tbl_users->enable('select_all');
480 $tbl_users->setSelectAllCheckbox('search_name_to_usr');
481 $tbl_users->setFormName('recipients');
482
483 $this->tpl->setVariable('TABLE_USERS', $tbl_users->getHTML());
484 }
485
486 $group_results = new ilSearchResult();
487
488 $query_parser = new ilQueryParser(addcslashes(ilSession::get('mail_search_search'), '%_'));
489 $query_parser->setCombination(ilQueryParser::QP_COMBINATION_AND);
490 $query_parser->setMinWordLength(3);
491 $query_parser->parse();
492
494 $search->setFilter(['grp']);
495 $result = $search->performSearch();
496 $group_results->mergeEntries($result);
497 $group_results->setMaxHits(PHP_INT_MAX);
498 $group_results->preventOverwritingMaxhits(true);
499 $group_results->setRequiredPermission('read');
500 $group_results->filter(ROOT_FOLDER_ID, true);
501
502 $visible_groups = [];
503 if ($group_results->getResults()) {
504 $tbl_grp = new ilMailSearchResultsTableGUI($this, 'showResults', 'grp');
505 $tbl_grp->setTitle($this->lng->txt('system') . ': ' . $this->lng->txt('groups'));
506 $tbl_grp->setRowTemplate('tpl.mail_search_groups_row.html', 'Services/Contact');
507
508 $result = [];
509 $counter = 0;
510
511 $this->object_data_cache->preloadReferenceCache(array_keys($group_results->getResults()));
512
513 $groups = $group_results->getResults();
514 foreach ($groups as $grp) {
515 if (!ilParticipants::hasParticipantListAccess($grp['obj_id'])) {
516 continue;
517 }
518
519 if ($this->isDefaultRequestContext()) {
520 $members = [];
521 $roles = $this->rbacreview->getAssignableChildRoles($grp['ref_id']);
522 foreach ($roles as $role) {
523 if (
524 strpos($role['title'], 'il_grp_member_') === 0 ||
525 strpos($role['title'], 'il_grp_admin_') === 0
526 ) {
527 // FIX for Mantis: 7523
528 $members[] = '#' . $role['title'];
529 }
530 }
531 $str_members = implode(',', $members);
532
533 foreach (['to', 'cc', 'bcc'] as $recipient_type) {
534 $this->appendRecipientSelection($result, $counter, 'grp', $recipient_type, $str_members);
535 }
536 } else {
537 $this->appendRecipientSelection($result, $counter, 'grp', 'to', (string) $grp['obj_id']);
538 }
539 $result[$counter]['title'] = $this->object_data_cache->lookupTitle((int) $grp['obj_id']);
540 $result[$counter]['description'] = $this->object_data_cache->lookupDescription((int) $grp['obj_id']);
541
542 ++$counter;
543 $visible_groups[] = $grp;
544 }
545
546 if ($visible_groups) {
547 $tbl_grp->setData($result);
548
549 if ($this->isDefaultRequestContext()) {
550 $tbl_grp->addColumn(
551 $this->lng->txt('mail_to') . '/' . $this->lng->txt('mail_cc') . '/' . $this->lng->txt('mail_bcc'),
552 'check',
553 '10%'
554 );
555 } else {
556 $tbl_grp->addColumn('', '', '1%');
557 }
558 $tbl_grp->addColumn($this->lng->txt('title'), 'title', '15%');
559 $tbl_grp->addColumn($this->lng->txt('description'), 'description', '15%');
560
561 $tbl_grp->setDefaultOrderField('title');
562 $tbl_grp->enable('select_all');
563 $tbl_grp->setSelectAllCheckbox('search_name_to_grp');
564 $tbl_grp->setFormName('recipients');
565
566 $this->tpl->setVariable('TABLE_GRP', $tbl_grp->getHTML());
567 }
568 }
569
570 if (count($users) || count($visible_groups) || count($relations)) {
571 $this->tpl->setVariable("IMG_ARROW", ilUtil::getImagePath("arrow_downright.svg"));
572 $this->tpl->setVariable("ALT_ARROW", '');
573 $this->tpl->setVariable("IMG_ARROW_UP", ilUtil::getImagePath("arrow_upright.svg"));
574 $this->tpl->setVariable("ALT_ARROW_UP", '');
575
576 if ($this->isDefaultRequestContext()) {
577 $this->tpl->setVariable('BUTTON_ADOPT', $this->lng->txt('adopt'));
578 } else {
579 $this->tpl->setVariable('BUTTON_ADOPT', $this->lng->txt('wsp_share_with_users'));
580 }
581 } else {
582 $this->lng->loadLanguageModule('search');
583 $this->tpl->setOnScreenMessage('info', $this->lng->txt('search_no_match'));
584 }
585
586 if ($this->isDefaultRequestContext()) {
587 $this->tpl->printToStdout();
588 }
589 }
590
594 protected function addPermission(array $a_obj_ids): void
595 {
596 if (!is_array($a_obj_ids)) {
597 $a_obj_ids = [$a_obj_ids];
598 }
599
600 $existing = $this->wsp_access_handler->getPermissions($this->wsp_node_id);
601 $added = false;
602 foreach ($a_obj_ids as $object_id) {
603 if (!in_array($object_id, $existing, true)) {
604 $added = $this->wsp_access_handler->addPermission($this->wsp_node_id, $object_id);
605 }
606 }
607
608 if ($added) {
609 $this->tpl->setOnScreenMessage('success', $this->lng->txt('wsp_share_success'), true);
610 }
611 }
612}
Builds data types.
Definition: Factory.php:21
static getInstanceByGlobalUser()
language handling
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static prepareFormOutput($a_str, bool $a_strip=false)
GlobalHttpState $http
addPermission(array $a_obj_ids)
appendRecipientSelection(array &$result, int $index, string $search_type, string $recipient_type, string $value)
ilCtrlInterface $ctrl
ilObjectDataCache $object_data_cache
ilGlobalTemplateInterface $tpl
static _lookupName(int $a_user_id)
lookup user name
static _lookupPref(int $a_usr_id, string $a_keyword)
static _lookupLogin(int $a_user_id)
static _lookupEmail(int $a_user_id)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _getObjectSearchInstance(ilQueryParser $query_parser)
static _getUserSearchInstance(ilQueryParser $query_parser)
static hasParticipantListAccess(int $a_obj_id, int $a_usr_id=null)
Check if (current) user has access to the participant list.
This class represents a property form user interface.
class ilRbacReview Contains Review functions of core Rbac.
static get(string $a_var)
static set(string $a_var, $a_val)
Set a value.
static strLen(string $a_string)
Definition: class.ilStr.php:63
This class represents a text property in a property form.
static getImagePath(string $img, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
const ROOT_FOLDER_ID
Definition: constants.php:32
global $DIC
Definition: feed.php:28
Interface GlobalHttpState.
Interface ResponseHeader.
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...
if($format !==null) $name
Definition: metadata.php:247
$index
Definition: metadata.php:145
Class FlySystemFileAccessTest \Provider\FlySystem @runTestsInSeparateProcesses @preserveGlobalState d...
static http()
Fetches the global http state from ILIAS.
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
string $key
Consumer key/client ID value.
Definition: System.php:193
Class ChatMainBarProvider \MainMenu\Provider.