{include file='header' sidebarOrientation='left'}
<header class="boxHeadline">
- <h1>{lang}wcf.user.notification.notifications{/lang} <span class="badge jsNotificationsBadge">{#$__wcf->getUserNotificationHandler()->getNotificationCount()}</span></h1>
+ <h1>{lang}wcf.user.notification.notifications{/lang} <span class="badge jsNotificationsBadge">{#$__wcf->getUserNotificationHandler()->countAllNotifications()}</span></h1>
</header>
{include file='userNotice'}
<nav>
<ul>
{content}
- {if $notifications[notifications]}<li class="jsOnly"><a class="button jsMarkAllAsConfirmed"><span class="icon icon16 icon-remove"></span> <span>{lang}wcf.user.notification.markAllAsConfirmed{/lang}</span></a></li>{/if}
+ {if $__wcf->getUserNotificationHandler()->getNotificationCount()}<li class="jsOnly"><a class="button jsMarkAllAsConfirmed"><span class="icon icon16 fa-check"></span> <span>{lang}wcf.user.notification.markAllAsConfirmed{/lang}</span></a></li>{/if}
{event name='contentNavigationButtonsTop'}
{/content}
<div class="details">
<div class="containerHeadline">
<h3>
+ {if !$notification[confirmed]}<span class="badge label newContentBadge">{lang}wcf.message.new{/lang}</span>{/if}
+
{if $notification[event]->getAuthor()->userID}
<a href="{link controller='User' object=$notification[event]->getAuthor()}{/link}" class="userLink" data-user-id="{@$notification[event]->getAuthor()->userID}">{$notification[event]->getAuthor()->username}</a>
{else}
<p>{@$notification[event]->getMessage()}</p>
- <nav class="jsMobileNavigation buttonGroupNavigation">
- <ul class="buttonList iconList jsOnly">
- <li><a class="jsMarkAsConfirmed jsTooltip" title="{lang}wcf.user.notification.markAsConfirmed{/lang}"><span class="icon icon16 icon-remove"></span></a></li>
- </ul>
- </nav>
+ {if !$notification[confirmed]}
+ <nav class="jsMobileNavigation buttonGroupNavigation">
+ <ul class="buttonList iconList jsOnly">
+ <li><a class="jsMarkAsConfirmed jsTooltip" title="{lang}wcf.user.notification.markAsConfirmed{/lang}"><span class="icon icon16 fa-check"></span></a></li>
+ </ul>
+ </nav>
+ {/if}
</div>
</div>
</li>
*/
_addDefaultItems: function(dropdownMenu) {
this._addDivider(dropdownMenu);
- if (this._container.data('count')) {
- $('<li><a href="' + this._showAllLink + '">' + WCF.Language.get('wcf.user.notification.showAll') + '</a></li>').appendTo(dropdownMenu);
- this._addDivider(dropdownMenu);
- }
+ $('<li><a href="' + this._showAllLink + '">' + WCF.Language.get('wcf.user.notification.showAll') + '</a></li>').appendTo(dropdownMenu);
+ this._addDivider(dropdownMenu);
$('<li id="userNotificationsMarkAllAsConfirmed"><a>' + WCF.Language.get('wcf.user.notification.markAllAsConfirmed') + '</a></li>').click($.proxy(this._markAllAsConfirmed, this)).appendTo(dropdownMenu);
},
return;
}
- this._items[data.returnValues.notificationID].remove();
- delete this._items[data.returnValues.notificationID];
-
- // reduce badge count
- this._badge.html(data.returnValues.totalCount);
+ this._items[data.returnValues.notificationID].find('.newContentBadge').remove();
+ this._items[data.returnValues.notificationID].find('.jsMarkAsConfirmed').parents('nav:eq(0)').remove();
// remove previous notification count
document.title = document.title.replace(/^\(([0-9]+)\) /, '');
if (data.returnValues.totalCount > 0) {
document.title = '(' + data.returnValues.totalCount + ') ' + document.title;
}
+ else {
+ var $listItem = $('.contentNavigation .jsMarkAllAsConfirmed').parent();
+ var $list = $listItem.parent();
+ $listItem.remove();
+
+ if (!$list.children('li').length) {
+ $list.parents('nav:eq(0)').remove();
+ }
+ }
break;
}
}
*/
public function markAsConfirmed() {
if (!isset($this->parameters['alreadyConfirmed'])) {
- $sql = "DELETE FROM wcf".WCF_N."_user_notification_to_user
- WHERE notificationID = ?
- AND userID = ?";
+ $sql = "UPDATE wcf".WCF_N."_user_notification_to_user
+ SET confirmed = ?
+ WHERE notificationID = ?
+ AND userID = ?";
$statement = WCF::getDB()->prepareStatement($sql);
$statement->execute(array(
+ 1,
$this->parameters['notificationID'],
WCF::getUser()->userID
));
- // remove entirely read notifications
- $sql = "SELECT COUNT(*) as count
- FROM wcf".WCF_N."_user_notification_to_user
- WHERE notificationID = ?";
- $statement = WCF::getDB()->prepareStatement($sql);
- $statement->execute(array($this->parameters['notificationID']));
- $row = $statement->fetchArray();
- if (!$row['count']) {
- UserNotificationEditor::deleteAll(array($this->parameters['notificationID']));
- }
-
// reset notification count
UserStorageHandler::getInstance()->reset(array(WCF::getUser()->userID), 'userNotificationCount');
}
*/
public function markAllAsConfirmed() {
// remove notifications for this user
- $sql = "DELETE FROM wcf".WCF_N."_user_notification_to_user
- WHERE userID = ?";
+ $sql = "UPDATE wcf".WCF_N."_user_notification_to_user
+ SET confirmed = ?
+ WHERE userID = ?";
$statement = WCF::getDB()->prepareStatement($sql);
- $statement->execute(array(WCF::getUser()->userID));
+ $statement->execute(array(
+ 1,
+ WCF::getUser()->userID
+ ));
// reset notification count
UserStorageHandler::getInstance()->reset(array(WCF::getUser()->userID), 'userNotificationCount');
$conditionBuilder = new PreparedStatementConditionBuilder();
$conditionBuilder->add('notification.notificationID = notification_to_user.notificationID');
$conditionBuilder->add('notification_to_user.userID = ?', array(WCF::getUser()->userID));
+ $conditionBuilder->add('notification_to_user.confirmed = ?', array(0));
$sql = "SELECT COUNT(*) AS count
FROM wcf".WCF_N."_user_notification_to_user notification_to_user,
return $this->notificationCount;
}
+ /**
+ * Counts all existing notifications for current user and returns it.
+ *
+ * @return integer
+ */
+ public function countAllNotifications() {
+ $sql = "SELECT COUNT(*) AS count
+ FROM wcf".WCF_N."_user_notification_to_user
+ WHERE userID = ?";
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute(array(WCF::getUser()->userID));
+ $row = $statement->fetchArray();
+
+ return $row['count'];
+ }
+
/**
* Returns a limited list of outstanding notifications.
*
* @param integer $limit
* @param integer $offset
+ * @param boolean $showConfirmedNotifications
* @return array<array>
*/
- public function getNotifications($limit = 5, $offset = 0) {
+ public function getNotifications($limit = 5, $offset = 0, $showConfirmedNotifications = false) {
// build enormous query
$conditions = new PreparedStatementConditionBuilder();
$conditions->add("notification_to_user.userID = ?", array(WCF::getUser()->userID));
+ if (!$showConfirmedNotifications) $conditions->add("notification_to_user.confirmed = ?", array(0));
$conditions->add("notification.notificationID = notification_to_user.notificationID");
$sql = "SELECT notification_to_user.notificationID, notification_event.eventID,
object_type.objectType, notification.objectID,
notification.additionalData, notification.authorID,
- notification.time
+ notification.time".($showConfirmedNotifications ? ", notification_to_user.confirmed" : "")."
FROM wcf".WCF_N."_user_notification_to_user notification_to_user,
wcf".WCF_N."_user_notification notification
LEFT JOIN wcf".WCF_N."_user_notification_event notification_event
'time' => $event['time']
);
+ if ($showConfirmedNotifications) {
+ $data['confirmed'] = $event['confirmed'];
+ }
+
$notifications[] = $data;
}
}
/**
- * Deletes notifications.
+ * This method does not delete notifications, instead it marks them as confirmed. The system
+ * does not allow to delete them, but since it was intended in WCF 2.0, this method only
+ * exists for compatibility reasons.
*
+ * Please consider replacing your calls with markAsConfirmed().
+ *
+ * @deprecated
* @param string $eventName
* @param string $objectType
* @param array<integer> $recipientIDs
* @param array<integer> $objectIDs
*/
public function deleteNotifications($eventName, $objectType, array $recipientIDs, array $objectIDs = array()) {
+ $this->markAsConfirmed($eventName, $objectType, $recipientIDs, $objectIDs);
+ }
+
+ /**
+ * Marks notifications as confirmed
+ *
+ * @param string $eventName
+ * @param string $objectType
+ * @param array<integer> $recipientIDs
+ * @param array<integer> $objectIDs
+ */
+ public function markAsConfirmed($eventName, $objectType, array $recipientIDs, array $objectIDs = array()) {
// check given object type and event name
if (!isset($this->availableEvents[$objectType][$eventName])) {
throw new SystemException("Unknown event ".$objectType."-".$eventName." given");
$event = $this->availableEvents[$objectType][$eventName];
// delete notifications
- $sql = "DELETE FROM wcf".WCF_N."_user_notification_to_user
- WHERE notificationID IN (
- SELECT notificationID
- FROM wcf".WCF_N."_user_notification
- WHERE packageID = ?
- AND eventID = ?
- ".(!empty($objectIDs) ? "AND objectID IN (?".(count($objectIDs) > 1 ? str_repeat(',?', count($objectIDs) - 1) : '').")" : '')."
- )
- ".(!empty($recipientIDs) ? ("AND userID IN (?".(count($recipientIDs) > 1 ? str_repeat(',?', count($recipientIDs) - 1) : '').")") : '');
- $parameters = array($objectTypeObject->packageID, $event->eventID);
+ $sql = "UPDATE wcf".WCF_N."_user_notification_to_user
+ SET confirmed = ?
+ WHERE notificationID IN (
+ SELECT notificationID
+ FROM wcf".WCF_N."_user_notification
+ WHERE packageID = ?
+ AND eventID = ?
+ ".(!empty($objectIDs) ? "AND objectID IN (?".(count($objectIDs) > 1 ? str_repeat(',?', count($objectIDs) - 1) : '').")" : '')."
+ )
+ ".(!empty($recipientIDs) ? ("AND userID IN (?".(count($recipientIDs) > 1 ? str_repeat(',?', count($recipientIDs) - 1) : '').")") : '');
+ $parameters = array(1, $objectTypeObject->packageID, $event->eventID);
if (!empty($objectIDs)) $parameters = array_merge($parameters, $objectIDs);
if (!empty($recipientIDs)) $parameters = array_merge($parameters, $recipientIDs);
$statement = WCF::getDB()->prepareStatement($sql);
}
}
- > .containerHeadline > .containerContentType {
- color: lighten(@wcfDimmedColor, 20%);
- position: absolute;
- right: 0;
- top: 3px;
+ > .containerHeadline {
+ > .containerContentType {
+ color: lighten(@wcfDimmedColor, 20%);
+ position: absolute;
+ right: 0;
+ top: 3px;
+
+ .transition(color, .1s);
+ }
- .transition(color, .1s);
+ .newContentBadge {
+ //background-color: darken(@wcfTabularBoxBackgroundColor, 10%);
+ color: @wcfTabularBoxColor;
+ text-transform: uppercase;
+
+ .textShadow(darken(@wcfTabularBoxBackgroundColor, 10%));
+ .linearGradient(darken(@wcfTabularBoxBackgroundColor, 10%), @wcfTabularBoxBackgroundColor, darken(@wcfTabularBoxBackgroundColor, 10%));
+ }
}
}
}
<item name="wcf.user.notification.mailNotificationType.instant"><![CDATA[Sofortige E-Mail-Benachrichtigung]]></item>
<item name="wcf.user.notification.mailNotificationType.daily"><![CDATA[Tägliche E-Mail-Benachrichtigung]]></item>
<item name="wcf.user.notification.markAllAsConfirmed"><![CDATA[Alle Benachrichtigungen verwerfen]]></item>
- <item name="wcf.user.notification.markAllAsConfirmed.confirmMessage"><![CDATA[Wollen Sie wirklich alle Benachrichtigungen verwerfen?]]></item>
- <item name="wcf.user.notification.markAsConfirmed"><![CDATA[Verwerfen]]></item>
- <item name="wcf.user.notification.noMoreNotifications"><![CDATA[Keine weiteren Benachrichtigungen]]></item>
- <item name="wcf.user.notification.noNotifications"><![CDATA[Es sind keine neuen Benachrichtigungen vorhanden.]]></item>
+ <item name="wcf.user.notification.markAllAsConfirmed.confirmMessage"><![CDATA[Wollen Sie wirklich alle Benachrichtigungen als gelesen markieren?]]></item>
+ <item name="wcf.user.notification.markAsConfirmed"><![CDATA[Alls gelesen markieren]]></item>
+ <item name="wcf.user.notification.noMoreNotifications"><![CDATA[Keine neuen Benachrichtigungen]]></item>
+ <item name="wcf.user.notification.noNotifications"><![CDATA[Sie haben keine Benachrichtigungen.]]></item>
<item name="wcf.user.notification.notifications"><![CDATA[Benachrichtigungen]]></item>
<item name="wcf.user.notification.showAll"><![CDATA[Alle Benachrichtigungen anzeigen]]></item>
<item name="wcf.user.notification.com.woltlab.wcf.user"><![CDATA[Benutzer-Profile]]></item>
<item name="wcf.user.notification.mailNotificationType.none"><![CDATA[No Email Notification]]></item>
<item name="wcf.user.notification.mailNotificationType.instant"><![CDATA[Instant Email Notification]]></item>
<item name="wcf.user.notification.mailNotificationType.daily"><![CDATA[Daily Email Notification]]></item>
- <item name="wcf.user.notification.markAllAsConfirmed"><![CDATA[Discard All Notifications]]></item>
- <item name="wcf.user.notification.markAllAsConfirmed.confirmMessage"><![CDATA[Do you really want to discard all notifications?]]></item>
- <item name="wcf.user.notification.markAsConfirmed"><![CDATA[Discard]]></item>
- <item name="wcf.user.notification.noMoreNotifications"><![CDATA[No more notifications]]></item>
- <item name="wcf.user.notification.noNotifications"><![CDATA[There are no more notifications.]]></item>
+ <item name="wcf.user.notification.markAllAsConfirmed"><![CDATA[Mark All as Read]]></item>
+ <item name="wcf.user.notification.markAllAsConfirmed.confirmMessage"><![CDATA[Do you really want to mark all notifications as read?]]></item>
+ <item name="wcf.user.notification.markAsConfirmed"><![CDATA[Mark as Read]]></item>
+ <item name="wcf.user.notification.noMoreNotifications"><![CDATA[No new notifications]]></item>
+ <item name="wcf.user.notification.noNotifications"><![CDATA[You have no notifications.]]></item>
<item name="wcf.user.notification.notifications"><![CDATA[Notifications]]></item>
<item name="wcf.user.notification.showAll"><![CDATA[Show All Notifications]]></item>
<item name="wcf.user.notification.com.woltlab.wcf.user"><![CDATA[User Profiles]]></item>
notificationID INT(10) NOT NULL,
userID INT(10) NOT NULL,
mailNotified TINYINT(1) NOT NULL DEFAULT 0,
+ confirmed TINYINT(1) NOT NULL DEFAULT 0,
UNIQUE KEY notificationID (notificationID, userID)
);