From a0306edc60ecb907e3ac838ff7a5cecb7bd84988 Mon Sep 17 00:00:00 2001 From: nmatuschek Date: Mon, 22 Jan 2024 11:27:56 +0100 Subject: [PATCH] [LUI]: Contact: Replacing LUI Tables with KS Tables: MailSearchObjectsTable and MailSearchObjectMembershipsTable Co-authored-by: Michael Jansen Co-authored-by: Nadia Ahmad --- ...class.MailSearchObjectMembershipsTable.php | 347 +++++++ .../classes/class.MailSearchObjectsTable.php | 314 ++++++ .../classes/class.ilMailSearchCoursesGUI.php | 28 +- .../classes/class.ilMailSearchGroupsGUI.php | 27 +- .../classes/class.ilMailSearchObjectGUI.php | 940 ++++++++++-------- ....ilMailSearchObjectMembershipsTableGUI.php | 241 ----- .../class.ilMailSearchObjectsTableGUI.php | 161 --- .../templates/default/tpl.mail_members.html | 16 - .../tpl.mail_search_objects_members_row.html | 8 - .../default/tpl.mail_search_objects_row.html | 7 - .../Mail/classes/class.ilMailFormGUI.php | 4 - lang/ilias_de.lang | 1 - lang/ilias_en.lang | 1 - 13 files changed, 1205 insertions(+), 890 deletions(-) create mode 100644 components/ILIAS/Contact/classes/class.MailSearchObjectMembershipsTable.php create mode 100644 components/ILIAS/Contact/classes/class.MailSearchObjectsTable.php delete mode 100755 components/ILIAS/Contact/classes/class.ilMailSearchObjectMembershipsTableGUI.php delete mode 100755 components/ILIAS/Contact/classes/class.ilMailSearchObjectsTableGUI.php delete mode 100755 components/ILIAS/Contact/templates/default/tpl.mail_members.html delete mode 100755 components/ILIAS/Contact/templates/default/tpl.mail_search_objects_members_row.html delete mode 100755 components/ILIAS/Contact/templates/default/tpl.mail_search_objects_row.html diff --git a/components/ILIAS/Contact/classes/class.MailSearchObjectMembershipsTable.php b/components/ILIAS/Contact/classes/class.MailSearchObjectMembershipsTable.php new file mode 100644 index 000000000000..bab948a97a0d --- /dev/null +++ b/components/ILIAS/Contact/classes/class.MailSearchObjectMembershipsTable.php @@ -0,0 +1,347 @@ +>|null */ + private ?array $records = null; + private bool $buddysystem_enabled; + private bool $mailing_allowed = false; + + /** + * @param int[] $obj_ids + */ + public function __construct( + private readonly array $obj_ids, + private readonly ilMailSearchObjectGUI $parent_gui, + private readonly int $current_user_id, + private readonly ilCtrl $ctrl, + private readonly ilLanguage $lng, + private readonly Factory $ui_factory, + private readonly GlobalHttpState $http, + private readonly Refinery $refinery, + private readonly ilObjectDataCache $object_data_cache, + ) { + $this->request = $this->http->request(); + $this->data_factory = new DataFactory(); + + $this->lng->loadLanguageModule('crs'); + $this->lng->loadLanguageModule('wsp'); + $this->lng->loadLanguageModule('buddysystem'); + + $this->buddysystem_enabled = ilBuddySystem::getInstance()->isEnabled(); + } + + public function setMailingAllowed(bool $mailing_allowed): void + { + $this->mailing_allowed = $mailing_allowed; + } + + public function getComponent(): Data + { + return $this->ui_factory->table() + ->data( + $this, + $this->lng->txt('members'), + $this->getColumns(), + ) + ->withActions($this->getActions()) + ->withRequest($this->request); + } + + public function getRows( + DataRowBuilder $row_builder, + array $visible_column_ids, + Range $range, + Order $order, + mixed $additional_viewcontrol_data, + mixed $filter_data, + mixed $additional_parameters, + ): Generator { + $records = $this->getRecords($range, $order); + + foreach ($records as $record) { + $row_id = $record['obj_id'] . '_' . $record['members_id']; + $data_row = $row_builder->buildDataRow($row_id, $record); + + if (!$record['buddy_request_allowed']) { + $data_row = $data_row->withDisabledAction(ilMailSearchObjectGUI::ACTION_BUDDY_REQUEST); + } + + yield $data_row; + } + } + + public function getTotalRowCount( + mixed $additional_viewcontrol_data, + mixed $filter_data, + mixed $additional_parameters, + ): ?int { + $this->initRecords(); + + return count($this->records); + } + + private function isMailingAllowed(): bool + { + return $this->mailing_allowed; + } + + private function isBuddysystemEnabled(): bool + { + return $this->buddysystem_enabled; + } + + /** + * @return array + */ + private function getColumns(): array + { + $columns = [ + 'members_login' => $this->ui_factory->table() + ->column() + ->text($this->lng->txt('login')) + ->withIsSortable(true), + 'members_name' => $this->ui_factory->table() + ->column() + ->text($this->lng->txt('name')) + ->withIsSortable(true), + 'members_crs_grp' => $this->ui_factory->table() + ->column() + ->text($this->parent_gui->getObjectTypeLabel()) + ->withIsSortable(true), + ]; + + if ($this->isBuddysystemEnabled()) { + $columns['status'] = $this->ui_factory->table() + ->column() + ->text($this->lng->txt('buddy_tbl_filter_state')) + ->withIsSortable(true); + } + + return $columns; + } + + /** + * @return array + */ + private function getActions(): array + { + $query_params_namespace = ['contact', 'mailinglist', 'search']; + + $uri = $this->data_factory->uri( + ILIAS_HTTP_PATH . '/' . $this->ctrl->getLinkTarget( + $this->parent_gui, + ilMailSearchObjectGUI::CMD_HANDLE_MAIL_SEARCH_OBJECT_ACTIONS, + ), + ); + + $url_builder = new URLBuilder($uri); + [ + $url_builder, + $action_parameter_token_copy, + $row_id_token, + $obj_ids_token, + ] = + $url_builder->acquireParameters( + $query_params_namespace, + 'action', + 'members_ids', + 'obj_ids', + ); + + $url_builder = $url_builder->withParameter( + $obj_ids_token, + $this->objIdsForActionUrl(), + ); + + $actions = []; + if ($this->parent_gui->isDefaultRequestContext() && $this->isMailingAllowed()) { + $actions[ilMailSearchObjectGUI::ACTION_MAIL_MEMBERS] = $this->ui_factory->table()->action()->standard( + $this->lng->txt('mail_members'), + $url_builder->withParameter($action_parameter_token_copy, ilMailSearchObjectGUI::ACTION_MAIL_MEMBERS), + $row_id_token, + ); + } elseif ($this->parent_gui->getContext() === ilMailSearchObjectGUI::CONTEXT_WORKSPACE) { + $actions[ilMailSearchObjectGUI::ACTION_SHARE_MEMBERS] = $this->ui_factory->table()->action()->standard( + $this->lng->txt('wsp_share_with_members'), + $url_builder->withParameter($action_parameter_token_copy, ilMailSearchObjectGUI::ACTION_SHARE_MEMBERS), + $row_id_token, + ); + } + + if ($this->parent_gui->isDefaultRequestContext() && $this->isBuddysystemEnabled()) { + $buddy_url_builder = new URLBuilder( + $this->data_factory->uri( + ILIAS_HTTP_PATH . '/' . $this->ctrl->getLinkTargetByClass( + [$this->parent_gui::class, ilBuddySystemGUI::class], + 'request', + ), + ), + ); + [ + $buddy_url_builder, + $buddy_row_id_token, + $buddy_obj_ids_token, + ] = $buddy_url_builder->acquireParameters( + $query_params_namespace, + 'members_ids', + 'obj_ids', + ); + $buddy_url_builder = $buddy_url_builder->withParameter( + $buddy_obj_ids_token, + $this->objIdsForActionUrl(), + ); + + $actions[ilMailSearchObjectGUI::ACTION_BUDDY_REQUEST] = $this->ui_factory->table()->action()->single( + $this->lng->txt('buddy_bs_btn_txt_unlinked_a'), + $buddy_url_builder, + $buddy_row_id_token, + ); + } + + return $actions; + } + + /** + * @return string|list + */ + private function objIdsForActionUrl(): string|array + { + return $this->http->wrapper()->query()->retrieve( + 'contact_mailinglist_search_obj_ids', + $this->refinery->byTrying([ + $this->refinery->custom()->transformation( + static function (mixed $value): array { + if ($value === ['ALL_OBJECTS']) { + return ['ALL_OBJECTS']; + } + throw new Exception('not all objects'); + } + ), + $this->refinery->always(implode(',', array_map(strval(...), $this->obj_ids))), + ]) + ); + } + + private function initRecords(): void + { + if ($this->records !== null) { + return; + } + + $this->records = []; + $counter = 0; + + foreach ($this->obj_ids as $obj_id) { + $ref_id = new ObjectId($obj_id)->toReferenceIds()[0]->toInt(); + $members_obj = ilParticipants::getInstance($ref_id); + + $usr_ids = array_map( + intval(...), + ilUtil::_sortIds($members_obj->getParticipants(), 'usr_data', 'lastname', 'usr_id'), + ); + foreach ($usr_ids as $usr_id) { + $user = new ilObjUser($usr_id); + if (!$user->getActive()) { + continue; + } + + $fullname = ''; + if (in_array(ilObjUser::_lookupPref($user->getId(), 'public_profile'), ['g', 'y'])) { + $fullname = $user->getLastname() . ', ' . $user->getFirstname(); + } + + $this->records[$counter] = [ + 'members_id' => $user->getId(), + 'members_login' => $user->getLogin(), + 'members_name' => $fullname, + 'members_crs_grp' => $this->object_data_cache->lookupTitle($obj_id), + 'obj_id' => $obj_id, + 'buddy_request_allowed' => false, + ]; + + if ($this->parent_gui->isDefaultRequestContext() && $this->isBuddysystemEnabled()) { + $relation = ilBuddyList::getInstanceByGlobalUser()->getRelationByUserId($user->getId()); + $state_name = ilStr::convertUpperCamelCaseToUnderscoreCase($relation->getState()->getName()); + $this->records[$counter]['status'] = ''; + if ($user->getId() !== $this->current_user_id) { + $this->records[$counter]['status'] = $this->lng->txt( + "buddy_bs_state_$state_name" . ($relation->isOwnedByActor() ? '_a' : '_p'), + ); + $this->records[$counter]['buddy_request_allowed'] = $relation->isUnlinked() + && $this->refinery->custom()->transformation( + static fn(string $value): bool => strtolower($value) === 'y', + )->transform((string) ilObjUser::_lookupPref($user->getId(), 'bs_allow_to_contact_me')); + } + } + ++$counter; + } + } + } + + /** + * @return list> + */ + private function sortedRecords(Order $order): array + { + $records = $this->records; + [$order_field, $order_direction] = $order->join([], static fn($ret, $key, $value): array => [$key, $value]); + + return ilArrayUtil::stableSortArray($records, $order_field, strtolower($order_direction)); + } + + /** + * @return list> + */ + private function getRecords(Range $range, Order $order): array + { + $this->initRecords(); + $records = $this->sortedRecords($order); + + return $this->limitRecords($records, $range); + } + + /** + * @param list> $records + * @return list> + */ + private function limitRecords(array $records, Range $range): array + { + return array_slice($records, $range->getStart(), $range->getLength()); + } +} diff --git a/components/ILIAS/Contact/classes/class.MailSearchObjectsTable.php b/components/ILIAS/Contact/classes/class.MailSearchObjectsTable.php new file mode 100644 index 000000000000..7a279b16d05c --- /dev/null +++ b/components/ILIAS/Contact/classes/class.MailSearchObjectsTable.php @@ -0,0 +1,314 @@ +>|null */ + private ?array $records = null; + + public function __construct( + private readonly ilObjUser $user, + private readonly ilMailSearchObjectGUI $parent_gui, + private readonly ilCtrl $ctrl, + private readonly ilLanguage $lng, + private readonly Factory $ui_factory, + GlobalHttpState $http, + private readonly ilTree $tree, + ) { + $this->request = $http->request(); + $this->data_factory = new DataFactory(); + + $this->lng->loadLanguageModule('crs'); + $this->lng->loadLanguageModule('buddysystem'); + } + + public function setMailingAllowed(bool $mailing_allowed): void + { + $this->mailing_allowed = $mailing_allowed; + } + + public function getComponent(): Data + { + return $this->ui_factory->table() + ->data( + $this, + $this->parent_gui->getSearchTableTitle(), + $this->getColumns(), + ) + ->withActions($this->getActions()) + ->withRequest($this->request); + } + + public function getNumHiddenMembers(): int + { + return $this->num_hidden_members; + } + + public function getRows( + DataRowBuilder $row_builder, + array $visible_column_ids, + Range $range, + Order $order, + mixed $additional_viewcontrol_data, + mixed $filter_data, + mixed $additional_parameters, + ): Generator { + $records = $this->getRecords($range, $order); + + foreach ($records as $record) { + $row_id = (string) $record['obj_id']; + $data_row = $row_builder->buildDataRow($row_id, $record); + + if (!$record['expose_members']) { + $data_row = $data_row->withDisabledAction(ilMailSearchObjectGUI::ACTION_SHOW_MEMBERS); + } + + if ( + $this->parent_gui->isDefaultRequestContext() + && $this->isMailingAllowed() + && !$record['can_send_mails'] + ) { + $data_row = $data_row->withDisabledAction(ilMailSearchObjectGUI::ACTION_MAIL_OBJECTS); + } + + yield $data_row; + } + } + + public function getTotalRowCount( + mixed $additional_viewcontrol_data, + mixed $filter_data, + mixed $additional_parameters, + ): ?int { + $this->initRecords(); + + return count($this->records); + } + + /** + * @return array + */ + private function getColumns(): array + { + return [ + 'obj_title' => $this->ui_factory->table() + ->column() + ->text($this->parent_gui->getSearchTableTitle()) + ->withIsSortable(true), + 'obj_path' => $this->ui_factory->table() + ->column() + ->text($this->lng->txt('path')) + ->withIsSortable(true), + 'obj_cnt_members' => $this->ui_factory->table() + ->column() + ->number($this->lng->txt('obj_count_members')) + ->withIsSortable(true), + ]; + } + + /** + * @return array + */ + private function getActions(): array + { + $query_params_namespace = ['contact', 'mailinglist', 'search']; + + $uri = $this->data_factory->uri( + ILIAS_HTTP_PATH . '/' . $this->ctrl->getLinkTarget( + $this->parent_gui, + ilMailSearchObjectGUI::CMD_HANDLE_MAIL_SEARCH_OBJECT_ACTIONS, + ), + ); + + $url_builder = new URLBuilder($uri); + [ + $url_builder, + $action_parameter_token_copy, + $row_id_token, + ] = + $url_builder->acquireParameters( + $query_params_namespace, + 'action', + 'obj_ids', + ); + + $actions = []; + + if ($this->parent_gui->isDefaultRequestContext() && $this->isMailingAllowed()) { + $actions[ilMailSearchObjectGUI::ACTION_MAIL_OBJECTS] = $this->ui_factory->table()->action()->standard( + $this->lng->txt('mail_members'), + $url_builder->withParameter($action_parameter_token_copy, ilMailSearchObjectGUI::ACTION_MAIL_OBJECTS), + $row_id_token, + ); + } elseif ($this->parent_gui->getContext() === ilMailSearchObjectGUI::CONTEXT_WORKSPACE) { + $actions[ilMailSearchObjectGUI::ACTION_SHARE_OBJECTS] = $this->ui_factory->table()->action()->standard( + $this->lng->txt('wsp_share_with_members'), + $url_builder->withParameter($action_parameter_token_copy, ilMailSearchObjectGUI::ACTION_SHARE_OBJECTS), + $row_id_token, + ); + } + + $actions[ilMailSearchObjectGUI::ACTION_SHOW_MEMBERS] = $this->ui_factory->table()->action()->standard( + $this->lng->txt('mail_list_members'), + $url_builder->withParameter($action_parameter_token_copy, ilMailSearchObjectGUI::ACTION_SHOW_MEMBERS), + $row_id_token, + ); + + return $actions; + } + + private function initRecords(): void + { + if ($this->records !== null) { + return; + } + + $this->records = []; + $counter = 0; + + $objs_ids = ilParticipants::_getMembershipByType($this->user->getId(), [$this->parent_gui->getObjectType()]); + if ($objs_ids === []) { + return; + } + + $this->num_hidden_members = 0; + foreach ($objs_ids as $obj_id) { + $object = $this->getCurrentObject($obj_id); + + $has_untrashed_references = ilObject::_hasUntrashedReference($object->getId()); + $can_send_mails = ilParticipants::canSendMailToMembers( + $object->getRefId(), + $this->user->getId(), + ilMailGlobalServices::getMailObjectRefId(), + ); + + if ($has_untrashed_references && ($can_send_mails || $this->parent_gui->doesExposeMembers($object))) { + $participants = ilParticipants::getInstance($object->getRefId()); + + $usr_ids = array_filter( + $participants->getParticipants(), + ilObjUser::_lookupActive(...), + ); + + $expose_members = $this->parent_gui->doesExposeMembers($object); + $title = $object->getTitle(); + if (!$expose_members) { + ++$this->num_hidden_members; + $title .= '*'; + } + + $this->records[$counter]['obj_id'] = $object->getId(); + $this->records[$counter]['obj_title'] = $title; + $this->records[$counter]['obj_cnt_members'] = count($usr_ids); + $this->records[$counter]['obj_path'] = $this->getObjectPath($object); + $this->records[$counter]['expose_members'] = $expose_members; + $this->records[$counter]['can_send_mails'] = $can_send_mails; + + ++$counter; + } + } + } + + private function getCurrentObject(int $obj_id): ilObjCourse|ilObjGroup + { + /** @var ilObjCourse|ilObjGroup $object */ + $object = ilObjectFactory::getInstanceByObjId($obj_id); + + $ref_ids = array_keys(ilObject::_getAllReferences($object->getId())); + $ref_id = $ref_ids[0]; + $object->setRefId($ref_id); + + return $object; + } + + private function getObjectPath(ilObjGroup|ilObjCourse $object): string + { + $path_arr = $this->tree->getPathFull($object->getRefId(), $this->tree->getRootId()); + $path = ''; + foreach ($path_arr as $data) { + if ($path !== '') { + $path .= ' -> '; + } + $path .= $data['title']; + } + + return $path; + } + + private function isMailingAllowed(): bool + { + return $this->mailing_allowed; + } + + /** + * @return list> + */ + private function sortedRecords(Order $order): array + { + $records = $this->records; + [$order_field, $order_direction] = $order->join([], fn($ret, $key, $value) => [$key, $value]); + $is_numeric = $this->numericOrdering($order_field); + + return ilArrayUtil::stableSortArray($records, $order_field, strtolower($order_direction), $is_numeric); + } + + /** + * @return list> + */ + private function getRecords(Range $range, Order $order): array + { + $this->initRecords(); + + $records = $this->sortedRecords($order); + + return $this->limitRecords($records, $range); + } + + /** + * @param list> $records + * @return list> + */ + private function limitRecords(array $records, Range $range): array + { + return array_slice($records, $range->getStart(), $range->getLength()); + } + + private function numericOrdering(string $field): bool + { + return $field === 'obj_cnt_members'; + } +} diff --git a/components/ILIAS/Contact/classes/class.ilMailSearchCoursesGUI.php b/components/ILIAS/Contact/classes/class.ilMailSearchCoursesGUI.php index e9ff137f6668..2a9bcd0f5cbb 100755 --- a/components/ILIAS/Contact/classes/class.ilMailSearchCoursesGUI.php +++ b/components/ILIAS/Contact/classes/class.ilMailSearchCoursesGUI.php @@ -25,11 +25,28 @@ */ class ilMailSearchCoursesGUI extends ilMailSearchObjectGUI { - protected function getObjectType(): string + public function getObjectType(): string { return 'crs'; } + public function getObjectTypeLabel(): string + { + return $this->lng->txt('course'); + } + + public function getSearchTableTitle(): string + { + return $this->lng->txt('mail_my_courses'); + } + + public function doesExposeMembers(ilObject $object): bool + { + $is_privileged_user = $this->rbacsystem->checkAccess('write', $object->getRefId()); + + return ($object->isActivated() && $object->getShowMembers()) || $is_privileged_user; + } + protected function getLocalDefaultRolePrefixes(): array { return [ @@ -38,13 +55,4 @@ protected function getLocalDefaultRolePrefixes(): array 'il_crs_admin_', ]; } - - protected function doesExposeMembers(ilObject $object): bool - { - $isOffline = !$object->isActivated(); - $showMemberListEnabled = (bool) $object->getShowMembers(); - $isPrivilegedUser = $this->rbacsystem->checkAccess('write', $object->getRefId()); - - return (!$isOffline && $showMemberListEnabled) || $isPrivilegedUser; - } } diff --git a/components/ILIAS/Contact/classes/class.ilMailSearchGroupsGUI.php b/components/ILIAS/Contact/classes/class.ilMailSearchGroupsGUI.php index 8ca951fe166d..9e026e4b1a2e 100755 --- a/components/ILIAS/Contact/classes/class.ilMailSearchGroupsGUI.php +++ b/components/ILIAS/Contact/classes/class.ilMailSearchGroupsGUI.php @@ -25,11 +25,28 @@ */ class ilMailSearchGroupsGUI extends ilMailSearchObjectGUI { - protected function getObjectType(): string + public function getObjectType(): string { return 'grp'; } + public function getObjectTypeLabel(): string + { + return $this->lng->txt('group'); + } + + public function getSearchTableTitle(): string + { + return $this->lng->txt('mail_my_groups'); + } + + public function doesExposeMembers(ilObject $object): bool + { + $is_privileged_user = $this->rbacsystem->checkAccess('write', $object->getRefId()); + + return $object->getShowMembers() || $is_privileged_user; + } + protected function getLocalDefaultRolePrefixes(): array { return [ @@ -37,12 +54,4 @@ protected function getLocalDefaultRolePrefixes(): array 'il_grp_admin_', ]; } - - protected function doesExposeMembers(ilObject $object): bool - { - $showMemberListEnabled = (bool) $object->getShowMembers(); - $isPrivilegedUser = $this->rbacsystem->checkAccess('write', $object->getRefId()); - - return $showMemberListEnabled || $isPrivilegedUser; - } } diff --git a/components/ILIAS/Contact/classes/class.ilMailSearchObjectGUI.php b/components/ILIAS/Contact/classes/class.ilMailSearchObjectGUI.php index df2d19c38bea..e32246b1cd71 100755 --- a/components/ILIAS/Contact/classes/class.ilMailSearchObjectGUI.php +++ b/components/ILIAS/Contact/classes/class.ilMailSearchObjectGUI.php @@ -18,34 +18,52 @@ declare(strict_types=1); +use ILIAS\Data\ObjectId; use ILIAS\HTTP\GlobalHttpState; use ILIAS\Refinery\Factory as Refinery; +use ILIAS\UI\Factory; +use ILIAS\UI\Renderer; -abstract class ilMailSearchObjectGUI +abstract class ilMailSearchObjectGUI implements ilCtrlSecurityInterface { - protected GlobalHttpState $http; - protected Refinery $refinery; - protected ?string $view = null; - protected ilGlobalTemplateInterface $tpl; - protected ilCtrlInterface $ctrl; - protected ilLanguage $lng; - protected ilObjUser $user; - protected ilErrorHandling $error; - protected ilRbacSystem $rbacsystem; - protected ilRbacReview $rbacreview; - protected ilTree $tree; - protected ilObjectDataCache $cache; - protected ilFormatMail $umail; - protected bool $mailing_allowed; - protected \ILIAS\UI\Factory $ui_factory; - protected \ILIAS\UI\Renderer $ui_renderer; + public const string CONTEXT_CONTACT = 'contact'; + public const string CONTEXT_MAIL = 'mail'; + public const string CONTEXT_WORKSPACE = 'wsp'; + public const string CMD_SHOW_MY_OBJECTS = 'showMyObjects'; + public const string CMD_HANDLE_MAIL_SEARCH_OBJECT_ACTIONS = 'handleMailSearchObjectActions'; + public const string CMD_CANCEL = 'cancel'; + public const string ACTION_MAIL_OBJECTS = 'mailObjects'; + public const string ACTION_MAIL_MEMBERS = 'mailMembers'; + public const string ACTION_SHARE_OBJECTS = 'shareObjects'; + public const string ACTION_SHARE_MEMBERS = 'shareMembers'; + public const string ACTION_SHOW_MEMBERS = 'showMembers'; + public const string ACTION_BUDDY_REQUEST = 'buddyRequest'; + + private readonly ilTabsGUI $tabs; + protected readonly GlobalHttpState $http; + protected readonly Refinery $refinery; + protected readonly ilGlobalTemplateInterface $tpl; + protected readonly ilCtrlInterface $ctrl; + protected readonly ilLanguage $lng; + protected readonly ilObjUser $user; + protected readonly ilErrorHandling $error; + protected readonly ilRbacSystem $rbacsystem; + protected readonly ilRbacReview $rbacreview; + protected readonly ilTree $tree; + protected readonly ilObjectDataCache $cache; + protected readonly ilFormatMail $umail; + protected readonly bool $mailing_allowed; + protected readonly Factory $ui_factory; + protected readonly Renderer $ui_renderer; + private ?string $context = null; /** - * @param ilWorkspaceAccessHandler|ilPortfolioAccessHandler|null $wsp_access_handler * @throws ilCtrlException */ - public function __construct(protected $wsp_access_handler = null, protected ?int $wsp_node_id = null) - { + public function __construct( + protected readonly ilPortfolioAccessHandler|ilWorkspaceAccessHandler|null $wsp_access_handler = null, + protected readonly ?int $wsp_node_id = null, + ) { global $DIC; $this->tpl = $DIC['tpl']; @@ -61,271 +79,139 @@ public function __construct(protected $wsp_access_handler = null, protected ?int $this->refinery = $DIC->refinery(); $this->ui_factory = $DIC->ui()->factory(); $this->ui_renderer = $DIC->ui()->renderer(); + $this->tabs = $DIC->tabs(); $this->ctrl->saveParameter($this, 'mobj_id'); $this->ctrl->saveParameter($this, 'ref'); - $mail = new ilMail($this->user->getId()); - $this->mailing_allowed = $this->rbacsystem->checkAccess('internal_mail', $mail->getMailObjectReferenceId()); + $this->mailing_allowed = $this->rbacsystem->checkAccess( + 'internal_mail', + new ilMail($this->user->getId())->getMailObjectReferenceId(), + ); $this->umail = new ilFormatMail($this->user->getId()); $this->lng->loadLanguageModule('mail'); } - private function isDefaultRequestContext(): bool - { - return ( - !$this->http->wrapper()->query()->has('ref') || - $this->http->wrapper()->query()->retrieve('ref', $this->refinery->kindlyTo()->string()) !== 'wsp' - ); - } + abstract public function getObjectType(): string; - private function getContext(): string - { - $context = 'mail'; - if ($this->http->wrapper()->query()->has('ref')) { - $context = $this->http->wrapper()->query()->retrieve('ref', $this->refinery->kindlyTo()->string()); - } + abstract public function getObjectTypeLabel(): string; - return $context; - } + abstract public function getSearchTableTitle(): string; - private function isLocalRoleTitle(string $title): bool - { - foreach ($this->getLocalDefaultRolePrefixes() as $local_role_prefix) { - if (str_starts_with($title, $local_role_prefix)) { - return true; - } - } - - return false; - } - - abstract protected function getObjectType(): string; + abstract public function doesExposeMembers(ilObject $object): bool; /** * @return string[] Returns an array like ['il_crs_member_', 'il_crs_tutor', ...] */ abstract protected function getLocalDefaultRolePrefixes(): array; - protected function getRequestValue(string $key, \ILIAS\Refinery\Transformation $trafo, $default = null) + public function getUnsafeGetCommands(): array { - $value = $default; - if ($this->http->wrapper()->query()->has($key)) { - $value = $this->http->wrapper()->query()->retrieve($key, $trafo); - } - - if ($this->http->wrapper()->post()->has($key)) { - $value = $this->http->wrapper()->post()->retrieve($key, $trafo); - } + return [ + self::CMD_HANDLE_MAIL_SEARCH_OBJECT_ACTIONS, + ]; + } - return $value; + public function getSafePostCommands(): array + { + return []; } /** - * @param int[] $a_obj_ids + * @throws ilCtrlException */ - protected function addPermission(array $a_obj_ids): void + public function executeCommand(): bool { - $added = $this->wsp_access_handler->addMissingPermissionForObjects($this->wsp_node_id, $a_obj_ids); + $forward_class = $this->ctrl->getNextClass($this) ?? ''; + switch (strtolower($forward_class)) { + case strtolower(ilBuddySystemGUI::class): + if (!ilBuddySystem::getInstance()->isEnabled()) { + $this->error->raiseError($this->lng->txt('msg_no_perm_read'), $this->error->MESSAGE); + } - if ($added) { - $this->tpl->setOnScreenMessage('success', $this->lng->txt('wsp_share_success'), true); + $buddy_user_id = $this->resolveBuddyUserIdFromQuery(); + if ($buddy_user_id !== null) { + $this->ctrl->setParameterByClass(ilBuddySystemGUI::class, 'user_id', $buddy_user_id); + } + + $obj_ids = $this->retrieveObjectIdsFromQuery(); + $this->ctrl->setParameter($this, 'contact_mailinglist_search_action', self::ACTION_SHOW_MEMBERS); + if ($obj_ids !== []) { + $this->ctrl->setParameter( + $this, + 'contact_mailinglist_search_obj_ids', + implode(',', $obj_ids) + ); + } + $this->ctrl->setReturn($this, self::CMD_HANDLE_MAIL_SEARCH_OBJECT_ACTIONS); + $this->ctrl->forwardCommand(new ilBuddySystemGUI()); + break; + + default: + match ($this->ctrl->getCmd()) { + self::CMD_HANDLE_MAIL_SEARCH_OBJECT_ACTIONS => $this->handleMailSearchObjectActions(), + self::CMD_CANCEL => $this->cancel(), + default => $this->showMyObjects(), + }; + break; } - $this->ctrl->redirectByClass(ilWorkspaceAccessGUI::class, 'share'); + + return true; } - protected function share(): void + public function getContext(): string { - $view = ''; - if ($this->http->wrapper()->query()->has('view')) { - $view = $this->http->wrapper()->query()->retrieve('view', $this->refinery->kindlyTo()->string()); + if ($this->context === null) { + $context = $this->http->wrapper()->query()->retrieve( + 'ref', + $this->refinery->byTrying([ + $this->refinery->kindlyTo()->string(), + $this->refinery->always(self::CONTEXT_CONTACT) + ]), + ); + $this->context = in_array($context, [self::CONTEXT_CONTACT, self::CONTEXT_MAIL, self::CONTEXT_WORKSPACE], true) + ? $context + : self::CONTEXT_CONTACT; } - if ($view === 'myobjects') { - $obj_ids = []; - if ($this->http->wrapper()->query()->has('search_' . $this->getObjectType())) { - $obj_ids = [ - $this->http->wrapper()->query()->retrieve( - 'search_' . $this->getObjectType(), - $this->refinery->kindlyTo()->int() - ) - ]; - } elseif ($this->http->wrapper()->post()->has('search_' . $this->getObjectType())) { - $obj_ids = $this->http->wrapper()->post()->retrieve( - 'search_' . $this->getObjectType(), - $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int()) - ); - } - - if ($obj_ids !== []) { - $this->addPermission($obj_ids); - } else { - $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_select_' . $this->getObjectType())); - $this->showMyObjects(); - } - } elseif ($view === $this->getObjectType() . '_members') { - $usr_ids = []; - if ($this->http->wrapper()->query()->has('search_members')) { - $usr_ids = [ - $this->http->wrapper()->query()->retrieve( - 'search_members', - $this->refinery->kindlyTo()->int() - ) - ]; - } elseif ($this->http->wrapper()->post()->has('search_members')) { - $usr_ids = $this->http->wrapper()->post()->retrieve( - 'search_members', - $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int()) - ); - } + return $this->context; + } - if ($usr_ids !== []) { - $this->addPermission($usr_ids); - } else { - $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_select_one_entry')); - $this->showMembers(); - } - } else { - $this->showMyObjects(); - } + public function isDefaultRequestContext(): bool + { + return in_array($this->getContext(), [self::CONTEXT_CONTACT, self::CONTEXT_MAIL], true); } - protected function mail(): void + /** + * @param int[] $a_obj_ids + */ + protected function addPermission(array $a_obj_ids): void { - $view = ''; - if ($this->http->wrapper()->query()->has('view')) { - $view = $this->http->wrapper()->query()->retrieve('view', $this->refinery->kindlyTo()->string()); + if ($this->wsp_access_handler === null || $this->wsp_node_id === null) { + $this->error->raiseError($this->lng->txt('msg_no_perm_read'), $this->error->MESSAGE); } - if ($view === 'myobjects') { - $obj_ids = []; - if ($this->http->wrapper()->query()->has('search_' . $this->getObjectType())) { - $obj_ids = [ - $this->http->wrapper()->query()->retrieve( - 'search_' . $this->getObjectType(), - $this->refinery->kindlyTo()->int() - ) - ]; - } elseif ($this->http->wrapper()->post()->has('search_' . $this->getObjectType())) { - $obj_ids = $this->http->wrapper()->post()->retrieve( - 'search_' . $this->getObjectType(), - $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int()) - ); - } - - if ($obj_ids !== []) { - $this->mailObjects(); - } else { - $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_select_' . $this->getObjectType())); - $this->showMyObjects(); - } - } elseif ($view === $this->getObjectType() . '_members') { - $usr_ids = []; - if ($this->http->wrapper()->query()->has('search_members')) { - $usr_ids = [ - $this->http->wrapper()->query()->retrieve( - 'search_members', - $this->refinery->kindlyTo()->int() - ) - ]; - } elseif ($this->http->wrapper()->post()->has('search_members')) { - $usr_ids = $this->http->wrapper()->post()->retrieve( - 'search_members', - $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int()) - ); - } + $added = $this->wsp_access_handler->addMissingPermissionForObjects($this->wsp_node_id, $a_obj_ids); - if ($usr_ids !== []) { - $this->mailMembers(); - } else { - $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_select_one_entry')); - $this->showMembers(); - } - } else { - $this->showMyObjects(); + if ($added) { + $this->tpl->setOnScreenMessage('success', $this->lng->txt('wsp_share_success'), true); } + $this->ctrl->redirectByClass(ilWorkspaceAccessGUI::class, 'share'); } - protected function mailObjects(): void + private function mailMembers(): void { $members = []; - $mail_data = $this->umail->retrieveFromStage(); - $obj_ids = []; - if ($this->http->wrapper()->query()->has('search_' . $this->getObjectType())) { - $obj_ids = [ - $this->http->wrapper()->query()->retrieve( - 'search_' . $this->getObjectType(), - $this->refinery->kindlyTo()->int() - ) - ]; - } elseif ($this->http->wrapper()->post()->has('search_' . $this->getObjectType())) { - $obj_ids = $this->http->wrapper()->post()->retrieve( - 'search_' . $this->getObjectType(), - $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int()) - ); - } + $usr_ids = $this->resolveUserIds(); - foreach ($obj_ids as $obj_id) { - $ref_ids = ilObject::_getAllReferences($obj_id); - foreach ($ref_ids as $ref_id) { - $can_send_mails = ilParticipants::canSendMailToMembers( - $ref_id, - $this->user->getId(), - ilMailGlobalServices::getMailObjectRefId() - ); - if (!$can_send_mails) { - continue; - } - - $roles = $this->rbacreview->getAssignableChildRoles($ref_id); - foreach ($roles as $role) { - if ($this->isLocalRoleTitle($role['title'])) { - $recipient = (new ilRoleMailboxAddress($role['obj_id']))->value(); - if (!$this->umail->existsRecipient($recipient, (string) $mail_data['rcp_to'])) { - $members[] = $recipient; - } - } - } - } - } - - $mail_data = $members !== [] ? $this->umail->appendSearchResult(array_unique($members), 'to') : $this->umail->retrieveFromStage(); - - $this->umail->persistToStage( - (int) $mail_data['user_id'], - $mail_data['rcp_to'], - $mail_data['rcp_cc'], - $mail_data['rcp_bcc'], - $mail_data['m_subject'], - $mail_data['m_message'], - $mail_data['attachments'], - $mail_data['use_placeholders'], - $mail_data['tpl_ctx_id'], - $mail_data['tpl_ctx_params'] - ); - - $this->ctrl->redirectToURL('ilias.php?baseClass=ilMailGUI&type=search_res'); - } + if ($usr_ids === []) { + $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_select_one_entry')); + $this->showMembers(); - public function mailMembers(): void - { - $members = []; - $usr_ids = []; - if ($this->http->wrapper()->query()->has('search_members')) { - $usr_ids = [ - $this->http->wrapper()->query()->retrieve( - 'search_members', - $this->refinery->kindlyTo()->int() - ) - ]; - } elseif ($this->http->wrapper()->post()->has('search_members')) { - $usr_ids = $this->http->wrapper()->post()->retrieve( - 'search_members', - $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int()) - ); + return; } $mail_data = $this->umail->retrieveFromStage(); @@ -335,6 +221,7 @@ public function mailMembers(): void $members[] = $login; } } + $mail_data = $this->umail->appendSearchResult(array_unique($members), 'to'); $this->umail->persistToStage( @@ -350,10 +237,11 @@ public function mailMembers(): void $mail_data['tpl_ctx_params'] ); - $this->ctrl->redirectToURL('ilias.php?baseClass=ilMailGUI&type=search_res'); + $this->ctrl->setParameterByClass(ilMailGUI::class, 'type', ilMailFormGUI::MAIL_FORM_TYPE_SEARCH_RESULT); + $this->ctrl->redirectByClass(ilMailGUI::class); } - public function cancel(): void + private function cancel(): void { $view = ''; if ($this->http->wrapper()->query()->has('view')) { @@ -367,33 +255,35 @@ public function cancel(): void } } - public function showMembers(): void + private function showMembers(): void { - $obj_ids = []; - if ($this->http->wrapper()->query()->has('search_' . $this->getObjectType())) { - $obj_ids = $this->refinery->kindlyTo()->listOf( - $this->refinery->kindlyTo()->int() - )->transform(explode(',', (string) $this->http->wrapper()->query()->retrieve( - 'search_' . $this->getObjectType(), - $this->refinery->kindlyTo()->string() - ))); - } elseif ($this->http->wrapper()->post()->has('search_' . $this->getObjectType())) { - $obj_ids = $this->http->wrapper()->post()->retrieve( - 'search_' . $this->getObjectType(), - $this->refinery->kindlyTo()->listOf( - $this->refinery->kindlyTo()->int() - ) + if ($this->getContext() === self::CONTEXT_WORKSPACE) { + $this->tabs->clearTargets(); + $this->tabs->setBack2Target( + $this->lng->txt('back'), + $this->ctrl->getParentReturn($this) + ); + $this->tabs->setBackTarget( + $this->lng->txt('cancel'), + $this->ctrl->getLinkTarget($this, self::CMD_SHOW_MY_OBJECTS) + ); + } elseif ($this->isDefaultRequestContext()) { + $this->tabs->clearTargets(); + $this->tabs->setBackTarget( + $this->lng->txt('back'), + $this->ctrl->getLinkTarget($this, self::CMD_SHOW_MY_OBJECTS) ); - } elseif (ilSession::get('search_' . $this->getObjectType())) { - $obj_ids = $this->refinery->kindlyTo()->listOf( - $this->refinery->kindlyTo()->int() - )->transform(explode(',', (string) ilSession::get('search_' . $this->getObjectType()))); - ilSession::set('search_' . $this->getObjectType(), ''); } + $obj_ids = $this->retrieveObjectIdsFromQuery(); + if ($obj_ids === []) { - $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_select_' . $this->getObjectType())); + $this->tpl->setOnScreenMessage( + 'info', + $this->lng->txt($this->getObjectType() === 'crs' ? 'mail_select_crs' : 'mail_select_grp'), + ); $this->showMyObjects(); + return; } @@ -406,8 +296,12 @@ public function showMembers(): void $object->setRefId($ref_id); if (!$this->doesExposeMembers($object)) { - $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_crs_list_members_not_available_for_at_least_one_crs')); + $this->tpl->setOnScreenMessage( + 'info', + $this->lng->txt('mail_crs_list_members_not_available_for_at_least_one_crs') + ); $this->showMyObjects(); + return; } } @@ -420,230 +314,412 @@ public function showMembers(): void if ($obj_ids !== []) { $this->ctrl->setParameter($this, 'search_' . $this->getObjectType(), implode(',', $obj_ids)); } + $this->ctrl->clearParameters($this); + $this->lng->loadLanguageModule($this->getObjectType()); - $context = $this->getContext(); + $search_tpl = new ilTemplate( + 'tpl.mail_search_template.html', + true, + true, + 'components/ILIAS/Contact' + ); - $table = new ilMailSearchObjectMembershipsTableGUI( + $table = new MailSearchObjectMembershipsTable( + $obj_ids, $this, - $this->getObjectType(), - $context, - $obj_ids + $this->user->getId(), + $this->ctrl, + $this->lng, + $this->ui_factory, + $this->http, + $this->refinery, + $this->cache ); - $tableData = []; - $searchTpl = new ilTemplate('tpl.mail_search_template.html', true, true, 'components/ILIAS/Contact'); - foreach ($obj_ids as $obj_id) { - $members_obj = ilParticipants::getInstanceByObjId($obj_id); - $usr_ids = array_map('\intval', ilUtil::_sortIds($members_obj->getParticipants(), 'usr_data', 'lastname', 'usr_id')); - foreach ($usr_ids as $usr_id) { - $user = new ilObjUser($usr_id); - if (!$user->getActive()) { - continue; - } + if ($this->isDefaultRequestContext()) { + $table->setMailingAllowed($this->mailing_allowed); + } - $fullname = ''; - if (in_array(ilObjUser::_lookupPref($user->getId(), 'public_profile'), ['g', 'y'])) { - $fullname = $user->getLastname() . ', ' . $user->getFirstname(); - } + $search_tpl->setVariable('TABLE', $this->ui_renderer->render($table->getComponent())); + $this->tpl->setContent($search_tpl->get()); - $rowData = [ - 'members_id' => $user->getId(), - 'members_login' => $user->getLogin(), - 'members_name' => $fullname, - 'members_crs_grp' => $this->cache->lookupTitle((int) $obj_id), - 'search_' . $this->getObjectType() => $obj_id - ]; - - if ('mail' === $context && ilBuddySystem::getInstance()->isEnabled()) { - $relation = ilBuddyList::getInstanceByGlobalUser()->getRelationByUserId($user->getId()); - $state_name = ilStr::convertUpperCamelCaseToUnderscoreCase($relation->getState()->getName()); - $rowData['status'] = ''; - if ($user->getId() !== $this->user->getId()) { - if ($relation->isOwnedByActor()) { - $rowData['status'] = $this->lng->txt('buddy_bs_state_' . $state_name . '_a'); - } else { - $rowData['status'] = $this->lng->txt('buddy_bs_state_' . $state_name . '_p'); - } - } - } + if ($this->isDefaultRequestContext()) { + $this->tpl->printToStdout(); + } + } - $tableData[] = $rowData; - } + private function showMyObjects(): void + { + $this->tpl->setTitle($this->lng->txt('mail_addressbook')); + + if ($this->getContext() === self::CONTEXT_MAIL) { + $this->tabs->clearTargets(); + $this->ctrl->setParameter($this, 'view', 'myobjects'); + $this->tabs->setBackTarget( + $this->lng->txt('back'), + $this->ctrl->getLinkTarget($this, self::CMD_CANCEL) + ); + } + + $search_tpl = new ilTemplate( + 'tpl.mail_search_template.html', + true, + true, + 'components/ILIAS/Contact' + ); + + $this->lng->loadLanguageModule('crs'); + + $table = new MailSearchObjectsTable( + $this->user, + $this, + $this->ctrl, + $this->lng, + $this->ui_factory, + $this->http, + $this->tree, + ); + + if ($this->isDefaultRequestContext()) { + $table->setMailingAllowed($this->mailing_allowed); } - $table->setData($tableData); - if ($tableData !== []) { - $searchTpl->setVariable('TXT_MARKED_ENTRIES', $this->lng->txt('marked_entries')); + if ($table->getNumHiddenMembers() > 0) { + $search_tpl->setCurrentBlock('caption_block'); + $search_tpl->setVariable( + 'TXT_LIST_MEMBERS_NOT_AVAILABLE', + $this->lng->txt('mail_crs_list_members_not_available') + ); + $search_tpl->parseCurrentBlock(); } - $searchTpl->setVariable('TABLE', $table->getHTML()); - $this->tpl->setContent($searchTpl->get()); + $search_tpl->setVariable('TABLE', $this->ui_renderer->render($table->getComponent())); + $this->tpl->setContent($search_tpl->get()); if ($this->isDefaultRequestContext()) { $this->tpl->printToStdout(); } } - abstract protected function doesExposeMembers(ilObject $object): bool; + private function isLocalRoleTitle(string $title): bool + { + return array_any( + $this->getLocalDefaultRolePrefixes(), + static fn(string $local_role_prefix): bool => str_starts_with($title, $local_role_prefix), + ); + } - public function showMyObjects(): void + private function shareObjects(): void { - $this->tpl->setTitle($this->lng->txt('mail_addressbook')); + $obj_ids = $this->resolveObjectIds( + $this->retrieveIdsFromQuery('contact_mailinglist_search_obj_ids') + ); - $searchTpl = new ilTemplate('tpl.mail_search_template.html', true, true, 'components/ILIAS/Contact'); + if ($obj_ids !== []) { + $this->addPermission($obj_ids); + } else { + $this->tpl->setOnScreenMessage( + 'info', + $this->lng->txt($this->getObjectType() === 'crs' ? 'mail_select_crs' : 'mail_select_grp'), + ); + $this->showMyObjects(); + } + } - $this->lng->loadLanguageModule('crs'); + private function shareMembers(): void + { + $usr_ids = $this->resolveUserIds(); - $table = new ilMailSearchObjectsTableGUI( - $this, - $this->getObjectType(), - $this->getContext() + if ($usr_ids !== []) { + $this->addPermission(array_unique($usr_ids)); + } else { + $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_select_one_entry')); + $this->showMembers(); + } + } + + private function mailObjects(): void + { + $members = []; + $mail_data = $this->umail->retrieveFromStage(); + + $obj_ids = $this->resolveObjectIds( + $this->retrieveIdsFromQuery('contact_mailinglist_search_obj_ids') ); - $table->setId('search_' . $this->getObjectType() . '_tbl'); - - $objs_ids = ilParticipants::_getMembershipByType($this->user->getId(), [$this->getObjectType()]); - $counter = 0; - $tableData = []; - if ($objs_ids !== []) { - $num_courses_hidden_members = 0; - foreach ($objs_ids as $obj_id) { - /** @var ilObjCourse|ilObjGroup $object */ - $object = ilObjectFactory::getInstanceByObjId($obj_id); - - $ref_ids = array_keys(ilObject::_getAllReferences($object->getId())); - $ref_id = $ref_ids[0]; - $object->setRefId($ref_id); - - $has_untrashed_references = ilObject::_hasUntrashedReference($object->getId()); + + if ($obj_ids === []) { + $this->tpl->setOnScreenMessage( + 'info', + $this->lng->txt($this->getObjectType() === 'crs' ? 'mail_select_crs' : 'mail_select_grp'), + ); + $this->showMyObjects(); + + return; + } + + foreach ($obj_ids as $obj_id) { + $ref_ids = ilObject::_getAllReferences($obj_id); + foreach ($ref_ids as $ref_id) { $can_send_mails = ilParticipants::canSendMailToMembers( - $object->getRefId(), + $ref_id, $this->user->getId(), ilMailGlobalServices::getMailObjectRefId() ); - $exposes_members = $this->doesExposeMembers($object); - ; - if ($has_untrashed_references && ($can_send_mails || $exposes_members)) { - $participants = ilParticipants::getInstanceByObjId($object->getId()); - $usr_ids = $participants->getParticipants(); + if (!$can_send_mails) { + continue; + } - foreach ($usr_ids as $key => $usr_id) { - $is_active = ilObjUser::_lookupActive($usr_id); - if (!$is_active) { - unset($usr_ids[$key]); + $roles = $this->rbacreview->getAssignableChildRoles($ref_id); + foreach ($roles as $role) { + if ($this->isLocalRoleTitle($role['title'])) { + $recipient = new ilRoleMailboxAddress($role['obj_id'])->value(); + if (!$this->umail->existsRecipient($recipient, (string) $mail_data['rcp_to'])) { + $members[] = $recipient; } } - $usr_ids = array_values($usr_ids); + } + } + } - if (!$exposes_members) { - ++$num_courses_hidden_members; - } + $mail_data = $members !== [] ? $this->umail->appendSearchResult( + array_unique($members), + 'to' + ) : $this->umail->retrieveFromStage(); - $path_arr = $this->tree->getPathFull($object->getRefId(), $this->tree->getRootId()); - $path = ''; - foreach ($path_arr as $data) { - if ($path !== '') { - $path .= ' -> '; - } - $path .= $data['title']; - } + $this->umail->persistToStage( + (int) $mail_data['user_id'], + $mail_data['rcp_to'], + $mail_data['rcp_cc'], + $mail_data['rcp_bcc'], + $mail_data['m_subject'], + $mail_data['m_message'], + $mail_data['attachments'], + $mail_data['use_placeholders'], + $mail_data['tpl_ctx_id'], + $mail_data['tpl_ctx_params'] + ); - $this->ctrl->setParameter($this, 'search_' . $this->getObjectType(), $object->getId()); - $this->ctrl->setParameter($this, 'view', 'myobjects'); - $buttons = []; - - if ($this->isDefaultRequestContext()) { - if ($this->mailing_allowed && $can_send_mails) { - $buttons[] = $this->ui_factory - ->button() - ->shy( - $this->lng->txt('mail_members'), - $this->ctrl->getLinkTarget($this, 'mail') - ); - } - } else { - $buttons[] = $this->ui_factory - ->button() - ->shy( - $this->lng->txt('wsp_share_with_members'), - $this->ctrl->getLinkTarget($this, 'share') - ); - } + $this->ctrl->setParameterByClass(ilMailGUI::class, 'type', ilMailFormGUI::MAIL_FORM_TYPE_SEARCH_RESULT); + $this->ctrl->redirectByClass(ilMailGUI::class); + } - if ($exposes_members) { - $buttons[] = $this->ui_factory - ->button() - ->shy( - $this->lng->txt('mail_list_members'), - $this->ctrl->getLinkTarget($this, 'showMembers') - ); - } + private function handleMailSearchObjectActions(): void + { + $query = $this->http->wrapper()->query(); - $this->ctrl->clearParameters($this); + if (!$query->has('contact_mailinglist_search_action')) { + $this->ctrl->redirect($this, self::CMD_SHOW_MY_OBJECTS); + return; + } - $drop_down = null; - if ($buttons !== []) { - $drop_down = $this->ui_factory - ->dropdown() - ->standard($buttons) - ->withLabel($this->lng->txt('actions')); - } + $action = $query->retrieve('contact_mailinglist_search_action', $this->refinery->to()->string()); - $rowData = [ - 'OBJECT_ID' => $object->getId(), - 'OBJECT_NAME' => $object->getTitle(), - 'OBJECT_NO_MEMBERS' => count($usr_ids), - 'OBJECT_PATH' => $path, - 'COMMAND_SELECTION_LIST' => $drop_down ? $this->ui_renderer->render($drop_down) : '', - 'hidden_members' => !$exposes_members, - ]; - $counter++; - $tableData[] = $rowData; - } - } + if ( + in_array($action, [self::ACTION_MAIL_OBJECTS, self::ACTION_MAIL_MEMBERS], true) + && !$this->isMailActionAllowed() + ) { + $this->error->raiseError($this->lng->txt('msg_no_perm_read'), $this->error->MESSAGE); + } - if ($num_courses_hidden_members > 0) { - $searchTpl->setCurrentBlock('caption_block'); - $searchTpl->setVariable('TXT_LIST_MEMBERS_NOT_AVAILABLE', $this->lng->txt('mail_crs_list_members_not_available')); - $searchTpl->parseCurrentBlock(); - } + if ( + in_array($action, [self::ACTION_SHARE_OBJECTS, self::ACTION_SHARE_MEMBERS], true) + && !$this->isShareActionAllowed() + ) { + $this->error->raiseError($this->lng->txt('msg_no_perm_read'), $this->error->MESSAGE); } - $searchTpl->setVariable('TXT_MARKED_ENTRIES', $this->lng->txt('marked_entries')); + match ($action) { + self::ACTION_MAIL_OBJECTS => $this->mailObjects(), + self::ACTION_MAIL_MEMBERS => $this->mailMembers(), + self::ACTION_SHARE_OBJECTS => $this->shareObjects(), + self::ACTION_SHARE_MEMBERS => $this->shareMembers(), + self::ACTION_SHOW_MEMBERS => $this->showMembers(), + default => $this->ctrl->redirect($this, self::CMD_SHOW_MY_OBJECTS), + }; + } - $table->setData($tableData); - $searchTpl->setVariable('TABLE', $table->getHTML()); - $this->tpl->setContent($searchTpl->get()); + private function isMailActionAllowed(): bool + { + return $this->isDefaultRequestContext() && $this->mailing_allowed; + } - if ($this->isDefaultRequestContext()) { - $this->tpl->printToStdout(); + private function isShareActionAllowed(): bool + { + return $this->getContext() === self::CONTEXT_WORKSPACE + && $this->wsp_access_handler !== null + && $this->wsp_node_id !== null; + } + + private function resolveBuddyUserIdFromQuery(): ?int + { + $member_row_ids = $this->retrieveMemberRowIdsFromQuery(); + + if ($member_row_ids === 'ALL_OBJECTS' || $member_row_ids === []) { + return null; } + + $member_row_id = is_array($member_row_ids) + ? (string) ($member_row_ids[0] ?? '') + : $member_row_ids; + + if (!str_contains($member_row_id, '_')) { + return null; + } + + return (int) explode('_', $member_row_id, 2)[1]; } - public function executeCommand(): bool + /** + * @return list + */ + private function retrieveObjectIdsFromQuery(): array { - $forward_class = $this->ctrl->getNextClass($this) ?? ''; - switch (strtolower($forward_class)) { - case strtolower(ilBuddySystemGUI::class): - if (!ilBuddySystem::getInstance()->isEnabled()) { - $this->error->raiseError($this->lng->txt('msg_no_perm_read'), $this->error->MESSAGE); - } + $obj_ids = $this->resolveObjectIds( + $this->retrieveIdsFromQuery('contact_mailinglist_search_obj_ids') + ); + if ($obj_ids !== []) { + return $obj_ids; + } - $this->ctrl->saveParameter($this, 'search_' . $this->getObjectType()); + return $this->resolveObjectIds( + $this->retrieveIdsFromQuery('search_' . $this->getObjectType()) + ); + } - $this->ctrl->setReturn($this, 'showMembers'); - $this->ctrl->forwardCommand(new ilBuddySystemGUI()); - break; + /** + * @param list|string $obj_ids + * @return list + */ + private function resolveObjectIds(array|string $obj_ids): array + { + $own_obj_ids = $this->getOwnObjectIds(); + if ($obj_ids === 'ALL_OBJECTS') { + return $own_obj_ids; + } - default: - if (!($cmd = $this->ctrl->getCmd())) { - $cmd = 'showMyObjects'; - } + return array_values(array_intersect($obj_ids, $own_obj_ids)); + } - $this->$cmd(); - break; + /** + * @return list + */ + private function getOwnObjectIds(): array + { + return array_values(array_filter( + ilParticipants::_getMembershipByType($this->user->getId(), [$this->getObjectType()]), + ilObject::_hasUntrashedReference(...), + )); + } + + /** + * @return list + */ + private function resolveUserIds(): array + { + $member_row_ids = $this->retrieveMemberRowIdsFromQuery(); + + $obj_ids = $this->retrieveObjectIdsFromQuery(); + $allowed_member_row_ids = $this->collectMemberRowIds($obj_ids); + if ($member_row_ids === 'ALL_OBJECTS') { + return array_values(array_unique(array_map( + static fn(string $member_row_id): int => (int) explode('_', $member_row_id, 2)[1], + $allowed_member_row_ids, + ))); } - return true; + $allowed_row_ids = array_flip($allowed_member_row_ids); + $usr_ids = []; + foreach ($member_row_ids as $member_row_id) { + $member_row_id = (string) $member_row_id; + if (!isset($allowed_row_ids[$member_row_id])) { + continue; + } + + $usr_ids[] = (int) explode('_', $member_row_id, 2)[1]; + } + + return array_values(array_unique($usr_ids)); + } + + /** + * @param list $obj_ids + * @return list + */ + private function collectMemberRowIds(array $obj_ids): array + { + $member_row_ids = []; + foreach ($obj_ids as $obj_id) { + $ref_ids = new ObjectId($obj_id)->toReferenceIds(); + if ($ref_ids === []) { + continue; + } + + foreach (ilParticipants::getInstance($ref_ids[0]->toInt())->getParticipants() as $participant) { + if (ilObjUser::_lookupActive($participant)) { + $member_row_ids[] = "{$obj_id}_$participant"; + } + } + } + + return $member_row_ids; + } + + /** + * @return list|string + */ + private function retrieveMemberRowIdsFromQuery(): array|string + { + return $this->http->wrapper()->query()->retrieve( + 'contact_mailinglist_search_members_ids', + $this->refinery->byTrying([ + $this->refinery->custom()->transformation( + static function (mixed $value): string { + if ($value === 'ALL_OBJECTS' || (is_array($value) && ($value[0] ?? null) === 'ALL_OBJECTS')) { + return 'ALL_OBJECTS'; + } + + throw new Exception('not all objects'); + } + ), + $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->string()), + $this->refinery->custom()->transformation( + static function (mixed $value): array { + if (!is_string($value) || $value === '') { + throw new Exception('invalid ids'); + } + + return explode(',', $value); + } + ), + $this->refinery->always([]) + ]) + ); + } + + /** + * @return list|string + */ + private function retrieveIdsFromQuery(string $key): array|string + { + return $this->http->wrapper()->query()->retrieve( + $key, + $this->refinery->byTrying([ + $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int()), + $this->refinery->custom()->transformation( + static function (mixed $value): array|string { + if ($value === ['ALL_OBJECTS']) { + return 'ALL_OBJECTS'; + } + if (!is_string($value) || $value === '') { + throw new Exception('invalid ids'); + } + + return array_map(intval(...), explode(',', $value)); + } + ), + $this->refinery->always([]) + ]) + ); } } diff --git a/components/ILIAS/Contact/classes/class.ilMailSearchObjectMembershipsTableGUI.php b/components/ILIAS/Contact/classes/class.ilMailSearchObjectMembershipsTableGUI.php deleted file mode 100755 index 265c65289679..000000000000 --- a/components/ILIAS/Contact/classes/class.ilMailSearchObjectMembershipsTableGUI.php +++ /dev/null @@ -1,241 +0,0 @@ - - * @ingroup ServicesMail - */ -class ilMailSearchObjectMembershipsTableGUI extends ilTable2GUI -{ - private readonly GlobalHttpState $http; - private readonly Refinery $refinery; - private readonly ilObjUser $user; - /** @var array */ - private readonly array $mode; - private bool $mailing_allowed; - private readonly \ILIAS\UI\Factory $ui_factory; - private readonly \ILIAS\UI\Renderer $ui_renderer; - - /** - * @param ilMailSearchCoursesGUI|ilMailSearchGroupsGUI $a_parent_obj $a_parent_obj - */ - public function __construct( - $a_parent_obj, - string $type = 'crs', - string $context = 'mail', - array $contextObjects = [] - ) { - global $DIC; - - $this->ctrl = $DIC['ilCtrl']; - $this->lng = $DIC['lng']; - $this->user = $DIC['ilUser']; - $this->http = $DIC->http(); - $this->refinery = $DIC->refinery(); - $this->ui_factory = $DIC->ui()->factory(); - $this->ui_renderer = $DIC->ui()->renderer(); - - $tableId = ilStr::subStr($type . '_cml_' . md5(implode('_', $contextObjects)), 0, 30); - $this->setId($tableId); - parent::__construct($a_parent_obj, 'showMembers'); - - $this->context = $context; - if ($this->context === 'mail') { - $mail = new ilMail($this->user->getId()); - $this->mailing_allowed = $DIC->rbac()->system()->checkAccess('internal_mail', $mail->getMailObjectReferenceId()); - } - - $this->setDefaultOrderDirection('ASC'); - $this->setDefaultOrderField('members_login'); - - $this->lng->loadLanguageModule('crs'); - $this->lng->loadLanguageModule('buddysystem'); - - $mode = []; - if ($type === 'crs') { - $mode['checkbox'] = 'search_crs'; - $mode['short'] = 'crs'; - $mode['long'] = 'course'; - $mode['lng_type'] = $this->lng->txt('course'); - $mode['view'] = 'crs_members'; - } elseif ($type === 'grp') { - $mode['checkbox'] = 'search_grp'; - $mode['short'] = 'grp'; - $mode['long'] = 'group'; - $mode['lng_type'] = $this->lng->txt('group'); - $mode['view'] = 'grp_members'; - } - - $this->setTitle($this->lng->txt('members')); - $this->mode = $mode; - - $this->ctrl->setParameter($a_parent_obj, 'view', $mode['view']); - - if ( - $this->http->wrapper()->query()->has('ref') && - $this->http->wrapper()->query()->retrieve('ref', $this->refinery->kindlyTo()->string()) !== '' - ) { - $this->ctrl->setParameter( - $a_parent_obj, - 'ref', - $this->http->wrapper()->query()->retrieve('ref', $this->refinery->kindlyTo()->string()) - ); - } - - if ($this->http->wrapper()->post()->has($mode['checkbox'])) { - $ids = $this->http->wrapper()->post()->retrieve( - $mode['checkbox'], - $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int()) - ); - - if ($ids !== []) { - $this->ctrl->setParameter( - $a_parent_obj, - $mode['checkbox'], - implode(', ', $ids) - ); - } - } - - $this->setFormAction($this->ctrl->getFormAction($a_parent_obj)); - - $this->setRowTemplate('tpl.mail_search_objects_members_row.html', 'components/ILIAS/Contact'); - - $this->addColumn('', '', '1%', true); - $this->addColumn($this->lng->txt('login'), 'members_login', '22%'); - $this->addColumn($this->lng->txt('name'), 'members_name', '22%'); - $this->addColumn($this->lng->txt($mode['long']), 'members_crs_grp', '22%'); - if (ilBuddySystem::getInstance()->isEnabled()) { - $this->addColumn($this->lng->txt('buddy_tbl_filter_state'), 'status', '23%'); - } - $this->addColumn($this->lng->txt('actions'), '', '10%'); - - if ($this->context === 'mail') { - if ($this->mailing_allowed) { - $this->setSelectAllCheckbox('search_members[]'); - $this->addMultiCommand('mail', $this->lng->txt('mail_members')); - } - } else { - $this->setSelectAllCheckbox('search_members[]'); - $this->lng->loadLanguageModule('wsp'); - $this->addMultiCommand('share', $this->lng->txt('wsp_share_with_members')); - } - $this->lng->loadLanguageModule('buddysystem'); - $this->addCommandButton('cancel', $this->lng->txt('cancel')); - } - - protected function getRequestValue(string $key, \ILIAS\Refinery\Transformation $trafo, $default = null) - { - $value = $default; - if ($this->http->wrapper()->query()->has($key)) { - $value = $this->http->wrapper()->query()->retrieve($key, $trafo); - } - - if ($this->http->wrapper()->post()->has($key)) { - $value = $this->http->wrapper()->post()->retrieve($key, $trafo); - } - - return $value; - } - - protected function fillRow(array $a_set): void - { - $trafo = $this->refinery->custom()->transformation(function ($value): string { - if (is_string($value)) { - return $this->refinery - ->custom() - ->transformation(fn(string $value): string => ilUtil::stripSlashes($value)) - ->transform($value); - } - - return implode( - ',', - $this->refinery->kindlyTo()->listOf( - $this->refinery->in()->series([ - $this->refinery->kindlyTo()->int(), - $this->refinery->kindlyTo()->string() - ]) - )->transform($value) - ); - }); - - $buttons = []; - - $this->ctrl->setParameter($this->parent_obj, 'search_members', $a_set['members_id']); - $this->ctrl->setParameter( - $this->parent_obj, - 'search_' . $this->mode['short'], - $this->getRequestValue('search_' . $this->mode['short'], $trafo) - ); - $this->ctrl->setParameter($this->parent_obj, 'view', $this->mode['view']); - - $action_html = ''; - if ($this->context === 'mail') { - if ($this->mailing_allowed) { - $buttons[] = $this->ui_factory - ->button() - ->shy( - $this->lng->txt('mail_member'), - $this->ctrl->getLinkTarget($this->parent_obj, 'mail') - ); - } - } else { - $buttons[] = $this->ui_factory - ->button() - ->shy( - $this->lng->txt('wsp_share_with_members'), - $this->ctrl->getLinkTarget($this->parent_obj, 'share') - ); - } - - if ($this->context === 'mail' && ilBuddySystem::getInstance()->isEnabled()) { - $relation = ilBuddyList::getInstanceByGlobalUser()->getRelationByUserId((int) $a_set['members_id']); - if ( - $a_set['members_id'] !== $this->user->getId() && - $relation->isUnlinked() && - ilUtil::yn2tf((string) ilObjUser::_lookupPref($a_set['members_id'], 'bs_allow_to_contact_me')) - ) { - $this->ctrl->setParameterByClass(ilBuddySystemGUI::class, 'user_id', $a_set['members_id']); - $buttons[] = $this->ui_factory - ->button() - ->shy( - $this->lng->txt('buddy_bs_btn_txt_unlinked_a'), - $this->ctrl->getLinkTargetByClass(ilBuddySystemGUI::class, 'request') - ); - } - } - - if ($buttons !== []) { - $drop_down = $this->ui_factory - ->dropdown() - ->standard($buttons) - ->withLabel($this->lng->txt('actions')); - $action_html = $this->ui_renderer->render($drop_down); - } - $this->tpl->setVariable('CURRENT_ACTION_LIST', $action_html); - - foreach ($a_set as $key => $value) { - $this->tpl->setVariable(strtoupper($key), $value); - } - } -} diff --git a/components/ILIAS/Contact/classes/class.ilMailSearchObjectsTableGUI.php b/components/ILIAS/Contact/classes/class.ilMailSearchObjectsTableGUI.php deleted file mode 100755 index 8a3f74fc8bc2..000000000000 --- a/components/ILIAS/Contact/classes/class.ilMailSearchObjectsTableGUI.php +++ /dev/null @@ -1,161 +0,0 @@ -lng = $DIC['lng']; - $this->ctrl = $DIC['ilCtrl']; - $this->user = $DIC['ilUser']; - $this->rbacsystem = $DIC['rbacsystem']; - - $this->lng->loadLanguageModule('crs'); - $this->lng->loadLanguageModule('buddysystem'); - - if ($context === 'mail') { - $mail = new ilMail($this->user->getId()); - $this->mailing_allowed = $this->rbacsystem->checkAccess('internal_mail', $mail->getMailObjectReferenceId()); - } - - $mode = []; - if ($type === 'crs') { - $mode['short'] = 'crs'; - $mode['long'] = 'course'; - $mode['checkbox'] = 'search_crs'; - $mode['tableprefix'] = 'crstable'; - $mode['lng_mail'] = $this->lng->txt('mail_my_courses'); - $mode['view'] = 'myobjects'; - $this->setTitle($mode['lng_mail']); - } elseif ($type === 'grp') { - $mode['short'] = 'grp'; - $mode['long'] = 'group'; - $mode['checkbox'] = 'search_grp'; - $mode['tableprefix'] = 'grptable'; - $mode['lng_mail'] = $this->lng->txt('mail_my_groups'); - $mode['view'] = 'myobjects'; - $this->setTitle($mode['lng_mail']); - } - - $this->setId('search_' . $mode['short']); - parent::__construct($a_parent_obj); - - $this->parentObject = $a_parent_obj; - $this->mode = $mode; - $this->context = $context; - - $this->ctrl->setParameter($a_parent_obj, 'view', $mode['view']); - - $http = $DIC['http']; - $refinery = $DIC->refinery(); - - - if ( - $http->wrapper()->query()->has('ref') && - $http->wrapper()->query()->retrieve('ref', $refinery->kindlyTo()->string()) !== '' - ) { - $this->ctrl->setParameter( - $a_parent_obj, - 'ref', - $http->wrapper()->query()->retrieve('ref', $refinery->kindlyTo()->string()) - ); - } - - if ($http->wrapper()->post()->has($mode['checkbox'])) { - $ids = $http->wrapper()->post()->retrieve( - $mode['checkbox'], - $refinery->kindlyTo()->listOf( - $refinery->in()->series([ - $refinery->kindlyTo()->int(), - $refinery->kindlyTo()->string() - ]) - ) - ); - - if ($ids !== []) { - $this->ctrl->setParameter( - $a_parent_obj, - $mode['checkbox'], - implode(', ', $ids) - ); - } - } - - $this->setFormAction($this->ctrl->getFormAction($a_parent_obj)); - $this->ctrl->clearParameters($a_parent_obj); - - $this->setSelectAllCheckbox($mode["checkbox"] . '[]'); - $this->setRowTemplate('tpl.mail_search_objects_row.html', 'components/ILIAS/Contact'); - - $this->setShowRowsSelector(true); - - $this->addColumn('', '', '1px', true); - $this->addColumn($mode["lng_mail"], 'OBJECT_NAME', '30%'); - $this->addColumn($this->lng->txt('path'), 'OBJECT_PATH', '30%'); - $this->addColumn($this->lng->txt('obj_count_members'), 'OBJECT_NO_MEMBERS', '20%'); - $this->addColumn($this->lng->txt('actions'), '', '19%'); - - if ($context === "mail") { - if ($this->mailing_allowed) { - $this->addMultiCommand('mail', $this->lng->txt('mail_members')); - } - } elseif ($context === "wsp") { - $this->lng->loadLanguageModule("wsp"); - $this->addMultiCommand('share', $this->lng->txt('wsp_share_with_members')); - } - $this->addMultiCommand('showMembers', $this->lng->txt('mail_list_members')); - - if ( - $http->wrapper()->query()->has('ref') && - $http->wrapper()->query()->retrieve('ref', $refinery->to()->string()) === 'mail' - ) { - $this->addCommandButton('cancel', $this->lng->txt('cancel')); - } - } - - protected function fillRow(array $a_set): void - { - if ($a_set['hidden_members']) { - $this->tpl->setCurrentBlock('caption_asterisk'); - $this->tpl->touchBlock('caption_asterisk'); - $this->tpl->parseCurrentBlock(); - } - foreach ($a_set as $key => $value) { - $this->tpl->setVariable(strtoupper($key), $value); - } - $this->tpl->setVariable('SHORT', $this->mode["short"]); - } - - public function numericOrdering(string $a_field): bool - { - return $a_field === 'OBJECT_NO_MEMBERS'; - } -} diff --git a/components/ILIAS/Contact/templates/default/tpl.mail_members.html b/components/ILIAS/Contact/templates/default/tpl.mail_members.html deleted file mode 100755 index c275d862dac8..000000000000 --- a/components/ILIAS/Contact/templates/default/tpl.mail_members.html +++ /dev/null @@ -1,16 +0,0 @@ -
- - - - - - - - - - - - -
{TXT_COMPOSE_MESSAGE}
{CHECK_MAILBOX} {MAILBOX}
{TXT_MARKED_ENTRIES}  -
-
\ No newline at end of file diff --git a/components/ILIAS/Contact/templates/default/tpl.mail_search_objects_members_row.html b/components/ILIAS/Contact/templates/default/tpl.mail_search_objects_members_row.html deleted file mode 100755 index d636af249f75..000000000000 --- a/components/ILIAS/Contact/templates/default/tpl.mail_search_objects_members_row.html +++ /dev/null @@ -1,8 +0,0 @@ - - - {MEMBERS_LOGIN} - {MEMBERS_NAME} - {MEMBERS_CRS_GRP} - {STATUS} - {CURRENT_ACTION_LIST} - diff --git a/components/ILIAS/Contact/templates/default/tpl.mail_search_objects_row.html b/components/ILIAS/Contact/templates/default/tpl.mail_search_objects_row.html deleted file mode 100755 index fb93e2f0a8c5..000000000000 --- a/components/ILIAS/Contact/templates/default/tpl.mail_search_objects_row.html +++ /dev/null @@ -1,7 +0,0 @@ - - - {OBJECT_NAME}* - {OBJECT_PATH} - {OBJECT_NO_MEMBERS} - {COMMAND_SELECTION_LIST} - diff --git a/components/ILIAS/Mail/classes/class.ilMailFormGUI.php b/components/ILIAS/Mail/classes/class.ilMailFormGUI.php index 6f9da67b36c2..d8ae254bbc2d 100755 --- a/components/ILIAS/Mail/classes/class.ilMailFormGUI.php +++ b/components/ILIAS/Mail/classes/class.ilMailFormGUI.php @@ -522,10 +522,6 @@ public function searchCoursesTo(): void { $this->saveMailBeforeSearch(); - if (ilSession::get('search_crs')) { - $this->ctrl->setParameterByClass('ilmailsearchcoursesgui', 'cmd', 'showMembers'); - } - $this->ctrl->setParameterByClass(ilMailSearchCoursesGUI::class, 'ref', 'mail'); $this->ctrl->redirectByClass(ilMailSearchCoursesGUI::class); } diff --git a/lang/ilias_de.lang b/lang/ilias_de.lang index dcb66a5c1591..8c070f4c9fe8 100644 --- a/lang/ilias_de.lang +++ b/lang/ilias_de.lang @@ -4661,7 +4661,6 @@ common#:#main_menu#:#Hauptmenü common#:#mainbar_aria_label#:#Hauptleiste common#:#mainbar_more_label#:#Mehr common#:#manage_members#:#Mitglieder verwalten -common#:#marked_entries#:#Markierte Einträge common#:#matriculation#:#Matrikelnummer common#:#max_previews_per_object#:#Anzahl Vorschaubilder common#:#max_previews_per_object_info#:#Anzahl an Vorschaubildern, die pro Datei angezeigt werden. diff --git a/lang/ilias_en.lang b/lang/ilias_en.lang index b88393331fde..eb8818ee06a1 100644 --- a/lang/ilias_en.lang +++ b/lang/ilias_en.lang @@ -4662,7 +4662,6 @@ common#:#main_menu#:#Main Menu common#:#mainbar_aria_label#:#Mainbar common#:#mainbar_more_label#:#More common#:#manage_members#:#Manage Members -common#:#marked_entries#:#Marked Entries common#:#matriculation#:#Matriculation Number common#:#max_previews_per_object#:#Number of preview images per file common#:#max_previews_per_object_info#:#Defines the maximum number of preview images that are created per file.