3 namespace wcf\system\comment
;
5 use wcf\data\comment\CommentEditor
;
6 use wcf\data\comment\CommentList
;
7 use wcf\data\comment\response\CommentResponse
;
8 use wcf\data\comment\response\CommentResponseList
;
9 use wcf\data\comment\StructuredComment
;
10 use wcf\data\comment\StructuredCommentList
;
11 use wcf\data\
object\type\ObjectType
;
12 use wcf\data\
object\type\ObjectTypeCache
;
13 use wcf\data\user\notification\UserNotificationList
;
14 use wcf\system\comment\manager\ICommentManager
;
15 use wcf\system\exception\NamedUserException
;
16 use wcf\system\exception\SystemException
;
17 use wcf\system\exception\UserInputException
;
18 use wcf\system\flood\FloodControl
;
19 use wcf\system\message\censorship\Censorship
;
20 use wcf\system\reaction\ReactionHandler
;
21 use wcf\system\SingletonFactory
;
22 use wcf\system\user\activity\event\UserActivityEventHandler
;
23 use wcf\system\user\notification\UserNotificationHandler
;
27 * Provides methods for comment object handling.
29 * @author Alexander Ebert
30 * @copyright 2001-2020 WoltLab GmbH
31 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
32 * @package WoltLabSuite\Core\System\Comment
34 class CommentHandler
extends SingletonFactory
45 protected function init()
49 'objectTypeIDs' => [],
52 $cache = ObjectTypeCache
::getInstance()->getObjectTypes('com.woltlab.wcf.comment.commentableContent');
53 foreach ($cache as $objectType) {
54 $this->cache
['objectTypes'][$objectType->objectTypeID
] = $objectType;
55 $this->cache
['objectTypeIDs'][$objectType->objectType
] = $objectType->objectTypeID
;
60 * Returns the id of the comment object type with the given name or `null` if no
61 * such object type exists.
63 * @param string $objectType
66 public function getObjectTypeID($objectType)
68 return $this->cache
['objectTypeIDs'][$objectType] ??
null;
72 * Returns the comment object type with the given name or `null` if no such
75 * @param int $objectTypeID
76 * @return ObjectType|null
78 public function getObjectType($objectTypeID)
80 return $this->cache
['objectTypes'][$objectTypeID] ??
null;
84 * Returns comment manager object for given object type.
86 * @param string $objectType
87 * @return ICommentManager
88 * @throws SystemException
90 public function getCommentManager($objectType)
92 $objectTypeID = $this->getObjectTypeID($objectType);
93 if ($objectTypeID === null) {
94 throw new SystemException("Unable to find object type for '" . $objectType . "'");
97 return $this->getObjectType($objectTypeID)->getProcessor();
101 * Returns a comment list for a given object type and object id.
103 * @param ICommentManager $commentManager
104 * @param int $objectTypeID
105 * @param int $objectID
106 * @param bool $readObjects
107 * @return StructuredCommentList
109 public function getCommentList(ICommentManager
$commentManager, $objectTypeID, $objectID, $readObjects = true)
111 $commentList = new StructuredCommentList($commentManager, $objectTypeID, $objectID);
113 $commentList->readObjects();
120 * Removes all comments for given objects.
122 * @param string $objectType
123 * @param int[] $objectIDs
125 public function deleteObjects($objectType, array $objectIDs)
127 $objectTypeID = $this->getObjectTypeID($objectType);
128 $objectTypeObj = $this->getObjectType($objectTypeID);
131 $commentList = new CommentList();
132 $commentList->getConditionBuilder()->add('comment.objectTypeID = ?', [$objectTypeID]);
133 $commentList->getConditionBuilder()->add('comment.objectID IN (?)', [$objectIDs]);
134 $commentList->readObjectIDs();
135 $commentIDs = $commentList->getObjectIDs();
137 // no comments -> skip
138 if (empty($commentIDs)) {
143 $responseList = new CommentResponseList();
144 $responseList->getConditionBuilder()->add('comment_response.commentID IN (?)', [$commentIDs]);
145 $responseList->readObjectIDs();
146 $responseIDs = $responseList->getObjectIDs();
149 $notificationObjectTypes = [];
150 if (UserNotificationHandler
::getInstance()->getObjectTypeID($objectTypeObj->objectType
. '.like.notification')) {
151 $notificationObjectTypes[] = $objectTypeObj->objectType
. '.like.notification';
154 ReactionHandler
::getInstance()->removeReactions(
155 'com.woltlab.wcf.comment',
157 $notificationObjectTypes
160 // delete activity events
161 if (UserActivityEventHandler
::getInstance()->getObjectTypeID($objectTypeObj->objectType
. '.recentActivityEvent')) {
162 UserActivityEventHandler
::getInstance()
163 ->removeEvents($objectTypeObj->objectType
. '.recentActivityEvent', $commentIDs);
165 // delete notifications
166 if (UserNotificationHandler
::getInstance()->getObjectTypeID($objectTypeObj->objectType
. '.notification')) {
167 UserNotificationHandler
::getInstance()
168 ->removeNotifications($objectTypeObj->objectType
. '.notification', $commentIDs);
171 if (!empty($responseIDs)) {
172 // delete likes (for responses)
173 $notificationObjectTypes = [];
174 if (UserNotificationHandler
::getInstance()->getObjectTypeID($objectTypeObj->objectType
. '.response.like.notification')) {
175 $notificationObjectTypes[] = $objectTypeObj->objectType
. '.response.like.notification';
178 ReactionHandler
::getInstance()->removeReactions(
179 'com.woltlab.wcf.comment.response',
181 $notificationObjectTypes
184 // delete activity events (for responses)
185 if (UserActivityEventHandler
::getInstance()->getObjectTypeID($objectTypeObj->objectType
. '.response.recentActivityEvent')) {
186 UserActivityEventHandler
::getInstance()
187 ->removeEvents($objectTypeObj->objectType
. '.response.recentActivityEvent', $responseIDs);
189 // delete notifications (for responses)
190 if (UserNotificationHandler
::getInstance()->getObjectTypeID($objectTypeObj->objectType
. '.response.notification')) {
191 UserNotificationHandler
::getInstance()
192 ->removeNotifications($objectTypeObj->objectType
. '.response.notification', $responseIDs);
196 // delete comments / responses
197 CommentEditor
::deleteAll($commentIDs);
201 * Enforces the flood control.
203 * @throws NamedUserException if flood control is exceeded
205 public static function enforceFloodControl()
207 $floodControlTime = WCF
::getSession()->getPermission('user.comment.floodControlTime');
208 if (!$floodControlTime) {
212 $lastTime = FloodControl
::getInstance()->getLastTime('com.woltlab.wcf.comment');
213 if ($lastTime !== null && $lastTime > TIME_NOW
- $floodControlTime) {
214 throw new NamedUserException(WCF
::getLanguage()->getDynamicVariable(
215 'wcf.comment.error.floodControl',
216 ['lastCommentTime' => $lastTime]
222 * Marks all comment-related notifications for objects of the given object type and with
223 * the given ids as confirmed for the active user.
225 * @param string $objectType comment object type name
226 * @param int[] $objectIDs ids of the objects whose comment-related notifications will be marked as confirmed
227 * @param int $time only notifications older than the given timestamp will be marked as confirmed
228 * @throws \InvalidArgumentException if invalid comment object type name is given
231 public function markNotificationsAsConfirmed($objectType, array $objectIDs, $time = TIME_NOW
)
233 // notifications are only relevant for logged-in users
234 if (!WCF
::getUser()->userID
) {
238 if ($this->getObjectTypeID($objectType) === null) {
239 throw new \
InvalidArgumentException("Unknown comment object type '{$objectType}'.");
242 if (empty($objectIDs)) {
248 // mark comment notifications as confirmed
250 if (UserNotificationHandler
::getInstance()->getObjectTypeID($objectType . '.notification')) {
251 foreach (UserNotificationHandler
::getInstance()->getEvents($objectType . '.notification') as $event) {
252 $commentEvents[$event->eventID
] = [
253 'eventName' => $event->eventName
,
254 'objectType' => $objectType . '.notification',
259 if (!empty($commentEvents)) {
260 $notificationList = new UserNotificationList();
261 $notificationList->getConditionBuilder()->add(
262 'user_notification.eventID IN (?)',
263 [\array_keys
($commentEvents)]
265 $notificationList->getConditionBuilder()->add('user_notification.userID = ?', [WCF
::getUser()->userID
]);
266 $notificationList->sqlJoins
.= "
267 LEFT JOIN wcf" . WCF_N
. "_comment comment
268 ON comment.commentID = user_notification.objectID
269 AND comment.objectTypeID = " . \
intval($this->getObjectTypeID($objectType));
270 $notificationList->getConditionBuilder()->add('comment.objectID IN (?)', [$objectIDs]);
271 $notificationList->getConditionBuilder()->add('comment.time <= ?', [$time]);
272 $notificationList->readObjects();
274 $notificationObjectIDs = [];
275 foreach ($notificationList as $notification) {
276 if (!isset($notificationObjectIDs[$notification->eventID
])) {
277 $notificationObjectIDs[$notification->eventID
] = [];
280 $notificationObjectIDs[$notification->eventID
][] = $notification->objectID
;
283 if (!empty($notificationObjectIDs)) {
284 foreach ($notificationObjectIDs as $eventID => $commentIDs) {
285 UserNotificationHandler
::getInstance()->markAsConfirmed(
286 $commentEvents[$eventID]['eventName'],
287 $commentEvents[$eventID]['objectType'],
288 [WCF
::getUser()->userID
],
295 // mark comment reaction notifications as confirmed
296 $reactionCommentEvents = [];
297 if (UserNotificationHandler
::getInstance()->getObjectTypeID($objectType . '.like.notification') !== null) {
298 foreach (UserNotificationHandler
::getInstance()->getEvents($objectType . '.like.notification') as $event) {
299 $reactionCommentEvents[$event->eventID
] = [
300 'eventName' => $event->eventName
,
301 'objectType' => $objectType . '.like.notification',
306 if (!empty($reactionCommentEvents)) {
307 // the value of the `objectID` property of the notifications is the like object
308 // id which is currently unknown, thus it needs to be read from database
309 $notificationList = new UserNotificationList();
310 $notificationList->getConditionBuilder()->add(
311 'user_notification.eventID IN (?)',
312 [\array_keys
($reactionCommentEvents)]
314 $notificationList->getConditionBuilder()->add('user_notification.userID = ?', [WCF
::getUser()->userID
]);
315 $notificationList->sqlJoins
.= "
316 LEFT JOIN wcf" . WCF_N
. "_comment comment
317 ON comment.commentID = user_notification.baseObjectID
318 AND comment.objectTypeID = " . \
intval($this->getObjectTypeID($objectType));
319 $notificationList->getConditionBuilder()->add('comment.objectID IN (?)', [$objectIDs]);
320 $notificationList->getConditionBuilder()->add('comment.time <= ?', [$time]);
321 $notificationList->readObjects();
323 $notificationObjectIDs = [];
324 foreach ($notificationList as $notification) {
325 if (!isset($notificationObjectIDs[$notification->eventID
])) {
326 $notificationObjectIDs[$notification->eventID
] = [];
329 $notificationObjectIDs[$notification->eventID
][] = $notification->objectID
;
332 if (!empty($notificationObjectIDs)) {
333 foreach ($notificationObjectIDs as $eventID => $reactionIDs) {
334 UserNotificationHandler
::getInstance()->markAsConfirmed(
335 $reactionCommentEvents[$eventID]['eventName'],
336 $reactionCommentEvents[$eventID]['objectType'],
337 [WCF
::getUser()->userID
],
346 // mark response notifications as confirmed
347 $responseEvents = [];
348 if (UserNotificationHandler
::getInstance()->getObjectTypeID($objectType . '.response.notification')) {
349 foreach (UserNotificationHandler
::getInstance()->getEvents($objectType . '.response.notification') as $event) {
350 $responseEvents[$event->eventID
] = [
351 'eventName' => $event->eventName
,
352 'objectType' => $objectType . '.response.notification',
357 if (!empty($responseEvents)) {
358 $notificationList = new UserNotificationList();
359 $notificationList->getConditionBuilder()->add(
360 'user_notification.eventID IN (?)',
361 [\array_keys
($responseEvents)]
363 $notificationList->getConditionBuilder()->add('user_notification.userID = ?', [WCF
::getUser()->userID
]);
364 $notificationList->sqlJoins
.= "
365 LEFT JOIN wcf" . WCF_N
. "_comment_response comment_response
366 ON comment_response.responseID = user_notification.objectID
367 LEFT JOIN wcf" . WCF_N
. "_comment comment
368 ON comment.commentID = comment_response.commentID";
369 $notificationList->getConditionBuilder()->add(
370 'comment.objectTypeID IN (?)',
371 [$this->getObjectTypeID($objectType)]
373 $notificationList->getConditionBuilder()->add('comment.objectID IN (?)', [$objectIDs]);
374 $notificationList->getConditionBuilder()->add('comment_response.time <= ?', [$time]);
375 $notificationList->readObjects();
377 $notificationObjectIDs = [];
378 foreach ($notificationList as $notification) {
379 if (!isset($notificationObjectIDs[$notification->eventID
])) {
380 $notificationObjectIDs[$notification->eventID
] = [];
383 $notificationObjectIDs[$notification->eventID
][] = $notification->objectID
;
386 if (!empty($notificationObjectIDs)) {
387 foreach ($notificationObjectIDs as $eventID => $responseIDs) {
388 UserNotificationHandler
::getInstance()->markAsConfirmed(
389 $responseEvents[$eventID]['eventName'],
390 $responseEvents[$eventID]['objectType'],
391 [WCF
::getUser()->userID
],
398 // mark comment response reaction notifications as confirmed
399 $reactionResponseEvents = [];
400 if (UserNotificationHandler
::getInstance()->getObjectTypeID($objectType . '.response.like.notification') !== null) {
401 foreach (UserNotificationHandler
::getInstance()->getEvents($objectType . '.response.like.notification') as $event) {
402 $reactionResponseEvents[$event->eventID
] = [
403 'eventName' => $event->eventName
,
404 'objectType' => $objectType . '.response.like.notification',
409 if (!empty($reactionResponseEvents)) {
410 // the value of the `objectID` property of the notifications is the like object
411 // id which is currently unknown, thus it needs to be read from database
412 $notificationList = new UserNotificationList();
413 $notificationList->getConditionBuilder()->add(
414 'user_notification.eventID IN (?)',
415 [\array_keys
($reactionResponseEvents)]
417 $notificationList->getConditionBuilder()->add('user_notification.userID = ?', [WCF
::getUser()->userID
]);
418 $notificationList->sqlJoins
.= "
419 LEFT JOIN wcf" . WCF_N
. "_comment_response comment_response
420 ON comment_response.responseID = user_notification.baseObjectID
421 LEFT JOIN wcf" . WCF_N
. "_comment comment
422 ON comment.commentID = comment_response.commentID";
423 $notificationList->getConditionBuilder()->add(
424 'comment.objectTypeID IN (?)',
425 [$this->getObjectTypeID($objectType)]
427 $notificationList->getConditionBuilder()->add('comment.objectID IN (?)', [$objectIDs]);
428 $notificationList->getConditionBuilder()->add('comment_response.time <= ?', [$time]);
429 $notificationList->readObjects();
431 $notificationObjectIDs = [];
432 foreach ($notificationList as $notification) {
433 if (!isset($notificationObjectIDs[$notification->eventID
])) {
434 $notificationObjectIDs[$notification->eventID
] = [];
437 $notificationObjectIDs[$notification->eventID
][] = $notification->objectID
;
440 if (!empty($notificationObjectIDs)) {
441 foreach ($notificationObjectIDs as $eventID => $reactionIDs) {
442 UserNotificationHandler
::getInstance()->markAsConfirmed(
443 $reactionResponseEvents[$eventID]['eventName'],
444 $reactionResponseEvents[$eventID]['objectType'],
445 [WCF
::getUser()->userID
],
454 * Marks all comment-related notifications for objects of the given object type in the
455 * given comment list as confirmed for the active user.
457 * @param string $objectType comment object type name
458 * @param StructuredComment[] $comments comments whose notifications will be marked as read
459 * @throws \InvalidArgumentException if invalid comment object type name is given
462 public function markNotificationsAsConfirmedForComments($objectType, array $comments)
464 // notifications are only relevant for logged-in users
465 if (!WCF
::getUser()->userID
) {
469 if ($this->getObjectTypeID($objectType) === null) {
470 throw new \
InvalidArgumentException("Unknown comment object type '{$objectType}'.");
473 if (\
count($comments) === 0) {
478 foreach ($comments as $comment) {
479 $commentIDs[] = $comment->commentID
;
484 // mark comment notifications as confirmed
486 if (UserNotificationHandler
::getInstance()->getObjectTypeID($objectType . '.notification')) {
487 foreach (UserNotificationHandler
::getInstance()->getEvents($objectType . '.notification') as $event) {
488 $commentEvents[$event->eventID
] = [
489 'eventName' => $event->eventName
,
490 'objectType' => $objectType . '.notification',
495 if (!empty($commentEvents)) {
496 foreach ($commentEvents as $eventData) {
497 UserNotificationHandler
::getInstance()->markAsConfirmed(
498 $eventData['eventName'],
499 $eventData['objectType'],
500 [WCF
::getUser()->userID
],
506 // mark comment reaction notifications as confirmed
507 $reactionCommentEvents = [];
508 if (UserNotificationHandler
::getInstance()->getObjectTypeID($objectType . '.like.notification') !== null) {
509 foreach (UserNotificationHandler
::getInstance()->getEvents($objectType . '.like.notification') as $event) {
510 $reactionCommentEvents[$event->eventID
] = [
511 'eventName' => $event->eventName
,
512 'objectType' => $objectType . '.like.notification',
517 if (!empty($reactionCommentEvents)) {
518 // the value of the `objectID` property of the notifications is the like object
519 // id which is currently unknown, thus it needs to be read from database
520 $notificationList = new UserNotificationList();
521 $notificationList->getConditionBuilder()->add(
522 'user_notification.eventID IN (?)',
523 [\array_keys
($reactionCommentEvents)]
525 $notificationList->getConditionBuilder()->add('user_notification.userID = ?', [WCF
::getUser()->userID
]);
526 $notificationList->getConditionBuilder()->add('user_notification.baseObjectID IN (?)', [$commentIDs]);
527 $notificationList->readObjects();
530 foreach ($notificationList as $notification) {
531 if (!isset($objectIDs[$notification->eventID
])) {
532 $objectIDs[$notification->eventID
] = [];
535 $objectIDs[$notification->eventID
][] = $notification->objectID
;
538 if (!empty($objectIDs)) {
539 foreach ($objectIDs as $eventID => $reactionIDs) {
540 UserNotificationHandler
::getInstance()->markAsConfirmed(
541 $reactionCommentEvents[$eventID]['eventName'],
542 $reactionCommentEvents[$eventID]['objectType'],
543 [WCF
::getUser()->userID
],
553 foreach ($comments as $comment) {
554 // as we do not know whether `Comment::getUnfilteredResponseIDs()`
555 // or `Comment::getResponseIDs()` has been used, collect response
557 foreach ($comment as $response) {
558 $responseIDs[] = $response->responseID
;
562 if (!empty($responseIDs)) {
563 // mark response notifications as confirmed
564 $responseEvents = [];
565 if (UserNotificationHandler
::getInstance()->getObjectTypeID($objectType . '.response.notification')) {
566 foreach (UserNotificationHandler
::getInstance()->getEvents($objectType . '.response.notification') as $event) {
567 $responseEvents[$event->eventID
] = [
568 'eventName' => $event->eventName
,
569 'objectType' => $objectType . '.response.notification',
574 if (!empty($responseEvents)) {
575 foreach ($responseEvents as $eventData) {
576 UserNotificationHandler
::getInstance()->markAsConfirmed(
577 $eventData['eventName'],
578 $eventData['objectType'],
579 [WCF
::getUser()->userID
],
585 // mark comment response reaction notifications as confirmed
586 $reactionResponseEvents = [];
587 if (UserNotificationHandler
::getInstance()->getObjectTypeID($objectType . '.response.like.notification') !== null) {
588 foreach (UserNotificationHandler
::getInstance()->getEvents($objectType . '.response.like.notification') as $event) {
589 $reactionResponseEvents[$event->eventID
] = [
590 'eventName' => $event->eventName
,
591 'objectType' => $objectType . '.response.like.notification',
596 if (!empty($reactionResponseEvents)) {
597 // the value of the `objectID` property of the notifications is the like object
598 // id which is currently unknown, thus it needs to be read from database
599 $notificationList = new UserNotificationList();
600 $notificationList->getConditionBuilder()->add(
601 'user_notification.eventID IN (?)',
602 [\array_keys
($reactionResponseEvents)]
604 $notificationList->getConditionBuilder()->add(
605 'user_notification.userID = ?',
606 [WCF
::getUser()->userID
]
608 $notificationList->getConditionBuilder()->add('user_notification.baseObjectID IN (?)', [$responseIDs]);
609 $notificationList->readObjects();
612 foreach ($notificationList as $notification) {
613 if (!isset($objectIDs[$notification->eventID
])) {
614 $objectIDs[$notification->eventID
] = [];
617 $objectIDs[$notification->eventID
][] = $notification->objectID
;
620 if (!empty($objectIDs)) {
621 foreach ($objectIDs as $eventID => $reactionIDs) {
622 UserNotificationHandler
::getInstance()->markAsConfirmed(
623 $reactionResponseEvents[$eventID]['eventName'],
624 $reactionResponseEvents[$eventID]['objectType'],
625 [WCF
::getUser()->userID
],
635 * Marks all comment response-related notifications for objects of the given object type in
636 * the given comment response list as confirmed for the active user.
638 * @param string $objectType comment object type name
639 * @param CommentResponse[] $responses comment responses whose notifications will be marked as read
641 * @throws \InvalidArgumentException if invalid comment object type name is given
644 public function markNotificationsAsConfirmedForResponses($objectType, array $responses)
646 // notifications are only relevant for logged-in users
647 if (!WCF
::getUser()->userID
) {
651 if ($this->getObjectTypeID($objectType) === null) {
652 throw new \
InvalidArgumentException("Unknown comment object type '{$objectType}'.");
655 if (\
count($responses) === 0) {
660 foreach ($responses as $response) {
661 $responseIDs[] = $response->responseID
;
664 $responseEvents = [];
665 if (UserNotificationHandler
::getInstance()->getObjectTypeID($objectType . '.response.notification')) {
666 foreach (UserNotificationHandler
::getInstance()->getEvents($objectType . '.response.notification') as $event) {
667 $responseEvents[$event->eventID
] = [
668 'eventName' => $event->eventName
,
669 'objectType' => $objectType . '.response.notification',
674 if (!empty($responseEvents)) {
675 foreach ($responseEvents as $eventData) {
676 UserNotificationHandler
::getInstance()->markAsConfirmed(
677 $eventData['eventName'],
678 $eventData['objectType'],
679 [WCF
::getUser()->userID
],
685 // mark comment response reaction notifications as confirmed
686 $reactionResponseEvents = [];
687 if (UserNotificationHandler
::getInstance()->getObjectTypeID($objectType . '.response.like.notification') !== null) {
688 foreach (UserNotificationHandler
::getInstance()->getEvents($objectType . '.response.like.notification') as $event) {
689 $reactionResponseEvents[$event->eventID
] = [
690 'eventName' => $event->eventName
,
691 'objectType' => $objectType . '.response.like.notification',
696 if (!empty($reactionResponseEvents)) {
697 // the value of the `objectID` property of the notifications is the like object
698 // id which is currently unknown, thus it needs to be read from database
699 $notificationList = new UserNotificationList();
700 $notificationList->getConditionBuilder()->add(
701 'user_notification.eventID IN (?)',
702 [\array_keys
($reactionResponseEvents)]
704 $notificationList->getConditionBuilder()->add('user_notification.userID = ?', [WCF
::getUser()->userID
]);
705 $notificationList->getConditionBuilder()->add('user_notification.baseObjectID IN (?)', [$responseIDs]);
706 $notificationList->readObjects();
709 foreach ($notificationList as $notification) {
710 if (!isset($objectIDs[$notification->eventID
])) {
711 $objectIDs[$notification->eventID
] = [];
714 $objectIDs[$notification->eventID
][] = $notification->objectID
;
717 if (!empty($objectIDs)) {
718 foreach ($objectIDs as $eventID => $reactionIDs) {
719 UserNotificationHandler
::getInstance()->markAsConfirmed(
720 $reactionResponseEvents[$eventID]['eventName'],
721 $reactionResponseEvents[$eventID]['objectType'],
722 [WCF
::getUser()->userID
],
731 * Enforces the censorship.
733 * @param string $text
734 * @throws UserInputException
736 public static function enforceCensorship($text)
738 // search for censored words
739 if (ENABLE_CENSORSHIP
) {
740 $result = Censorship
::getInstance()->test($text);
742 throw new UserInputException(
744 WCF
::getLanguage()->getDynamicVariable(
745 'wcf.message.error.censoredWordsFound',
746 ['censoredWords' => $result]