Commit | Line | Data |
---|---|---|
9544b6b4 MW |
1 | <?php |
2 | namespace wcf\page; | |
2e0bc870 | 3 | use wcf\data\conversation\label\ConversationLabel; |
9d25a4e3 | 4 | use wcf\data\conversation\label\ConversationLabelList; |
9544b6b4 | 5 | use wcf\data\conversation\message\ConversationMessage; |
65f1cc0b | 6 | use wcf\data\conversation\message\ViewableConversationMessageList; |
232cdc4b | 7 | use wcf\data\conversation\Conversation; |
9544b6b4 | 8 | use wcf\data\conversation\ConversationAction; |
530c5f83 | 9 | use wcf\data\conversation\ConversationParticipantList; |
2e0bc870 | 10 | use wcf\data\conversation\ViewableConversation; |
83e23d22 | 11 | use wcf\data\modification\log\ConversationLogModificationLogList; |
b2de9161 | 12 | use wcf\data\smiley\SmileyCache; |
41c23899 | 13 | use wcf\system\attachment\AttachmentHandler; |
a21c8732 | 14 | use wcf\system\bbcode\BBCodeHandler; |
9544b6b4 MW |
15 | use wcf\system\exception\IllegalLinkException; |
16 | use wcf\system\exception\PermissionDeniedException; | |
2d181735 | 17 | use wcf\system\message\quote\MessageQuoteManager; |
e298db3c | 18 | use wcf\system\page\PageLocationManager; |
9544b6b4 MW |
19 | use wcf\system\request\LinkHandler; |
20 | use wcf\system\WCF; | |
21 | use wcf\util\HeaderUtil; | |
41c23899 | 22 | use wcf\util\StringUtil; |
9544b6b4 MW |
23 | |
24 | /** | |
25 | * Shows a conversation. | |
61f754e0 | 26 | * |
9544b6b4 | 27 | * @author Marcel Werk |
65f1cc0b | 28 | * @copyright 2001-2016 WoltLab GmbH |
9544b6b4 | 29 | * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php> |
c032049e | 30 | * @package WoltLabSuite\Core\Page |
7e95339f MS |
31 | * |
32 | * @property ViewableConversationMessageList $objectList | |
9544b6b4 MW |
33 | */ |
34 | class ConversationPage extends MultipleLinkPage { | |
35 | /** | |
65f1cc0b | 36 | * @inheritDoc |
9544b6b4 MW |
37 | */ |
38 | public $itemsPerPage = CONVERSATION_MESSAGES_PER_PAGE; | |
39 | ||
40 | /** | |
65f1cc0b | 41 | * @inheritDoc |
9544b6b4 MW |
42 | */ |
43 | public $sortOrder = 'ASC'; | |
44 | ||
45 | /** | |
65f1cc0b | 46 | * @inheritDoc |
9544b6b4 | 47 | */ |
65f1cc0b | 48 | public $objectListClassName = ViewableConversationMessageList::class; |
9544b6b4 | 49 | |
84e18f05 | 50 | /** |
65f1cc0b | 51 | * @inheritDoc |
84e18f05 MS |
52 | */ |
53 | public $loginRequired = true; | |
54 | ||
c764783c | 55 | /** |
65f1cc0b | 56 | * @inheritDoc |
c764783c | 57 | */ |
65f1cc0b | 58 | public $neededModules = ['MODULE_CONVERSATION']; |
c764783c MW |
59 | |
60 | /** | |
65f1cc0b | 61 | * @inheritDoc |
c764783c | 62 | */ |
65f1cc0b | 63 | public $neededPermissions = ['user.conversation.canUseConversation']; |
c764783c | 64 | |
9544b6b4 MW |
65 | /** |
66 | * conversation id | |
61f754e0 | 67 | * @var integer |
9544b6b4 MW |
68 | */ |
69 | public $conversationID = 0; | |
70 | ||
71 | /** | |
a208d1f4 | 72 | * viewable conversation object |
65f1cc0b | 73 | * @var ViewableConversation |
9544b6b4 MW |
74 | */ |
75 | public $conversation = null; | |
76 | ||
2e0bc870 AE |
77 | /** |
78 | * conversation label list | |
65f1cc0b | 79 | * @var ConversationLabelList |
2e0bc870 AE |
80 | */ |
81 | public $labelList = null; | |
82 | ||
9544b6b4 MW |
83 | /** |
84 | * message id | |
61f754e0 | 85 | * @var integer |
9544b6b4 MW |
86 | */ |
87 | public $messageID = 0; | |
88 | ||
89 | /** | |
90 | * conversation message object | |
65f1cc0b | 91 | * @var ConversationMessage |
9544b6b4 MW |
92 | */ |
93 | public $message = null; | |
94 | ||
a208d1f4 AE |
95 | /** |
96 | * modification log list object | |
65f1cc0b | 97 | * @var ConversationLogModificationLogList |
a208d1f4 AE |
98 | */ |
99 | public $modificationLogList = null; | |
100 | ||
530c5f83 MW |
101 | /** |
102 | * list of participants | |
65f1cc0b | 103 | * @var ConversationParticipantList |
530c5f83 MW |
104 | */ |
105 | public $participantList = null; | |
106 | ||
9544b6b4 | 107 | /** |
65f1cc0b | 108 | * @inheritDoc |
9544b6b4 MW |
109 | */ |
110 | public function readParameters() { | |
111 | parent::readParameters(); | |
112 | ||
113 | if (isset($_REQUEST['id'])) $this->conversationID = intval($_REQUEST['id']); | |
114 | if (isset($_REQUEST['messageID'])) $this->messageID = intval($_REQUEST['messageID']); | |
115 | if ($this->messageID) { | |
116 | $this->message = new ConversationMessage($this->messageID); | |
117 | if (!$this->message->messageID) { | |
118 | throw new IllegalLinkException(); | |
119 | } | |
c764783c | 120 | $this->conversationID = $this->message->conversationID; |
9544b6b4 MW |
121 | } |
122 | ||
123 | $this->conversation = Conversation::getUserConversation($this->conversationID, WCF::getUser()->userID); | |
124 | if ($this->conversation === null) { | |
125 | throw new IllegalLinkException(); | |
126 | } | |
127 | if (!$this->conversation->canRead()) { | |
128 | throw new PermissionDeniedException(); | |
129 | } | |
130 | ||
2e0bc870 AE |
131 | // load labels |
132 | $this->labelList = ConversationLabel::getLabelsByUser(); | |
133 | $this->conversation = ViewableConversation::getViewableConversation($this->conversation, $this->labelList); | |
134 | ||
b41c9fd6 MS |
135 | // messages per page |
136 | /** @noinspection PhpUndefinedFieldInspection */ | |
137 | if (WCF::getUser()->conversationMessagesPerPage) { | |
138 | /** @noinspection PhpUndefinedFieldInspection */ | |
139 | $this->itemsPerPage = WCF::getUser()->conversationMessagesPerPage; | |
140 | } | |
ecadd37d | 141 | |
65f1cc0b | 142 | $this->canonicalURL = LinkHandler::getInstance()->getLink('Conversation', [ |
f6eb15c3 | 143 | 'object' => $this->conversation |
65f1cc0b | 144 | ], ($this->pageNo ? 'pageNo=' . $this->pageNo : '')); |
9544b6b4 MW |
145 | } |
146 | ||
147 | /** | |
65f1cc0b | 148 | * @inheritDoc |
9544b6b4 MW |
149 | */ |
150 | protected function initObjectList() { | |
151 | parent::initObjectList(); | |
152 | ||
65f1cc0b | 153 | $this->objectList->getConditionBuilder()->add('conversation_message.conversationID = ?', [$this->conversation->conversationID]); |
28bd6cbd | 154 | $this->objectList->setConversation($this->conversation->getDecoratedObject()); |
9544b6b4 MW |
155 | |
156 | // handle jump to | |
157 | if ($this->action == 'lastPost') $this->goToLastPost(); | |
158 | if ($this->action == 'firstNew') $this->goToFirstNewPost(); | |
159 | if ($this->messageID) $this->goToPost(); | |
160 | } | |
161 | ||
162 | /** | |
65f1cc0b | 163 | * @inheritDoc |
9544b6b4 MW |
164 | */ |
165 | public function readData() { | |
166 | parent::readData(); | |
167 | ||
168 | // add breadcrumbs | |
e298db3c | 169 | PageLocationManager::getInstance()->addParentLocation('com.woltlab.wcf.conversation.ConversationList'); |
f34884b9 | 170 | if ($this->conversation->isDraft) { |
e298db3c | 171 | /* TODO |
65f1cc0b | 172 | WCF::getBreadcrumbs()->add(new Breadcrumb(WCF::getLanguage()->get('wcf.conversation.folder.draft'), LinkHandler::getInstance()->getLink('ConversationList', [ |
f34884b9 | 173 | 'filter' => 'draft' |
65f1cc0b | 174 | ]))); |
e298db3c | 175 | */ |
f34884b9 | 176 | } |
9544b6b4 MW |
177 | |
178 | // update last visit time count | |
179 | if ($this->conversation->isNew() && $this->objectList->getMaxPostTime() > $this->conversation->lastVisitTime) { | |
c0dd7a12 MW |
180 | $visitTime = $this->objectList->getMaxPostTime(); |
181 | if ($visitTime == $this->conversation->lastPostTime) $visitTime = TIME_NOW; | |
65f1cc0b | 182 | $conversationAction = new ConversationAction([$this->conversation->getDecoratedObject()], 'markAsRead', ['visitTime' => $visitTime]); |
9544b6b4 MW |
183 | $conversationAction->executeAction(); |
184 | } | |
530c5f83 MW |
185 | |
186 | // get participants | |
8a6ee075 | 187 | $this->participantList = new ConversationParticipantList($this->conversationID, WCF::getUser()->userID, $this->conversation->userID == WCF::getUser()->userID); |
530c5f83 | 188 | $this->participantList->readObjects(); |
42335f61 AE |
189 | |
190 | // init quote objects | |
65f1cc0b | 191 | $messageIDs = []; |
42335f61 AE |
192 | foreach ($this->objectList as $message) { |
193 | $messageIDs[] = $message->messageID; | |
194 | } | |
195 | MessageQuoteManager::getInstance()->initObjects('com.woltlab.wcf.conversation.message', $messageIDs); | |
f7b9b1f3 MW |
196 | |
197 | // set attachment permissions | |
198 | if ($this->objectList->getAttachmentList() !== null) { | |
65f1cc0b | 199 | $this->objectList->getAttachmentList()->setPermissions([ |
f7b9b1f3 | 200 | 'canDownload' => true, |
a480521b | 201 | 'canViewPreview' => true |
65f1cc0b | 202 | ]); |
f7b9b1f3 | 203 | } |
a208d1f4 AE |
204 | |
205 | // get timeframe for modifications | |
206 | $this->objectList->rewind(); | |
207 | $startTime = $this->objectList->current()->time; | |
a7e5e13c | 208 | $endTime = TIME_NOW; |
a208d1f4 AE |
209 | |
210 | $count = count($this->objectList); | |
a7e5e13c | 211 | if ($count > 1) { |
a208d1f4 | 212 | $this->objectList->seek($count - 1); |
a7e5e13c MW |
213 | if ($this->objectList->current()->time < $this->conversation->lastPostTime) { |
214 | $sql = "SELECT time | |
215 | FROM wcf".WCF_N."_conversation_message | |
216 | WHERE conversationID = ? | |
217 | AND time > ? | |
218 | ORDER BY time"; | |
219 | $statement = WCF::getDB()->prepareStatement($sql, 1); | |
eaf1c8eb | 220 | $statement->execute([$this->conversationID, $this->objectList->current()->time]); |
a7e5e13c MW |
221 | $endTime = $statement->fetchSingleColumn() - 1; |
222 | } | |
a208d1f4 AE |
223 | } |
224 | $this->objectList->rewind(); | |
225 | ||
226 | // load modification log entries | |
a7e5e13c | 227 | $this->modificationLogList = new ConversationLogModificationLogList($this->conversation->conversationID); |
65f1cc0b | 228 | $this->modificationLogList->getConditionBuilder()->add("modification_log.time BETWEEN ? AND ?", [$startTime, $endTime]); |
a208d1f4 | 229 | $this->modificationLogList->readObjects(); |
9544b6b4 MW |
230 | } |
231 | ||
232 | /** | |
65f1cc0b | 233 | * @inheritDoc |
9544b6b4 MW |
234 | */ |
235 | public function assignVariables() { | |
236 | parent::assignVariables(); | |
237 | ||
2d181735 AE |
238 | MessageQuoteManager::getInstance()->assignVariables(); |
239 | ||
41c23899 AE |
240 | $tmpHash = StringUtil::getRandomID(); |
241 | $attachmentHandler = new AttachmentHandler('com.woltlab.wcf.conversation.message', 0, $tmpHash, 0); | |
242 | ||
65f1cc0b | 243 | WCF::getTPL()->assign([ |
41c23899 AE |
244 | 'attachmentHandler' => $attachmentHandler, |
245 | 'attachmentObjectID' => 0, | |
246 | 'attachmentObjectType' => 'com.woltlab.wcf.conversation.message', | |
247 | 'attachmentParentObjectID' => 0, | |
248 | 'tmpHash' => $tmpHash, | |
9544b6b4 | 249 | 'attachmentList' => $this->objectList->getAttachmentList(), |
2e0bc870 | 250 | 'labelList' => $this->labelList, |
a208d1f4 | 251 | 'modificationLogList' => $this->modificationLogList, |
9544b6b4 MW |
252 | 'sortOrder' => $this->sortOrder, |
253 | 'conversation' => $this->conversation, | |
530c5f83 | 254 | 'conversationID' => $this->conversationID, |
52971287 | 255 | 'participants' => $this->participantList->getObjects(), |
cadc85bd | 256 | 'defaultSmilies' => SmileyCache::getInstance()->getCategorySmilies() |
65f1cc0b | 257 | ]); |
a21c8732 | 258 | |
dfecaf59 | 259 | BBCodeHandler::getInstance()->setDisallowedBBCodes(explode(',', WCF::getSession()->getPermission('user.message.disallowedBBCodes'))); |
9544b6b4 MW |
260 | } |
261 | ||
262 | /** | |
263 | * Calculates the position of a specific post in this conversation. | |
264 | */ | |
265 | protected function goToPost() { | |
266 | $conditionBuilder = clone $this->objectList->getConditionBuilder(); | |
65f1cc0b | 267 | $conditionBuilder->add('time '.($this->sortOrder == 'ASC' ? '<=' : '>=').' ?', [$this->message->time]); |
9544b6b4 MW |
268 | |
269 | $sql = "SELECT COUNT(*) AS messages | |
a480521b | 270 | FROM wcf".WCF_N."_conversation_message conversation_message |
9544b6b4 | 271 | ".$conditionBuilder; |
a21c8732 MS |
272 | $statement = WCF::getDB()->prepareStatement($sql); |
273 | $statement->execute($conditionBuilder->getParameters()); | |
9544b6b4 MW |
274 | $row = $statement->fetchArray(); |
275 | $this->pageNo = intval(ceil($row['messages'] / $this->itemsPerPage)); | |
276 | } | |
277 | ||
278 | /** | |
279 | * Gets the id of the last post in this conversation and forwards the user to this post. | |
280 | */ | |
281 | protected function goToLastPost() { | |
4f13dcae | 282 | $sql = "SELECT conversation_message.messageID |
a480521b | 283 | FROM wcf".WCF_N."_conversation_message conversation_message |
9544b6b4 | 284 | ".$this->objectList->getConditionBuilder()." |
a480521b | 285 | ORDER BY time ".($this->sortOrder == 'ASC' ? 'DESC' : 'ASC'); |
249da2b9 MS |
286 | $statement = WCF::getDB()->prepareStatement($sql, 1); |
287 | $statement->execute($this->objectList->getConditionBuilder()->getParameters()); | |
9544b6b4 | 288 | $row = $statement->fetchArray(); |
65f1cc0b | 289 | HeaderUtil::redirect(LinkHandler::getInstance()->getLink('Conversation', [ |
655bead9 | 290 | 'encodeTitle' => true, |
9544b6b4 MW |
291 | 'object' => $this->conversation, |
292 | 'messageID' => $row['messageID'] | |
65f1cc0b | 293 | ]).'#message'.$row['messageID']); |
9544b6b4 MW |
294 | exit; |
295 | } | |
296 | ||
297 | /** | |
298 | * Forwards the user to the first new message in this conversation. | |
299 | */ | |
300 | protected function goToFirstNewPost() { | |
301 | $conditionBuilder = clone $this->objectList->getConditionBuilder(); | |
65f1cc0b | 302 | $conditionBuilder->add('time > ?', [$this->conversation->lastVisitTime]); |
9544b6b4 MW |
303 | |
304 | $sql = "SELECT conversation_message.messageID | |
a480521b | 305 | FROM wcf".WCF_N."_conversation_message conversation_message |
9544b6b4 | 306 | ".$conditionBuilder." |
a480521b | 307 | ORDER BY time ASC"; |
a21c8732 MS |
308 | $statement = WCF::getDB()->prepareStatement($sql, 1); |
309 | $statement->execute($conditionBuilder->getParameters()); | |
9544b6b4 MW |
310 | $row = $statement->fetchArray(); |
311 | if ($row !== false) { | |
65f1cc0b | 312 | HeaderUtil::redirect(LinkHandler::getInstance()->getLink('Conversation', [ |
655bead9 | 313 | 'encodeTitle' => true, |
9544b6b4 MW |
314 | 'object' => $this->conversation, |
315 | 'messageID' => $row['messageID'] | |
65f1cc0b | 316 | ]).'#message'.$row['messageID']); |
9544b6b4 MW |
317 | exit; |
318 | } | |
319 | else { | |
320 | $this->goToLastPost(); | |
321 | } | |
322 | } | |
78fd78a7 | 323 | } |