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