• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

Not a bug Empty PM after moving from 1.5.15a to 2.0 beta 7

Affected version
beta 7

Andy.N

Well-known member
#1
I did a test upgrade of the site and notice there are multiple PM in the inbox that has no title and dated 1969. I wonder if these are the conversations that I left but shown up now?

Screen Shot 2017-10-23 at 3.40.52 PM.png
 

Andy.N

Well-known member
#2
Clicking on each of those conversations will yield the following error in ACP admin log
Code:
Server error log
* ErrorException: [E_NOTICE] Trying to get property of non-object
* src/XF/Pub/Controller/Conversation.php:164

Stack trace
#0 src/XF/Pub/Controller/Conversation.php(164): XF::handlePhpError(8, '[E_NOTICE] Tryi...', '/home/nginx/dom...', 164, Array)
#1 src/XF/Mvc/Dispatcher.php(249): XF\Pub\Controller\Conversation->actionView(Object(XF\Mvc\ParameterBag))
#2 src/XF/Mvc/Dispatcher.php(88): XF\Mvc\Dispatcher->dispatchClass('XF\\Pub\\Controll...', 'View', 'html', Object(XF\Mvc\ParameterBag), 'conversations', Object(XF\Pub\Controller\Conversation), Object(XF\Mvc\Reply\Reroute))
#3 src/XF/Mvc/Dispatcher.php(41): XF\Mvc\Dispatcher->dispatchLoop(Object(XF\Mvc\RouteMatch))
#4 src/XF/App.php(1844): XF\Mvc\Dispatcher->run()
#5 src/XF.php(328): XF\App->run()
#6 index.php(13): XF::runApp('XF\\Pub\\App')
#7 {main}Request state
array(4) {
  ["url"] => string(21) "/conversations/23505/"
  ["referrer"] => string(39) "https://www.site.com/conversations/"
  ["_GET"] => array(1) {
    ["q"] => string(21) "/conversations/23505/"
  }
  ["_POST"] => array(0) {
  }
}
 

Chris D

XenForo developer
Staff member
#3
Can you try and track down those conversations in the pre 2.0 database (23505 is one of the IDs it seems) and let us know some details.

Specifically, the output of these queries might be useful:
SQL:
SELECT *
FROM xf_conversation_master
WHERE conversation_id = 23505

SELECT *
FROM xf_conversation_message
WHERE conversation_id = 23505

SELECT *
FROM xf_conversation_recipient
WHERE conversation_id = 23505

SELECT *
FROM xf_conversation_user
WHERE conversation_id = 23505
 

Mike

XenForo developer
Staff member
#4
I'm pretty sure XF1 used INNER JOINs here so they just wouldn't be displayed. However, this is the first I've really noticed any situation where data hasn't been synced in these tables. Notably, it'd be the master record for a conversation that's missing.

I'm tempted to not really change anything here. There are situations where we can be much more efficient depending on the type of join in use when doing things like counts, but it would be useful to know how this situation managed to come about.
 

Chris D

XenForo developer
Staff member
#6
This is what we sort of expected.

Interesting to note that the recipient_state there suggests that the conversations haven't been "left" but instead user ID 2 (is that you?) and the other recipient are still "active".

As Mike says, these have probably existed for a while, but our code in XF1 would have hidden them. (Actually, to be more accurate, XF1 found conversations by the master record whereas in XF2 we find them by the user record).

The key thing to figure out is how they came to be. Do those dates correspond to a time before you were on XF? Or do you have any add-ons which have anything to do with conversations (particularly anything that might allow you to delete conversations). Or could you have ever manually removed entries from the conversation tables?

EDIT: Timestamp of the "last_message_date" is "Tuesday, 5 January 2016 05:14:13"
 

Andy.N

Well-known member
#7
I checked with a dozen or so different conversation id and the first query always return 0. So it looks like the master records are not there.
 

Andy.N

Well-known member
#8
The conversations were after we started using XF. User ID 2 is me. I believe I left those messages, some of with option to receive future messages, some of them not.
I don't recall removing them from the table. And I don't have any addon that conversation related.
 

Chris D

