[BUGFIX] Unknown t3lib_TcaRelationService in StaticRecordCollection
authorOliver Hader <oliver@typo3.org>
Wed, 15 Feb 2012 12:33:03 +0000 (13:33 +0100)
committerSteffen Ritter <info@rs-websystems.de>
Tue, 27 Mar 2012 13:08:26 +0000 (15:08 +0200)
t3lib_collection_StaticRecordCollection::loadContents() tries to
access class t3lib_TcaRelationService which is not available in
the TYPO3 Core. The accordant dependent feature request was
pending for master (see #32148). Since the TcaRelationService
was dropped for 4.7, this fix uses plain MM queries to get the
desired results.

Change-Id: I72fa5f7dc0fcf269ef00f9ec17bff6dd5bd95173
Fixes: #33942
Releases: 6.0, 4.7
Reviewed-on: http://review.typo3.org/9028
Reviewed-by: Oliver Hader
Tested-by: Oliver Hader
Reviewed-by: Steffen Ritter
Tested-by: Steffen Ritter
t3lib/collection/StaticRecordCollection.php
tests/t3lib/collection/RecordCollectionRepositoryTest.php

index 8f84da0..ebb0316 100644 (file)
  */
 class t3lib_collection_StaticRecordCollection extends t3lib_collection_AbstractRecordCollection implements t3lib_collection_Editable {
        /**
+        * Creates a new collection objects and reconstitutes the
+        * given database record to the new object.
+        *
+        * @static
+        * @param array $collectionRecord Database record
+        * @param bool $fillItems Populates the entries directly on load, might be bad for memory on large collections
+        * @return t3lib_collection_StaticRecordCollection
+        */
+       public static function create(array $collectionRecord, $fillItems = FALSE) {
+               /** @var $collection t3lib_collection_StaticRecordCollection */
+               $collection = t3lib_div::makeInstance(
+                       't3lib_collection_StaticRecordCollection',
+                       $collectionRecord['table_name']
+               );
+
+               $collection->fromArray($collectionRecord);
+
+               if ($fillItems) {
+                       $collection->loadContents();
+               }
+
+               return $collection;
+       }
+
+       /**
+        * Creates this object.
+        *
+        * @param string $tableName Name of the table to be working on
+        */
+       public function __construct($tableName = NULL) {
+               parent::__construct();
+
+               if (!empty($tableName)) {
+                       $this->setItemTableName($tableName);
+               } elseif (empty($this->itemTableName)) {
+                       throw new RuntimeException(
+                               't3lib_collection_StaticRecordCollection needs a valid itemTableName.',
+                               1330293778
+                       );
+               }
+       }
+
+       /**
         * Populates the content-entries of the storage
         *
         * Queries the underlying storage for entries of the collection
@@ -47,11 +90,9 @@ class t3lib_collection_StaticRecordCollection extends t3lib_collection_AbstractR
         * @return void
         */
        public function loadContents() {
-               /** @var t3lib_TcaRelationService $relationService */
-               $relationService = t3lib_div::makeInstance('t3lib_TcaRelationService', self::$storageTableName, self::$storageItemsField, $this->itemTableName);
-
-               $entries = $relationService->getRecordsWithRelationFromCurrentRecord($this->toArray());
+               $entries = $this->getCollectedRecords();
                $this->removeAll();
+
                foreach ($entries as $entry) {
                        $this->add($entry);
                }
@@ -127,5 +168,33 @@ class t3lib_collection_StaticRecordCollection extends t3lib_collection_AbstractR
        public function removeAll() {
                $this->storage = new SplDoublyLinkedList();
        }
+
+       /**
+        * Gets the collected records in this collection, by
+        * looking up the MM relations of this record to the
+        * table name defined in the local field 'table_name'.
+        *
+        * @return array
+        */
+       protected function getCollectedRecords() {
+               $relatedRecords = array();
+
+               $resource = $GLOBALS['TYPO3_DB']->exec_SELECT_mm_query(
+                       $this->getItemTableName() . '.*',
+                       self::$storageTableName,
+                       'sys_collection_entries',
+                       $this->getItemTableName(),
+                       'AND ' . self::$storageTableName . '.uid=' . intval($this->getIdentifier())
+               );
+
+               if ($resource) {
+                       while ($record = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($resource)) {
+                               $relatedRecords[] = $record;
+                       }
+                       $GLOBALS['TYPO3_DB']->sql_free_result($resource);
+               }
+
+               return $relatedRecords;
+       }
 }
 ?>
\ No newline at end of file
index 99e0078..7bd6070 100644 (file)
@@ -54,6 +54,11 @@ class t3lib_collection_RecordCollectionRepositoryTest extends Tx_Phpunit_TestCas
        protected $getRowsCallbackReturnValue;
 
        /**
+        * @var string
+        */
+       protected $testTableName;
+
+       /**
         * Sets up this test case.
         */
        protected function setUp() {
@@ -70,6 +75,8 @@ class t3lib_collection_RecordCollectionRepositoryTest extends Tx_Phpunit_TestCas
                        ->expects($this->any())
                        ->method('getDatabase')
                        ->will($this->returnValue($this->databaseMock));
+
+               $this->testTableName = uniqid('tx_testtable');
        }
 
        /**
@@ -80,6 +87,7 @@ class t3lib_collection_RecordCollectionRepositoryTest extends Tx_Phpunit_TestCas
                unset($this->fixture);
                unset($this->getSingleRowCallbackReturnValue);
                unset($this->getRowsCallbackReturnValue);
+               unset($this->testTableName);
        }
 
        /**
@@ -111,6 +119,7 @@ class t3lib_collection_RecordCollectionRepositoryTest extends Tx_Phpunit_TestCas
                $this->getSingleRowCallbackReturnValue = array(
                        'uid' => $testUid,
                        'type' => t3lib_collection_RecordCollectionRepository::TYPE_Static,
+                       'table_name' => $this->testTableName,
                );
 
                $object = $this->fixture->findByUid($testUid);
@@ -165,8 +174,8 @@ class t3lib_collection_RecordCollectionRepositoryTest extends Tx_Phpunit_TestCas
                        ->method('exec_SELECTgetRows')
                        ->will($this->returnCallback(array($this, 'getRowsCallback')));
                $this->getRowsCallbackReturnValue =     array(
-                       array('uid' => $testUid, 'type' => $type),
-                       array('uid' => $testUid, 'type' => $type),
+                       array('uid' => $testUid, 'type' => $type, 'table_name' => $this->testTableName),
+                       array('uid' => $testUid, 'type' => $type, 'table_name' => $this->testTableName),
                );
 
                $objects = $this->fixture->findByType($type);
@@ -206,8 +215,8 @@ class t3lib_collection_RecordCollectionRepositoryTest extends Tx_Phpunit_TestCas
                        ->method('exec_SELECTgetRows')
                        ->will($this->returnCallback(array($this, 'getRowsCallback')));
                $this->getRowsCallbackReturnValue = array(
-                       array('uid' => $testUid, 'type' => $type),
-                       array('uid' => $testUid, 'type' => $type),
+                       array('uid' => $testUid, 'type' => $type, 'table_name' => $this->testTableName),
+                       array('uid' => $testUid, 'type' => $type, 'table_name' => $this->testTableName),
                );
 
                $objects = $this->fixture->findByTableName($testTable);
@@ -248,8 +257,8 @@ class t3lib_collection_RecordCollectionRepositoryTest extends Tx_Phpunit_TestCas
                        ->method('exec_SELECTgetRows')
                        ->will($this->returnCallback(array($this, 'getRowsCallback')));
                $this->getRowsCallbackReturnValue = array(
-                       array('uid' => $testUid, 'type' => $type),
-                       array('uid' => $testUid, 'type' => $type),
+                       array('uid' => $testUid, 'type' => $type, 'table_name' => $this->testTableName),
+                       array('uid' => $testUid, 'type' => $type, 'table_name' => $this->testTableName),
                );
 
                $objects = $this->fixture->findByTypeAndTableName($type, $testTable);