ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilMailSearchGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
24 
30 {
35  private ilLanguage $lng;
37  private bool $errorDelete = false;
41  private $wsp_access_handler = null;
42  private ?int $wsp_node_id = null;
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),
239  $this->isDefaultRequestContext()
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"])) {
349  $name = ilObjUser::_lookupName($user);
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"])) {
439  $name = ilObjUser::_lookupName($user);
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 
493  $search = ilObjectSearchFactory::_getObjectSearchInstance($query_parser);
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 }
Interface GlobalHttpState.
static get(string $a_var)
static getInstanceByGlobalUser()
const ROOT_FOLDER_ID
Definition: constants.php:32
Class ChatMainBarProvider .
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
static getImagePath(string $img, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
static _lookupName(int $a_user_id)
lookup user name
static _lookupPref(int $a_usr_id, string $a_keyword)
static _getUserSearchInstance(ilQueryParser $query_parser)
static prepareFormOutput($a_str, bool $a_strip=false)
$index
Definition: metadata.php:145
ilObjectDataCache $object_data_cache
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
global $DIC
Definition: feed.php:28
static strLen(string $a_string)
Definition: class.ilStr.php:63
if($format !==null) $name
Definition: metadata.php:247
static http()
Fetches the global http state from ILIAS.
static _getObjectSearchInstance(ilQueryParser $query_parser)
string $key
Consumer key/client ID value.
Definition: System.php:193
ilCtrlInterface $ctrl
static hasParticipantListAccess(int $a_obj_id, int $a_usr_id=null)
Check if (current) user has access to the participant list.
static formCheckbox(bool $checked, string $varname, string $value, bool $disabled=false)
ilGlobalTemplateInterface $tpl
addPermission(array $a_obj_ids)
__construct(Container $dic, ilPlugin $plugin)
appendRecipientSelection(array &$result, int $index, string $search_type, string $recipient_type, string $value)
GlobalHttpState $http
static _lookupEmail(int $a_user_id)
static set(string $a_var, $a_val)
Set a value.
Class FlySystemFileAccessTest disabled disabled disabled.
static _lookupLogin(int $a_user_id)