XenForo developer
Staff member
#9
These conversations haven't been "left" in the conventional way though.

If you leave a conversation the xf_conversation_recipient table has the recipient_state updated to either deleted or delete_ignore.

The recipient state in both cases is still active.

In addition to this, when you leave a conversation, you are removed from the xf_conversation_user table. That record still exists.

The only circumstance where we physically delete the master record (which would remove the messages) would be if there are no active recipients. (everyone has left the conversation). Clearly, however, these conversations do have recipients so we wouldn't have deleted them.

With that in mind, I'm still fairly convinced that something outside of the core software has removed these records.
 

Andy.N

Well-known member
#10
These conversations haven't been "left" in the conventional way though.

If you leave a conversation the xf_conversation_recipient table has the recipient_state updated to either deleted or delete_ignore.

The recipient state in both cases is still active.

In addition to this, when you leave a conversation, you are removed from the xf_conversation_user table. That record still exists.

The only circumstance where we physically delete the master record (which would remove the messages) would be if there are no active recipients. (everyone has left the conversation). Clearly, however, these conversations do have recipients so we wouldn't have deleted them.

With that in mind, I'm still fairly convinced that something outside of the core software has removed these records.
Makes sense, Chris.
Can we run a query to show all conversations that are in similar limbo status and which users are affected? Then we can narrow it down to isolated cases (manual deletion) or widespread (addon caused it) and find a way to deal with it.
 

Chris D

XenForo developer
Staff member
#11
Something like this might help:
SQL:
SELECT DISTINCT(u.conversation_id)
FROM xf_conversation_user AS u
LEFT JOIN xf_conversation_master AS m ON
    (u.conversation_id = m.conversation_id)
WHERE m.conversation_id IS NULL
 

Andy.N

Well-known member
#13
On the bright side, 831 of those are from my account
SQL:
SELECT DISTINCT(u.conversation_id), u.owner_user_id
FROM xf_conversation_user AS u
LEFT JOIN xf_conversation_master AS m ON
    (u.conversation_id = m.conversation_id)
WHERE m.conversation_id IS NULL and u.owner_user_id =2
 

Mike

XenForo developer
Staff member
#14
It's worth noting that I just ran that query here and it didn't give any results, so I'm not sure if it's part of normal XF execution (though I can't be 100% sure of that).

Have you ever done any manual database manipulation or a partial data restore?
 

Andy.N

Well-known member
#15
Have you ever done any manual database manipulation or a partial data restore?
I won't rule it out. We ran out site from 2007, converted to XF in XF early days, have done restoration, etc. I can't even rule out that I delete those messages myself from DB. I don't remember an can't tell why.
So if it's not XF 2 bugs, is it a good idea to remove those records completely?
 

Mike

XenForo developer
Staff member
#16
Any conversation that doesn't have a master record shouldn't have any records in xf_conversation_user, xf_conversation_recipient or xf_conversation_message.

We could probably prevent the error if this happens, but overall, I don't think we're going to hide these records.
 

Chris D

XenForo developer
Staff member
#17
So if it's not XF 2 bugs, is it a good idea to remove those records completely?
Yeah basically.

The following queries should help you do this though I must stress they haven't been tested properly. Please take a database backup first, and be prepared to restore from that backup in case anything unexpected happens:
SQL:
DELETE FROM xf_conversation_user
WHERE conversation_id IN
(
    SELECT * FROM
    (
        SELECT DISTINCT(u.conversation_id)
        FROM xf_conversation_user AS u
        LEFT JOIN xf_conversation_master AS m ON
            (u.conversation_id = m.conversation_id)
        WHERE m.conversation_id IS NULL
    ) AS na
);

DELETE FROM xf_conversation_recipient
WHERE conversation_id IN
(
    SELECT * FROM
    (
        SELECT DISTINCT(r.conversation_id)
        FROM xf_conversation_recipient AS r
        LEFT JOIN xf_conversation_master AS m ON
            (r.conversation_id = m.conversation_id)
        WHERE m.conversation_id IS NULL
    ) AS na
);
You have an idea of how many missing master records there are so the "rows affected" for each query should be <that number> * <number of recipients>.