use wcf\system\database\util\PreparedStatementConditionBuilder;
use wcf\system\exception\SystemException;
use wcf\system\WCF;
-use wcf\util\StringUtil;
+use wcf\util\ClassUtil;
/**
* Abstract class for a list of database objects.
*
* @author Marcel Werk
- * @copyright 2001-2012 WoltLab GmbH
+ * @copyright 2001-2014 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @package com.woltlab.wcf
* @subpackage data
*/
public $className = '';
+ /**
+ * class name of the object decorator; if left empty, no decorator is used
+ * @var string
+ */
+ public $decoratorClassName = '';
+
/**
* object class name
* @var string
/**
* result objects
- * @var array<wcf\data\DatabaseObject>
+ * @var array<\wcf\data\DatabaseObject>
*/
public $objects = array();
* ids of result objects
* @var array<integer>
*/
- public $objectIDs = null;
+ public $objectIDs = null;
/**
* sql offset
* sql limit
* @var integer
*/
- public $sqlLimit = 20;
+ public $sqlLimit = 0;
/**
* sql order by statement
public $sqlJoins = '';
/**
- * enables the automatic usage of the qualified shorthand
+ * enables the automatic usage of the qualified shorthand
* @var boolean
*/
public $useQualifiedShorthand = true;
/**
* sql conditions
- * @var wcf\system\database\util\PreparedStatementConditionBuilder
+ * @var \wcf\system\database\util\PreparedStatementConditionBuilder
*/
protected $conditionBuilder = null;
if (empty($this->className)) {
$className = get_called_class();
- if (StringUtil::substring($className, -4) == 'List') {
- $this->className = StringUtil::substring($className, 0, -4);
+ if (mb_substr($className, -4) == 'List') {
+ $this->className = mb_substr($className, 0, -4);
+ }
+ }
+
+ if (!empty($this->decoratorClassName)) {
+ // validate decorator class name
+ if (!ClassUtil::isInstanceOf($this->decoratorClassName, 'wcf\data\DatabaseObjectDecorator')) {
+ throw new SystemException("'".$this->decoratorClassName."' should extend 'wcf\data\DatabaseObjectDecorator'");
+ }
+
+ $objectClassName = $this->objectClassName ?: $this->className;
+ $baseClassName = call_user_func(array($this->decoratorClassName, 'getBaseClass'));
+ if ($objectClassName != $baseClassName && !ClassUtil::isInstanceOf($baseClassName, $objectClassName)) {
+ throw new SystemException("'".$this->decoratorClassName."' can't decorate objects of class '".$objectClassName."'");
}
}
$sql = "SELECT COUNT(*) AS count
FROM ".$this->getDatabaseTableName()." ".$this->getDatabaseTableAlias()."
".$this->sqlConditionJoins."
- ".$this->getConditionBuilder()->__toString();
+ ".$this->getConditionBuilder();
$statement = WCF::getDB()->prepareStatement($sql);
$statement->execute($this->getConditionBuilder()->getParameters());
$row = $statement->fetchArray();
$sql = "SELECT ".$this->getDatabaseTableAlias().".".$this->getDatabaseTableIndexName()." AS objectID
FROM ".$this->getDatabaseTableName()." ".$this->getDatabaseTableAlias()."
".$this->sqlConditionJoins."
- ".$this->getConditionBuilder()->__toString()."
+ ".$this->getConditionBuilder()."
".(!empty($this->sqlOrderBy) ? "ORDER BY ".$this->sqlOrderBy : '');
$statement = WCF::getDB()->prepareStatement($sql, $this->sqlLimit, $this->sqlOffset);
$statement->execute($this->getConditionBuilder()->getParameters());
*/
public function readObjects() {
if ($this->objectIDs !== null) {
- if (!count($this->objectIDs)) {
+ if (empty($this->objectIDs)) {
return;
}
$sql = "SELECT ".(!empty($this->sqlSelects) ? $this->sqlSelects.($this->useQualifiedShorthand ? ',' : '') : '')."
".($this->useQualifiedShorthand ? $this->getDatabaseTableAlias().'.*' : '')."
FROM ".$this->getDatabaseTableName()." ".$this->getDatabaseTableAlias()."
".$this->sqlJoins."
- ".$this->getConditionBuilder()->__toString()."
+ ".$this->getConditionBuilder()."
".(!empty($this->sqlOrderBy) ? "ORDER BY ".$this->sqlOrderBy : '');
$statement = WCF::getDB()->prepareStatement($sql, $this->sqlLimit, $this->sqlOffset);
$statement->execute($this->getConditionBuilder()->getParameters());
$this->objects = $statement->fetchObjects(($this->objectClassName ?: $this->className));
}
+ // decorate objects
+ if (!empty($this->decoratorClassName)) {
+ foreach ($this->objects as &$object) {
+ $object = new $this->decoratorClassName($object);
+ }
+ unset($object);
+ }
+
// use table index as array index
$objects = array();
- foreach($this->objects as $object) {
- $objectID = $object->{$this->getDatabaseTableIndexName()};
+ foreach ($this->objects as $object) {
+ $objectID = $object->getObjectID();
$objects[$objectID] = $object;
$this->indexToObject[] = $objectID;
return $this->objectIDs;
}
+ /**
+ * Sets the object ids.
+ *
+ * @param array<integer> $objectIDs
+ */
+ public function setObjectIDs(array $objectIDs) {
+ $this->objectIDs = array_merge($objectIDs);
+ }
+
/**
* Returns the objects of the list.
*
- * @return array<wcf\data\DatabaseObject>
+ * @return array<\wcf\data\DatabaseObject>
*/
public function getObjects() {
return $this->objects;
/**
* Returns the condition builder object.
*
- * @return wcf\system\database\util\PreparedStatementConditionBuilder
+ * @return \wcf\system\database\util\PreparedStatementConditionBuilder
*/
public function getConditionBuilder() {
return $this->conditionBuilder;
}
/**
- * @see wcf\data\ITraversableObject::seekTo()
+ * @see \wcf\data\ITraversableObject::seekTo()
*/
public function seekTo($objectID) {
$this->index = array_search($objectID, $this->indexToObject);
}
/**
- * @see wcf\data\ITraversableObject::search()
+ * @see \wcf\data\ITraversableObject::search()
*/
public function search($objectID) {
try {