Community Framework 2.1 introduces a new edit history. It allows you to easily save older versions of your content. You only have to tell the system when it should save a new version and how to revert to an older version. Everything else, such as generating the differences and bulk reverting are automatically provided for you. You only need an object type, two PHP classes and a small modification to your “update” function, as well as your templates.
…
<type>
<name>com.woltlab.wbb.post</name>
<definitionname>com.woltlab.wcf.edit.historySavingObject</definitionname>
<classname>wbb\data\post\HistorySavingPostProvider</classname>
</type>
…
<?php
namespace wbb\data\post;
use wcf\data\object\type\AbstractObjectTypeProvider;
use wcf\system\edit\IHistorySavingObject;
use wcf\system\edit\IHistorySavingObjectTypeProvider;
use wcf\system\exception\PermissionDeniedException;
/**
* Object type provider for history saving posts.
*
* @author Tim Duesterhus
* @copyright 2001-2014 WoltLab GmbH
* @license WoltLab License <http://www.woltlab.com/license-agreement.html>
* @package com.woltlab.wbb
* @subpackage data.post
* @category Burning Board
*/
class HistorySavingPostProvider extends AbstractObjectTypeProvider implements IHistorySavingObjectTypeProvider {
/**
* @see \wcf\data\object\type\AbstractObjectTypeProvider::$className
*/
// the IDatabaseObject content that is being versioned
public $className = 'wbb\data\post\Post';
/**
* @see \wcf\data\object\type\AbstractObjectTypeProvider::$decoratorClassName
*/
// your IHistorySavingObject implementation
public $decoratorClassName = 'wbb\data\post\HistorySavingPost';
/**
* @see \wcf\data\object\type\AbstractObjectTypeProvider::$listClassName
*/
// the IDatabaseObjectList of the content to versionize
public $listClassName = 'wbb\data\post\PostList';
/**
* @see \wcf\system\edit\IHistorySavingObjectTypeProvider::checkPermissions()
*/
// this method must *throw* a PermissionDeniedException if the current user may not see old versions
public function checkPermissions(IHistorySavingObject $object) {
if (!($object instanceof HistorySavingPost)) return false;
$thread = $object->getThread();
$board = $thread->getBoard();
if (!$board->getModeratorPermission('canEditPost')) {
throw new PermissionDeniedException();
}
}
/**
* @see \wcf\system\edit\IHistorySavingObjectTypeProvider::getActivePageMenuItem()
*/
// returns the identifier of the page menu item to show as active
public function getActivePageMenuItem() {
return 'wbb.header.menu.board';
}
}
Display More
<?php
namespace wbb\data\post;
use wbb\system\WBBCore;
use wcf\data\edit\history\entry\EditHistoryEntry;
use wcf\data\object\type\ObjectTypeCache;
use wcf\data\DatabaseObject;
use wcf\data\DatabaseObjectDecorator;
use wcf\system\breadcrumb\Breadcrumb;
use wcf\system\edit\IHistorySavingObject;
use wcf\system\WCF;
/**
* History Saving Posts are posts that can be reverted to an older version.
*
* @author Tim Duesterhus
* @copyright 2001-2014 WoltLab GmbH
* @license WoltLab License <http://www.woltlab.com/license-agreement.html>
* @package com.woltlab.wbb
* @subpackage data.post
* @category Burning Board
*/
class HistorySavingPost extends DatabaseObjectDecorator implements IHistorySavingObject {
/**
* @see \wcf\data\DatabaseObjectDecorator::$baseClass
*/
protected static $baseClass = 'wbb\data\post\Post';
/**
* userID of the last editor
* @var integer
*/
public $userID = 0;
/**
* username of the last editor
* @var string
*/
public $username = '';
/**
* last edit time
* @var integer
*/
public $time = 0;
/**
* reason for the last edit
* @var string
*/
public $reason = '';
/**
* Fetches the information of the latest edit.
*
* @see \wcf\data\DatabaseObjectDecorator::__construct()
*/
public function __construct(DatabaseObject $object) {
parent::__construct($object);
// the contents of the constructor may differ a lot, therefore we omit this for simplicity and brevity
}
/**
* @see \wcf\data\ITitledObject::getTitle()
*/
public function getTitle() {
return $this->getDecoratedObject()->getTitle();
}
/**
* @see \wcf\data\ILinkableObject::getLink()
*/
public function getLink() {
return $this->getDecoratedObject()->getLink();
}
/**
* @see \wcf\data\IUserContent::getUsername()
*/
public function getUsername() {
return $this->username;
}
/**
* @see \wcf\data\IUserContent::getUserID()
*/
public function getUserID() {
return $this->userID;
}
/**
* @see \wcf\data\IUserContent::getTime()
*/
public function getTime() {
return $this->time;
}
/**
* @see \wcf\system\edit\IHistorySavingObject::revertVersion()
*/
public function revertVersion(EditHistoryEntry $edit) {
// updates the message with the contents of the given EditHistoryEntry
$postAction = new PostAction(array($this->getDecoratedObject()), 'update', array(
'isEdit' => true,
'data' => array(
'message' => $edit->message,
'editReason' => WCF::getLanguage()->getDynamicVariable('wcf.edit.reverted', array('edit' => $edit))
)
));
$postAction->executeAction();
}
/**
* @see \wcf\system\edit\IHistorySavingObject::addBreadcrumbs()
*/
public function addBreadcrumbs() {
// adds the appropriate bread crumbs for this object
WBBCore::getInstance()->setBreadcrumbs($this->getThread()->getBoard()->getParentBoards(), $this->getThread()->getBoard(), $this->getThread());
WCF::getBreadcrumbs()->add(new Breadcrumb($this->getTitle(), $this->getLink()));
}
/**
* @see \wcf\system\edit\IHistorySavingObject::getEditReason()
*/
public function getEditReason() {
// returns the edit reason for the *current* version
// the reason for first version usually is empty
return $this->reason;
}
/**
* @see \wcf\system\edit\IHistorySavingObject::getMessage()
*/
public function getMessage() {
// returns the message, as it *currently* looks like
return $this->getDecoratedObject()->getMessage();
}
}
Display More
Now you have to call EditHistoryManager::getInstance()->add($objectType, $objectID, $currentMessageText, $currentUserID, $currentUsername, $reason); whenever the content is edited:
…
if (isset($this->parameters['data']['message'])) {
$historySavingPost = new HistorySavingPost($post->getDecoratedObject());
$userID = $historySavingPost->getUserID();
$username = $historySavingPost->getUsername();
$time = $historySavingPost->getTime();
$reason = $historySavingPost->getEditReason();
EditHistoryManager::getInstance()->add('com.woltlab.wbb.post', $post->postID, $post->message, $time, $userID, $username, $reason, WCF::getUser()->userID);
}
…
And EditHistoryManager::getInstance()->delete($objectType, $objectIDs); whenever content is removed.
The edit history will be ready now, but you really should provide a link for the user to view it! You can create the link like this: