Skip to content

Commit

Permalink
Added modification log
Browse files Browse the repository at this point in the history
  • Loading branch information
dtdesign committed Jun 11, 2012
1 parent 8bb37da commit 3a2de7f
Show file tree
Hide file tree
Showing 7 changed files with 198 additions and 0 deletions.
4 changes: 4 additions & 0 deletions com.woltlab.wcf/objectTypeDefinition.xml
Expand Up @@ -13,5 +13,9 @@
<interfacename>wcf\system\category\ICategoryType</interfacename>
<name>com.woltlab.wcf.category</name>
</definition>

<definition>
<name>com.woltlab.wcf.modifiableContent</name>
</definition>
</import>
</data>
@@ -0,0 +1,25 @@
<?php
namespace wcf\data\modification\log;
use wcf\data\DatabaseObject;

/**
* Represents a modification log.
*
* @author Alexander Ebert
* @copyright 2001-2012 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @package com.woltlab.wcf
* @subpackage data.modification.log
* @category Community Framework
*/
class ModificationLog extends DatabaseObject {
/**
* @see wcf\data\DatabaseObject::$databaseTableName
*/
protected static $databaseTableName = 'modification_log';

/**
* @see wcf\data\DatabaseObject::$databaseTableIndexName
*/
protected static $databaseTableIndexName = 'logID';
}

This comment has been minimized.

Copy link
@Gravatronics

Gravatronics Jun 11, 2012

Contributor

Add possibility to access an additionalData element directly using __get() (cf. ObjectType)?

@@ -0,0 +1,15 @@
<?php
namespace wcf\data\modification\log;
use wcf\data\AbstractDatabaseObjectAction;

/**
* Executes modification log-related actions.
*
* @author Alexander Ebert
* @copyright 2001-2012 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @package com.woltlab.wcf
* @subpackage data.modification.log
* @category Community Framework
*/
class ModificationLogAction extends AbstractDatabaseObjectAction { }
@@ -0,0 +1,20 @@
<?php
namespace wcf\data\modification\log;
use wcf\data\DatabaseObjectEditor;

/**
* Provides functions to edit modification logs.
*
* @author Alexander Ebert
* @copyright 2001-2012 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @package com.woltlab.wcf
* @subpackage data.modification.log
* @category Community Framework
*/
class ModificationLogEditor extends DatabaseObjectEditor {
/**
* @see wcf\data\DatabaseObjectDecorator::$baseClass
*/
protected static $baseClass = 'wcf\data\modification\log\ModificationLog';
}
@@ -0,0 +1,20 @@
<?php
namespace wcf\data\modification\log;
use wcf\data\DatabaseObjectList;

/**
* Represents a list of modification logs.
*
* @author Alexander Ebert
* @copyright 2001-2012 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @package com.woltlab.wcf
* @subpackage data.modification.log
* @category Community Framework
*/
class ModificationLogList extends DatabaseObjectList {
/**
* @see wcf\data\DatabaseObjectList::$className
*/
public $className = 'wcf\data\modification\log\ModificationLog';
}
@@ -0,0 +1,99 @@
<?php
namespace wcf\system\log\modification;
use wcf\data\modification\log\ModificationLogEditor;
use wcf\data\object\type\ObjectTypeCache;
use wcf\system\database\util\PreparedStatementConditionBuilder;
use wcf\system\exception\SystemException;
use wcf\system\SingletonFactory;
use wcf\system\WCF;

