<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[BuddyPress][13383] trunk/src/bp-messages: Improve consistency between private message status & notification</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="http://buddypress.trac.wordpress.org/changeset/13383">13383</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"http://buddypress.trac.wordpress.org/changeset/13383","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>imath</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2022-12-14 21:42:06 +0000 (Wed, 14 Dec 2022)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Improve consistency between private message status & notification

A private message can have a status set to read or unread by the user. When the Notifications component is active, a notification is generated each time a message is sent. When the user opens this message, 2 actions are performed:

1. Set the message status as read.
2. Mark the notification about this message as read.

When opening a message, even if the message has a read status, we still need to check if there's an existing notification about it as notifications can be marked unread from the user's notifications screen. If it's the case, then we need to make sure to mark this unread notification as read {U+01F92A}.

Props niftythree

Closes https://github.com/buddypress/buddypress/pull/43
See <a href="http://buddypress.trac.wordpress.org/ticket/8778">#8778</a> (trunk)</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcbpmessagesactionsviewphp">trunk/src/bp-messages/actions/view.php</a></li>
<li><a href="#trunksrcbpmessagesbpmessagesnotificationsphp">trunk/src/bp-messages/bp-messages-notifications.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcbpmessagesactionsviewphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/bp-messages/actions/view.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/bp-messages/actions/view.php    2022-12-13 21:44:28 UTC (rev 13382)
+++ trunk/src/bp-messages/actions/view.php      2022-12-14 21:42:06 UTC (rev 13383)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -53,6 +53,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * If an admin visits a thread, it shouldn't change the read status.
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        if ( bp_is_my_profile() ) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                // This is marking the messages as read inside the BP Messages component's recipient table.
</ins><span class="cx" style="display: block; padding: 0 10px">                 messages_mark_thread_read( $thread_id );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span></span></pre></div>
<a id="trunksrcbpmessagesbpmessagesnotificationsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/bp-messages/bp-messages-notifications.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/bp-messages/bp-messages-notifications.php       2022-12-13 21:44:28 UTC (rev 13382)
+++ trunk/src/bp-messages/bp-messages-notifications.php 2022-12-14 21:42:06 UTC (rev 13383)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -261,16 +261,48 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * @param int $thread_id ID of the thread being marked as read.
</span><span class="cx" style="display: block; padding: 0 10px">  * @param int $user_id   ID of the user who read the thread.
</span><span class="cx" style="display: block; padding: 0 10px">  * @param int $num_rows  The number of affected rows by the "mark read" update query.
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @return bool True on success. False otherwise.
</ins><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> function bp_messages_mark_notification_on_mark_thread( $thread_id, $user_id = 0, $num_rows = 0 ) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        $unread_messages = array();
+
</ins><span class="cx" style="display: block; padding: 0 10px">         if ( ! $num_rows ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                return;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         /**
+                * The thread might have been marked read, but a notification about the thread might also have been
+                * marked back as unread from the BP Notifications screen. We then need to check a notification exists
+                * about `new_message` action before checking found message ids are part of the thread.
+                *
+                * @see https://buddypress.trac.wordpress.org/ticket/8778
+                */
+               $notifications = bp_notifications_get_all_notifications_for_user( $user_id );
+               if ( $notifications ) {
+                       $unread_messages = wp_filter_object_list(
+                               $notifications,
+                               array(
+                                       'component_action' => 'new_message',
+                                       'is_new'           => 1,
+                               ),
+                               'and',
+                               'item_id'
+                       );
+
+                       $num_rows = count( $unread_messages );
+                       if ( $num_rows ) {
+                               $unread_messages = array_map( 'intval', $unread_messages );
+                       } else {
+                               return false;
+                       }
+               }
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        $thread_messages = BP_Messages_Thread::get_messages( $thread_id );
</span><span class="cx" style="display: block; padding: 0 10px">        $message_ids     = wp_list_pluck( $thread_messages, 'id' );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        bp_notifications_mark_notifications_by_item_ids( $user_id, $message_ids, 'messages', 'new_message', false );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( $unread_messages && ! array_intersect( $message_ids, $unread_messages ) ) {
+               return false;
+       }
+
+       return bp_notifications_mark_notifications_by_item_ids( $user_id, $message_ids, 'messages', 'new_message', false );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'messages_thread_mark_as_read', 'bp_messages_mark_notification_on_mark_thread', 10, 3 );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span></span></pre>
</div>
</div>

</body>
</html>