ExtBase
authorJochen Rau <j.rau@web.de>
Fri, 27 Mar 2009 02:08:02 +0000 (02:08 +0000)
committerJochen Rau <j.rau@web.de>
Fri, 27 Mar 2009 02:08:02 +0000 (02:08 +0000)
* Revised Object Storage
* Added test cases for the Object Storage
* Moved check for empty $where clause to the fetch method
* fetchWithRelationTable() is broken -> fixed with a work-around

typo3/sysext/extbase/Classes/Persistence/Mapper/ObjectRelationalMapper.php
typo3/sysext/extbase/Classes/Persistence/ObjectStorage.php
typo3/sysext/extbase/Tests/DataMap_testcase.php
typo3/sysext/extbase/Tests/ObjectRelationalMapper_testcase.php
typo3/sysext/extbase/Tests/ObjectStorage_testcase.php
typo3/sysext/extbase/Tests/Repository_testcase.php

index 13bd165..b9466f3 100644 (file)
@@ -96,11 +96,7 @@ class Tx_ExtBase_Persistence_Mapper_ObjectRelationalMapper implements t3lib_Sing
                if (is_array($conditions)) {
                        $where = $this->queryByConditions($dataMap, $conditions);
                } elseif (is_string($conditions)) {
-                       if (strlen($conditions) === 0) {
-                               $where = '1=1';
-                       } else {
-                               $where = $conditions;
-                       }
+                       $where = $conditions;
                }
                return $this->fetch($className, $where, $groupBy, $orderBy, $limit, $useEnableFields);
        }
@@ -172,6 +168,7 @@ class Tx_ExtBase_Persistence_Mapper_ObjectRelationalMapper implements t3lib_Sing
                                $sql = substr($sql, 0, $markPos) . $dataMap->convertPropertyValueToFieldValue($parameter) . substr($sql, $markPos + 1);
                        }
                }
+               // TODO Exception mehr parameter als fragezeichen; mehr fragezeichen als 
                return $sql;
        }
 
@@ -187,7 +184,11 @@ class Tx_ExtBase_Persistence_Mapper_ObjectRelationalMapper implements t3lib_Sing
         * @param string $limit LIMIT statement
         * @return array The matched rows
         */