/**
* Handles modification logs.
*
* @author Alexander Ebert
* @copyright 2001-2012 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @package com.woltlab.wcf
* @subpackage system.log.modification
* @category Community Framework
*/
class ModificationLogHandler extends SingletonFactory {
/**
* list of object types
* @var array<wcf\data\object\type\ObjectType>
*/
protected $cache = array();

/**
* @see wcf\system\SingletonFactory::init()
*/
protected function init() {
$this->cache = ObjectTypeCache::getInstance()->getObjectTypes('com.woltlab.wcf.modifiableContent');
}

/**
* Returns object type by object type name.
*
* @param string $objectType
* @return wcf\data\object\type\ObjectType
*/
public function getObjectType($objectType) {
foreach ($this->cache as $objectTypeObj) {
if ($objectTypeObj->objectType == $objectType) {
return $objectTypeObj;
}
}

return null;
}

/**
* Adds a new entry to modification log.
*
* @param string $objectType
* @param integer $objectID
* @param string $action
* @param array $data
* @param integer $time
* @param integer $userID
* @param string $username
* @return wcf\data\modification\log\ModificationLog
*/
public function add($objectType, $objectID, $action, array $data = array(), $time = TIME_NOW, $userID = null, $username = null) {
$objectType = $this->getObjectType($objectType);
if ($objectType === null) {
throw new SystemException("Object type '".$objectType."' not found within definition 'com.woltlab.wcf.modifiableContent'");

This comment has been minimized.

Copy link
@Gravatronics

Gravatronics Jun 14, 2012

Contributor

$objectType is null now, not the object type name.

}

return ModificationLogEditor::create(array(
'objectTypeID' => $objectType->objectTypeID,
'objectID' => $objectID,
'userID' => ($userID === null ? WCF::getUser()->userID : $userID),
'username' => ($username === null ? WCF::getUser()->username : $username),
'time' => $time,
'data' => serialize($data)

This comment has been minimized.

Copy link
@MatzeKitt

MatzeKitt Jun 11, 2012

Someone told me that 'data' should be 'additionalData'...

));
}

/**
* Removes log entries.
*
* @param string $objectType
* @param array<integer> $objectIDs
*/
public function remove($objectType, array $objectIDs) {
$objectType = $this->getObjectType($objectType);
if ($objectType === null) {
throw new SystemException("Object type '".$objectType."' not found within definition 'com.woltlab.wcf.modifiableContent'");
}

$conditions = new PreparedStatementConditionBuilder();
$conditions->add("objectTypeID = ?", array($objectType->objectTypeID));
$conditions->add("objectID IN (?)", array($objectIDs));

$sql = "DELETE FROM wcf".WCF_N."_modification_log
".$conditions;
$statement = WCF::getDB()->prepareStatement($sql);
$statement->execute($conditions->getParameters());
}
}
15 changes: 15 additions & 0 deletions wcfsetup/setup/db/install.sql
Expand Up @@ -238,6 +238,18 @@ CREATE TABLE wcf1_language_to_package (
UNIQUE KEY languageID (languageID, packageID)
);

DROP TABLE IF EXISTS wcf1_modification_log;
CREATE TABLE wcf1_modification_log (
logID INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
objectTypeID INT(10) NOT NULL,
objectID INT(10) NOT NULL,
userID INT(10),
username VARCHAR(255) NOT NULL DEFAULT '',
time INT(10) NOT NULL DEFAULT 0,
action VARCHAR(80) NOT NULL,
additionalData MEDIUMTEXT
);

DROP TABLE IF EXISTS wcf1_object_type;
CREATE TABLE wcf1_object_type (
objectTypeID INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
Expand Down Expand Up @@ -785,6 +797,9 @@ ALTER TABLE wcf1_language_item ADD FOREIGN KEY (packageID) REFERENCES wcf1_packa
ALTER TABLE wcf1_language_to_package ADD FOREIGN KEY (languageID) REFERENCES wcf1_language (languageID) ON DELETE CASCADE;
ALTER TABLE wcf1_language_to_package ADD FOREIGN KEY (packageID) REFERENCES wcf1_package (packageID) ON DELETE CASCADE;

ALTER TABLE wcf1_modification_log ADD FOREIGN KEY (objectTypeID) REFERENCES wcf1_object_type (objectTypeID) ON DELETE CASCADE;
ALTER TABLE wcf1_modification_log ADD FOREIGN KEY (userID) REFERENCES wcf1_user (userID) ON DELETE SET NULL;

ALTER TABLE wcf1_object_type ADD FOREIGN KEY (definitionID) REFERENCES wcf1_object_type_definition (definitionID) ON DELETE CASCADE;
ALTER TABLE wcf1_object_type ADD FOREIGN KEY (packageID) REFERENCES wcf1_package (packageID) ON DELETE CASCADE;

Expand Down

3 comments on commit 3a2de7f

@Gravatronics
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice, comes very handy.

@Gravatronics
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the namespace (part) really be system/log/modification, while it's data/modification/log?

@dtdesign
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This kind of inversion isn't unfamiliar, there are a few places in which we decided to invert the directory logic. The system directory would be incredibly overcrowded if we would not group them together. Some good examples are wcf\system\menu, wcf\system\option, splitting them up would create a massive fragmentation of classes which more or less belong together.

Since there might be a growing amount of logging-related classes in the future, I thought it would be easier to group them.

Please sign in to comment.