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