--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<data xmlns="http://www.woltlab.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.woltlab.com http://www.woltlab.com/XSD/coreobject.xsd">
+ <import>
+ <coreobject>
+ <objectname><![CDATA[wcf\system\user\notification\UserNotificationHandler]]></objectname>
+ </coreobject>
+ </import>
+</data>
<?php
namespace wcf\data\user\notification;
use wcf\data\DatabaseObjectEditor;
+use wcf\system\WCF;
/**
* Provides functions to edit user notifications.
*/
class UserNotificationEditor extends DatabaseObjectEditor {
/**
- * @see DatabaseObjectEditor::$baseClass
+ * @see DatabaseObjectDecorator::$baseClass
*/
protected static $baseClass = 'wcf\data\user\notification\UserNotification';
+
+ /**
+ * @see EditableObject::create()
+ */
+ public static function create(array $parameters = array()) {
+ $recipientIDs = array();
+ if (isset($parameters['recipientIDs']) && is_array($parameters['recipientIDs'])) {
+ $recipientIDs = $parameters['recipientIDs'];
+ unset($parameters['recipientIDs']);
+ }
+
+ $notification = parent::create($parameters);
+
+ // save recpients
+ if (count($recipientIDs)) {
+ $sql = "INSERT INTO wcf".WCF_N."_user_notification_to_user
+ (notificationID, userID)
+ VALUES (?, ?)";
+ $statement = WCF::getDB()->prepareStatement($sql);
+ foreach ($recipientIDs as $recipientID) {
+ $statement->execute(array($notification->notificationID, $recipientID));
+ }
+ }
+
+ return $notification;
+ }
}
*/
class UserNotificationEventEditor extends DatabaseObjectEditor {
/**
- * @see DatabaseObjectEditor::$baseClass
+ * @see DatabaseObjectDecorator::$baseClass
*/
protected static $baseClass = 'wcf\data\user\notification\event\UserNotificationEvent';
}
*/
class UserNotificationObjectTypeEditor extends DatabaseObjectEditor {
/**
- * @see DatabaseObjectEditor::$baseClass
+ * @see DatabaseObjectDecorator::$baseClass
*/
protected static $baseClass = 'wcf\data\user\notification\object\type\UserNotificationObjectType';
}
--- /dev/null
+<?php
+namespace wcf\data\user\notification\recipient;
+use wcf\data\user\notification\type\UserNotificationType;
+use wcf\data\user\User;
+use wcf\data\DatabaseObjectDecorator;
+use wcf\system\WCF;
+
+/**
+ * Decorates the user object to provide special functions for handling recipients of user notifications.
+ *
+ * @author Marcel Werk
+ * @copyright 2001-2011 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf.notification
+ * @subpackage data.user.notification.user
+ * @category Community Framework
+ */
+class UserNotificationRecipient extends DatabaseObjectDecorator {
+ /**
+ * @see DatabaseObjectDecorator::$baseClass
+ */
+ protected static $baseClass = 'wcf\data\user\User';
+
+ /**
+ * Creates a new UserNotificationRecipient object.
+ *
+ * @param wcf\data\user\User $object
+ */
+ public function __construct(User $object) {
+ parent::__construct($object);
+
+ // get notification types
+ if (!isset($this->object->data['notificationTypes'])) {
+ $this->object->data['notificationTypes'] = array();
+ $sql = "SELECT event_to_user.eventID, notification_type.*
+ FROM wcf".WCF_N."_user_notification_event_to_user event_to_user
+ LEFT JOIN wcf".WCF_N."_user_notification_type notification_type
+ ON (notification_type.notificationTypeID = event_to_user.notificationTypeID)
+ WHERE event_to_user.userID = ?
+ AND event_to_user.enabled = ?";
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute(array($this->userID, 1));
+ while ($row = $statement->fetchArray()) {
+ $this->object->data['notificationTypes'][$row['eventID']] = new UserNotificationType(null, $row);
+ }
+ }
+ }
+
+ /**
+ * Returns the enabled notification types for the given event.
+ *
+ * @param integer $eventID
+ * @return array<wcf\data\user\notification\type\UserNotificationType>
+ */
+ public function getNotificationTypes($eventID) {
+ if (isset($this->notificationTypes[$eventID])) {
+ return $this->notificationTypes[$eventID];
+ }
+
+ return array();
+ }
+}
--- /dev/null
+<?php
+namespace wcf\data\user\notification\recipient;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
+use wcf\data\user\notification\type\UserNotificationType;
+use wcf\data\user\UserList;
+
+/**
+ * Decorates the user object to provide special functions for handling recipients of user notifications.
+ *
+ * @author Marcel Werk
+ * @copyright 2001-2011 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf.notification
+ * @subpackage data.user.notification.user
+ * @category Community Framework
+ */
+class UserNotificationRecipientList extends UserList {
+ /**
+ * @see wcf\data\DatabaseObjectList\DatabaseObjectList::readObjects()
+ */
+ public function readObjects() {
+ if ($this->objectIDs === null) {
+ $this->readObjectIDs();
+ }
+
+ if (!count($this->objectIDs)) {
+ return;
+ }
+
+ // get notification types
+ $notificationTypes = array();
+ $conditionBuilder = new PreparedStatementConditionBuilder();
+ $conditionBuilder->add('event_to_user.userID IN (?)', array($this->objectIDs));
+ $conditionBuilder->add('event_to_user.enabled = ?', array(1));
+
+ $sql = "SELECT event_to_user.eventID, event_to_user.userID, notification_type.*
+ FROM wcf".WCF_N."_user_notification_event_to_user event_to_user
+ LEFT JOIN wcf".WCF_N."_user_notification_type notification_type
+ ON (notification_type.notificationTypeID = event_to_user.notificationTypeID)
+ ".$conditionBuilder->__toString();
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute($conditionBuilder->getParameters());
+ while ($row = $statement->fetchArray()) {
+ $notificationTypes[$row['userID']][$row['eventID']] = new UserNotificationType(null, $row);
+ }
+
+ // get users
+ $sql = "SELECT ".(!empty($this->sqlSelects) ? $this->sqlSelects.',' : '')."
+ ".$this->getDatabaseTableAlias().".*
+ FROM ".$this->getDatabaseTableName()." ".$this->getDatabaseTableAlias()."
+ ".$this->sqlJoins."
+ WHERE ".$this->getDatabaseTableAlias().".".$this->getDatabaseTableIndexName()." IN (?".str_repeat(',?', count($this->objectIDs)).")
+ ".(!empty($this->sqlOrderBy) ? "ORDER BY ".$this->sqlOrderBy : '');
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute($this->objectIDs);
+ while ($row = $statement->fetchArray()) {
+ $row['notificationTypes'] = (isset($notificationTypes[$row['userID']]) ? $notificationTypes[$row['userID']] : array());
+ $this->objects[] = new UserNotificationRecipient(null, $row);
+ }
+ }
+}
*/
class UserNotificationTypeEditor extends DatabaseObjectEditor {
/**
- * @see DatabaseObjectEditor::$baseClass
+ * @see DatabaseObjectDecorator::$baseClass
*/
protected static $baseClass = 'wcf\data\user\notification\type\UserNotificationType';
}
--- /dev/null
+<?php
+namespace wcf\system\cache;
+use wcf\data\user\notification\event\UserNotificationEvent;
+use wcf\data\user\notification\object\type\UserNotificationObjectType;
+use wcf\system\WCF;
+
+/**
+ * Caches user notification object types and events.
+ *
+ * @author Marcell Werk, Oliver Kliebisch
+ * @copyright 2001-2011 WoltLab GmbH, Oliver Kliebisch
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf.notification
+ * @subpackage system.cache
+ * @category Community Framework
+ */
+class CacheBuilderUserNotificationObjectType implements CacheBuilder {
+ /**
+ * @see CacheBuilder::getData()
+ */
+ public function getData($cacheResource) {
+ $data = array();
+
+ // get package id
+ $tmp = explode('-', $cacheResource['cache']);
+ $packageID = array_pop($packageID);
+
+ // get object types
+ $typeIDArray = array();
+ $sql = "SELECT object_type.*
+ FROM wcf".WCF_N."_user_notification_object_type object_type,
+ wcf".WCF_N."_package_dependency package_dependency
+ WHERE object_type.packageID = package_dependency.dependency
+ AND package_dependency.packageID = ?
+ ORDER BY package_dependency.priority DESC";
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute(array($packageID));
+ while ($row = $statement->fetchArray()) {
+ if (!isset($data[$row['objectType']])) {
+ $data[$row['objectType']] = array(
+ 'object' => new UserNotificationObjectType(null, $row),
+ 'events' => array()
+ );
+ }
+ }
+
+ // get events
+ $sql = "SELECT event.*, object_type.objectType
+ FROM wcf".WCF_N."_package_dependency package_dependency,
+ wcf".WCF_N."_user_notification_event event
+ LEFT JOIN wcf".WCF_N."_user_notification_object_type object_type
+ ON (object_type.objectTypeID = event.objectTypeID)
+ WHERE event.packageID = package_dependency.dependency
+ AND package_dependency.packageID = ?
+ ORDER BY package_dependency.priority DESC";
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute(array($packageID));
+ while ($row = $statement->fetchArray()) {
+ if (isset($data[$row['objectType']]) && !isset($data[$row['objectType']]['events'][$row['eventName']])) {
+ $data[$row['objectType']]['events'][$row['eventName']] = new UserNotificationEvent(null, $row);
+ }
+ }
+
+ return $data;
+ }
+}
<?php
namespace wcf\system\package\plugin;
+use wcf\system\exception\SystemException;
use wcf\system\WCF;
/**
* @see AbstractXMLPackageInstallationPlugin::prepareImport()
*/
protected function prepareImport(array $data) {
- $objectTypeID = 0;
+ // get object type id
+ $sql = "SELECT notification_object_type.objectTypeID
+ FROM wcf".WCF_N."_package_dependency package_dependency,
+ wcf".WCF_N."_user_notification_object_type notification_object_type
+ WHERE notification_object_type.packageID = package_dependency.dependency
+ AND package_dependency.packageID = ?
+ AND notification_object_type.objectType = ?
+ ORDER BY package_dependency.priority DESC";
+ $statement = WCF::getDB()->prepareStatement($sql, 1);
+ $statement->execute(array($this->installation->getPackageID(), $data['elements']['objecttype']));
+ $row = $statement->fetchArray();
+ if (empty($row['objectTypeID'])) throw new SystemException("unknown notification object type '".$data['elements']['objecttype']."' given");
+ $objectTypeID = $row['objectTypeID'];
+
+ // get notification type id
$defaultNotificationTypeID = 0;
+ if (!empty($data['elements']['defaultnotificationtype'])) {
+ $sql = "SELECT notification_type.notificationTypeID
+ FROM wcf".WCF_N."_package_dependency package_dependency,
+ wcf".WCF_N."_user_notification_type notification_type
+ WHERE notification_type.packageID = package_dependency.dependency
+ AND package_dependency.packageID = ?
+ AND notification_type.notificationType = ?
+ ORDER BY package_dependency.priority DESC";
+ $statement = WCF::getDB()->prepareStatement($sql, 1);
+ $statement->execute(array($this->installation->getPackageID(), $data['elements']['defaultnotificationtype']));
+ $row = $statement->fetchArray();
+ if (empty($row['objectTypeID'])) throw new SystemException("unknown notification type '".$data['elements']['defaultnotificationtype']."' given");
+ $defaultNotificationTypeID = $row['notificationTypeID'];
+ }
return array(
'eventName' => $data['elements']['name'],
--- /dev/null
+<?php
+namespace wcf\system\user\notification;
+use wcf\data\user\notification\event\UserNotificationEvent;
+use wcf\data\user\notification\object\type\UserNotificationObjectType;
+use wcf\data\user\notification\recipient\UserNotificationRecipientList;
+use wcf\data\user\notification\UserNotificationAction;
+use wcf\system\cache\CacheHandler;
+use wcf\system\exception\SystemException;
+use wcf\system\user\notification\object\UserNotificationObject;
+use wcf\system\SingletonFactory;
+
+/**
+ * Handles user notifications.
+ *
+ * @author Marcel Werk, Oliver Kliebisch
+ * @copyright 2001-2011 WoltLab GmbH, Oliver Kliebisch
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf.notification
+ * @subpackage system.user.notification
+ * @category Community Framework
+ */
+class UserNotificationHandler extends SingletonFactory {
+ /**
+ * list of available object types
+ * @var array
+ */
+ protected $availableObjectTypes = array();
+
+ /**
+ * @see wcf\system\SingletonFactory::init()
+ */
+ protected function init() {
+ // load cache
+ CacheHandler::getInstance()->addResource('user-notification-object-type-'.PACKAGE_ID, WCF_DIR.'cache/cache.user-notification-object-type-'.PACKAGE_ID.'.php', 'wcf\system\cache\CacheBuilderUserNotificationObjectType');
+ $this->availableObjectTypes = CacheHandler::getInstance()->get('user-notification-object-type-'.PACKAGE_ID);
+ }
+
+ /**
+ * Triggers a notification event.
+ *
+ * @param string $eventName
+ * @param string $objectType
+ * @param wcf\system\user\notification\object\UserNotificationObject $notificationObject
+ * @param array<integer> $recipientIDs
+ * @param array<mixed> $additionalData
+ */
+ public function fireEvent($eventName, $objectType, UserNotificationObject $notificationObject, array $recipientIDs, array $additionalData = array()) {
+ // check given object type and event name
+ if (!isset($this->availableObjectTypes[$objectType]['events'][$eventName])) {
+ throw new SystemException("Unknown event '.$objectType.'-.$eventName.' given");
+ }
+
+ // get objects
+ $objectTypeData = $this->availableObjectTypes[$objectType]['object'];
+ $eventData = $this->availableObjectTypes[$objectType]['events'][$eventName];
+
+ // save notification
+ $action = new UserNotificationAction(array(), 'create', array(
+ 'packageID' => PACKAGE_ID,
+ 'eventID' => $eventData->eventID,
+ 'objectID' => $notificationObject->getObjectID(),
+ 'time' => TIME_NOW,
+ 'shortOutput' => $eventData->getObject()->getShortOutput($eventName),
+ 'mediumOutput' => $eventData->getObject()->getMediumOutput($eventName),
+ 'longOutput' => $eventData->getObject()->getOutput($eventName),
+ 'additionalData' => serialize($additionalData),
+ 'recipientIDs' => $recipientIDs
+ ));
+ $notification = $action->executeAction();
+
+ // get recipients
+ $recipientList = new UserNotificationRecipientList();
+ $recipientList->getConditionBuilder()->add('user_table.userID = ?', array($recipientIDs));
+ $recipientList->readObjects();
+
+ // sends notifications
+ foreach ($recipientList->getObjects() as $recipient) {
+ foreach ($recipient->getNotificationTypes($eventData->eventID) as $notificationType) {
+ if ($eventData->getObject()->supportsNotificationType($notificationType)) {
+ $notificationType->getObject()->send($notification, $recipient, $eventData);
+ }
+ }
+ }
+ }
+}
--- /dev/null
+<?php
+namespace wcf\system\user\notification\event;
+use wcf\data\user\notification\type;
+
+/**
+ * This interface should be implemented by every event which is fired by the notification system.
+ *
+ * @author Marcel Werk, Oliver Kliebisch
+ * @copyright 2001-2011 WoltLab GmbH, Oliver Kliebisch
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf.notification
+ * @subpackage system.user.notification.event
+ * @category Community Framework
+ */
+interface UserNotificationEvent {
+ /**
+ * Returns the message for this notification event.
+ *
+ * @param wcf\data\user\notification\type\UserNotificationType $notificationType
+ * @return string
+ */
+ public function getMessage(UserNotificationType $notificationType);
+
+ /**
+ * Returns the short output for this notification event.
+ *
+ * @return string
+ */
+ public function getShortOutput();
+
+ /**
+ * Returns the medium output for this notification event.
+ *
+ * @return string
+ */
+ public function getMediumOutput();
+
+ /**
+ * Returns the full output for this notification event.
+ *
+ * @return string
+ */
+ public function getOutput();
+
+ /**
+ * Returns the human-readable title of this event.
+ *
+ * @return string
+ */
+ public function getTitle();
+
+ /**
+ * Returns the human-readable description of this event.
+ *
+ * @return string
+ */
+ public function getDescription();
+
+ /**
+ * Returns true if this event supports the given notification type.
+ *
+ * @param wcf\data\user\notification\type\UserNotificationType $notificationType
+ * @return boolean
+ */
+ public function supportsNotificationType(UserNotificationType $notificationType);
+}
--- /dev/null
+<?php
+namespace wcf\system\user\notification\object;
+
+/**
+ * This interface should be implemented by every object which is part of a notification.
+ *
+ * @author Marcel Werk, Oliver Kliebisch
+ * @copyright 2001-2011 WoltLab GmbH, Oliver Kliebisch
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf.notification
+ * @subpackage system.user.notification.object
+ * @category Community Framework
+ */
+interface UserNotificationObject {
+ /**
+ * Returns the ID of this object.
+ *
+ * @return integer
+ */
+ public function getObjectID();
+
+ /**
+ * Returns the title of this object.
+ *
+ * @return string
+ */
+ public function getTitle();
+
+ /**
+ * Returns the url of this object.
+ *
+ * @return string
+ */
+ public function getURL();
+}
--- /dev/null
+<?php
+namespace wcf\system\user\notification\object\type;
+
+/**
+ * This interface defines the basic methods every notification object type should implement.
+ *
+ * @author Marcel Werk, Oliver Kliebisch
+ * @copyright 2001-2011 WoltLab GmbH, Oliver Kliebisch
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf.notification
+ * @subpackage system.user.notification.object.type
+ * @category Community Framework
+ */
+interface UserNotificationObjectType {
+ /**
+ * Gets a notification object by its ID.
+ *
+ * @param integer $objectID
+ * @return wcf\system\user\notification\object\UserNotificationObject
+ */
+ public function getObjectByID($objectID);
+
+ /**
+ * Gets notification objects by their IDs.
+ *
+ * @param array<integer> $objectIDs
+ * @return array<wcf\system\user\notification\object\UserNotificationObject>
+ */
+ public function getObjectsByIDs($objectIDs);
+
+}
--- /dev/null
+<?php
+namespace wcf\system\user\notification\type;
+use wcf\data\user\notification\event\UserNotificationEvent;
+use wcf\data\user\notification\UserNotification;
+use wcf\data\user\UserEditor;
+use wcf\data\user\User;
+use wcf\system\mail\Mail;
+
+/**
+ * A notification type for sending mail notifications.
+ *
+ * @author Marcel Werk, Oliver Kliebisch
+ * @copyright 2001-2011 WoltLab GmbH, Oliver Kliebisch
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf.notification
+ * @subpackage system.user.notification.type
+ * @category Community Framework
+ */
+class MailUserNotificationType implements UserNotificationType {
+ /**
+ * @see wcf\system\user\notification\type\UserNotificationType::send()
+ */
+ public function send(UserNotification $notification, User $user, UserNotificationEvent $event) {
+ // get message
+ $message = $event->getMessage($this, array(
+ 'user' => $user,
+ 'pageURL' => FileUtil::addTrailingSlash(PAGE_URL)
+ ));
+
+ // append notification mail footer
+ $token = $user->notificationMailToken;
+ if (!$token) {
+ // generate token if not present
+ $token = StringUtil::substring($token = StringUtil::getHash(serialize(array($user->userID, StringUtil::getRandomID()))), 0, 20);
+ $editor = new UserEditor($user);
+ $editor->updateUserOptions(array('notificationMailToken' => $token));
+ }
+ $message .= "\n".$event->getLanguage()->getDynamicVariable('wcf.user.notification.type.mail.footer', array(
+ 'user' => $user,
+ 'pageURL' => FileUtil::addTrailingSlash(PAGE_URL),
+ 'token' => $token,
+ 'notification' => $notification
+ ));
+
+ // use short output as mail subject and strip its HTML
+ $shortMessage = StringUtil::stripHTML($notification->shortOutput);
+
+ // build mail
+ $mail = new Mail(array($user->username => $user->email), $event->getLanguageVariable('wcf.user.notification.type.mail.subject', array('title' => $shortMessage)), $message);
+ $mail->send();
+ }
+
+ /**
+ * @see wcf\system\user\notification\type\UserNotificationType::revoke()
+ */
+ public function revoke(UserNotification $notification, User $user, UserNotificationEvent $event) {
+ // unsupported
+ return;
+ }
+}
--- /dev/null
+<?php
+namespace wcf\system\user\notification\type;
+use wcf\data\user\notification\event\UserNotificationEvent;
+use wcf\data\user\notification\UserNotification;
+use wcf\data\user\User;
+
+/**
+ * This interface should be implemented by every user notification type.
+ *
+ * @author Marcel Werk, Oliver Kliebisch
+ * @copyright 2001-2011 WoltLab GmbH, Oliver Kliebisch
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf.notification
+ * @subpackage system.user.notification.type
+ * @category Community Framework
+ */
+interface UserNotificationType {
+ /**
+ * Sends the notification using this notification transport type.
+ *
+ * @param wcf\data\user\notification\UserNotification $notification
+ * @param wcf\data\user\User $user
+ * @param wcf\data\user\notification\event\UserNotificationEvent $event
+ */
+ public function send(UserNotification $notification, User $user, UserNotificationEvent $event);
+
+ /**
+ * Tries to revoke the notification. This might not be applicable for all notification types.
+ *
+ * @param wcf\data\user\notification\UserNotification $notification
+ * @param wcf\data\user\User $user
+ * @param wcf\data\user\notification\event\UserNotificationEvent $event
+ */
+ public function revoke(UserNotification $notification, User $user, UserNotificationEvent $event);
+}
CREATE TABLE wcf1_user_notification_to_user (
notificationID INT(10) NOT NULL,
userID INT(10) NOT NULL,
- confirmed TINYINT(1) NOT NULL,
+ confirmed TINYINT(1) NOT NULL DEFAULT 0,
confirmationTime INT(10) NOT NULL DEFAULT 0,
UNIQUE KEY notificationID (notificationID, userID)
);
acceptURL VARCHAR(255) NOT NULL DEFAULT '',
declineURL VARCHAR(255) NOT NULL DEFAULT '',
permissions TEXT,
- options TEXT,
+ options TEXT,
UNIQUE KEY packageID (packageID, eventName)
);
<?xml version="1.0" encoding="UTF-8"?>
-<package name="com.woltlab.wcf.user.notification" xmlns="http://www.woltlab.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.woltlab.com/XSD/package.xsd">
+<package name="com.woltlab.wcf.notification" xmlns="http://www.woltlab.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.woltlab.com/XSD/package.xsd">
<packageinformation>
- <packagename>User Notification System</packagename>
+ <packagename>User Notification System</packagename>
+ <packagedescription>Provides functions to deliver notification messages</packagedescription>
<version>1.0.0 Alpha 1</version>
<date>2010-08-22</date>
<isunique>1</isunique>
<instruction type="packageinstallationplugins">pip.xml</instruction>
<instruction type="files">files.tar</instruction>
<instruction type="sql">install.sql</instruction>
+ <instruction type="userNotificationType">userNotificationType.xml</instruction>
+ <instruction type="coreobject">coreobject.xml</instruction>
</instructions>
</package>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<data xmlns="http://www.woltlab.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.woltlab.com http://www.woltlab.com/XSD/user-notification-type.xsd">
+ <import>
+ <notificationtype>
+ <name>mail</name>
+ <classname>wcf\system\user\notification\type\MailUserNotificationType</classname>
+ </notificationtype>
+ </import>
+</data>
\ No newline at end of file