Merge branch '2.0'
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / system / message / QuickReplyManager.class.php
CommitLineData
d45eaff6
MW
1<?php
2namespace wcf\system\message;
3use wcf\data\DatabaseObjectDecorator;
f1f694ff 4use wcf\data\IAttachmentMessageQuickReplyAction;
d45eaff6
MW
5use wcf\data\IMessage;
6use wcf\data\IMessageQuickReplyAction;
7use wcf\system\bbcode\PreParser;
8use wcf\system\event\EventHandler;
9use wcf\system\exception\SystemException;
10use wcf\system\exception\UserInputException;
11use wcf\system\SingletonFactory;
12use wcf\system\WCF;
13use wcf\util\ArrayUtil;
14use wcf\util\ClassUtil;
81c3ee0e 15use wcf\util\MessageUtil;
67837071 16use wcf\util\StringUtil;
d45eaff6
MW
17
18/**
19 * Manages quick replies and stored messages.
20 *
21 * @author Alexander Ebert
ca4ba303 22 * @copyright 2001-2014 WoltLab GmbH
d45eaff6 23 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
f4f05aa5 24 * @package com.woltlab.wcf
d45eaff6
MW
25 * @subpackage system.message
26 * @category Community Framework
27 */
28class QuickReplyManager extends SingletonFactory {
29 /**
30 * list of allowed bbcodes
31 * @var array<string>
32 */
33 public $allowedBBodes = null;
34
35 /**
36 * container object
0ad90fc3 37 * @var \wcf\data\DatabaseObject
d45eaff6
MW
38 */
39 public $container = null;
40
41 /**
42 * object id
43 * @var integer
44 */
45 public $objectID = 0;
46
47 /**
48 * object type
49 * @var string
50 */
51 public $type = '';
52
04ac9c2b
TD
53 /**
54 * additional fields
55 * @var array
56 */
57 public $additionalFields = array();
58
59 /**
60 * the message that just was created
ef906cce 61 * @var \wcf\data\DatabaseObject
04ac9c2b
TD
62 */
63 public $message = null;
64
d45eaff6
MW
65 /**
66 * Returns a stored message from session.
67 *
68 * @param string $type
69 * @param integer $objectID
70 * @return string
71 */
72 public function getMessage($type, $objectID) {
73 $this->type = $type;
74 $this->objectID = $objectID;
75
76 // allow manipulation before fetching data
77 EventHandler::getInstance()->fireAction($this, 'getMessage');
78
79 $message = WCF::getSession()->getVar('quickReply-'.$this->type.'-'.$this->objectID);
80 return ($message === null ? '' : $message);
81 }
82
83 /**
84 * Stores a message in session.
85 *
86 * @param string $type
87 * @param integer $objectID
88 * @param string $message
89 */
90 public function setMessage($type, $objectID, $message) {
91 WCF::getSession()->register('quickReply-'.$type.'-'.$objectID, $message);
92 }
93
94 /**
95 * Removes a stored message from session.
96 *
97 * @param string $type
98 * @param integer $objectID
99 */
100 public function removeMessage($type, $objectID) {
101 WCF::getSession()->unregister('quickReply-'.$this->type.'-'.$objectID);
102 }
103
104 /**
105 * Sets the allowed bbcodes.
106 *
107 * @param array<string> $allowedBBCodes
108 */
109 public function setAllowedBBCodes(array $allowedBBCodes = null) {
110 $this->allowedBBodes = $allowedBBCodes;
111 }
112
113 /**
114 * Validates parameters for current request.
115 *
0ad90fc3 116 * @param \wcf\system\message\IMessageQuickReplyAction $object
d45eaff6
MW
117 * @param array<array> $parameters
118 * @param string $containerClassName
119 * @param string $containerDecoratorClassName
120 */
121 public function validateParameters(IMessageQuickReplyAction $object, array &$parameters, $containerClassName, $containerDecoratorClassName = '') {
122 if (!isset($parameters['data']['message']) || empty($parameters['data']['message'])) {
123 throw new UserInputException('message');
124 }
125
126 $parameters['lastPostTime'] = (isset($parameters['lastPostTime'])) ? intval($parameters['lastPostTime']) : 0;
127 if (!$parameters['lastPostTime']) {
128 throw new UserInputException('lastPostTime');
129 }
130
131 $parameters['pageNo'] = (isset($parameters['pageNo'])) ? intval($parameters['pageNo']) : 0;
132 if (!$parameters['pageNo']) {
133 throw new UserInputException('pageNo');
134 }
135
136 $parameters['objectID'] = (isset($parameters['objectID'])) ? intval($parameters['objectID']) : 0;
137 if (!$parameters['objectID']) {
138 throw new UserInputException('objectID');
139 }
140
141 $this->container = new $containerClassName($parameters['objectID']);
142 if (!empty($containerDecoratorClassName)) {
143 if (!ClassUtil::isInstanceOf($containerDecoratorClassName, 'wcf\data\DatabaseObjectDecorator')) {
144 throw new SystemException("'".$containerDecoratorClassName."' does not extend 'wcf\data\DatabaseObjectDecorator'");
145 }
146
147 $this->container = new $containerDecoratorClassName($this->container);
148 }
149 $object->validateContainer($this->container);
150
151 // validate message
152 $object->validateMessage($this->container, $parameters['data']['message']);
153
154 // check for message quote ids
155 $parameters['removeQuoteIDs'] = (isset($parameters['removeQuoteIDs']) && is_array($parameters['removeQuoteIDs'])) ? ArrayUtil::trim($parameters['removeQuoteIDs']) : array();
04ac9c2b 156
67837071
AE
157 // check for tmp hash (attachments)
158 $parameters['tmpHash'] = (isset($parameters['tmpHash'])) ? StringUtil::trim($parameters['tmpHash']) : '';
159
04ac9c2b 160 EventHandler::getInstance()->fireAction($this, 'validateParameters');
d45eaff6
MW
161 }
162
163 /**
164 * Creates a new message and returns the parsed template.
165 *
0ad90fc3 166 * @param \wcf\data\IMessageQuickReplyAction $object
d45eaff6
MW
167 * @param array<array> $parameters
168 * @param string $containerActionClassName
169 * @param string $sortOrder
170 * @param string $templateName
171 * @param string $application
172 * @return array
173 */
174 public function createMessage(IMessageQuickReplyAction $object, array &$parameters, $containerActionClassName, $sortOrder, $templateName, $application = 'wcf') {
04ac9c2b
TD
175 EventHandler::getInstance()->fireAction($this, 'createMessage');
176
d45eaff6
MW
177 $tableIndexName = call_user_func(array($this->container, 'getDatabaseTableIndexName'));
178 $parameters['data'][$tableIndexName] = $parameters['objectID'];
179 $parameters['data']['enableSmilies'] = WCF::getSession()->getPermission('user.message.canUseSmilies');
180 $parameters['data']['enableHtml'] = 0;
181 $parameters['data']['enableBBCodes'] = WCF::getSession()->getPermission('user.message.canUseBBCodes');
182 $parameters['data']['showSignature'] = (WCF::getUser()->userID ? WCF::getUser()->showSignature : 0);
183 $parameters['data']['time'] = TIME_NOW;
04ac9c2b 184 $parameters['data']['userID'] = WCF::getUser()->userID ?: null;
d45eaff6
MW
185 $parameters['data']['username'] = WCF::getUser()->username;
186
187 // pre-parse message text
81c3ee0e 188 $parameters['data']['message'] = MessageUtil::stripCrap($parameters['data']['message']);
d45eaff6
MW
189 $parameters['data']['message'] = PreParser::getInstance()->parse($parameters['data']['message'], $this->allowedBBodes);
190
04ac9c2b
TD
191 $parameters['data'] = array_merge($this->additionalFields, $parameters['data']);
192
67837071
AE
193 // attachment support
194 if (MODULE_ATTACHMENT && $object instanceof IAttachmentMessageQuickReplyAction) {
195 $parameters['attachmentHandler'] = $object->getAttachmentHandler($this->container);
196 }
197
04ac9c2b
TD
198 // clean up
199 $this->additionalFields = array();
200
201 $this->message = $object->create();
202 EventHandler::getInstance()->fireAction($this, 'createdMessage');
203 $message = $this->message;
204
205 // clean up
206 $this->message = null;
207
d45eaff6
MW
208 if ($message instanceof IMessage && !$message->isVisible()) {
209 return array(
210 'isVisible' => false
211 );
212 }
213
214 // resolve the page no
215 list($pageNo, $count) = $object->getPageNo($this->container);
216
217 // we're still on current page
218 if ($pageNo == $parameters['pageNo']) {
219 // check for additional messages
220 $messageList = $object->getMessageList($this->container, $parameters['lastPostTime']);
221
222 // calculate start index
223 $startIndex = $count - (count($messageList) - 1);
224
225 WCF::getTPL()->assign(array(
226 'attachmentList' => $messageList->getAttachmentList(),
227 'container' => $this->container,
228 'objects' => $messageList,
229 'startIndex' => $startIndex,
230 'sortOrder' => $sortOrder,
231 ));
232
233 // assign 'to top' link
234 if (isset($parameters['anchor'])) {
235 WCF::getTPL()->assign('anchor', $parameters['anchor']);
236 }
237
238 // update visit time (messages shouldn't occur as new upon next visit)
239 if (ClassUtil::isInstanceOf($containerActionClassName, 'wcf\data\IVisitableObjectAction')) {
240 $containerAction = new $containerActionClassName(array(($this->container instanceof DatabaseObjectDecorator ? $this->container->getDecoratedObject() : $this->container)), 'markAsRead');
241 $containerAction->executeAction();
242 }
243
244 return array(
245 'lastPostTime' => $message->time,
246 'template' => WCF::getTPL()->fetch($templateName, $application)
247 );
248 }
249 else {
250 // redirect
251 return array(
252 'url' => $object->getRedirectUrl($this->container, $message)
253 );
254 }
255 }
256
257 /**
258 * Returns the container object.
259 *
0ad90fc3 260 * @return \wcf\data\DatabaseObject
d45eaff6
MW
261 */
262 public function getContainer() {
263 return $this->container;
264 }
265}