Added detailed list of received/given likes in user profiles
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / data / DatabaseObjectList.class.php
index 9d8b8e102b73a8d8486c294c9fc7c70ff1d4af3e..f4aaa1945673e34c2e5172ee266d53039faa70a6 100644 (file)
@@ -3,13 +3,13 @@ namespace wcf\data;
 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
@@ -22,6 +22,12 @@ abstract class DatabaseObjectList implements \Countable, ITraversableObject {
         */
        public $className = '';
        
+       /**
+        * class name of the object decorator; if left empty, no decorator is used
+        * @var string
+        */
+       public $decoratorClassName = '';
+       
        /**
         * object class name
         * @var string
@@ -30,7 +36,7 @@ abstract class DatabaseObjectList implements \Countable, ITraversableObject {
        
        /**
         * result objects
-        * @var array<wcf\data\DatabaseObject>
+        * @var array<\wcf\data\DatabaseObject>
         */
        public $objects = array();
        
@@ -38,7 +44,7 @@ abstract class DatabaseObjectList implements \Countable, ITraversableObject {
         * ids of result objects
         * @var array<integer>
         */
-       public $objectIDs = null; 
+       public $objectIDs = null;
        
        /**
         * sql offset
@@ -50,7 +56,7 @@ abstract class DatabaseObjectList implements \Countable, ITraversableObject {
         * sql limit
         * @var integer
         */
-       public $sqlLimit = 20;
+       public $sqlLimit = 0;
        
        /**
         * sql order by statement
@@ -77,14 +83,14 @@ abstract class DatabaseObjectList implements \Countable, ITraversableObject {
        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;
        
@@ -108,8 +114,21 @@ abstract class DatabaseObjectList implements \Countable, ITraversableObject {
                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."'");
                        }
                }
                
@@ -125,7 +144,7 @@ abstract class DatabaseObjectList implements \Countable, ITraversableObject {
                $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();
@@ -140,7 +159,7 @@ abstract class DatabaseObjectList implements \Countable, ITraversableObject {
                $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());
@@ -172,17 +191,25 @@ abstract class DatabaseObjectList implements \Countable, ITraversableObject {
                                        ".($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;
@@ -206,13 +233,13 @@ abstract class DatabaseObjectList implements \Countable, ITraversableObject {
         * @param       array<integer>          $objectIDs
         */
        public function setObjectIDs(array $objectIDs) {
-               $this->objectIDs = $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;
@@ -221,7 +248,7 @@ abstract class DatabaseObjectList implements \Countable, ITraversableObject {
        /**
         * Returns the condition builder object.
         * 
-        * @return      wcf\system\database\util\PreparedStatementConditionBuilder
+        * @return      \wcf\system\database\util\PreparedStatementConditionBuilder
         */
        public function getConditionBuilder() {
                return $this->conditionBuilder;
@@ -312,7 +339,7 @@ abstract class DatabaseObjectList implements \Countable, ITraversableObject {
        }
        
        /**
-        * @see wcf\data\ITraversableObject::seekTo()
+        * @see \wcf\data\ITraversableObject::seekTo()
         */
        public function seekTo($objectID) {
                $this->index = array_search($objectID, $this->indexToObject);
@@ -323,7 +350,7 @@ abstract class DatabaseObjectList implements \Countable, ITraversableObject {
        }
        
        /**
-        * @see wcf\data\ITraversableObject::search()
+        * @see \wcf\data\ITraversableObject::search()
         */
        public function search($objectID) {
                try {