From 9143dcd95be999e8867b277802126f24c75a2287 Mon Sep 17 00:00:00 2001 From: Matthias Schmidt Date: Fri, 23 Oct 2020 14:54:32 +0200 Subject: [PATCH] Add flood control methods to count contents in certain period of time --- .../lib/system/flood/FloodControl.class.php | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/wcfsetup/install/files/lib/system/flood/FloodControl.class.php b/wcfsetup/install/files/lib/system/flood/FloodControl.class.php index 82020b7d22..0eeb39de8f 100644 --- a/wcfsetup/install/files/lib/system/flood/FloodControl.class.php +++ b/wcfsetup/install/files/lib/system/flood/FloodControl.class.php @@ -3,6 +3,7 @@ namespace wcf\system\flood; use wcf\data\object\type\ObjectTypeCache; use wcf\system\SingletonFactory; use wcf\system\WCF; +use wcf\util\DateUtil; use wcf\util\UserUtil; /** @@ -15,6 +16,71 @@ use wcf\util\UserUtil; * @since 5.4 */ class FloodControl extends SingletonFactory { + /** + * Returns the number of contents by a certain identifier type within a certain + * period of time `[$time-$interval, $time]` and the earliest time within the period content + * was created. + */ + protected function countContentByIdentifier(string $objectType, string $identifier, \DateInterval $interval, int $time): array { + $sql = "SELECT COUNT(*) AS count, MIN(time) AS earliestTime + FROM wcf" . WCF_N . "_flood_control + WHERE objectTypeID = ? + AND identifier = ? + AND time >= ? + AND time <= ?"; + $statement = WCF::getDB()->prepareStatement($sql); + $statement->execute([ + $this->getObjectTypeID($objectType), + $identifier, + DateUtil::getDateTimeByTimestamp($time)->sub($interval)->getTimestamp(), + $time, + ]); + + return $statement->fetchSingleRow(); + } + + /** + * Returns the number of contents the active user created of the given type within a certain + * period of time `[$time-$interval, $time]` and the earliest time within the period content + * was created. + */ + public function countContent(string $objectType, \DateInterval $interval, int $time = TIME_NOW): array { + if (WCF::getUser()->userID) { + return $this->countUserContent($objectType, WCF::getUser()->userID, $interval, $time); + } + else { + return $this->countGuestContent($objectType, UserUtil::getIpAddress(), $interval, $time); + } + } + + /** + * Returns the number of contents a guest created of the given type within a certain period + * of time `[$time-$interval, $time]` and the earliest time within the period content was + * created. + */ + public function countGuestContent(string $objectType, string $ipAddress, \DateInterval $interval, int $time = TIME_NOW): array { + return $this->countContentByIdentifier( + $objectType, + $this->getUserIdentifier($objectType, $ipAddress), + $interval, + $time + ); + } + + /** + * Returns the number of contents a user created of the given type within a certain period + * of time `[$time-$interval, $time]` and the earliest time within the period content was + * created. + */ + public function countUserContent(string $objectType, int $userID, \DateInterval $interval, int $time = TIME_NOW): array { + return $this->countContentByIdentifier( + $objectType, + $this->getUserIdentifier($objectType, $userID), + $interval, + $time + ); + } + /** * Returns the identifier used for a guest with the given ip address for content of the * given object type. -- 2.20.1