-       public function fetch($className, $where = '1=1', $groupBy = '', $orderBy = '', $limit = '', $useEnableFields = TRUE) {
+       public function fetch($className, $where = '', $groupBy = '', $orderBy = '', $limit = '', $useEnableFields = TRUE) {
+               // if (!is_string($where)) 
+               if (strlen($where) === 0) {
+                       $where = '1=1';
+               }
                $dataMap = $this->getDataMap($className);
                if ($useEnableFields === TRUE) {
                        $enableFields = $GLOBALS['TSFE']->sys_page->enableFields($dataMap->getTableName());
@@ -204,6 +205,8 @@ class Tx_ExtBase_Persistence_Mapper_ObjectRelationalMapper implements t3lib_Sing
                        $orderBy,
                        $limit
                        );
+                       // TODO language overlay; workspace overlay
+                       
                $fieldMap = array();
                $i = 0;
                // FIXME mysql_fetch_field should be available in t3lib_db (patch core)
@@ -219,7 +222,6 @@ class Tx_ExtBase_Persistence_Mapper_ObjectRelationalMapper implements t3lib_Sing
 
                
                // SK: Do we want to make it possible to ignore "enableFields"?
-               // TODO language overlay; workspace overlay
                $objects = array();
                if (is_array($rows)) {
                        if (count($rows) > 0) {
@@ -257,7 +259,7 @@ class Tx_ExtBase_Persistence_Mapper_ObjectRelationalMapper implements t3lib_Sing
         * @param string Optional LIMIT value ([begin,]max), defaults to blank string.
         */
        public function fetchWithRelationTable($parentObject, $columnMap, $where = '1=1', $groupBy = '', $orderBy = '', $limit = '', $useEnableFields = TRUE) {
-               $dataMap = $this->getDataMap(get_class($parentObject));
+               $dataMap = $this->getDataMap('Tx_BlogExample_Domain_Tag'); // FIXME hard-coded class name
                if ($useEnableFields === TRUE) {
                        $enableFields = $GLOBALS['TSFE']->sys_page->enableFields($columnMap->getChildTableName());
                } else {
@@ -311,6 +313,7 @@ class Tx_ExtBase_Persistence_Mapper_ObjectRelationalMapper implements t3lib_Sing
                                        $object->_reconstituteProperty($columnMap->getPropertyName(), $relatedObjects);
                                } elseif ($columnMap->getTypeOfRelation() === Tx_ExtBase_Persistence_Mapper_ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY) {
                                        $relatedDataMap = $this->getDataMap($columnMap->getChildClassName());
+                                       // FIXME fetchWithRelationTable()
                                        $relatedObjects = $this->fetchWithRelationTable($object, $columnMap);
                                        $object->_reconstituteProperty($columnMap->getPropertyName(), $relatedObjects);
                                }
index 018b33c..1b3f4f2 100644 (file)
@@ -101,9 +101,11 @@ class Tx_ExtBase_Persistence_ObjectStorage implements Iterator, Countable, Array
         * @return void
         */
        public function offsetSet($offset, $obj) {
-               if (!is_object($offset)) throw new InvalidArgumentException('Expects Parameter 1 to be object, null given');
-               if (is_object($obj) && !$this->contains($obj)) {
-                       $this->storage[$offset] = $obj;
+               if (!is_object($offset)) throw new Tx_ExtBase_Exception_InvalidArgumentType('Expected parameter 1 to be object, ' . gettype($offset) . ' given');
+               if (!is_object($obj)) throw new Tx_ExtBase_Exception_InvalidArgumentType('Expected parameter 2 to be object, ' . gettype($offset) . ' given');
+               if (!($offset === $obj)) throw new Tx_ExtBase_Exception_InvalidArgumentType('Parameter 1 and parameter 2 must be a reference to the same object.');
+               if (!$this->contains($obj)) {
+                       $this->storage[spl_object_hash($offset)] = $obj;
                }
        }
 
@@ -114,7 +116,8 @@ class Tx_ExtBase_Persistence_ObjectStorage implements Iterator, Countable, Array
         * @return boolean TRUE if the given offset exists; otherwise FALSE
         */
        public function offsetExists($offset) {
-               return isset($this->storage[$offset]);
+               if (!is_object($offset)) throw new Tx_ExtBase_Exception_InvalidArgumentType('Expected parameter to be an object, ' . gettype($offset) . ' given');
+               return isset($this->storage[spl_object_hash($offset)]);
        }
 
        /**
@@ -124,7 +127,8 @@ class Tx_ExtBase_Persistence_ObjectStorage implements Iterator, Countable, Array
         * @return void
         */
        public function offsetUnset($offset) {
-               unset($this->storage[$offset]);
+               if (!is_object($offset)) throw new Tx_ExtBase_Exception_InvalidArgumentType('Expected parameter to be an object, ' . gettype($offset) . ' given');
+               unset($this->storage[spl_object_hash($offset)]);
        }
 
        /**
@@ -134,22 +138,19 @@ class Tx_ExtBase_Persistence_ObjectStorage implements Iterator, Countable, Array
         * @return Object The object
         */
        public function offsetGet($offset) {
-               return isset($this->storage[$offset]) ? $this->storage[$offset] : NULL;
+               if (!is_object($offset)) throw new Tx_ExtBase_Exception_InvalidArgumentType('Expected parameter to be an object, ' . gettype($offset) . ' given');
+               return isset($this->storage[spl_object_hash($offset)]) ? $this->storage[spl_object_hash($offset)] : NULL;
        }
 
        /**
         * Checks if the storage contains the given object
         *
-        * @param Object $obj The object to be checked for
+        * @param Object $object The object to be checked for
         * @return boolean TRUE|FALSE Returns TRUE if the storage contains the object; otherwise FALSE
         */
-       public function contains($obj) {
-               if (is_object($obj)) {
-                       foreach($this->storage as $object) {
-                               if ($object === $obj) return TRUE;
-                       }
-               }
-               return FALSE;
+       public function contains($object) {
+               if (!is_object($object)) throw new Tx_ExtBase_Exception_InvalidArgumentType('Expected parameter to be an object, ' . gettype($object) . ' given');
+               return array_key_exists(spl_object_hash($object), $this->storage);
        }
 
        /**
@@ -158,28 +159,22 @@ class Tx_ExtBase_Persistence_ObjectStorage implements Iterator, Countable, Array
         * @param Object $obj The Object to be attached
         * @return void
         */
-       public function attach($obj) {
-               if (is_object($obj) && !$this->contains($obj)) {
-                       $this->storage[] = $obj;
+       public function attach($object) {
+               if (!is_object($object)) throw new Tx_ExtBase_Exception_InvalidArgumentType('Expected parameter to be an object, ' . gettype($object) . ' given');
+               if (!$this->contains($object)) {
+                       $this->storage[spl_object_hash($object)] = $object;
                }
        }
 
        /**
-        * Detaches an object to the storage
+        * Detaches an object from the storage
         *
-        * @param Object $obj The object to be removed from the storage
+        * @param Object $object The object to be removed from the storage
         * @return void
         */
-       public function detach($obj) {
-               if (is_object($obj)) {
-                       foreach($this->storage as $key => $object) {
-                               if ($object === $obj) {
-                                       unset($this->storage[$key]);
-                                       $this->rewind();
-                                       return;
-                               }
-                       }
-               }
+       public function detach($object) {
+               if (!is_object($object)) throw new Tx_ExtBase_Exception_InvalidArgumentType('Expected parameter to be an object, ' . gettype($object) . ' given');
+               unset($this->storage[spl_object_hash($object)]);
        }
 
        /**
index 092096f..0d67388 100644 (file)
@@ -24,8 +24,6 @@
 
 require_once(PATH_tslib . 'class.tslib_content.php');
 
-require_once('Base_testcase.php');
-
 class Tx_ExtBase_Persistence_Mapper_DataMap_testcase extends Tx_ExtBase_Base_testcase {
        
        public function setUp() {
index 3e4b5ba..7d37f97 100644 (file)
@@ -22,8 +22,6 @@
 *  This copyright notice MUST APPEAR in all copies of the script!
 ***************************************************************/
 
-require_once('Base_testcase.php');
-
 class Tx_ExtBase_Persistence_Mapper_ObjectRelationalMapper_testcase extends Tx_ExtBase_Base_testcase {
 
        public function setUp() {
index 2d78d08..0237de0 100644 (file)
 *  This copyright notice MUST APPEAR in all copies of the script!
 ***************************************************************/
 
-require_once('Base_testcase.php');
-
 class Tx_ExtBase_Persistence_ObjectStorage_testcase extends Tx_ExtBase_Base_testcase {
        
        public function setUp() {
        }
        
-       public function test_AddingAnObjectWithoutOffsetThrowsAnException() {
-               $this->setExpectedException('InvalidArgumentException');
+       public function test_AnObjectCanBeAttached() {
+               $objectStorage = new Tx_ExtBase_Persistence_ObjectStorage();
+               $object = $this->getMock('Tx_ExtBase_DomainObject_AbstractEntity');
+               $objectStorage->attach($object);
+               $result = $objectStorage->offsetGet($object);
+               $this->assertEquals($result, $object, 'The retrieved object differs from the attached object.');                
+       }
+       
+       public function test_AttachingSomethingElseThanAnObjectThrowsAnException() {
+               $this->setExpectedException('Tx_ExtBase_Exception_InvalidArgumentType');
+               $objectStorage = new Tx_ExtBase_Persistence_ObjectStorage();
+               $objectStorage->attach('foo');
+       }
+       
+       public function test_AnObjectCanBeDetached() {
+               $objectStorage = new Tx_ExtBase_Persistence_ObjectStorage();
+               $object = $this->getMock('Tx_ExtBase_DomainObject_AbstractEntity');
+               $objectStorage->offsetSet($object, $object);
+               $resultBeforeDetaching = $objectStorage->offsetGet($object);
+               $this->assertEquals($resultBeforeDetaching, $object, 'The object could not be set via offsetSet().');           
+               $objectStorage->detach($object);
+               $resultAfterDetaching = $objectStorage->offsetGet($object);
+               $this->assertEquals($resultAfterDetaching, NULL, 'The object could not be detached.');          
+       }
+       
+       public function test_DetachingSomethingElseThanAnObjectThrowsAnException() {
+               $this->setExpectedException('Tx_ExtBase_Exception_InvalidArgumentType');
+               $objectStorage = new Tx_ExtBase_Persistence_ObjectStorage();
+               $objectStorage->detach('foo');
+       }
+       
+       public function test_AddingAnObjectWithoutAnObjectAsOffsetThrowsAnException() {
+               $this->setExpectedException('Tx_ExtBase_Exception_InvalidArgumentType');
                $objectStorage = new Tx_ExtBase_Persistence_ObjectStorage();
                $object = $this->getMock('Tx_ExtBase_DomainObject_AbstractEntity');
                $objectStorage[] = $object;
        }
+               
+       public function test_AddingAValueOtherThanAnObjectThrowsAnException() {
+               $this->setExpectedException('Tx_ExtBase_Exception_InvalidArgumentType');
+               $objectStorage = new Tx_ExtBase_Persistence_ObjectStorage();
+               $object = $this->getMock('Tx_ExtBase_DomainObject_AbstractEntity');
+               $objectStorage[$object] = 'foo';
+       }
+       
+       public function test_IfTheOffsetAndTheValueAreNotEqualAnExceptionIsThrown() {
+               $this->setExpectedException('Tx_ExtBase_Exception_InvalidArgumentType');
+               $objectStorage = new Tx_ExtBase_Persistence_ObjectStorage();
+               $object1 = $this->getMock('Tx_ExtBase_DomainObject_AbstractEntity');
+               $object2 = $this->getMock('Tx_ExtBase_DomainObject_AbstractEntity');
+               $objectStorage[$object1] = $object2;
+       }       
+       
+       public function test_AnObjectCouldBeSetViaAnOffset() {
+               $objectStorage = new Tx_ExtBase_Persistence_ObjectStorage();
+               $object = $this->getMock('Tx_ExtBase_DomainObject_AbstractEntity');
+               $objectStorage[$object] = $object;
+               $result = $objectStorage->offsetGet($object);
+               $this->assertEquals($result, $object, 'The retrieved object differs from the attached object.');
+       }
        
+       public function test_ItCanBeTestedIfTheStorageContainsAnObject() {
+               $objectStorage = new Tx_ExtBase_Persistence_ObjectStorage();
+               $object = $this->getMock('Tx_ExtBase_DomainObject_AbstractEntity');
+               $objectStorage->attach($object);
+               $result = $objectStorage->contains($object);
+               $this->assertEquals($result, TRUE, 'The method object differs from the attached object.');              
+       }
+       
+       public function test_UnsettingSomethingElseThanAnObjectThrowsAnException() {
+               $this->setExpectedException('Tx_ExtBase_Exception_InvalidArgumentType');
+               $objectStorage = new Tx_ExtBase_Persistence_ObjectStorage();
+               // $object = $this->getMock('Tx_ExtBase_DomainObject_AbstractEntity');
+               // $objectStorage->offsetSet($object, $object);
+               $objectStorage->offsetUnset('foo');
+       }
+
+       public function test_AnObjectCanBeUnset() {
+               $objectStorage = new Tx_ExtBase_Persistence_ObjectStorage();
+               $object = $this->getMock('Tx_ExtBase_DomainObject_AbstractEntity');
+               $objectStorage->offsetSet($object, $object);
+               $resultBeforeDetaching = $objectStorage->offsetGet($object);
+               $this->assertEquals($resultBeforeDetaching, $object, 'The object could not be set via offsetSet().');           
+               $objectStorage->offsetUnset($object);
+               $resultAfterDetaching = $objectStorage->offsetGet($object);
+               $this->assertEquals($resultAfterDetaching, NULL, 'The object could not be unsetted.');          
+       }
+
+       public function test_TheStorageCanBeRetrievedAsArray() {
+               $objectStorage = new Tx_ExtBase_Persistence_ObjectStorage();
+               $object1 = $this->getMock('Tx_ExtBase_DomainObject_AbstractEntity');
+               $objectStorage->offsetSet($object1, $object1);
+               $object2 = $this->getMock('Tx_ExtBase_DomainObject_AbstractEntity');
+               $objectStorage->offsetSet($object2, $object2);
+               $result = $objectStorage->toArray();
+               $this->assertEquals(is_array($result), TRUE, 'The result was not an array as expected.');               
+               $this->assertEquals(count($result), 2, 'The retrieved array did not contain two elements.');            
+       }
+
 }
 ?>
\ No newline at end of file
index 5e4ddb7..d9fb8ef 100644 (file)
@@ -22,8 +22,6 @@
 *  This copyright notice MUST APPEAR in all copies of the script!
 ***************************************************************/
 
-require_once('Base_testcase.php');
-
 class Tx_ExtBase_Persistence_Repository_testcase extends Tx_ExtBase_Base_testcase {
        public function __construct() {
                require_once(t3lib_extMgm::extPath('blogexample', 'Classes/Domain/BlogRepository.php'));