Fixed time zone calculation issue
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / system / comment / CommentHandler.class.php
1 <?php
2 namespace wcf\system\comment;
3 use wcf\data\comment\response\CommentResponseList;
4 use wcf\data\comment\CommentEditor;
5 use wcf\data\comment\CommentList;
6 use wcf\data\comment\StructuredCommentList;
7 use wcf\data\object\type\ObjectTypeCache;
8 use wcf\system\comment\manager\ICommentManager;
9 use wcf\system\exception\NamedUserException;
10 use wcf\system\exception\SystemException;
11 use wcf\system\like\LikeHandler;
12 use wcf\system\user\activity\event\UserActivityEventHandler;
13 use wcf\system\user\notification\UserNotificationHandler;
14 use wcf\system\SingletonFactory;
15 use wcf\system\WCF;
16
17 /**
18 * Provides methods for comment object handling.
19 *
20 * @author Alexander Ebert
21 * @copyright 2001-2014 WoltLab GmbH
22 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
23 * @package com.woltlab.wcf
24 * @subpackage system.comment
25 * @category Community Framework
26 */
27 class CommentHandler extends SingletonFactory {
28 /**
29 * cached object types
30 * @var array<array>
31 */
32 protected $cache = null;
33
34 /**
35 * @see \wcf\system\SingletonFactory::init()
36 */
37 protected function init() {
38 $this->cache = array(
39 'objectTypes' => array(),
40 'objectTypeIDs' => array()
41 );
42
43 $cache = ObjectTypeCache::getInstance()->getObjectTypes('com.woltlab.wcf.comment.commentableContent');
44 foreach ($cache as $objectType) {
45 $this->cache['objectTypes'][$objectType->objectTypeID] = $objectType;
46 $this->cache['objectTypeIDs'][$objectType->objectType] = $objectType->objectTypeID;
47 }
48 }
49
50 /**
51 * Returns the object type id for a given object type.
52 *
53 * @param string $objectType
54 * @return integer
55 */
56 public function getObjectTypeID($objectType) {
57 if (isset($this->cache['objectTypeIDs'][$objectType])) {
58 return $this->cache['objectTypeIDs'][$objectType];
59 }
60
61 return null;
62 }
63
64 /**
65 * Returns the object type for a given object type id.
66 *
67 * @param integer $objectTypeID
68 * @return \wcf\data\object\type\ObjectType
69 */
70 public function getObjectType($objectTypeID) {
71 if (isset($this->cache['objectTypes'][$objectTypeID])) {
72 return $this->cache['objectTypes'][$objectTypeID];
73 }
74
75 return null;
76 }
77
78 /**
79 * Returns comment manager object for given object type.
80 *
81 * @param string $objectType
82 * @return \wcf\system\comment\manager\ICommentManager
83 */
84 public function getCommentManager($objectType) {
85 $objectTypeID = $this->getObjectTypeID($objectType);
86 if ($objectTypeID === null) {
87 throw new SystemException("Unable to find object type for '".$objectType."'");
88 }
89
90 return $this->getObjectType($objectTypeID)->getProcessor();
91
92 }
93
94 /**
95 * Returns a comment list for a given object type and object id.
96 *
97 * @param \wcf\data\comment\manager\ICommentManager $commentManager
98 * @param integer $objectTypeID
99 * @param integer $objectID
100 * @param boolean $readObjects
101 * @return \wcf\data\comment\StructuredCommentList
102 */
103 public function getCommentList(ICommentManager $commentManager, $objectTypeID, $objectID, $readObjects = true) {
104 $commentList = new StructuredCommentList($commentManager, $objectTypeID, $objectID);
105 if ($readObjects) {
106 $commentList->readObjects();
107 }
108
109 return $commentList;
110 }
111
112 /**
113 * Removes all comments for given objects.
114 *
115 * @param string $objectType
116 * @param array<integer> $objectIDs
117 */
118 public function deleteObjects($objectType, array $objectIDs) {
119 $objectTypeID = $this->getObjectTypeID($objectType);
120 $objectTypeObj = $this->getObjectType($objectTypeID);
121
122 // get comment ids
123 $commentList = new CommentList();
124 $commentList->getConditionBuilder()->add('comment.objectTypeID = ?', array($objectTypeID));
125 $commentList->getConditionBuilder()->add('comment.objectID IN (?)', array($objectIDs));
126 $commentList->readObjectIDs();
127 $commentIDs = $commentList->getObjectIDs();
128
129 // no comments -> skip
130 if (empty($commentIDs)) return;
131
132 // get response ids
133 $responseList = new CommentResponseList();
134 $responseList->getConditionBuilder()->add('comment_response.commentID IN (?)', array($commentIDs));
135 $responseList->readObjectIDs();
136 $responseIDs = $responseList->getObjectIDs();
137
138 // delete likes
139 LikeHandler::getInstance()->removeLikes('com.woltlab.wcf.comment', $commentIDs);
140
141 // delete activity events
142 if (UserActivityEventHandler::getInstance()->getObjectTypeID($objectTypeObj->objectType.'.recentActivityEvent')) {
143 UserActivityEventHandler::getInstance()->removeEvents($objectTypeObj->objectType.'.recentActivityEvent', $commentIDs);
144 }
145 // delete notifications
146 if (UserNotificationHandler::getInstance()->getObjectTypeID($objectTypeObj->objectType.'.notification')) {
147 UserNotificationHandler::getInstance()->deleteNotifications('comment', $objectTypeObj->objectType.'.notification', array(), $commentIDs);
148 }
149
150 if (!empty($responseIDs)) {
151 // delete likes (for responses)
152 LikeHandler::getInstance()->removeLikes('com.woltlab.wcf.comment.response', $responseIDs);
153
154 // delete activity events (for responses)
155 if (UserActivityEventHandler::getInstance()->getObjectTypeID($objectTypeObj->objectType.'.response.recentActivityEvent')) {
156 UserActivityEventHandler::getInstance()->removeEvents($objectTypeObj->objectType.'.response.recentActivityEvent', $responseIDs);
157 }
158 // delete notifications (for responses)
159 if (UserNotificationHandler::getInstance()->getObjectTypeID($objectTypeObj->objectType.'.response.notification')) {
160 UserNotificationHandler::getInstance()->deleteNotifications('commentResponse', $objectTypeObj->objectType.'.response.notification', array(), $responseIDs);
161 UserNotificationHandler::getInstance()->deleteNotifications('commentResponseOwner', $objectTypeObj->objectType.'.response.notification', array(), $responseIDs);
162 }
163 }
164
165 // delete comments / responses
166 CommentEditor::deleteAll($commentIDs);
167 }
168
169 /**
170 * Enforces the flood control.
171 */
172 public static function enforceFloodControl() {
173 if (!WCF::getSession()->getPermission('user.comment.floodControlTime')) {
174 return;
175 }
176
177 // check for comments
178 $sql = "SELECT time
179 FROM wcf".WCF_N."_comment
180 WHERE userID = ?
181 AND time > ?
182 ORDER BY time DESC";
183 $statement = WCF::getDB()->prepareStatement($sql, 1);
184 $statement->execute(array(
185 WCF::getUser()->userID,
186 (TIME_NOW - WCF::getSession()->getPermission('user.comment.floodControlTime'))
187 ));
188 if (($row = $statement->fetchArray()) !== false) {
189 throw new NamedUserException(WCF::getLanguage()->getDynamicVariable('wcf.comment.error.floodControl', array('lastCommentTime' => $row['time'])));
190 }
191 else {
192 // check for comment response
193 $sql = "SELECT time
194 FROM wcf".WCF_N."_comment_response
195 WHERE userID = ?
196 AND time > ?
197 ORDER BY time DESC";
198 $statement = WCF::getDB()->prepareStatement($sql, 1);
199 $statement->execute(array(
200 WCF::getUser()->userID,
201 (TIME_NOW - WCF::getSession()->getPermission('user.comment.floodControlTime'))
202 ));
203 if (($row = $statement->fetchArray()) !== false) {
204 throw new NamedUserException(WCF::getLanguage()->getDynamicVariable('wcf.comment.error.floodControl', array('lastCommentTime' => $row['time'])));
205 }
206 }
207 }
208 }