WCF 2.1 — Integrating nicely into Community Framework 2.1 (Part 3)

  • The first and second developer spotlight dealt with the new administrator’s features. But of course there were some great new features for the members of the community as well:


    Notification stacking


    The current notification system has got a big downside: Similar notifications were not grouped together. This restricted the possibilities, as you could not send notifications for likes and other events happening at a similar rate. It would completely clutter the notification center. Therefore we introduced notification stacking. Making use of stacking only requires small changes to your IUserNotificationEvent implementation:

    • Set the attribute $stackable to true
    • Override getEventHash() in case the default implementation (eventID + objectID) does not fit. The system groups notifications with the same hash.
    • Update getTitle() and getMessage()



    Like notifications


    Read “Notification stacking” first, please.


    One of the most requested feature was notifications for likes. You definitely should not leave them out when updating your plugin to make use of the new features of Community Framework 2.1!


    The sendNotification(Like $like) method of your \wcf\data\like\object\ILikeObject implementation will be called when you should send a new notification. As the actual objects can differ a lot there is unfortunately no default implementation for this method. We provided you with a default IUserNotificationObject implementation and a default IUserNotificationObjectType implementation, though. For a proper implementation the following is required:

    • An object type
    • A user notification event definition
    • Implementation of sendNotification()
    • Implementation of the IUserNotificationEvent
    • Some language items


    If you already implemented notifications the following should look familiar:


    Embedded objects


    You could not properly quote attachments in Community Framework 2.0 for performance reasons. Community Framework 2.1 solves this issue by the embedded object system. You are now able to register the objects that are embedded in your message and can afterwards fetch them with a single function call. This allows for some other great futures, such as avatars beside quotes as well. This is how you integrate the embedded object system:


    XML: objectType.xml
    <type>
    <name>com.woltlab.wbb.post</name>
    <definitionname>com.woltlab.wcf.message</definitionname>
    </type>


    When adding a new message:

    PHP: PostAction.class.php
    // registerObjects() returns true if there are embedded objects
    // 'com.woltlab.wbb.post' must match your objectType.xml
    if (MessageEmbeddedObjectManager::getInstance()->registerObjects('com.woltlab.wbb.post', $post->postID, $post->message)) {
    $postEditor->update(array(
    'hasEmbeddedObjects' => 1
    ));
    }


    When updating a message:


    When deleting a message:

    PHP: PostAction.class.php
    MessageEmbeddedObjectManager::getInstance()->removeObjects('com.woltlab.wbb.post', $postIDs);


    When loading messages (example taken from quick reply):

    PHP: PostAction.class.php
    MessageEmbeddedObjectManager::getInstance()->loadObjects('com.woltlab.wbb.post', array($post->postID));


    When showing messages:

    PHP: Post.class.php
    // this replaces AttachmentBBCode::setObjectID($this->postID);
    MessageEmbeddedObjectManager::getInstance()->setActiveMessage('com.woltlab.wbb.post', $this->postID);


    This feature is not forward compatible: The installation will fail in Community Framework 2.0, due to the missing object type definition!

  • WCF 2.1 Beta 3 adds two additional attributes related to the autosave feature, both control the restore behavior:

    • data-autosave-prompt="true" will explicitly ask if saved content should be restored
    • data-autosave-last-edit-time="<timestamp>" will cause the editor to discard saved content if it is older than the given timestamp

    The check for lastEditTime is useful if you have a content type which can be expected to be edited by multiple people (e.g. forum posts). It attempts to circumvent the race condition taking place if user A starts editing but never submits it and the same content is edited afterwards by user B. If user A now attempts to edit the same content again the editor would load the draft - which is based upon the state before user B edited it - where the origin is out-of-sync.

    Viele Grüße,
    Magnus