Merge pull request #5987 from WoltLab/acp-dahsboard-box-hight
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / system / moderation / queue / ModerationQueueReportManager.class.php
CommitLineData
fc69b61d 1<?php
a9229942 2
fc69b61d 3namespace wcf\system\moderation\queue;
a9229942 4
71b3faba
MS
5use wcf\data\moderation\queue\ModerationQueue;
6use wcf\data\moderation\queue\ModerationQueueAction;
fc69b61d 7use wcf\data\moderation\queue\ViewableModerationQueue;
4493238c
C
8use wcf\data\object\type\ObjectTypeCache;
9use wcf\system\cache\builder\UserGroupOptionCacheBuilder;
10use wcf\system\cache\runtime\UserProfileRuntimeCache;
79bbb75a 11use wcf\system\exception\InvalidObjectTypeException;
fc69b61d 12use wcf\system\request\LinkHandler;
ae0d522c 13use wcf\system\user\notification\object\ModerationQueueUserNotificationObject;
4493238c 14use wcf\system\user\notification\object\type\TMultiRecipientModerationQueueCommentUserNotificationObjectType;
ae0d522c 15use wcf\system\user\notification\UserNotificationHandler;
fc69b61d
MW
16use wcf\system\WCF;
17
18/**
19 * Moderation queue implementation for reports.
a9229942
TD
20 *
21 * @author Alexander Ebert
22 * @copyright 2001-2019 WoltLab GmbH
23 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
fc69b61d 24 */
a9229942
TD
25class ModerationQueueReportManager extends AbstractModerationQueueManager
26{
27 /**
28 * @inheritDoc
29 */
30 protected $definitionName = 'com.woltlab.wcf.moderation.report';
31
32 /**
33 * Returns true if given item was already reported.
34 *
35 * @param string $objectType
36 * @param int $objectID
37 * @return bool
38 */
39 public function isAlreadyReported($objectType, $objectID)
40 {
41 $objectTypeID = $this->getObjectTypeID($objectType);
42
43 $sql = "SELECT COUNT(*)
44 FROM wcf" . WCF_N . "_moderation_queue
45 WHERE objectTypeID = ?
46 AND objectID = ?";
47 $statement = WCF::getDB()->prepareStatement($sql);
48 $statement->execute([
49 $objectTypeID,
50 $objectID,
51 ]);
52
53 return $statement->fetchSingleColumn() > 0;
54 }
55
56 /**
57 * Returns true if the object with the given data has a pending report.
58 * A pending report has a status other than done.
59 *
60 * @param string $objectType
61 * @param int $objectID
62 * @return bool
63 */
64 public function hasPendingReport($objectType, $objectID)
65 {
66 $objectTypeID = $this->getObjectTypeID($objectType);
67
68 $sql = "SELECT COUNT(*)
69 FROM wcf" . WCF_N . "_moderation_queue
70 WHERE objectTypeID = ?
71 AND objectID = ?
72 AND status IN (?, ?)";
73 $statement = WCF::getDB()->prepareStatement($sql);
74 $statement->execute([
75 $objectTypeID,
76 $objectID,
77 ModerationQueue::STATUS_OUTSTANDING,
78 ModerationQueue::STATUS_PROCESSING,
79 ]);
80
81 return $statement->fetchSingleColumn() > 0;
82 }
83
84 /**
85 * Returns true if current user can report given content.
86 *
87 * @param string $objectType
88 * @param int $objectID
89 * @return bool
90 */
91 public function canReport($objectType, $objectID)
92 {
93 return $this->getProcessor($objectType)->canReport($objectID);
94 }
95
96 /**
97 * @inheritDoc
98 */
99 public function getLink($queueID)
100 {
101 return LinkHandler::getInstance()->getLink('ModerationReport', [
102 'id' => $queueID,
103 'forceFrontend' => true,
104 ]);
105 }
106
107 /**
108 * Returns rendered template for reported content.
109 *
110 * @param ViewableModerationQueue $queue
111 * @return string
112 */
113 public function getReportedContent(ViewableModerationQueue $queue)
114 {
115 return $this->getProcessor(null, $queue->objectTypeID)->getReportedContent($queue);
116 }
117
118 /**
119 * Returns the reported object.
120 *
121 * @param string $objectType
122 * @param int $objectID
123 * @return \wcf\data\IUserContent
124 */
125 public function getReportedObject($objectType, $objectID)
126 {
127 return $this->getProcessor($objectType)->getReportedObject($objectID);
128 }
129
130 /**
131 * Adds a report for specified content.
132 *
133 * @param string $objectType
134 * @param int $objectID
135 * @param string $message
136 * @param array $additionalData
137 * @throws InvalidObjectTypeException
138 */
139 public function addReport($objectType, $objectID, $message, array $additionalData = [])
140 {
141 if (!$this->isValid($objectType)) {
142 throw new InvalidObjectTypeException($objectType, 'com.woltlab.wcf.moderation.report');
143 }
144
145 $additionalData['message'] = $message;
146 $this->addEntry(
147 $this->getObjectTypeID($objectType),
148 $objectID,
149 $this->getProcessor($objectType)->getContainerID($objectID),
150 $additionalData
151 );
152 }
153
154 /**
155 * @inheritDoc
156 */
157 protected function addEntry($objectTypeID, $objectID, $containerID = 0, array $additionalData = [])
158 {
159 $sql = "SELECT queueID
160 FROM wcf" . WCF_N . "_moderation_queue
161 WHERE objectTypeID = ?
162 AND objectID = ?
163 AND status <> ?";
164 $statement = WCF::getDB()->prepareStatement($sql);
165 $statement->execute([
166 $objectTypeID,
167 $objectID,
168 ModerationQueue::STATUS_DONE,
169 ]);
170 $row = $statement->fetchArray();
171
172 if ($row === false) {
173 $objectAction = new ModerationQueueAction([], 'create', [
174 'data' => [
175 'objectTypeID' => $objectTypeID,
176 'objectID' => $objectID,
177 'containerID' => $containerID,
178 'userID' => WCF::getUser()->userID ?: null,
179 'time' => TIME_NOW,
180 'additionalData' => \serialize($additionalData),
181 ],
182 ]);
183 $objectAction->executeAction();
4493238c 184 $queue = $objectAction->getReturnValues()['returnValues'];
a9229942
TD
185 } else {
186 $objectAction = new ModerationQueueAction([$row['queueID']], 'update', [
187 'data' => [
188 'status' => ModerationQueue::STATUS_OUTSTANDING,
189 'containerID' => $containerID,
190 'userID' => WCF::getUser()->userID ?: null,
191 'time' => TIME_NOW,
192 'additionalData' => \serialize($additionalData),
193 ],
194 ]);
195 $objectAction->executeAction();
4493238c 196 $queue = new ModerationQueue($row['queueID']);
a9229942
TD
197 }
198
199 ModerationQueueManager::getInstance()->resetModerationCount();
4493238c
C
200
201 $this->notifyModerators($queue);
202 }
203
204 private function notifyModerators(ModerationQueue $queue): void
205 {
206 /** @see TMultiRecipientModerationQueueCommentUserNotificationObjectType::loadModerators() */
207 $userGroupOptionCache = UserGroupOptionCacheBuilder::getInstance()->getData();
208 $canUseModerationOption = $userGroupOptionCache['options']['mod.general.canUseModeration'];
209
210 $sql = "SELECT DISTINCT userID
211 FROM (
212 SELECT userID
213 FROM wcf1_user_to_group
214 WHERE groupID IN (
215 SELECT groupID
216 FROM wcf1_user_group_option_value
217 WHERE optionID = ?
218 AND optionValue = ?
219 )
220 ) users_in_groups_with_access
221 WHERE userID NOT IN (
222 SELECT userID
223 FROM wcf1_user_to_group
224 WHERE groupID IN (
225 SELECT groupID
226 FROM wcf1_user_group_option_value
227 WHERE optionID = ?
228 AND optionValue = ?
229 )
230 )
231 AND userID NOT IN (
232 SELECT userID
233 FROM wcf1_moderation_queue_to_user
234 WHERE queueID = ?
235 )";
236 $statement = WCF::getDB()->prepare($sql);
237 $statement->execute([
238 $canUseModerationOption->optionID,
239 1,
240 $canUseModerationOption->optionID,
241 -1,
242 $queue->queueID,
243 ]);
244 $userIDs = $statement->fetchAll(\PDO::FETCH_COLUMN);
51ce68ad 245 if (!$userIDs) {
4493238c
C
246 return;
247 }
248 UserProfileRuntimeCache::getInstance()->cacheObjectIDs($userIDs);
249 $objectType = ObjectTypeCache::getInstance()->getObjectType($queue->objectTypeID);
250 $processor = $objectType->getProcessor();
51ce68ad 251 \assert($processor instanceof IModerationQueueHandler);
4493238c 252
4ff55e71
C
253 $userIDs = \array_filter($userIDs, function ($userID) use ($processor, $queue) {
254 return $processor->isAffectedUser($queue, $userID);
255 });
4493238c
C
256 if ($userIDs === []) {
257 return;
258 }
0d710eba
C
259 foreach ($userIDs as $userID) {
260 $user = UserProfileRuntimeCache::getInstance()->getObject($userID);
261 ModerationQueueManager::getInstance()->setAssignment([$queue->queueID => 1], $user->getDecoratedObject());
262 }
263
ae0d522c
C
264 UserNotificationHandler::getInstance()->fireEvent(
265 'report',
266 'com.woltlab.wcf.moderation.queue',
267 new ModerationQueueUserNotificationObject($queue),
268 $userIDs
269 );
a9229942 270 }
fc69b61d 271}