19declare(strict_types=1);
39 $this->gui->switchToVisibleMode();
45 $custom_username =
false;
52 $custom_username =
true;
61 $username = $chat_user->{
68 if (!$failure && trim($username) !==
'') {
69 if (!$room->isSubscribed($chat_user->getUserId())) {
70 $chat_user->setUsername($chat_user->buildUniqueUsername($username));
71 $chat_user->setProfilePictureVisible(!$custom_username);
76 $this->mainTpl->setOnScreenMessage(
'failure', $this->ilLng->txt(
'no_username_given'));
87 $this->mainTpl->addJavaScript(
'assets/js/socket.io.min.js');
88 $this->mainTpl->addJavaScript(
'assets/js/Chatroom.min.js');
89 $this->mainTpl->addJavaScript(
'assets/js/AdvancedSelectionList.js');
91 $this->mainTpl->setPermanentLink($this->gui->getObject()->getType(), $this->gui->getObject()->getRefId());
99 $this->redirectIfNoPermission(
'read');
103 $ref_id = $this->getRequestValue(
'ref_id', $this->
refinery->kindlyTo()->int());
111 $this->cancelJoin($this->ilLng->txt(
'banned'));
116 $connector = $this->gui->getConnector();
120 $this->mainTpl->setOnScreenMessage(
'failure', $this->ilLng->txt(
'unable_to_connect'),
true);
130 $this->mainTpl->setOnScreenMessage(
'failure', $this->ilLng->txt(
'unable_to_connect'),
true);
136 fn($entry) => $entry->type !==
'notice'
140 $show_auto_messages = !$this->ilUser->getPref(
'chat_hide_automsg_' . $room->
getRoomId());
142 $build = $this->buildChat($room, $connector->
getSettings());
144 $room_tpl = $build->template(
false, $build->initialData(
147 $this->ilCtrl->getLinkTarget($this->gui,
'view-lostConnection',
'',
false),
149 'moderator' => $is_moderator,
156 ), $this->panel($this->ilLng->txt(
'write_message'), $this->sendMessageForm()), $this->panel($this->ilLng->txt(
'messages'), $this->legacy(
'<div id="chat_messages"></div>')));
158 $this->mainTpl->setContent($room_tpl->get());
159 $this->mainTpl->setRightContent($this->userList() . $this->chatFunctions($show_auto_messages, $is_moderator));
164 $build = $this->buildChat($room, $this->gui->getConnector()->
getSettings());
166 return $build->template(
true, $build->initialData([],
true,
null, [
167 'moderator' =>
false,
170 'broadcast_typing' =>
false,
171 ],
$messages), $this->panel($this->ilLng->txt(
'messages'), $this->legacy(
'<div id="chat_messages"></div>')),
'');
176 $template =
new ilTemplate(
'tpl.chatroom_send_message_form.html',
true,
true,
'components/ILIAS/Chatroom');
177 $this->renderSendMessageBox($template);
179 return $this->
legacy($template->get());
184 $roomRightTpl =
new ilTemplate(
'tpl.chatroom_right.html',
true,
true,
'components/ILIAS/Chatroom');
185 $this->renderRightUsersBlock($roomRightTpl);
187 return $this->panel($this->ilLng->txt(
'users'), $this->legacy($roomRightTpl->get()));
190 private function chatFunctions(
bool $show_auto_messages,
bool $is_moderator): string
192 $txt = $this->ilLng->txt(...);
193 $js_escape = json_encode(...);
194 $format = fn($format, ...$args) => sprintf($format, ...array_map($js_escape, $args));
195 $register = fn($name,
$c) =>
$c->withOnLoadCode(fn(
$id) => $format(
196 'il.Chatroom.bus.send(%s, document.getElementById(%s));',
201 $b = $this->uiFactory->button();
202 $toggle = fn($label, $enabled) =>
$b->toggle($label,
'#',
'#', $enabled)->withAriaLabel($label);
204 $bind = fn($key, $m) => $m->withAdditionalOnLoadCode(fn(
string $id) => $format(
205 '$(() => il.Chatroom.bus.send(%s, {
206 node: document.getElementById(%s),
207 showModal: () => $(document).trigger(%s, {}),
208 closeModal: () => $(document).trigger(%s, {})
212 $m->getShowSignal()->getId(),
213 $m->getCloseSignal()->getId()
216 $interrupt = fn($key, $label, $text, $button =
null) => $bind($key, $this->uiFactory->modal()->interruptive(
220 ))->withActionButtonLabel($button ?? $label);
222 $auto_scroll = $register(
'auto-scroll-toggle', $toggle(
$txt(
'auto_scroll'),
true));
223 $messages = $register(
'system-messages-toggle', $toggle(
$txt(
'chat_show_auto_messages'), $show_auto_messages));
225 $invite = $bind(
'invite-modal', $this->uiFactory->modal()->roundtrip(
$txt(
'chat_invite'), $this->
legacy(
$txt(
'invite_to_private_room')), [
226 $this->uiFactory->input()->field()->text(
$txt(
'chat_invite')),
227 ])->withSubmitLabel(
$txt(
'chat_invite')));
230 $buttons[] = $register(
'invite-button',
$b->shy(
$txt(
'invite_to_private_room'),
''));
232 $buttons[] = $register(
'clear-history-button',
$b->shy(
$txt(
'clear_room_history'),
''));
235 return $this->panel(
$txt(
'chat_functions'), [
236 $this->
legacy(
'<div id="chat_function_list">'),
239 $interrupt(
'kick-modal',
$txt(
'chat_kick'),
$txt(
'kick_question')),
240 $interrupt(
'ban-modal',
$txt(
'chat_ban'),
$txt(
'ban_question')),
241 $interrupt(
'clear-history-modal',
$txt(
'clear_room_history'),
$txt(
'clear_room_history_question')),
243 $this->
legacy(sprintf(
'<div>%s%s</div>', $this->checkbox($auto_scroll), $this->checkbox(
$messages))),
249 return sprintf(
'<div class="chatroom-centered-checkboxes">%s</div>', $this->uiRenderer->render($component));
254 return $this->uiFactory->legacy()->content($html);
260 private function panel(
string $title, $body): string
262 if (is_array($body)) {
263 $body = $this->uiFactory->legacy()->content(join(
'', array_map($this->uiRenderer->render(...), $body)));
265 $panel = $this->uiFactory->panel()->secondary()->legacy($title, $body);
267 return $this->uiRenderer->render($panel);
272 $this->redirectIfNoPermission(
'read');
277 if ($this->
http->wrapper()->post()->has(
'state')) {
278 $state = $this->
http->wrapper()->post()->retrieve(
'state', $this->
refinery->kindlyTo()->int());
281 $this->ilUser->writePref(
282 'chat_hide_automsg_' . $room->getRoomId(),
283 (
string) ((
int) (!(
bool) $state))
286 $this->
http->saveResponse(
287 $this->
http->response()
288 ->withHeader(ResponseHeader::CONTENT_TYPE,
'application/json')
289 ->withBody(Streams::ofString(json_encode([
'success' =>
true], JSON_THROW_ON_ERROR)))
291 $this->
http->sendResponse();
292 $this->
http->close();
300 $this->mainTpl->setOnScreenMessage(
'failure',
$message);
305 $roomTpl->
setVariable(
'PLACEHOLDER', $this->ilLng->txt(
'chat_osc_write_a_msg'));
306 $roomTpl->
setVariable(
'LBL_SEND', $this->ilLng->txt(
'send'));
311 $roomTpl->
setVariable(
'LBL_NO_FURTHER_USERS', $this->ilLng->txt(
'no_further_users'));
318 $selectionForm = $formFactory->getUserChatNameSelectionForm($name_options);
322 $selectionForm->addCommandButton(
'view-joinWithCustomName', $this->ilLng->txt(
'enter'));
323 $selectionForm->setFormAction(
327 $this->mainTpl->setVariable(
'ADM_CONTENT', $selectionForm->getHTML());
338 $this->redirectIfNoPermission(
'read');
340 $this->gui->switchToVisibleMode();
341 $this->setupTemplate();
343 $chatSettings =
new ilSetting(
'chatroom');
344 if (!$chatSettings->get(
'chat_enabled',
'0')) {
350 if (!$room->getSetting(
'allow_anonymous') && $this->ilUser->isAnonymous()) {
351 $this->cancelJoin($this->ilLng->txt(
'chat_anonymous_not_allowed'));
357 if ($room->getSetting(
'allow_custom_usernames')) {
358 if ($room->isSubscribed($chat_user->getUserId())) {
359 $chat_user->setUsername($chat_user->getUsername());
360 $this->showRoom($room, $chat_user);
362 $this->showNameSelection($chat_user);
365 $chat_user->setUsername($this->ilUser->getPublicName());
366 $chat_user->setProfilePictureVisible(
true);
367 $this->showRoom($room, $chat_user);
373 $pid = $this->tree->getParentId($this->gui->getRefId());
380 if ($this->
http->wrapper()->query()->has(
'msg')) {
381 match ($this->
http->wrapper()->query()->retrieve(
'msg', $this->refinery->kindlyTo()->string())) {
382 'kicked' => $this->mainTpl->setOnScreenMessage(
'failure', $this->ilLng->txt(
'kicked'),
true),
383 'banned' => $this->mainTpl->setOnScreenMessage(
'failure', $this->ilLng->txt(
'banned'),
true),
384 default => $this->mainTpl->setOnScreenMessage(
'failure', $this->ilLng->txt(
'lost_connection'),
true),
387 $this->mainTpl->setOnScreenMessage(
'failure', $this->ilLng->txt(
'lost_connection'),
true);
393 public function getUserProfileImages(): void
399 $request = json_decode($this->
http->request()->getBody()->getContents(),
true, 512, JSON_THROW_ON_ERROR);
404 $this->refinery->kindlyTo()->recordOf([
405 'id' => $this->refinery->kindlyTo()->int(),
406 'username' => $this->refinery->kindlyTo()->string(),
407 'profile_picture_visible' => $this->refinery->kindlyTo()->bool(),
409 $this->refinery->kindlyTo()->recordOf([
410 'id' => $this->refinery->kindlyTo()->int(),
411 'username' => $this->refinery->kindlyTo()->string(),
413 ]))->transform($request[
'profiles'] ?? []);
415 $user_ids = array_column($users,
'id');
419 foreach ($users as $user) {
420 if ($user[
'profile_picture_visible'] ??
false) {
421 $public_image = $public_data[$user[
'id']][
'img'] ??
'';
424 $avatar =
$DIC[
"user.avatar.factory"]->avatar(
'xsmall');
427 $public_image = $avatar->getUrl();
430 $response[json_encode($user, JSON_THROW_ON_ERROR)] = $public_image;
440 $kindly = $this->
refinery->kindlyTo();
441 $s = $kindly->string();
442 $int = $kindly->int();
443 $get = $this->
http->wrapper()->query()->retrieve(...);
444 $get_or = fn($k, $t,
$d =
null) => $get($k, $this->
refinery->byTrying([$t, $this->refinery->always(
$d)]));
446 $ref_id = $get(
'ref_id', $int);
448 $username = $get(
'username', $s);
449 $actions = $get_or(
'actions', $kindly->dictOf($s), []);
451 $avatar =
$DIC[
"user.avatar.factory"]->avatar(
'xsmall');
454 $public_image = $avatar->getUrl();
455 $item = $this->uiFactory->item()->standard($username)->withLeadImage($this->uiFactory->image()->standard(
457 'Profile image of ' . $username
461 $item = $item->withProperties([
462 $this->ilLng->txt(
'role') => $this->ilLng->txt(
'il_chat_moderator'),
465 $item = $item->withActions($this->uiFactory->dropdown()->standard($this->buildUserActions(
$user_id, $actions)));
468 $this->sendResponse($this->uiRenderer->renderAsync($item),
'text/html');
477 $chat_settings =
new ilSetting(
'chatroom');
478 $osc_enabled = $chat_settings->get(
'chat_enabled') && $chat_settings->get(
'enable_osc');
480 'kick' => $this->ilLng->txt(
'chat_kick'),
481 'ban' => $this->ilLng->txt(
'chat_ban'),
485 $translations[
'chat'] = $this->ilLng->txt(
'start_private_chat');
489 foreach ($actions as $key => $bus_id) {
490 $label = $translations[$key] ??
false;
492 $buttons[] = $this->uiFactory->button()->shy($label,
'')->withAdditionalOnLoadCode(fn(
string $id):
string => (
493 'il.Chatroom.bus.send(' . json_encode(
496 ) .
', document.getElementById(' . json_encode(
$id, JSON_THROW_ON_ERROR) .
'));'
506 return new BuildChat($this->
ilCtrl, $this->ilLng, $this->gui, $room, $settings, $this->ilUser, $this->uiFactory, $this->uiRenderer);
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
setVariable($variable, $value='')
Sets a variable value.
Stream factory which enables the user to create streams without the knowledge of the concrete class.
Class ilChatroomGUIHandler.
hasRequestValue(string $key)
redirectIfNoPermission($permission)
Checks for requested permissions and redirects if the permission check failed.
getRequestValue(string $key, Transformation $trafo, $default=null)
Class ilChatroomServerSettings.
isProfilePictureVisible()
getChatNameSuggestions()
Returns an array of chat-name suggestions.
getUserId()
Returns Ilias User ID.
getUsername()
Returns username from Object or SESSION.
readOnlyChatWindow(ilChatroom $room, array $messages)
buildChat(ilChatroom $room, ilChatroomServerSettings $settings)
panel(string $title, $body)
renderRightUsersBlock(ilTemplate $roomTpl)
cancelJoin(string $message)
Calls ilUtil::sendFailure method using given $message as parameter.
checkbox(Component $component)
setupTemplate()
Adds CSS and JavaScript files that should be included in the header.
showNameSelection(ilChatroomUser $chat_user)
buildUserActions(int $user_id, array $actions)
toggleAutoMessageDisplayState()
executeDefault(string $requestedMethod)
Chatroom and Chatuser get prepared before $this->showRoom method is called.
chatFunctions(bool $show_auto_messages, bool $is_moderator)
showRoom(ilChatroom $room, ilChatroomUser $chat_user)
Prepares and displays chatroom and connects user to it.
renderSendMessageBox(ilTemplate $roomTpl)
getConnectedUsers(bool $only_data=true)
static checkPermissionsOfUser(int $usr_id, $permissions, int $ref_id)
Checks user permissions in question for a given user id in relation to a given ref_id.
connectUser(ilChatroomUser $user)
static checkUserPermissions($permissions, int $ref_id, bool $send_info=true)
Checks user permissions by given array and ref_id.
isUserBanned(int $user_id)
isSubscribed(int $chat_userid)
getLastMessages(int $number, ilChatroomUser $chatuser)
static byObjectId(int $object_id)
Class ilCtrl provides processing control methods.
redirectByClass( $a_class, ?string $a_cmd=null, ?string $a_anchor=null, bool $is_async=false)
@inheritDoc
getFormAction(object $a_gui_obj, ?string $a_fallback_cmd=null, ?string $a_anchor=null, bool $is_async=false, bool $has_xml_style=false)
@inheritDoc
saveParameter(object $a_gui_obj, $a_parameter)
@inheritDoc
redirect(object $a_gui_obj, ?string $a_cmd=null, ?string $a_anchor=null, bool $is_async=false)
@inheritDoc
setParameterByClass(string $a_class, string $a_parameter, $a_value)
@inheritDoc
getLinkTargetByClass( $a_class, ?string $a_cmd=null, ?string $a_anchor=null, bool $is_async=false, bool $has_xml_style=false)
@inheritDoc
static initLinkify(?ilGlobalTemplateInterface $a_tpl=null)
static _lookupPref(int $a_usr_id, string $a_keyword)
static subStr(string $a_str, int $a_start, ?int $a_length=null)
special template class to simplify handling of ITX/PEAR
static getNamePresentation( $a_user_id, bool $a_user_image=false, bool $a_profile_link=false, string $a_profile_back_link='', bool $a_force_first_lastname=false, bool $a_omit_login=false, bool $a_sortable=true, bool $a_return_data_array=false, $a_ctrl_path=null)
Default behaviour is:
static setTokenMaxLifetimeInSeconds(int $token_max_lifetime_in_seconds)
A component is the most general form of an entity in the UI.
static http()
Fetches the global http state from ILIAS.