mirror of
https://github.com/NamelessMC/Nameless
synced 2026-08-18 06:29:04 -04:00
* Remove old event system & Convert renderPost event * Remove old event system * Misc * Convert Custom Pages to use new event system * Change RenderPost to RenderContent * Convert profile posts and messaging * All events converted * Fixes * Fixes * Add tag support in Profile Posts & Messaging * Execute rendercreate for profile post reply * Update webhooks * Remove return function * Remove array response * Remove more array response * Remove fallback webhooks * Test phpstan * Fix phpdoc * Remove name() & description()
545 lines
21 KiB
PHP
545 lines
21 KiB
PHP
<?php
|
|
/**
|
|
* User messaging page
|
|
*
|
|
* @author Samerton
|
|
* @license MIT
|
|
* @version 2.3.0
|
|
*
|
|
* @var Cache $cache
|
|
* @var FakeSmarty $smarty
|
|
* @var Language $language
|
|
* @var Navigation $cc_nav
|
|
* @var Navigation $navigation
|
|
* @var Navigation $staffcp_nav
|
|
* @var Pages $pages
|
|
* @var TemplateBase $template
|
|
* @var User $user
|
|
* @var Widgets $widgets
|
|
*/
|
|
|
|
// Must be logged in
|
|
if (!$user->isLoggedIn()) {
|
|
Redirect::to(URL::build('/'));
|
|
}
|
|
|
|
// Always define page name for navbar
|
|
const PAGE = 'cc_messaging';
|
|
$page_title = $language->get('user', 'user_cp');
|
|
require_once ROOT_PATH . '/core/templates/frontend_init.php';
|
|
|
|
$timeago = new TimeAgo(TIMEZONE);
|
|
|
|
$template->getEngine()->addVariable('ERROR_TITLE', $language->get('general', 'error'));
|
|
|
|
// Get page
|
|
if (isset($_GET['p'])) {
|
|
if (!is_numeric($_GET['p'])) {
|
|
Redirect::to(URL::build('/user/messaging'));
|
|
}
|
|
|
|
if ($_GET['p'] == 1) {
|
|
// Avoid bug in pagination class
|
|
if (isset($_GET['message'])) {
|
|
Redirect::to(URL::build('/user/messaging/', 'action=view&message=' . urlencode($_GET['message'])));
|
|
} else {
|
|
Redirect::to(URL::build('/user/messaging'));
|
|
}
|
|
}
|
|
$p = $_GET['p'];
|
|
} else {
|
|
$p = 1;
|
|
}
|
|
|
|
if (!isset($_GET['action'])) {
|
|
// Get private messages
|
|
$messages = $user->listPMs($user->data()->id);
|
|
|
|
// Pagination
|
|
$paginator = new Paginator(
|
|
$template_pagination ?? null,
|
|
$template_pagination_left ?? null,
|
|
$template_pagination_right ?? null
|
|
);
|
|
$results = $paginator->getLimited($messages, 10, $p, count($messages));
|
|
$pagination = $paginator->generate(7, URL::build('/user/messaging/'));
|
|
|
|
$template->getEngine()->addVariable('PAGINATION', $pagination);
|
|
|
|
// Array to pass to template
|
|
$template_array = [];
|
|
|
|
// Display the correct number of messages
|
|
foreach ($results->data as $nValue) {
|
|
// Get participants list
|
|
$participants = '';
|
|
|
|
foreach ($nValue['users'] as $item) {
|
|
$participants .= '<a href="' . URL::build('/profile/' . urlencode($user->idToName($item))) . '">' . Output::getClean($user->idToNickname($item)) . '</a>, ';
|
|
}
|
|
$participants = rtrim($participants, ', ');
|
|
|
|
$target_user = new User($nValue['user_updated']);
|
|
$template_array[] = [
|
|
'id' => $nValue['id'],
|
|
'title' => Output::getClean($nValue['title']),
|
|
'participants' => $participants,
|
|
'link' => URL::build('/user/messaging/', 'action=view&message=' . urlencode($nValue['id'])),
|
|
'last_message_user_id' => Output::getClean($nValue['user_updated']),
|
|
'last_message_user' => $target_user->getDisplayname(),
|
|
'last_message_user_profile' => $target_user->getProfileURL(),
|
|
'last_message_user_avatar' => $target_user->getAvatar(30),
|
|
'last_message_user_style' => $target_user->getGroupStyle(),
|
|
'last_message_date' => $timeago->inWords($nValue['updated'], $language),
|
|
'last_message_date_full' => date(DATE_FORMAT, $nValue['updated'])
|
|
];
|
|
}
|
|
|
|
// Assign template variables
|
|
$template->getEngine()->addVariables([
|
|
'USER_CP' => $language->get('user', 'user_cp'),
|
|
'MESSAGING' => $language->get('user', 'messaging'),
|
|
'MESSAGES' => $template_array,
|
|
'NO_MESSAGES' => $language->get('user', 'no_messages_full'),
|
|
'MESSAGE_TITLE' => $language->get('user', 'message_title'),
|
|
'PARTICIPANTS' => $language->get('user', 'participants'),
|
|
'LAST_MESSAGE' => $language->get('user', 'last_message'),
|
|
]);
|
|
|
|
if ($user->hasPermission('usercp.messaging')) {
|
|
// Can send messages
|
|
$template->getEngine()->addVariables([
|
|
'NEW_MESSAGE' => $language->get('user', 'new_message'),
|
|
'NEW_MESSAGE_LINK' => URL::build('/user/messaging/', 'action=new')
|
|
]);
|
|
}
|
|
|
|
// Load modules + template
|
|
Module::loadPage($user, $pages, $cache, $smarty, [$navigation, $cc_nav, $staffcp_nav], $widgets, $template);
|
|
|
|
require ROOT_PATH . '/core/templates/cc_navbar.php';
|
|
|
|
$template->onPageLoad();
|
|
|
|
require ROOT_PATH . '/core/templates/navbar.php';
|
|
require ROOT_PATH . '/core/templates/footer.php';
|
|
|
|
// Display template
|
|
$template->displayTemplate('user/messaging');
|
|
|
|
} else {
|
|
if ($_GET['action'] == 'new') {
|
|
if (!$user->hasPermission('usercp.messaging')) {
|
|
Redirect::to(URL::build('/user/messaging'));
|
|
}
|
|
// New PM
|
|
if (Input::exists()) {
|
|
if (Token::check()) {
|
|
// Validate input
|
|
$validation = Validate::check($_POST, [
|
|
'title' => [
|
|
Validate::REQUIRED => true,
|
|
Validate::MIN => 2,
|
|
Validate::MAX => 64
|
|
],
|
|
'content' => [
|
|
Validate::REQUIRED => true,
|
|
Validate::MIN => 2,
|
|
Validate::MAX => 20480
|
|
],
|
|
'to' => [
|
|
Validate::REQUIRED => true
|
|
]
|
|
])->messages([
|
|
'title' => [
|
|
Validate::REQUIRED => $language->get('user', 'title_required'),
|
|
Validate::MIN => $language->get('user', 'title_min_2'),
|
|
Validate::MAX => $language->get('user', 'title_max_64')
|
|
],
|
|
'content' => [
|
|
Validate::REQUIRED => $language->get('user', 'content_required'),
|
|
Validate::MIN => $language->get('user', 'content_min_2'),
|
|
Validate::MAX => $language->get('user', 'content_max_20480')
|
|
],
|
|
'to' => $language->get('user', 'users_to_required')
|
|
]);
|
|
|
|
if ($validation->passed()) {
|
|
// Validation passed, validate recipients
|
|
$users = Input::get('to');
|
|
$users = explode(',', $users);
|
|
$n = 0;
|
|
|
|
// Replace white space at start of username, also limit to 10 users
|
|
foreach ($users as $item) {
|
|
if ($item[0] === ' ') {
|
|
$users[$n] = substr($item, 1);
|
|
$username = $users[$n];
|
|
} else {
|
|
$username = $item;
|
|
}
|
|
|
|
if ($username == $user->data()->nickname || $username == $user->data()->username) {
|
|
unset($users[$n]);
|
|
continue;
|
|
}
|
|
|
|
$user_id = $user->nameToId($item);
|
|
if ($user_id) {
|
|
if ($user->isBlocked($user_id, $user->data()->id) && !$user->canViewStaffCP()) {
|
|
$blocked = true;
|
|
unset($users[$n]);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if ($n == 10) {
|
|
$max_users = true;
|
|
break;
|
|
}
|
|
$n++;
|
|
}
|
|
|
|
if (isset($blocked)) {
|
|
$error = $language->get('user', 'one_or_more_users_blocked');
|
|
|
|
} else {
|
|
if (!count($users)) {
|
|
$error = $language->get('user', 'cant_send_to_self');
|
|
|
|
} else {
|
|
// Ensure people haven't been added twice
|
|
$users = array_unique($users);
|
|
|
|
if (!isset($max_users)) {
|
|
|
|
// Input the content
|
|
DB::getInstance()->insert(
|
|
'private_messages',
|
|
[
|
|
'author_id' => $user->data()->id,
|
|
'title' => Input::get('title'),
|
|
'created' => date('U'),
|
|
'last_reply_user' => $user->data()->id,
|
|
'last_reply_date' => date('U')
|
|
]
|
|
);
|
|
|
|
// Get the PM ID
|
|
$last_id = DB::getInstance()->lastId();
|
|
|
|
$event = new ContentCreateEvent(Input::get('content'), $user);
|
|
EventHandler::executeEvent($event);
|
|
|
|
// Insert post content into database
|
|
DB::getInstance()->insert(
|
|
'private_messages_replies',
|
|
[
|
|
'pm_id' => $last_id,
|
|
'author_id' => $user->data()->id,
|
|
'created' => date('U'),
|
|
'content' => $event->content
|
|
]
|
|
);
|
|
|
|
// Add users to conversation
|
|
foreach ($users as $item) {
|
|
// Get ID
|
|
$user_id = $user->nameToId($item);
|
|
|
|
if ($user_id) {
|
|
// Not the author
|
|
DB::getInstance()->insert(
|
|
'private_messages_users',
|
|
[
|
|
'pm_id' => $last_id,
|
|
'user_id' => $user_id
|
|
]
|
|
);
|
|
}
|
|
}
|
|
|
|
// Add the author to the list of users
|
|
DB::getInstance()->insert('private_messages_users', [
|
|
'pm_id' => $last_id,
|
|
'user_id' => $user->data()->id,
|
|
'read' => true,
|
|
]);
|
|
|
|
// Sent successfully
|
|
Session::flash('user_messaging_success', $language->get('user', 'message_sent_successfully'));
|
|
Redirect::to(URL::build('/user/messaging'));
|
|
}
|
|
|
|
// Over 10 users added
|
|
$error = $language->get('user', 'max_pm_10_users');
|
|
}
|
|
}
|
|
} else {
|
|
// Errors
|
|
$errors = $validation->errors();
|
|
|
|
$error = implode('<br />', $errors);
|
|
}
|
|
|
|
} else {
|
|
// Invalid token
|
|
$error = $language->get('general', 'invalid_token');
|
|
}
|
|
}
|
|
|
|
if (isset($error)) {
|
|
$template->getEngine()->addVariable('ERROR', $error);
|
|
}
|
|
|
|
if (isset($_GET['uid'])) {
|
|
// Messaging a specific user
|
|
$user_messaging = DB::getInstance()->get('users', ['id', $_GET['uid']]);
|
|
|
|
if ($user_messaging->count()) {
|
|
$template->getEngine()->addVariable('TO_USER', Output::getClean($user_messaging->first()->username));
|
|
}
|
|
}
|
|
|
|
$content = null;
|
|
if (isset($_POST['content'])) {
|
|
$render_event = new RenderContentEditEvent($_POST['content']);
|
|
EventHandler::executeEvent($render_event);
|
|
$content = $render_event->content;
|
|
}
|
|
|
|
// Assign template variables
|
|
$template->getEngine()->addVariables([
|
|
'NEW_MESSAGE' => $language->get('user', 'new_message'),
|
|
'CANCEL' => $language->get('general', 'cancel'),
|
|
'CONFIRM_CANCEL' => $language->get('general', 'confirm_cancel'),
|
|
'CANCEL_LINK' => URL::build('/user/messaging'),
|
|
'SUBMIT' => $language->get('general', 'submit'),
|
|
'TOKEN' => Token::get(),
|
|
'MESSAGE_TITLE' => $language->get('user', 'message_title'),
|
|
'MESSAGE_TITLE_VALUE' => (isset($_POST['title']) ? Output::getPurified($_POST['title']) : ''),
|
|
'TO' => $language->get('user', 'to'),
|
|
'SEPARATE_USERS_WITH_COMMAS' => $language->get('user', 'separate_users_with_commas'),
|
|
'ALL_USERS' => $user->listAllOtherUsers()
|
|
]);
|
|
|
|
$template->assets()->include([
|
|
AssetTree::TINYMCE,
|
|
]);
|
|
|
|
$template->addJSScript(Input::createTinyEditor($language, 'reply', $content));
|
|
|
|
// Load modules + template
|
|
Module::loadPage($user, $pages, $cache, $smarty, [$navigation, $cc_nav, $staffcp_nav], $widgets, $template);
|
|
|
|
require ROOT_PATH . '/core/templates/cc_navbar.php';
|
|
|
|
$template->onPageLoad();
|
|
|
|
require ROOT_PATH . '/core/templates/navbar.php';
|
|
require ROOT_PATH . '/core/templates/footer.php';
|
|
|
|
// Display template
|
|
$template->displayTemplate('user/new_message');
|
|
|
|
} else if ($_GET['action'] == 'view') {
|
|
// Ensure message is specified
|
|
if (!isset($_GET['message']) || !is_numeric($_GET['message'])) {
|
|
Redirect::to(URL::build('/user/messaging'));
|
|
}
|
|
|
|
// Ensure message exists
|
|
$pm = $user->getPM($_GET['message'], $user->data()->id); // Get the PM - this also handles setting it as "read"
|
|
|
|
if (!$pm) { // Either PM doesn't exist, or the user doesn't have permission to view it
|
|
Redirect::to(URL::build('/user/messaging'));
|
|
}
|
|
|
|
// Deal with input
|
|
if (Input::exists()) {
|
|
// Check token
|
|
if (Token::check()) {
|
|
// Valid token
|
|
// Validate input
|
|
$validation = Validate::check($_POST, [
|
|
'content' => [
|
|
Validate::REQUIRED => true,
|
|
Validate::MIN => 2,
|
|
Validate::MAX => 20480
|
|
]
|
|
])->messages([
|
|
'content' => [
|
|
Validate::REQUIRED => $language->get('user', 'content_required'),
|
|
Validate::MIN => $language->get('user', 'content_min_2'),
|
|
Validate::MAX => $language->get('user', 'content_max_20480')
|
|
]
|
|
]);
|
|
|
|
if ($validation->passed()) {
|
|
$event = new ContentCreateEvent(Input::get('content'), $user);
|
|
EventHandler::executeEvent($event);
|
|
|
|
// Insert post content into database
|
|
DB::getInstance()->insert(
|
|
'private_messages_replies',
|
|
[
|
|
'pm_id' => $pm[0]->id,
|
|
'author_id' => $user->data()->id,
|
|
'created' => date('U'),
|
|
'content' => $event->content
|
|
]
|
|
);
|
|
|
|
// Update last reply PM information
|
|
DB::getInstance()->update(
|
|
'private_messages',
|
|
$pm[0]->id,
|
|
[
|
|
'last_reply_user' => $user->data()->id,
|
|
'last_reply_date' => date('U')
|
|
]
|
|
);
|
|
|
|
// Update PM as unread for all users
|
|
$users = DB::getInstance()->get('private_messages_users', ['pm_id', $pm[0]->id])->results();
|
|
|
|
foreach ($users as $item) {
|
|
if ($item->user_id != $user->data()->id) {
|
|
DB::getInstance()->update('private_messages_users', $item->id, [
|
|
'read' => false
|
|
]);
|
|
}
|
|
}
|
|
|
|
// Display success message
|
|
$template->getEngine()->addVariable('MESSAGE_SENT', $language->get('user', 'message_sent_successfully'));
|
|
unset($_POST['content']);
|
|
|
|
} else {
|
|
// Errors
|
|
$errors = $validation->errors();
|
|
$error = implode('<br />', $errors);
|
|
}
|
|
|
|
} else {
|
|
// Invalid token
|
|
$error = $language->get('general', 'invalid_token');
|
|
}
|
|
}
|
|
|
|
if (isset($error)) {
|
|
$template->getEngine()->addVariable('ERROR', $error);
|
|
}
|
|
|
|
// Get all PM replies
|
|
$pm_replies = DB::getInstance()->get('private_messages_replies', ['pm_id', $_GET['message']])->results();
|
|
|
|
// Pagination
|
|
$paginator = new Paginator(
|
|
$template_pagination ?? null,
|
|
$template_pagination_left ?? null,
|
|
$template_pagination_right ?? null
|
|
);
|
|
$results = $paginator->getLimited($pm_replies, 10, $p, count($pm_replies));
|
|
$pagination = $paginator->generate(7, URL::build('/user/messaging/', 'action=view&message=' . urlencode($pm[0]->id) . '&'));
|
|
|
|
$template->getEngine()->addVariable('PAGINATION', $pagination);
|
|
|
|
// Array to pass to template
|
|
$template_array = [];
|
|
|
|
// Display the correct number of messages
|
|
foreach ($results->data as $nValue) {
|
|
$target_user = new User($nValue->author_id);
|
|
|
|
$render_event = new RenderContentEvent($nValue->content);
|
|
EventHandler::executeEvent($render_event);
|
|
|
|
$template_array[] = [
|
|
'id' => $nValue->id,
|
|
'author_id' => $nValue->author_id,
|
|
'author_username' => $target_user->getDisplayname(),
|
|
'author_profile' => $target_user->getProfileURL(),
|
|
'author_avatar' => $target_user->getAvatar(100),
|
|
'author_style' => $target_user->getGroupStyle(),
|
|
'author_groups' => $target_user->getAllGroupHtml(),
|
|
'message_date' => $timeago->inWords($nValue->created, $language),
|
|
'message_date_full' => date(DATE_FORMAT, $nValue->created),
|
|
'content' => $render_event->content,
|
|
];
|
|
}
|
|
|
|
// Get participants list
|
|
$participants = '';
|
|
|
|
foreach ($pm[1] as $item) {
|
|
$participants .= '<a href="' . URL::build('/profile/' . urlencode($user->idToName($item))) . '">' . Output::getClean($user->idToNickname($item)) . '</a>, ';
|
|
}
|
|
$participants = rtrim($participants, ', ');
|
|
|
|
// Template variables
|
|
$template->getEngine()->addVariables([
|
|
'MESSAGE_TITLE' => Output::getClean($pm[0]->title),
|
|
'BACK' => $language->get('general', 'back'),
|
|
'BACK_LINK' => URL::build('/user/messaging'),
|
|
'LEAVE_CONVERSATION' => $language->get('user', 'leave_conversation'),
|
|
'CONFIRM_LEAVE' => $language->get('user', 'confirm_leave'),
|
|
'LEAVE_CONVERSATION_LINK' => URL::build('/user/messaging/', 'action=leave&message=' . urlencode($pm[0]->id)),
|
|
'PAGINATION' => $pagination,
|
|
'PARTICIPANTS_TEXT' => $language->get('user', 'participants'),
|
|
'PARTICIPANTS' => $participants,
|
|
'MESSAGES' => $template_array,
|
|
'NEW_REPLY' => $language->get('user', 'new_reply'),
|
|
'TOKEN' => Token::get(),
|
|
'SUBMIT' => $language->get('general', 'submit'),
|
|
'SUCCESS_TITLE' => $language->get('general', 'success'),
|
|
'YES' => $language->get('general', 'yes'),
|
|
'NO' => $language->get('general', 'no'),
|
|
]);
|
|
|
|
$content = null;
|
|
if (isset($_POST['content'])) {
|
|
$render_event = new RenderContentEditEvent($_POST['content']);
|
|
EventHandler::executeEvent($render_event);
|
|
$content = $render_event->content;
|
|
}
|
|
|
|
$template->assets()->include([
|
|
AssetTree::TINYMCE,
|
|
]);
|
|
|
|
$template->addJSScript(Input::createTinyEditor($language, 'reply', $content));
|
|
|
|
Module::loadPage($user, $pages, $cache, $smarty, [$navigation, $cc_nav, $staffcp_nav], $widgets, $template);
|
|
|
|
require ROOT_PATH . '/core/templates/cc_navbar.php';
|
|
|
|
$template->onPageLoad();
|
|
|
|
require ROOT_PATH . '/core/templates/navbar.php';
|
|
require ROOT_PATH . '/core/templates/footer.php';
|
|
|
|
// Display template
|
|
$template->displayTemplate('user/view_message');
|
|
|
|
} else if ($_GET['action'] == 'leave') {
|
|
// Try to remove the user from the conversation
|
|
if (!isset($_GET['message']) || !is_numeric($_GET['message']) || !Token::check($_POST['token'])) {
|
|
Redirect::to(URL::build('/user/messaging'));
|
|
}
|
|
|
|
$message = DB::getInstance()->get('private_messages_users', ['pm_id', $_GET['message']])->results();
|
|
|
|
if (count($message)) {
|
|
foreach ($message as $item) {
|
|
if ($item->user_id == $user->data()->id) {
|
|
DB::getInstance()->delete('private_messages_users', ['id', $item->id]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Done, redirect
|
|
Redirect::to(URL::build('/user/messaging'));
|
|
}
|
|
}
|