Commit | Line | Data |
---|---|---|
336dfb29 | 1 | <?php |
fea86294 | 2 | |
336dfb29 | 3 | namespace wcf\system\worker; |
fea86294 | 4 | |
336dfb29 | 5 | use wcf\data\conversation\Conversation; |
cb666ba9 | 6 | use wcf\data\conversation\ConversationAction; |
336dfb29 | 7 | use wcf\data\conversation\ConversationEditor; |
cb666ba9 | 8 | use wcf\data\conversation\ConversationList; |
336dfb29 MW |
9 | use wcf\system\WCF; |
10 | ||
11 | /** | |
12 | * Worker implementation for updating conversations. | |
fea86294 TD |
13 | * |
14 | * @author Marcel Werk | |
15 | * @copyright 2001-2019 WoltLab GmbH | |
16 | * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php> | |
fea86294 TD |
17 | * |
18 | * @method ConversationList getObjectList() | |
336dfb29 | 19 | */ |
fea86294 TD |
20 | class ConversationRebuildDataWorker extends AbstractRebuildDataWorker |
21 | { | |
22 | /** | |
23 | * @inheritDoc | |
24 | */ | |
25 | protected $limit = 100; | |
26 | ||
fea86294 TD |
27 | /** |
28 | * @inheritDoc | |
29 | */ | |
30 | public function countObjects() | |
31 | { | |
32 | if ($this->count === null) { | |
33 | $this->count = 0; | |
8fbd8b01 | 34 | $sql = "SELECT MAX(conversationID) AS conversationID |
bfb64f81 TD |
35 | FROM wcf1_conversation"; |
36 | $statement = WCF::getDB()->prepare($sql); | |
fea86294 TD |
37 | $statement->execute(); |
38 | $row = $statement->fetchArray(); | |
39 | if ($row !== false) { | |
40 | $this->count = $row['conversationID']; | |
41 | } | |
42 | } | |
43 | } | |
44 | ||
fea86294 TD |
45 | /** |
46 | * @inheritDoc | |
47 | */ | |
48 | protected function initObjectList() | |
49 | { | |
50 | $this->objectList = new ConversationList(); | |
51 | $this->objectList->sqlOrderBy = 'conversation.conversationID'; | |
52 | } | |
53 | ||
54 | /** | |
55 | * @inheritDoc | |
56 | */ | |
57 | public function execute() | |
58 | { | |
59 | $this->objectList->getConditionBuilder()->add( | |
60 | 'conversation.conversationID BETWEEN ? AND ?', | |
61 | [$this->limit * $this->loopCount + 1, $this->limit * $this->loopCount + $this->limit] | |
62 | ); | |
63 | ||
64 | parent::execute(); | |
65 | ||
66 | // prepare statements | |
8fbd8b01 | 67 | $sql = "SELECT messageID, time, userID, username |
bfb64f81 | 68 | FROM wcf1_conversation_message |
8fbd8b01 MS |
69 | WHERE conversationID = ? |
70 | ORDER BY time"; | |
bfb64f81 | 71 | $firstMessageStatement = WCF::getDB()->prepare($sql, 1); |
8fbd8b01 | 72 | $sql = "SELECT time, userID, username |
bfb64f81 | 73 | FROM wcf1_conversation_message |
8fbd8b01 MS |
74 | WHERE conversationID = ? |
75 | ORDER BY time DESC"; | |
bfb64f81 | 76 | $lastMessageStatement = WCF::getDB()->prepare($sql, 1); |
8fbd8b01 MS |
77 | $sql = "SELECT COUNT(*) AS messages, |
78 | SUM(attachments) AS attachments | |
bfb64f81 | 79 | FROM wcf1_conversation_message |
8fbd8b01 | 80 | WHERE conversationID = ?"; |
bfb64f81 | 81 | $statsStatement = WCF::getDB()->prepare($sql); |
8fbd8b01 | 82 | $sql = "SELECT COUNT(*) AS participants |
bfb64f81 | 83 | FROM wcf1_conversation_to_user conversation_to_user |
8fbd8b01 MS |
84 | WHERE conversation_to_user.conversationID = ? |
85 | AND conversation_to_user.hideConversation <> ? | |
86 | AND conversation_to_user.participantID <> ? | |
87 | AND conversation_to_user.isInvisible = ?"; | |
bfb64f81 | 88 | $participantCounterStatement = WCF::getDB()->prepare($sql); |
8fbd8b01 | 89 | $sql = "SELECT conversation_to_user.participantID AS userID, conversation_to_user.hideConversation, user_table.username |
bfb64f81 TD |
90 | FROM wcf1_conversation_to_user conversation_to_user |
91 | LEFT JOIN wcf1_user user_table | |
6124508f | 92 | ON user_table.userID = conversation_to_user.participantID |
8fbd8b01 MS |
93 | WHERE conversation_to_user.conversationID = ? |
94 | AND conversation_to_user.participantID <> ? | |
95 | AND conversation_to_user.isInvisible = ? | |
96 | ORDER BY user_table.username"; | |
bfb64f81 | 97 | $participantStatement = WCF::getDB()->prepare($sql, 5); |
fea86294 | 98 | |
8fbd8b01 | 99 | $sql = "SELECT COUNT(*) AS participants |
bfb64f81 | 100 | FROM wcf1_conversation_to_user |
8fbd8b01 MS |
101 | WHERE conversationID = ? |
102 | AND hideConversation <> ? | |
103 | AND participantID IS NOT NULL"; | |
bfb64f81 | 104 | $existingParticipantStatement = WCF::getDB()->prepare($sql); |
fea86294 TD |
105 | |
106 | $obsoleteConversations = []; | |
107 | $updateData = []; | |
108 | /** @var Conversation $conversation */ | |
109 | foreach ($this->objectList as $conversation) { | |
230cd7ee MS |
110 | // get stats |
111 | $statsStatement->execute([$conversation->conversationID]); | |
112 | $row = $statsStatement->fetchSingleRow(); | |
fea86294 TD |
113 | |
114 | // update data | |
115 | $data = [ | |
230cd7ee | 116 | 'attachments' => $row['attachments'] ?: 0, |
fea86294 TD |
117 | 'firstMessageID' => $conversation->firstMessageID, |
118 | 'lastPostTime' => $conversation->lastPostTime, | |
119 | 'lastPosterID' => $conversation->lastPosterID, | |
120 | 'lastPoster' => $conversation->lastPoster, | |
230cd7ee | 121 | 'replies' => $row['messages'] ? $row['messages'] - 1 : 0, |
fea86294 TD |
122 | 'userID' => $conversation->userID, |
123 | 'username' => $conversation->username, | |
124 | ]; | |
125 | ||
230cd7ee MS |
126 | // check for obsolete conversations |
127 | $obsolete = $row['messages'] == 0; | |
128 | if (!$obsolete) { | |
129 | if ($conversation->isDraft) { | |
130 | if (!$conversation->userID) { | |
131 | $obsolete = true; | |
132 | } | |
133 | } else { | |
134 | $existingParticipantStatement->execute([$conversation->conversationID, Conversation::STATE_LEFT]); | |
135 | $row = $existingParticipantStatement->fetchSingleRow(); | |
136 | if (!$row['participants']) { | |
137 | $obsolete = true; | |
138 | } | |
139 | } | |
140 | } | |
42795151 | 141 | |
230cd7ee MS |
142 | if ($obsolete) { |
143 | $obsoleteConversations[] = new ConversationEditor($conversation); | |
144 | continue; | |
145 | } | |
146 | ||
fea86294 TD |
147 | // get first post |
148 | $firstMessageStatement->execute([$conversation->conversationID]); | |
149 | if (($row = $firstMessageStatement->fetchSingleRow()) !== false) { | |
150 | $data['firstMessageID'] = $row['messageID']; | |
151 | $data['lastPostTime'] = $data['time'] = $row['time']; | |
152 | $data['userID'] = $row['userID']; | |
153 | $data['username'] = $row['username']; | |
154 | } | |
155 | ||
156 | // get last post | |
157 | $lastMessageStatement->execute([$conversation->conversationID]); | |
158 | if (($row = $lastMessageStatement->fetchSingleRow()) !== false) { | |
159 | $data['lastPostTime'] = $row['time']; | |
160 | $data['lastPosterID'] = $row['userID']; | |
161 | $data['lastPoster'] = $row['username']; | |
162 | } | |
163 | ||
fea86294 TD |
164 | // get number of participants |
165 | $participantCounterStatement->execute([ | |
166 | $conversation->conversationID, | |
167 | Conversation::STATE_LEFT, | |
168 | $conversation->userID, | |
169 | 0, | |
170 | ]); | |
171 | $data['participants'] = $participantCounterStatement->fetchSingleColumn(); | |
172 | ||
173 | // get participant summary | |
174 | $participantStatement->execute([$conversation->conversationID, $conversation->userID, 0]); | |
175 | $users = []; | |
176 | while ($row = $participantStatement->fetchArray()) { | |
177 | $users[] = $row; | |
178 | } | |
179 | $data['participantSummary'] = \serialize($users); | |
180 | ||
181 | $updateData[$conversation->conversationID] = $data; | |
182 | } | |
183 | ||
bfb64f81 | 184 | $sql = "UPDATE wcf1_conversation |
8fbd8b01 MS |
185 | SET firstMessageID = ?, |
186 | lastPostTime = ?, | |
187 | lastPosterID = ?, | |
188 | lastPoster = ?, | |
189 | userID = ?, | |
190 | username = ?, | |
191 | replies = ?, | |
192 | attachments = ?, | |
193 | participants = ?, | |
194 | participantSummary = ? | |
195 | WHERE conversationID = ?"; | |
bfb64f81 | 196 | $statement = WCF::getDB()->prepare($sql); |
fea86294 TD |
197 | |
198 | WCF::getDB()->beginTransaction(); | |
199 | foreach ($updateData as $conversationID => $data) { | |
200 | $statement->execute([ | |
201 | $data['firstMessageID'], | |
202 | $data['lastPostTime'], | |
203 | $data['lastPosterID'], | |
204 | $data['lastPoster'], | |
205 | $data['userID'], | |
206 | $data['username'], | |
207 | $data['replies'], | |
208 | $data['attachments'], | |
209 | $data['participants'], | |
210 | $data['participantSummary'], | |
211 | $conversationID, | |
212 | ]); | |
213 | } | |
214 | WCF::getDB()->commitTransaction(); | |
215 | ||
216 | // delete obsolete conversations | |
217 | if (!empty($obsoleteConversations)) { | |
218 | $action = new ConversationAction($obsoleteConversations, 'delete'); | |
219 | $action->executeAction(); | |
220 | } | |
221 | } | |
336dfb29 | 222 | } |