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