By making it more like other forum PMs systems like proboards's/XenForo's PM system?
It would make sense to describe how you want it to function. "Like something else" is not really a useful description. :)
Not really, no, though I suspect if you found the configuration for conversation mode you might find it's at least part way there.
Getting towards something like XF's conversations (functionally: collections of messages with participants attached to the whole collection, rather than to each individual message) is quite the undertaking inside SMF.
SMF Packs does a conversations mod that works well in 2.0 but not 2.1.
I can't get it to work in 2.1
Quote from: Mike66 on February 25, 2022, 06:20:20 AMSMF Packs does a conversations mod that works well in 2.0 but not 2.1.
I can't get it to work in 2.1
Just to clarify this, I haven't managed to install the mod in 2.1, the SMF Packs Personal Conversations mod wants to install by emulating 2.0.
When I tried that I got Test Failed for Execute Modification in Sources/Subs-Post.php
Which says: (code) (find) (select):
// Send off a personal message.
function sendpm($recipients, $subject, $message, $store_outbox = false, $from = null, $pm_head = 0)
And: (code) (replace) (select) (expand):
// Send off a personal conversation.
function sendpm($recipients, $subject, $message, $options = false, $from = null, $pm_head = 0)
{
global $scripturl, $txt, $user_info, $language;
global $modSettings, $smcFunc, $context;
// Check this one!
if (!is_array($options))
$options = array(
'is_starred' => 0
);
// Make sure the PM language file is loaded, we might need something out of it.
loadLanguage('PersonalMessage');
$onBehalf = $from !== null;
// Initialize log array.
$log = array(
'failed' => array(),
'sent' => array()
);
if ($from === null)
$from = array(
'id' => $user_info['id'],
'name' => $user_info['name'],
'username' => $user_info['username']
);
// Probably not needed. /me something should be of the typer.
else
$user_info['name'] = $from['name'];
// This is the one that will go in their inbox.
$htmlmessage = $smcFunc['htmlspecialchars']($message, ENT_QUOTES);
$htmlsubject = $smcFunc['htmlspecialchars']($subject);
preparsecode($htmlmessage);
// Integrated PMs
call_integration_hook('integrate_personal_message', array($recipients, $from['username'], $subject, $message));
// Get a list of usernames and convert them to IDs.
$usernames = array();
foreach ($recipients as $rec_type => $rec)
{
foreach ($rec as $id => $member)
{
if (!is_numeric($recipients[$rec_type][$id]) && ($from['id'] != $user_info['id'] || $id != $user_info['id']))
{
$recipients[$rec_type][$id] = $smcFunc['strtolower'](trim(preg_replace('/[<>&"\'=\\\]/', '', $recipients[$rec_type][$id])));
$usernames[$recipients[$rec_type][$id]] = 0;
}
}
}
if (!empty($usernames))
{
$request = $smcFunc['db_query']('pm_find_username', '
SELECT id_member, member_name
FROM {db_prefix}members
WHERE ' . ($smcFunc['db_case_sensitive'] ? 'LOWER(member_name)' : 'member_name') . ' IN ({array_string:usernames})',
array(
'usernames' => array_keys($usernames),
)
);
while ($row = $smcFunc['db_fetch_assoc']($request))
if (isset($usernames[$smcFunc['strtolower']($row['member_name'])]))
$usernames[$smcFunc['strtolower']($row['member_name'])] = $row['id_member'];
$smcFunc['db_free_result']($request);
// Replace the usernames with IDs. Drop usernames that couldn't be found.
foreach ($recipients as $rec_type => $rec)
foreach ($rec as $id => $member)
{
if (is_numeric($recipients[$rec_type][$id]))
continue;
if (!empty($usernames[$member]))
$recipients[$rec_type][$id] = $usernames[$member];
else
{
$log['failed'][$id] = sprintf($txt['pm_error_user_not_found'], $recipients[$rec_type][$id]);
unset($recipients[$rec_type][$id]);
}
}
}
// Make sure there are no duplicate 'to' members.
$recipients['bcc'] = !empty($recipients['bcc']) ? $recipients['bcc'] : array();
$recipients['to'] = array_merge($recipients['to'], $recipients['bcc']);
// Combine 'to' and 'bcc' recipients.
$all_to = array_unique($recipients['to']);
// Load the membergrounp message limits.
//!!! Consider caching this?
static $message_limit_cache = array();
if (!allowedTo('moderate_forum') && empty($message_limit_cache))
{
$request = $smcFunc['db_query']('', '
SELECT id_group, max_messages
FROM {db_prefix}membergroups',
array(
)
);
while ($row = $smcFunc['db_fetch_assoc']($request))
$message_limit_cache[$row['id_group']] = $row['max_messages'];
$smcFunc['db_free_result']($request);
}
// Load the groups that are allowed to read PMs.
$allowed_groups = array();
$disallowed_groups = array();
$request = $smcFunc['db_query']('', '
SELECT id_group, add_deny
FROM {db_prefix}permissions
WHERE permission = {string:read_permission}',
array(
'read_permission' => 'pm_read',
)
);
while ($row = $smcFunc['db_fetch_assoc']($request))
{
if (empty($row['add_deny']))
$disallowed_groups[] = $row['id_group'];
else
$allowed_groups[] = $row['id_group'];
}
$smcFunc['db_free_result']($request);
if (empty($modSettings['permission_enable_deny']))
$disallowed_groups = array();
$request = $smcFunc['db_query']('', '
SELECT
member_name, real_name, id_member, email_address, lngfile,
pm_email_notify, instant_messages,' . (allowedTo('moderate_forum') ? ' 0' : '
(pm_receive_from = {int:admins_only}' . (empty($modSettings['enable_buddylist']) ? '' : ' OR
(pm_receive_from = {int:buddies_only} AND FIND_IN_SET({string:from_id}, buddy_list) = 0) OR
(pm_receive_from = {int:not_on_ignore_list} AND FIND_IN_SET({string:from_id}, pm_ignore_list) != 0)') . ')') . ' AS ignored,
FIND_IN_SET({string:from_id}, buddy_list) != 0 AS is_buddy, is_activated,
additional_groups, id_group, id_post_group
FROM {db_prefix}members
WHERE id_member IN ({array_int:recipients})
ORDER BY lngfile
LIMIT {int:count_recipients}',
array(
'not_on_ignore_list' => 1,
'buddies_only' => 2,
'admins_only' => 3,
'recipients' => $all_to,
'count_recipients' => count($all_to),
'from_id' => $from['id'],
)
);
$notifications = array();
while ($row = $smcFunc['db_fetch_assoc']($request))
{
// We need to know this members groups.
$groups = explode(',', $row['additional_groups']);
$groups[] = $row['id_group'];
$groups[] = $row['id_post_group'];
$message_limit = -1;
// For each group see whether they've gone over their limit - assuming they're not an admin.
if (!in_array(1, $groups))
{
foreach ($groups as $id)
{
if (isset($message_limit_cache[$id]) && $message_limit != 0 && $message_limit < $message_limit_cache[$id])
$message_limit = $message_limit_cache[$id];
}
// !!! This is currently removed, maybe we can limit the number of conversations?
/*if ($message_limit > 0 && $message_limit <= $row['instant_messages'])
{
$log['failed'][$row['id_member']] = sprintf($txt['pm_error_data_limit_reached'], $row['real_name']);
unset($all_to[array_search($row['id_member'], $all_to)]);
continue;
}*/
// Do they have any of the allowed groups?
if (count(array_intersect($allowed_groups, $groups)) == 0 || count(array_intersect($disallowed_groups, $groups)) != 0)
{
$log['failed'][$row['id_member']] = sprintf($txt['pm_error_user_cannot_read'], $row['real_name']);
unset($all_to[array_search($row['id_member'], $all_to)]);
continue;
}
}
// Note that PostgreSQL can return a lowercase t/f for FIND_IN_SET
if (!empty($row['ignored']) && $row['ignored'] != 'f' && $row['id_member'] != $from['id'])
{
$log['failed'][$row['id_member']] = sprintf($txt['pm_error_ignored_by_user'], $row['real_name']);
unset($all_to[array_search($row['id_member'], $all_to)]);
continue;
}
// If the receiving account is banned (>=10) or pending deletion (4), refuse to send the PM.
if ($row['is_activated'] >= 10 || ($row['is_activated'] == 4 && !$user_info['is_admin']))
{
$log['failed'][$row['id_member']] = sprintf($txt['pm_error_user_cannot_read'], $row['real_name']);
unset($all_to[array_search($row['id_member'], $all_to)]);
continue;
}
// Send a notification, if enabled - taking the buddy list into account.
if (!empty($row['email_address']) && ($row['pm_email_notify'] == 1 || ($row['pm_email_notify'] > 1 && (!empty($modSettings['enable_buddylist']) && $row['is_buddy']))) && $row['is_activated'] == 1 && $from['id'] != $row['id_member'])
$notifications[empty($row['lngfile']) || empty($modSettings['userLanguage']) ? $language : $row['lngfile']][] = $row['email_address'];
if ($from['id'] == $user_info['id'])
$log['sent'][$row['id_member']] = sprintf(isset($txt['pm_successfully_sent']) ? $txt['pm_successfully_sent'] : '', $row['real_name']);
}
$smcFunc['db_free_result']($request);
// Save this moment!
$this_moment = time();
// Insert the message itself and then grab the last insert id.
if (empty($pm_head))
{
$smcFunc['db_insert']('',
'{db_prefix}conversations',
array(
'title' => 'string-255', 'is_locked' => 'int', 'starter_name' => 'string-64',
'start_date' => 'int', 'last_post' => 'int', 'starter' => 'int', 'allow_others' => 'int',
'last_post_by' => 'int', 'last_post_name' => 'string-64', 'last_post_date' => 'int',
'messages' => 'int', 'participants' => 'int'
),
array(
$htmlsubject, !empty($options['is_locked']) ? 1 : 0, $from['username'],
$this_moment, 0, $from['id'], !empty($options['allow_others']) ? 1 : 0,
$from['id'], $from['username'], $this_moment,
1, (count($all_to) + 1)
),
array('id_conversation')
);
$id_pm = $smcFunc['db_insert_id']('{db_prefix}conversations', 'id_conversation');
$new_conversation = true;
}
else
{
$id_pm = $pm_head;
$new_conversation = false;
// Update it
$smcFunc['db_query']('', '
UPDATE {db_prefix}conversations
SET messages = messages + 1
WHERE id_conversation = {int:conversation}
LIMIT 1',
array(
'conversation' => $id_pm,
)
);
}
// Store it
$context['id_conversation'] = $id_pm;
// Now add the message!
$smcFunc['db_insert']('',
'{db_prefix}conversations_messages',
array(
'id_conversation' => 'int', 'id_member' => 'int', 'date' => 'int',
'content' => 'string', 'real_name' => 'string-64'
),
array(
$id_pm, $from['id'], $this_moment,
$message, $from['username']
),
array('id_message')
);
$context['new_conversations_msg'] = $smcFunc['db_insert_id']('{db_prefix}conversations_messages', 'id_message');
// Add the recipients.
if ($new_conversation)
{
$insertRows = array(
array($from['id'], $this_moment, !empty($options['is_starred']) ? 1 : 0, $id_pm, 0, 1, time())
);
foreach ($all_to as $to)
{
// Skip ourselves!
if ($to != $from['id'])
$insertRows[] = array($to, $this_moment, 0, $id_pm, 1, 1, 0);
}
$smcFunc['db_insert']('insert',
'{db_prefix}conversations_participants',
array(
'id_member' => 'int', 'join_date' => 'int', 'starred' => 'int', 'id_conversation' => 'int',
'is_unread' => 'int', 'is_participant' => 'int', 'last_view' => 'int',
),
$insertRows,
array('id_pm', 'id_member')
);
}
// Should we do something?
else
{
// Starred?
if (isset($options['is_starred']))
{
$smcFunc['db_query']('', '
UPDATE {db_prefix}conversations_participants
SET starred = {int:starred}
WHERE id_conversation = {int:conversation}
AND id_member = {int:member}
LIMIT 1',
array(
'conversation' => $id_pm,
'member' => $from['id'],
'starred' => !empty($options['is_starred']) ? 1 : 0,
)
);
}
// Update it!
$smcFunc['db_query']('', '
UPDATE {db_prefix}conversations
SET last_post_by = {int:member}, last_post_date = {int:date}, last_post_name = {string:name}' . (isset($options['is_locked']) ? ', is_locked = {int:is_locked}' : '') . (isset($options['allow_others']) ? ', allow_others = {int:allow_others}' : '') . '
WHERE id_conversation = {int:conversation}
LIMIT 1',
array(
'name' => $from['username'],
'conversation' => $id_pm,
'date' => $this_moment,
'member' => $from['id'],
'is_locked' => !empty($options['is_locked']) ? 1 : 0,
'allow_others' => !empty($options['allow_others']) ? 1 : 0,
)
);
}
// Notify using the alerts system
if (function_exists('not_log_pm'))
not_log_pm(array_keys($log['sent']), $from['name'], $subject, $message, $id_pm);
censorText($message);
censorText($subject);
$message = trim(un_htmlspecialchars(strip_tags(strtr(parse_bbc(htmlspecialchars($message), false), array('<br />' => "\n", '</div>' => "\n", '</li>' => "\n", '[' => '[', ']' => ']')))));
foreach ($notifications as $lang => $notification_list)
{
// Make sure to use the right language.
loadLanguage('index+PersonalMessage', $lang, false);
loadLanguage('Conversations', $lang, false);
// Replace the right things in the message strings.
$mailsubject = str_replace(array('SUBJECT', 'SENDER'), array($subject, un_htmlspecialchars($from['name'])), $new_conversation ? $txt['new_pm_subject'] : $txt['new_reply_pm_subject']);
$mailmessage = str_replace(array('SUBJECT', 'MESSAGE', 'SENDER'), array($subject, $message, un_htmlspecialchars($from['name'])), $txt['pm_email']);
// Unlocked?
if (empty($options['is_locked']))
$mailmessage .= "\n\n" . $txt['instant_reply'] . ' ' . $scripturl . '?action=pm;sa=send;c=' . $id_pm;
// Off the notification email goes!
sendmail($notification_list, $mailsubject, $mailmessage, null, 'p' . $id_pm, false, 2, null, true);
}
// Load default languages
loadLanguage('index+PersonalMessage');
// Add one to their unread and read message counts.
foreach ($all_to as $k => $id)
if ($id == $from['id'] && $from['id'] == $user_info['id'])
unset($all_to[$k]);
// If it's new then mark it as unread
if ($new_conversation && !empty($all_to))
updateMemberData($all_to, array('instant_messages' => '+', 'unread_messages' => '+', 'new_pm' => 1));
// If it's not just mark it as unread for those who already saw everything else!
else if (!empty($all_to))
{
// Time to check if this is actually new
$dbquery = $smcFunc['db_query']('', '
SELECT is_unread, id_member
FROM {db_prefix}conversations_participants
WHERE id_conversation = {int:conversation}
AND id_member IN ({array_int:members})',
array(
'members' => $all_to,
'conversation' => $id_pm
)
);
$notify = array();
while ($row = $smcFunc['db_fetch_assoc']($dbquery))
{
if (empty($row['is_unread']))
$notify[] = $row['id_member'];
}
$smcFunc['db_free_result']($dbquery);
// Notify them!
if (!empty($notify))
updateMemberData($notify, array('instant_messages' => '+', 'unread_messages' => '+', 'new_pm' => 1));
}
// Last but not least! Mark this as unread for every participant!
if (!$new_conversation)
{
$smcFunc['db_query']('', '
UPDATE {db_prefix}conversations_participants
SET is_unread = 1
WHERE id_conversation = {int:conversation}
AND id_member != {int:member}',
array(
'member' => $user_info['id'],
'conversation' => $id_pm
)
);
}
return $log;
}
// Send off a personal message.
function sendpmlegacy($recipients, $subject, $message, $store_outbox = false, $from = null, $pm_head = 0)
But when I open Sources/Subs-Post.php I can't find that code to replace it.
Please discuss mod specific issues in rhe thread dedicated to supporting that mod
Valid point - sorry Kindred.
Feel free to move or delete my post.