From: Alexander Ebert Date: Thu, 19 Jun 2014 16:17:56 +0000 (+0200) Subject: Improved notifications, now counting trigger count X-Git-Tag: 2.1.0_Alpha_1~669^2~11 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=68206b3f8dc4c083449e504978ff1e615b35fa74;p=GitHub%2FWoltLab%2FWCF.git Improved notifications, now counting trigger count --- diff --git a/wcfsetup/install/files/lib/data/user/notification/UserNotificationAction.class.php b/wcfsetup/install/files/lib/data/user/notification/UserNotificationAction.class.php index ca46ccd38e..ec11526ad1 100644 --- a/wcfsetup/install/files/lib/data/user/notification/UserNotificationAction.class.php +++ b/wcfsetup/install/files/lib/data/user/notification/UserNotificationAction.class.php @@ -86,7 +86,7 @@ class UserNotificationAction extends AbstractDatabaseObjectAction { // get existing notifications $notificationList = new UserNotificationList(); $notificationList->getConditionBuilder()->add("eventID = ?", array($this->parameters['data']['eventID'])); - $notificationList->getConditionBuilder()->add("objectID = ?", array($this->parameters['data']['objectID'])); + $notificationList->getConditionBuilder()->add("eventHash = ?", array($this->parameters['data']['eventHash'])); $notificationList->getConditionBuilder()->add("userID IN (?)", array(array_keys($this->parameters['recipients']))); $notificationList->getConditionBuilder()->add("confirmed = ?", array(0)); $notificationList->readObjects(); @@ -127,6 +127,21 @@ class UserNotificationAction extends AbstractDatabaseObjectAction { } WCF::getDB()->commitTransaction(); + // update trigger count + $sql = "UPDATE wcf".WCF_N."_user_notification + SET timesTriggered = timesTriggered + ? + WHERE notificationID = ?"; + $statement = WCF::getDB()->prepareStatement($sql); + + WCF::getDB()->beginTransaction(); + foreach ($notifications as $notificationData) { + $statement->execute(array( + 1, + $notificationData['object']->notificationID + )); + } + WCF::getDB()->commitTransaction(); + return $notifications; } diff --git a/wcfsetup/install/files/lib/system/user/notification/UserNotificationHandler.class.php b/wcfsetup/install/files/lib/system/user/notification/UserNotificationHandler.class.php index bd51ddee2b..344964ed6a 100644 --- a/wcfsetup/install/files/lib/system/user/notification/UserNotificationHandler.class.php +++ b/wcfsetup/install/files/lib/system/user/notification/UserNotificationHandler.class.php @@ -14,7 +14,6 @@ use wcf\system\database\util\PreparedStatementConditionBuilder; use wcf\system\exception\SystemException; use wcf\system\mail\Mail; use wcf\system\user\notification\event\IUserNotificationEvent; -use wcf\system\user\notification\object\IStackableUserNotificationObject; use wcf\system\user\notification\object\IUserNotificationObject; use wcf\system\user\storage\UserStorageHandler; use wcf\system\SingletonFactory; @@ -110,7 +109,7 @@ class UserNotificationHandler extends SingletonFactory { $conditions = new PreparedStatementConditionBuilder(); $conditions->add("userID IN (?)", array($recipientIDs)); $conditions->add("eventID = ?", array($event->eventID)); - $conditions->add("objectID = ?", array($notificationObject->getObjectID())); + $conditions->add("eventHash = ?", array($event->getEventHash())); $conditions->add("confirmed = ?", array(0)); $sql = "SELECT notificationID, userID @@ -123,34 +122,55 @@ class UserNotificationHandler extends SingletonFactory { $notifications[$row['userID']] = $row['notificationID']; } - // skip recipients with outstanding notifications - if (!empty($notifications)) { - // filter by author + // check if event supports stacking and author should be added + if (!empty($notifications) && $event->isStackable()) { + $conditions = new PreparedStatementConditionBuilder(); + $conditions->add("notificationID IN (?)", array(array_values($notifications))); if ($notificationObject->getAuthorID()) { - $conditions = new PreparedStatementConditionBuilder(); - $conditions->add("notificationID IN (?)", array(array_values($notifications))); $conditions->add("authorID = ?", array($notificationObject->getAuthorID())); - - $sql = "SELECT notificationID - FROM wcf".WCF_N."_user_notification_author - ".$conditions; - $statement = WCF::getDB()->prepareStatement($sql); - $statement->execute($conditions->getParameters()); - $notificationIDs = array(); - while ($row = $statement->fetchArray()) { - $notificationIDs[] = $row['notificationID']; - } - + } + else { + $conditions->add("authorID IS NULL"); + } + + $sql = "SELECT notificationID + FROM wcf".WCF_N."_user_notification_author + ".$conditions; + $statement = WCF::getDB()->prepareStatement($sql); + $statement->execute($conditions->getParameters()); + $notificationIDs = array(); + while ($row = $statement->fetchArray()) { + $notificationIDs[] = $row['notificationID']; + } + + if (!empty($notificationIDs)) { + // filter array of existing notifications and remove values which do not have a notification from this author yet (inverse logic!) foreach ($notifications as $userID => $notificationID) { - // do not skip recipients with a similar notification but authored by somebody else if (!in_array($notificationID, $notificationIDs)) { unset($notifications[$userID]); } } + + // update trigger count + $sql = "UPDATE wcf".WCF_N."_user_notification + SET timesTriggered = timesTriggered + ? + WHERE notificationID = ?"; + $statement = WCF::getDB()->prepareStatement($sql); + + WCF::getDB()->beginTransaction(); + foreach ($notificationIDs as $notificationID) { + $statement->execute(array( + 1, + $notificationID + )); + } + WCF::getDB()->commitTransaction(); } - - $recipientIDs = array_diff($recipientIDs, array_keys($notifications)); - if (empty($recipientIDs)) return; + } + + $recipientIDs = array_diff($recipientIDs, array_keys($notifications)); + if (empty($recipientIDs)) { + return; } // get recipients @@ -165,7 +185,8 @@ class UserNotificationHandler extends SingletonFactory { 'data' => array( 'eventID' => $event->eventID, 'authorID' => ($event->getAuthorID() ?: null), - + 'objectID' => $notificationObject->getObjectID(), + 'eventHash' => $event->getEventHash(), 'packageID' => $objectTypeObject->packageID, 'time' => TIME_NOW, 'additionalData' => serialize($additionalData) @@ -173,15 +194,13 @@ class UserNotificationHandler extends SingletonFactory { 'recipients' => $recipients ); - if ($event->isStackable() && $notificationObject instanceof IStackableUserNotificationObject) { - $data['data']['objectID'] = $notificationObject->getRelatedObjectID(); + if ($event->isStackable()) { $data['notifications'] = $notifications; $action = new UserNotificationAction(array(), 'createStackable', $data); } else { - $data['data']['objectID'] = $notificationObject->getObjectID(); - + $data['data']['timesTriggered'] = 1; $action = new UserNotificationAction(array(), 'createDefault', $data); } @@ -277,7 +296,7 @@ class UserNotificationHandler extends SingletonFactory { if (!$showConfirmedNotifications) $conditions->add("notification.confirmed = ?", array(0)); $sql = "SELECT notification.notificationID, notification_event.eventID, notification.authorID, - notification.moreAuthors, object_type.objectType, notification.objectID, + notification.timesTriggered, object_type.objectType, notification.objectID, notification.additionalData, notification.time".($showConfirmedNotifications ? ", notification.confirmed" : "")." FROM wcf".WCF_N."_user_notification notification @@ -371,7 +390,8 @@ class UserNotificationHandler extends SingletonFactory { $notificationObjects[$notificationID], $objectTypes[$event['objectType']]['objects'][$event['objectID']], (isset($authors[$event['authorID']]) ? $authors[$event['authorID']] : $unknownAuthor), - unserialize($event['additionalData']) + unserialize($event['additionalData']), + $event['timesTriggered'] ); if (isset($authorToNotification[$notificationID])) { diff --git a/wcfsetup/install/files/lib/system/user/notification/event/AbstractUserNotificationEvent.class.php b/wcfsetup/install/files/lib/system/user/notification/event/AbstractUserNotificationEvent.class.php index 5c3b7296da..20a5a68d47 100644 --- a/wcfsetup/install/files/lib/system/user/notification/event/AbstractUserNotificationEvent.class.php +++ b/wcfsetup/install/files/lib/system/user/notification/event/AbstractUserNotificationEvent.class.php @@ -6,7 +6,6 @@ use wcf\data\user\UserProfile; use wcf\data\DatabaseObjectDecorator; use wcf\system\user\notification\object\IUserNotificationObject; use wcf\system\WCF; -use wcf\util\StringUtil; /** * Provides default a implementation for user notification events. @@ -40,7 +39,7 @@ abstract class AbstractUserNotificationEvent extends DatabaseObjectDecorator imp * notification stacking support * @var boolean */ - protected $isStackable = false; + protected $stackable = false; /** * user notification @@ -66,6 +65,12 @@ abstract class AbstractUserNotificationEvent extends DatabaseObjectDecorator imp */ protected $language = null; + /** + * notification trigger count + * @var integer + */ + protected $timesTriggered = 0; + /** * @see \wcf\system\user\notification\event\IUserNotificationEvent::setAuthors() */ @@ -76,11 +81,12 @@ abstract class AbstractUserNotificationEvent extends DatabaseObjectDecorator imp /** * @see \wcf\system\user\notification\event\IUserNotificationEvent::setObject() */ - public function setObject(UserNotification $notification, IUserNotificationObject $object, UserProfile $author, array $additionalData = array()) { + public function setObject(UserNotification $notification, IUserNotificationObject $object, UserProfile $author, array $additionalData = array(), $timesTriggered = 0) { $this->notification = $notification; $this->userNotificationObject = $object; $this->author = $author; $this->additionalData = $additionalData; + $this->timesTriggered = $timesTriggered; } /** @@ -149,6 +155,13 @@ abstract class AbstractUserNotificationEvent extends DatabaseObjectDecorator imp return $this->getMessage(); } + /** + * @see \wcf\system\user\notification\event\IUserNotificationEvent::getEventHash() + */ + public function getEventHash() { + return sha1($this->eventID . '-' . $this->userNotificationObject->getObjectID()); + } + /** * @see \wcf\system\user\notification\event\IUserNotificationEvent::setLanguage() */ @@ -170,6 +183,6 @@ abstract class AbstractUserNotificationEvent extends DatabaseObjectDecorator imp * @see \wcf\system\user\notification\event\IUserNotificationEvent::isStackable() */ public function isStackable() { - return $this->isStackable; + return $this->stackable; } } diff --git a/wcfsetup/install/files/lib/system/user/notification/event/IUserNotificationEvent.class.php b/wcfsetup/install/files/lib/system/user/notification/event/IUserNotificationEvent.class.php index bf8f23da7f..f883b42739 100644 --- a/wcfsetup/install/files/lib/system/user/notification/event/IUserNotificationEvent.class.php +++ b/wcfsetup/install/files/lib/system/user/notification/event/IUserNotificationEvent.class.php @@ -88,6 +88,13 @@ interface IUserNotificationEvent extends IDatabaseObjectProcessor { */ public function setAuthors(array $authors); + /** + * Returns a unique identifier of the event. + * + * @return string + */ + public function getEventHash(); + /** * Sets the object for the event. * @@ -95,8 +102,9 @@ interface IUserNotificationEvent extends IDatabaseObjectProcessor { * @param \wcf\system\user\notification\object\IUserNotificationObject $object * @param \wcf\data\user\UserProfile $author * @param array $additionalData + * @param integer $timesTriggered */ - public function setObject(UserNotification $notification, IUserNotificationObject $object, UserProfile $author, array $additionalData = array()); + public function setObject(UserNotification $notification, IUserNotificationObject $object, UserProfile $author, array $additionalData = array(), $timesTriggered = 0); /** * Sets the language for the event diff --git a/wcfsetup/install/files/lib/system/user/notification/event/UserFollowFollowingUserNotificationEvent.class.php b/wcfsetup/install/files/lib/system/user/notification/event/UserFollowFollowingUserNotificationEvent.class.php index e98073a3f6..475eea5430 100644 --- a/wcfsetup/install/files/lib/system/user/notification/event/UserFollowFollowingUserNotificationEvent.class.php +++ b/wcfsetup/install/files/lib/system/user/notification/event/UserFollowFollowingUserNotificationEvent.class.php @@ -14,9 +14,9 @@ use wcf\system\request\LinkHandler; */ class UserFollowFollowingUserNotificationEvent extends AbstractUserNotificationEvent { /** - * @see \wcf\system\user\notification\event\AbstractUserNotificationEvent::$isStackable + * @see \wcf\system\user\notification\event\AbstractUserNotificationEvent::$stackable */ - protected $isStackable = true; + protected $stackable = true; /** * @see \wcf\system\user\notification\event\IUserNotificationEvent::getTitle() @@ -62,4 +62,11 @@ class UserFollowFollowingUserNotificationEvent extends AbstractUserNotificationE public function getLink() { return LinkHandler::getInstance()->getLink('User', array('object' => $this->author)); } + + /** + * @see \wcf\system\user\notification\event\IUserNotificationEvent::getEventHash() + */ + public function getEventHash() { + return sha1($this->eventID . '-' . $this->userNotificationObject->followUserID); + } } diff --git a/wcfsetup/setup/db/install.sql b/wcfsetup/setup/db/install.sql index f5df2f9b36..5083ede344 100644 --- a/wcfsetup/setup/db/install.sql +++ b/wcfsetup/setup/db/install.sql @@ -1212,8 +1212,9 @@ CREATE TABLE wcf1_user_notification ( packageID INT(10) NOT NULL, -- DEPRECATED eventID INT(10) NOT NULL, objectID INT(10) NOT NULL DEFAULT 0, + eventHash VARCHAR(40) NOT NULL DEFAULT '', authorID INT(10) NULL, - moreAuthors INT(10) NOT NULL DEFAULT 0, + timesTriggered INT(10) NOT NULL DEFAULT 0, userID INT(10) NOT NULL, time INT(10) NOT NULL DEFAULT 0, mailNotified TINYINT(1) NOT NULL DEFAULT 0, @@ -1228,7 +1229,6 @@ CREATE TABLE wcf1_user_notification_author ( notificationID INT(10) NOT NULL, authorID INT(10) NOT NULL, time INT(10) NOT NULL DEFAULT 0, - canceled TINYINT(1) NOT NULL DEFAULT 0, UNIQUE KEY (notificationID, authorID) );