Remove unnecessary parentheses around join conditions
[GitHub/WoltLab/com.woltlab.wcf.conversation.git] / files / lib / data / conversation / UserConversationList.class.php
CommitLineData
9544b6b4 1<?php
fea86294 2
9544b6b4 3namespace wcf\data\conversation;
fea86294 4
6579145d 5use wcf\data\conversation\label\ConversationLabel;
6579145d 6use wcf\data\conversation\label\ConversationLabelList;
95ed3132 7use wcf\system\cache\runtime\UserProfileRuntimeCache;
02b42a61 8use wcf\system\database\util\PreparedStatementConditionBuilder;
9544b6b4
MW
9use wcf\system\WCF;
10
11/**
12 * Represents a list of 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>
17 * @package WoltLabSuite\Core\Data\Conversation
18 *
19 * @method ViewableConversation current()
20 * @method ViewableConversation[] getObjects()
21 * @method ViewableConversation|null search($objectID)
22 * @property ViewableConversation[] $objects
9544b6b4 23 */
fea86294
TD
24class UserConversationList extends ConversationList
25{
26 /**
27 * list of available filters
28 * @var string[]
29 */
30 public static $availableFilters = ['hidden', 'draft', 'outbox'];
31
32 /**
33 * active filter
34 * @var string
35 */
36 public $filter = '';
37
38 /**
39 * label list object
40 * @var ConversationLabelList
41 */
42 public $labelList;
43
44 /**
45 * @inheritDoc
46 */
47 public $decoratorClassName = ViewableConversation::class;
48
49 /**
50 * Creates a new UserConversationList
51 *
c85e9df8 52 * @param int $userID
fea86294 53 * @param string $filter
c85e9df8 54 * @param int $labelID
fea86294
TD
55 */
56 public function __construct($userID, $filter = '', $labelID = 0)
57 {
58 parent::__construct();
59
60 $this->filter = $filter;
61
62 // apply filter
63 if ($this->filter === 'draft') {
64 $this->getConditionBuilder()->add('conversation.userID = ?', [$userID]);
65 $this->getConditionBuilder()->add('conversation.isDraft = 1');
66 } else {
67 $this->getConditionBuilder()->add('conversation_to_user.participantID = ?', [$userID]);
68 $this->getConditionBuilder()
69 ->add('conversation_to_user.hideConversation = ?', [$this->filter == 'hidden' ? 1 : 0]);
6124508f 70 $this->sqlConditionJoins = "LEFT JOIN wcf" . WCF_N . "_conversation conversation ON conversation.conversationID = conversation_to_user.conversationID";
fea86294
TD
71 if ($this->filter == 'outbox') {
72 $this->getConditionBuilder()->add('conversation.userID = ?', [$userID]);
73 }
74 }
75
76 // filter by label id
77 if ($labelID) {
78 $this->getConditionBuilder()->add("conversation.conversationID IN (
8fbd8b01
MS
79 SELECT conversationID
80 FROM wcf" . WCF_N . "_conversation_label_to_object
81 WHERE labelID = ?
82 )", [$labelID]);
fea86294
TD
83 }
84
85 // own posts
86 $this->sqlSelects = "DISTINCT conversation_message.userID AS ownPosts";
6124508f 87 $this->sqlJoins = "LEFT JOIN wcf" . WCF_N . "_conversation_message conversation_message ON conversation_message.conversationID = conversation.conversationID AND conversation_message.userID = " . $userID;
fea86294
TD
88
89 // user info
90 if (!empty($this->sqlSelects)) {
91 $this->sqlSelects .= ',';
92 }
93 $this->sqlSelects .= "conversation_to_user.*";
6124508f 94 $this->sqlJoins .= "LEFT JOIN wcf" . WCF_N . "_conversation_to_user conversation_to_user ON conversation_to_user.participantID = " . $userID . " AND conversation_to_user.conversationID = conversation.conversationID";
fea86294
TD
95
96 if ($this->filter !== 'draft') {
97 $this->sqlSelects .= ", conversation.*, CASE WHEN conversation_to_user.leftAt <> 0 THEN conversation_to_user.leftAt ELSE conversation.lastPostTime END AS lastPostTime";
98 // this avoids appending `conversation.*` to the SELECT list
99 $this->useQualifiedShorthand = false;
100 }
101 }
102
103 /**
104 * Sets the label list of the user the conversations belong to.
105 *
106 * @param ConversationLabelList $labelList
107 */
108 public function setLabelList(ConversationLabelList $labelList)
109 {
110 $this->labelList = $labelList;
111 }
112
113 /**
114 * @inheritDoc
115 */
116 public function countObjects()
117 {
118 if ($this->filter == 'draft') {
119 return parent::countObjects();
120 }
121
8fbd8b01
MS
122 $sql = "SELECT COUNT(*) AS count
123 FROM wcf" . WCF_N . "_conversation_to_user conversation_to_user
124 " . $this->sqlConditionJoins . "
ad5cae90 125 " . $this->getConditionBuilder();
fea86294
TD
126 $statement = WCF::getDB()->prepareStatement($sql);
127 $statement->execute($this->getConditionBuilder()->getParameters());
128 $row = $statement->fetchArray();
129
130 return $row['count'];
131 }
132
133 /**
134 * @inheritDoc
135 */
136 public function readObjectIDs()
137 {
138 if ($this->filter === 'draft') {
139 parent::readObjectIDs();
140
141 return;
142 }
143
8fbd8b01
MS
144 $sql = "SELECT conversation_to_user.conversationID AS objectID
145 FROM wcf" . WCF_N . "_conversation_to_user conversation_to_user
146 " . $this->sqlConditionJoins . "
ad5cae90 147 " . $this->getConditionBuilder() . "
8fbd8b01 148 " . (!empty($this->sqlOrderBy) ? "ORDER BY " . $this->sqlOrderBy : '');
fea86294
TD
149 $statement = WCF::getDB()->prepareStatement($sql, $this->sqlLimit, $this->sqlOffset);
150 $statement->execute($this->getConditionBuilder()->getParameters());
151 $this->objectIDs = $statement->fetchAll(\PDO::FETCH_COLUMN);
152 }
153
154 /**
155 * @inheritDoc
156 */
157 public function readObjects()
158 {
159 if ($this->objectIDs === null) {
160 $this->readObjectIDs();
161 }
162
163 parent::readObjects();
164
165 if (!empty($this->objects)) {
166 $messageIDs = [];
167 foreach ($this->objects as $conversation) {
168 if ($conversation->lastMessageID) {
169 $messageIDs[] = $conversation->lastMessageID;
170 }
171 }
172 if (!empty($messageIDs)) {
173 $conditions = new PreparedStatementConditionBuilder();
174 $conditions->add("messageID IN (?)", [$messageIDs]);
175 $sql = "SELECT messageID, userID, username, time
8fbd8b01
MS
176 FROM wcf" . WCF_N . "_conversation_message
177 " . $conditions;
fea86294
TD
178 $statement = WCF::getDB()->prepareStatement($sql);
179 $statement->execute($conditions->getParameters());
180 $messageData = [];
181 while ($row = $statement->fetchArray()) {
182 $messageData[$row['messageID']] = $row;
183 }
184
185 foreach ($this->objects as $conversation) {
186 if ($conversation->lastMessageID) {
187 $data = (isset($messageData[$conversation->lastMessageID])) ? $messageData[$conversation->lastMessageID] : null;
188 if ($data !== null) {
189 $conversation->setLastMessage($data['userID'], $data['username'], $data['time']);
190 } else {
191 $conversation->setLastMessage(null, '', 0);
192 }
193 }
194 }
195 }
196
197 $labels = $this->loadLabelAssignments();
198
199 $userIDs = [];
200 foreach ($this->objects as $conversationID => $conversation) {
201 if (isset($labels[$conversationID])) {
202 foreach ($labels[$conversationID] as $label) {
203 $conversation->assignLabel($label);
204 }
205 }
206
207 if ($conversation->userID) {
208 $userIDs[] = $conversation->userID;
209 }
210 if ($conversation->lastPosterID) {
211 $userIDs[] = $conversation->lastPosterID;
212 }
213 }
214
215 if (!empty($userIDs)) {
216 UserProfileRuntimeCache::getInstance()->cacheObjectIDs($userIDs);
217 }
218 }
219 }
220
221 /**
222 * Returns a list of conversation labels.
223 *
224 * @return ConversationLabel[]
225 */
226 protected function getLabels()
227 {
228 if ($this->labelList === null) {
229 $this->labelList = ConversationLabel::getLabelsByUser();
230 }
231
232 return $this->labelList->getObjects();
233 }
234
235 /**
236 * Returns label assignments per conversation.
237 *
238 * @return ConversationLabel[][]
239 */
240 protected function loadLabelAssignments()
241 {
242 $labels = $this->getLabels();
243 if (empty($labels)) {
244 return [];
245 }
246
247 $conditions = new PreparedStatementConditionBuilder();
248 $conditions->add("conversationID IN (?)", [\array_keys($this->objects)]);
249 $conditions->add("labelID IN (?)", [\array_keys($labels)]);
250
8fbd8b01
MS
251 $sql = "SELECT labelID, conversationID
252 FROM wcf" . WCF_N . "_conversation_label_to_object
253 " . $conditions;
fea86294
TD
254 $statement = WCF::getDB()->prepareStatement($sql);
255 $statement->execute($conditions->getParameters());
256 $data = [];
257 while ($row = $statement->fetchArray()) {
258 if (!isset($data[$row['conversationID']])) {
259 $data[$row['conversationID']] = [];
260 }
261
262 $data[$row['conversationID']][$row['labelID']] = $labels[$row['labelID']];
263 }
264
265 return $data;
266 }
61f754e0 267}