Extbase:
authorSebastian Kurfürst <sebastian@typo3.org>
Fri, 10 Jul 2009 15:42:28 +0000 (15:42 +0000)
committerSebastian Kurfürst <sebastian@typo3.org>
Fri, 10 Jul 2009 15:42:28 +0000 (15:42 +0000)
(Changes by Jochen)
This commit merges the rewrite of the persistence layer back to trunk. It will probably break your existing installation. Please check out fluid and blog_example again.
* Implemented an Object Manager (a wrapper for t3lib_div::makeInstance())
* !!! Backport of the Query and the Query Object Model from FLOW3.
* !!! Removed Repository->fetch*()
* Splited the functionality of the Object Relational Mapper into the Persistence Backend, the Data Mapper and the SQL Storage Backend.
* Implemented the Lazy Loading Proxy.
* supported Request types is now Tx_Extbase_MVC_Request instead of Tx_Extbase_MVC_Web_Request.
* Changed _reconstituteProperty() to _setProperty() (according to FLOW3).
* Added _getProperty() to the Domain Object.
* The Dispatcher now instanciates and uses a PersistenceManager to commit changes.
* Added TypoScript converter method (to convert from new TS to classic TS). Fixes #3293.
* Renamed SqlBackend to Typo3DbBackend
* Now using constants in Tx_Extbase_Persistence_PropertyType instead of Tx_Extbase_Persistence_Mapper_ColumnMap
* Improved conversion from table value to property value
* Persistence_Repository: findByUid() checks now for positive integer
* Fixed: Only Aggregate Roots are now registered as Reconstituted Objects
* !!! Added _isNew() to the Domain Object Interface
* Revision of the Persistence Backend (CRUD operations work now - again)
* Fixed Query Object Model "UpperCase"
* Implemented addRow(), deleteRow() and updateRow()
* Fixed: _memorizeCleanState() now clones a property value if it is an object
* Argument->findObjectByUid() memorizes now the clean state (todo: check if the object is an Aggregate Root)
* Removed unnecessary method getRelations()
* Fixed wrong class name of PropertyError; resolves issue #3855
* Fixed typo in Persistence Query; resolves issue #3831
* Changed: Equivalent Value Objects (all properties are equal) are now persisted only once
* Backport and enhanced several Unit Tests (not finished yet)
* Enhanced Base Test Case
* Changed signature of hasValueObject()
* Changed: hasValueObject() returns the uid of the already persisted value object - if any
* Fixed: relation tables are now filled with the right values if a value object already exists in the database
* Changed: The Persistence Manager and the Query Factory are now "injected" into the Arguments and Argument
* Deleted obsolete files

119 files changed:
typo3/sysext/extbase/Classes/Controller/StandardController.php
typo3/sysext/extbase/Classes/Dispatcher.php
typo3/sysext/extbase/Classes/DomainObject/AbstractDomainObject.php
typo3/sysext/extbase/Classes/DomainObject/AbstractEntity.php
typo3/sysext/extbase/Classes/DomainObject/DomainObjectInterface.php
typo3/sysext/extbase/Classes/MVC/Controller/AbstractController.php
typo3/sysext/extbase/Classes/MVC/Controller/Argument.php
typo3/sysext/extbase/Classes/MVC/Controller/Arguments.php
typo3/sysext/extbase/Classes/MVC/Controller/ControllerContext.php
typo3/sysext/extbase/Classes/Object/Exception.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Object/Exception/CannotBuildObject.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Object/Exception/CannotReconstituteObject.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Object/Exception/InvalidClass.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Object/Exception/InvalidObject.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Object/Exception/InvalidObjectConfiguration.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Object/Exception/ObjectAlreadyRegistered.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Object/Exception/UnknownClass.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Object/Exception/UnknownInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Object/Exception/UnknownObject.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Object/Exception/UnresolvedDependencies.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Object/Exception/WrongScope.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Object/Manager.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Object/ManagerInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Object/RegistryInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Object/TransientRegistry.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/Backend.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/BackendInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/Exception/RepositoryException.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/Exception/UnknownObject.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/Exception/ValueFormatException.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/IteratorInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/LazyLoadingProxy.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/Manager.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/ManagerInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/Mapper/ColumnMap.php
typo3/sysext/extbase/Classes/Persistence/Mapper/DataMap.php
typo3/sysext/extbase/Classes/Persistence/Mapper/DataMapper.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/Mapper/ObjectRelationalMapper.php [deleted file]
typo3/sysext/extbase/Classes/Persistence/PreparedQuery.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/PreparedQueryInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/PropertyType.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/AndInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/BindVariableValue.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/BindVariableValueInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/ChildNodeJoinCondition.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/ChildNodeJoinConditionInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/Comparison.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/ComparisonInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/ConstraintInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/DynamicOperand.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/DynamicOperandInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/EquiJoinCondition.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/EquiJoinConditionInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/Join.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/JoinConditionInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/JoinInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/Literal.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/LogicalAnd.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/LogicalNot.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/LogicalOr.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/LowerCase.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/NotInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/Operand.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/OperandInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/OrInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/PropertyValue.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/PropertyValueInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/QueryObjectModel.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/QueryObjectModelConstantsInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/QueryObjectModelFactory.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/QueryObjectModelFactoryInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/QueryObjectModelInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/Selector.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/SelectorInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/SourceInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/StaticOperand.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/StaticOperandInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QOM/UpperCase.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/Query.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QueryFactory.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QueryFactoryInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QueryInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QueryResult.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QueryResultInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/RangeIterator.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/RangeIteratorInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/Repository.php
typo3/sysext/extbase/Classes/Persistence/RepositoryInterface.php
typo3/sysext/extbase/Classes/Persistence/Row.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/RowInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/RowIterator.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/RowIteratorInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/Session.php
typo3/sysext/extbase/Classes/Persistence/Storage/BackendInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/Storage/Typo3DbBackend.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/Value.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/ValueFactory.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/ValueFactoryInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/ValueInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Property/Mapper.php
typo3/sysext/extbase/Classes/Utility/Arrays.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Utility/Plugin.php
typo3/sysext/extbase/Classes/Validation/PropertyError.php
typo3/sysext/extbase/Classes/Validation/Validator/GenericObjectValidator.php
typo3/sysext/extbase/Classes/Validation/ValidatorResolver.php
typo3/sysext/extbase/Tests/Base_testcase.php
typo3/sysext/extbase/Tests/MVC/Controller/AbstractController_testcase.php
typo3/sysext/extbase/Tests/MVC/Controller/ActionController_testcase.php
typo3/sysext/extbase/Tests/MVC/Controller/Argument_testcase.php
typo3/sysext/extbase/Tests/MVC/Controller/Arguments_testcase.php
typo3/sysext/extbase/Tests/Persistence/Mapper/ObjectRelationalMapper_testcase.php
typo3/sysext/extbase/Tests/Persistence/Query_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Persistence/Repository_testcase.php
typo3/sysext/extbase/Tests/Persistence/Session_testcase.php
typo3/sysext/extbase/Tests/Validation/Validator/ChainValidator_testcase.php [deleted file]
typo3/sysext/extbase/Tests/Validation/Validator/ConjunctionValidator_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Validation/Validator/TextValidator_testcase.php
typo3/sysext/extbase/Tests/Validation/ValidatorResolver_testcase.php
typo3/sysext/extbase/ext_tables.php [new file with mode: 0644]

index a10bf75..40e6837 100755 (executable)
  * @package Extbase
  * @subpackage Controller
  * @version $ID:$
- * @todo - is this ever called?
  */
 class Tx_Extbase_Controller_StandardController extends Tx_Extbase_MVC_Controller_ActionController {
 
        /**
+        * @var Tx_Extbase_View_StandardView
+        */
+       protected $standardView;
+
+       /**
+        * Injects the StandardView.
+        *
+        * @param Tx_Extbase_View_StandardView $notFoundView
+        * @return void
+        */
+       public function injectStandardView(Tx_Extbase_View_StandardView $standardView) {
+               // TODO inject Standard View; implement view and template
+               $this->standardView = $standardView;
+       }
+
+       /**
         * Processes a generic request and returns a response
         *
         * @param Tx_Extbase_MVC_Request $request: The request
@@ -45,7 +60,7 @@ class Tx_Extbase_Controller_StandardController extends Tx_Extbase_MVC_Controller
        public function processRequest(Tx_Extbase_MVC_Request $request, Tx_Extbase_MVC_Response $response) {
                $response->setContent(
                        "\nWelcome to TYPO3!\n\n" .
-                       "This is the standard view of the TYPO3 MVC object. You see this message because no \n" .
+                       "This is the standard view of the TYPO3 Extbase project. You see this message because no \n" .
                        "other view is available. Please refer to the Developer's Guide for more information \n" .
                        "how to create and configure one.\n\n" .
                        "Have fun! The TYPO3 Development Team\n"
index 725c9c7..0a68f5b 100644 (file)
@@ -31,6 +31,7 @@
  * @version $ID:$
  */
 class Tx_Extbase_Dispatcher {
+       
        /**
         * @var Tx_Extbase_Reflection_Service
         */
@@ -48,11 +49,24 @@ class Tx_Extbase_Dispatcher {
                        t3lib_div::sysLog('Extbase was not able to dispatch the request. No configuration.', 'extbase', t3lib_div::SYSLOG_SEVERITY_ERROR);
                        return $content;
                }
+               
                $requestBuilder = t3lib_div::makeInstance('Tx_Extbase_MVC_Web_RequestBuilder');
                $request = $requestBuilder->initialize($configuration);
                $request = $requestBuilder->build();
                $response = t3lib_div::makeInstance('Tx_Extbase_MVC_Web_Response');
+
                $persistenceSession = t3lib_div::makeInstance('Tx_Extbase_Persistence_Session'); // singleton
+               $storageBackend = t3lib_div::makeInstance('Tx_Extbase_Persistence_Storage_Typo3DbBackend');
+               $dataMapper = t3lib_div::makeInstance('Tx_Extbase_Persistence_Mapper_DataMapper');
+
+               $persistenceBackend = t3lib_div::makeInstance('Tx_Extbase_Persistence_Backend', $persistenceSession, $storageBackend); // singleton
+               $persistenceBackend->injectDataMapper($dataMapper);
+               $persistenceBackend->injectIdentityMap(t3lib_div::makeInstance('Tx_Extbase_Persistence_IdentityMap'));
+               $persistenceBackend->injectQOMFactory(t3lib_div::makeInstance('Tx_Extbase_Persistence_QOM_QueryObjectModelFactory', $storageBackend, $dataMapper));
+               $persistenceBackend->injectValueFactory(t3lib_div::makeInstance('Tx_Extbase_Persistence_ValueFactory'));
+
+               $persistenceManager = t3lib_div::makeInstance('Tx_Extbase_Persistence_Manager', $persistenceBackend); // singleton
+               $persistenceManager->injectSession($persistenceSession);
 
                $dispatchLoopCount = 0;
                while (!$request->isDispatched()) {
@@ -62,13 +76,11 @@ class Tx_Extbase_Dispatcher {
                                $controller->processRequest($request, $response);
                        } catch (Tx_Extbase_Exception_StopAction $ignoredException) {
                        } catch (Tx_Extbase_Exception_InvalidArgumentValue $exception) {
-                               $persistenceSession->clear();
                                return '';
                        }
                }
 
-               $persistenceSession->commit();
-               $persistenceSession->clear();
+               $persistenceManager->persistAll();
                $this->reflectionService->shutdown();
                if (count($response->getAdditionalHeaderData()) > 0) {
                        $GLOBALS['TSFE']->additionalHeaderData[$request->getControllerExtensionName()] = implode("\n", $response->getAdditionalHeaderData());
@@ -110,6 +122,7 @@ class Tx_Extbase_Dispatcher {
                        $this->reflectionService->initialize();
                }
                $validatorResolver = t3lib_div::makeInstance('Tx_Extbase_Validation_ValidatorResolver');
+               $validatorResolver->injectObjectManager(t3lib_div::makeInstance('Tx_Extbase_Object_Manager'));
                $validatorResolver->injectReflectionService($this->reflectionService);
                $controller->injectValidatorResolver($validatorResolver);
                $controller->injectReflectionService($this->reflectionService);
@@ -164,4 +177,4 @@ class Tx_Extbase_Dispatcher {
        }
 
 }
-?>
\ No newline at end of file
+?>
index 77dbcab..265181b 100644 (file)
@@ -55,9 +55,6 @@ abstract class Tx_Extbase_DomainObject_AbstractDomainObject implements Tx_Extbas
         * @internal
         */
        public function __wakeup() {
-               foreach ($GLOBALS['Extbase']['reconstituteObject']['properties'] as $propertyName => $propertyValue) {
-                       $this->_reconstituteProperty($propertyName, $propertyValue);
-               }
                $this->initializeObject();
        }
 
@@ -73,48 +70,57 @@ abstract class Tx_Extbase_DomainObject_AbstractDomainObject implements Tx_Extbas
        /**
         * Getter for uid
         *
-        * @return string
+        * @return int
         */
        final public function getUid() {
-               return $this->uid;
+               return (int)$this->uid;
+       }
+
+       /**
+        * Getter for the identifier
+        *
+        * @return int
+        */
+       final public function getIdentifier() {
+               return (int)$this->uid;
        }
 
        /**
-        * Reconstitutes a property. This method should only be called at reconstitution time by the framework!
+        * Reconstitutes a property. Only for internal use.
         *
         * @param string $propertyName
         * @param string $value
         * @return void
         * @internal
         */
-       public function _reconstituteProperty($propertyName, $value) {
+       public function _setProperty($propertyName, $propertyValue) {
                if (property_exists($this, $propertyName)) {
-                       $this->$propertyName = $value;
+                       $this->$propertyName = $propertyValue;
                        return TRUE;
                }
                return FALSE;
        }
 
        /**
-        * Returns a hash map of property names and property values. Only for internal use.
+        * Returns the property value of the given property name. Only for internal use.
         *
-        * @return array The properties
+        * @return mixed The propertyValue
         * @internal
         */
-       public function _getProperties() {
-               $properties = get_object_vars($this);
-               // unset($properties['_cleanProperties']); // TODO Check this again
-               return $properties;
+       public function _getProperty($propertyName) {
+               return $this->$propertyName;
        }
 
        /**
-        * Returns the property value of the given property name. Only for internal use.
+        * Returns a hash map of property names and property values. Only for internal use.
         *
-        * @return array The propertyName
+        * @return array The properties
         * @internal
         */
-       public function _getPropertyValue($propertyName) {
-               return $this->$propertyName;
+       public function _getProperties() {
+               $properties = get_object_vars($this);
+               unset($properties['_cleanProperties']);
+               return $properties;
        }
 
        /**
index e358191..4716772 100644 (file)
@@ -41,22 +41,46 @@ abstract class Tx_Extbase_DomainObject_AbstractEntity extends Tx_Extbase_DomainO
         * Register an object's clean state, e.g. after it has been reconstituted
         * from the database
         *
+        * @param string $propertyName The name of the property to be memorized. If omittet all persistable properties are memorized.
         * @return void
         * @internal
         */
-       public function _memorizeCleanState() {
+       public function _memorizeCleanState($propertyName = NULL) {
                // TODO Remove dependency to $dataMapper
-               $dataMapper = t3lib_div::makeInstance('Tx_Extbase_Persistence_Mapper_ObjectRelationalMapper'); // singleton
-               $this->_cleanProperties = array();
-               $properties = get_object_vars($this);
-               foreach ($properties as $propertyName => $propertyValue) {
-                       if ($dataMapper->isPersistableProperty(get_class($this), $propertyName)) {
-                               $this->_cleanProperties[$propertyName] = $this->$propertyName;
+               if ($propertyName !== NULL) {
+               } else {
+                       $dataMapper = t3lib_div::makeInstance('Tx_Extbase_Persistence_Mapper_DataMapper'); // singleton
+                       $this->_cleanProperties = array();
+                       $properties = get_object_vars($this);
+                       foreach ($properties as $propertyName => $propertyValue) {
+                               if ($dataMapper->isPersistableProperty(get_class($this), $propertyName)) {
+                                       $this->_memorizePropertyCleanState($propertyName);
+                               }
                        }
                }
        }
 
        /**
+        * Register an properties's clean state, e.g. after it has been reconstituted
+        * from the database
+        *
+        * @param string $propertyName The name of the property to be memorized. If omittet all persistable properties are memorized.
+        * @return void
+        * @internal
+        */
+       public function _memorizePropertyCleanState($propertyName) {
+               $propertyValue = $this->$propertyName;
+               if (!is_array($this->_cleanProperties)) {
+                       $this->_cleanProperties = array();
+               }
+               if (is_object($propertyValue)) {
+                       $this->_cleanProperties[$propertyName] = clone($propertyValue);
+               } else {
+                       $this->_cleanProperties[$propertyName] = $propertyValue;
+               }
+       }
+
+       /**
         * Returns a hash map of dirty properties and $values
         *
         * @return array
index 8ec07d7..fd624d7 100644 (file)
 interface Tx_Extbase_DomainObject_DomainObjectInterface {
 
        /**
-        * Reconstitutes a property. This method should only be called at reconstitution time!
+        * Register an object's clean state, e.g. after it has been reconstituted
+        * from the database
         *
-        * @param string $propertyName
-        * @param string $value
         * @return void
         * @internal
         */
-       public function _reconstituteProperty($propertyName, $value);
+       public function _memorizeCleanState();
 
        /**
-        * Register an object's clean state, e.g. after it has been reconstituted
-        * from the database
+        * Returns TRUE if the object is new (the uid was not set, yet). Only for internal use
         *
-        * @return void
+        * @return boolean
         * @internal
         */
-       public function _memorizeCleanState();
+       public function _isNew();
 
        /**
         * Returns TRUE if the properties were modified after reconstitution
@@ -57,6 +55,25 @@ interface Tx_Extbase_DomainObject_DomainObjectInterface {
         * @internal
         */
        public function _isDirty();
+
+       /**
+        * Reconstitutes a property. Only for internal use.
+        *
+        * @param string $propertyName
+        * @param string $value
+        * @return void
+        * @internal
+        */
+       public function _setProperty($propertyName, $value);
+
+       /**
+        * Returns the property value of the given property name. Only for internal use.
+        *
+        * @return mixed The propertyValue
+        * @internal
+        */
+       public function _getProperty($propertyName);
+
        /**
         * Returns a hash map of property names and property values
         *
@@ -64,6 +81,7 @@ interface Tx_Extbase_DomainObject_DomainObjectInterface {
         * @internal
         */
        public function _getProperties();
+
        /**
         * Returns a hash map of dirty properties and $values
         *
index 7143a48..88a6f3d 100755 (executable)
 abstract class Tx_Extbase_MVC_Controller_AbstractController implements Tx_Extbase_MVC_Controller_ControllerInterface {
 
        /**
+        * @var Tx_Extbase_Object_ManageInterface
+        */
+       protected $objectManager;
+
+       /**
         * @var Tx_Extbase_MVC_Web_Routing_URIBuilder
         */
        protected $URIBuilder;
@@ -88,13 +93,16 @@ abstract class Tx_Extbase_MVC_Controller_AbstractController implements Tx_Extbas
         * (additional) request types.
         * @var array
         */
-       protected $supportedRequestTypes = array('Tx_Extbase_MVC_Web_Request');
+       protected $supportedRequestTypes = array('Tx_Extbase_MVC_Request');
 
        /**
         * Constructs the controller.
         */
        public function __construct() {
+               $this->objectManager = t3lib_div::makeInstance('Tx_Extbase_Object_Manager');
                $this->arguments = t3lib_div::makeInstance('Tx_Extbase_MVC_Controller_Arguments');
+               $this->arguments->injectPersistenceManager(t3lib_div::makeInstance('Tx_Extbase_Persistence_Manager'));
+               $this->arguments->injectQueryFactory(t3lib_div::makeInstance('Tx_Extbase_Persistence_QueryFactory'));
                list(, $this->extensionName) = explode('_', get_class($this));
        }
 
@@ -314,4 +322,4 @@ abstract class Tx_Extbase_MVC_Controller_AbstractController implements Tx_Extbas
                $this->argumentsMappingResults = $this->propertyMapper->getMappingResults();
        }
 }
-?>
\ No newline at end of file
+?>
index b0bd193..6b2acc3 100644 (file)
  * @scope prototype
  */
 class Tx_Extbase_MVC_Controller_Argument {
-       
+
+       /**
+        * @var Tx_Extbase_Persistence_ManagerInterface
+        */
+       protected $persistenceManager;
+
        /**
         * @var Tx_Extbase_Persistence_QueryFactory
         */
@@ -101,7 +106,6 @@ class Tx_Extbase_MVC_Controller_Argument {
         * @throws InvalidArgumentException if $name is not a string or empty
         */
        public function __construct($name, $dataType = 'Text') {
-               // $this->queryFactory = t3lib_div::makeInstance('Tx_Extbase_Persistence_QueryFactory');
                $this->propertyMapper = t3lib_div::makeInstance('Tx_Extbase_Property_Mapper');
                if (!is_string($name) || strlen($name) < 1) throw new InvalidArgumentException('$name must be of type string, ' . gettype($name) . ' given.', 1187951688);
                $this->name = $name;
@@ -111,6 +115,28 @@ class Tx_Extbase_MVC_Controller_Argument {
                        $this->setDataType($dataType);
                }
        }
+
+       /**
+        * Injects the Persistence Manager
+        *
+        * @param Tx_Extbase_Persistence_ManagerInterface
+        * @return void
+        * @internal
+        */
+       public function injectPersistenceManager(Tx_Extbase_Persistence_ManagerInterface $persistenceManager) {
+               $this->persistenceManager = $persistenceManager;
+       }
+
+       /**
+        * Injects a QueryFactory instance
+        *
+        * @param Tx_Extbase_Persistence_QueryFactoryInterface $queryFactory
+        * @return void
+        * @internal
+        */
+       public function injectQueryFactory(Tx_Extbase_Persistence_QueryFactoryInterface $queryFactory) {
+               $this->queryFactory = $queryFactory;
+       }
        
        /**
         * Returns the name of this argument
@@ -219,9 +245,9 @@ class Tx_Extbase_MVC_Controller_Argument {
         * @param array Object names of the validators
         * @return Tx_Extbase_MVC_Controller_Argument Returns $this (used for fluent interface)
         */
-       public function setNewValidatorChain(array $objectNames) {
+       public function setNewValidatorConjunction(array $objectNames) {
                if ($this->validator === NULL) {
-                       $this->validator = t3lib_div::makeInstance('Tx_Extbase_Validation_Validator_ChainValidator');
+                       $this->validator = t3lib_div::makeInstance('Tx_Extbase_Validation_Validator_ConjunctionValidator');
                }
                foreach ($objectNames as $objectName) {
                        if (!class_exists($objectName)) $objectName = 'Tx_Extbase_Validation_Validator_' . $objectName;
@@ -235,7 +261,7 @@ class Tx_Extbase_MVC_Controller_Argument {
         * @return Tx_Extbase_Validation_Validator_ValidatorInterface The set validator, NULL if none was set
         */
        public function getValidator() {
-               return $this->validator;
+               return $this->validator;
        }
 
        /**
@@ -277,18 +303,15 @@ class Tx_Extbase_MVC_Controller_Argument {
         * @return mixed Either the object matching the uid or, if none or more than one object was found, FALSE
         */
        protected function findObjectByUid($uid) {
-               $repositoryClassName = $this->dataType . 'Repository';
-               if (class_exists($repositoryClassName)) {
-                       $repository = t3lib_div::makeInstance($this->dataType . 'Repository');
-                       $object = $repository->findOneByUid($uid);
-               }
-               return $object;
-               // TODO replace code as soon as the query object is available
-               // $query = $this->queryFactory->create($this->dataType);
-               // $query->matching('uid=' . intval($uid));
-               // $objects = $query->execute();
-               // if (count($objects) === 1 ) return current($objects);
-               // return FALSE;
+                $query = $this->queryFactory->create($this->dataType);
+                $object = current($query->matching($query->withUid($uid))->execute());
+                 // TODO Check if the object is an Aggregate Root (this can be quite difficult because we have no Repository registration 
+                if ($object !== NULL) {
+                       $this->persistenceManager->getSession()->registerReconstitutedObject($object);
+                       return $object;
+                } else {
+                       return FALSE;
+                }
        }
 
        /**
index 3f231d5..32233f5 100644 (file)
 class Tx_Extbase_MVC_Controller_Arguments extends ArrayObject {
 
        /**
+        * @var Tx_Extbase_Persistence_ManagerInterface
+        */
+       protected $persistenceManager;
+
+       /**
+        * @var Tx_Extbase_Persistence_QueryFactory
+        */
+       protected $queryFactory;
+       
+       /**
         * @var array Names of the arguments contained by this object
         */
        protected $argumentNames = array();
 
        /**
+        * Injects the persistence manager
+        *
+        * @param Tx_Extbase_Persistence_ManagerInterface $persistenceManager
+        * @return void
+        */
+       public function injectPersistenceManager(Tx_Extbase_Persistence_ManagerInterface $persistenceManager) {
+               $this->persistenceManager = $persistenceManager;
+       }
+
+       /**
+        * Injects a QueryFactory instance
+        *
+        * @param Tx_Extbase_Persistence_QueryFactoryInterface $queryFactory
+        * @return void
+        * @internal
+        */
+       public function injectQueryFactory(Tx_Extbase_Persistence_QueryFactoryInterface $queryFactory) {
+               $this->queryFactory = $queryFactory;
+       }
+       
+       /**
         * Adds or replaces the argument specified by $value. The argument's name is taken from the
         * argument object itself, therefore the $offset does not have any meaning in this context.
         *
@@ -122,9 +153,10 @@ class Tx_Extbase_MVC_Controller_Arguments extends ArrayObject {
         */
        public function addNewArgument($name, $dataType = 'Text', $isRequired = FALSE, $defaultValue = NULL) {
                $argument = new Tx_Extbase_MVC_Controller_Argument($name, $dataType);
+               $argument->injectPersistenceManager($this->persistenceManager);
+               $argument->injectQueryFactory($this->queryFactory);
                $argument->setRequired($isRequired);
                $argument->setDefaultValue($defaultValue);
-               
                $this->addArgument($argument);
                return $argument;
        }
@@ -229,5 +261,18 @@ class Tx_Extbase_MVC_Controller_Arguments extends ArrayObject {
                }
                return '';
        }
+
+       /**
+        * Remove all arguments and resets this object
+        *
+        * @return void
+        * @internal
+        */
+       public function removeAll() {
+               foreach ($this->argumentNames as $argumentName => $booleanValue) {
+                       parent::offsetUnset($argumentName);
+               }
+               $this->argumentNames = array();
+       }
 }
 ?>
\ No newline at end of file
index 881e023..cefe46b 100644 (file)
@@ -66,7 +66,6 @@ class Tx_Extbase_MVC_Controller_ControllerContext {
         *
         * @param Tx_Extbase_MVC_Request $request
         * @return void
-        * @author Christopher Hlubek <hlubek@networkteam.com>
         * @internal
         */
        public function setRequest(Tx_Extbase_MVC_Request $request) {
@@ -77,7 +76,6 @@ class Tx_Extbase_MVC_Controller_ControllerContext {
         * Get the request of the controller
         *
         * @return Tx_Extbase_MVC_Request
-        * @author Christopher Hlubek <hlubek@networkteam.com>
         */
        public function getRequest() {
                return $this->request;
@@ -88,7 +86,6 @@ class Tx_Extbase_MVC_Controller_ControllerContext {
         *
         * @param Tx_Extbase_MVC_Response $request
         * @return void
-        * @author Christopher Hlubek <hlubek@networkteam.com>
         * @internal
         */
        public function setResponse(Tx_Extbase_MVC_Response $response) {
@@ -99,7 +96,6 @@ class Tx_Extbase_MVC_Controller_ControllerContext {
         * Get the response of the controller
         *
         * @return Tx_Extbase_MVC_Request
-        * @author Christopher Hlubek <hlubek@networkteam.com>
         */
        public function getResponse() {
                return $this->response;
@@ -110,7 +106,6 @@ class Tx_Extbase_MVC_Controller_ControllerContext {
         *
         * @param Tx_Extbase_MVC_Controller_Arguments $arguments
         * @return void
-        * @author Christopher Hlubek <hlubek@networkteam.com>
         * @internal
         */
        public function setArguments(Tx_Extbase_MVC_Controller_Arguments $arguments) {
@@ -121,7 +116,6 @@ class Tx_Extbase_MVC_Controller_ControllerContext {
         * Get the arguments of the controller
         *
         * @return Tx_Extbase_MVC_Controller_Arguments
-        * @author Christopher Hlubek <hlubek@networkteam.com>
         */
        public function getArguments() {
                return $this->arguments;
@@ -132,7 +126,6 @@ class Tx_Extbase_MVC_Controller_ControllerContext {
         *
         * @param Tx_Extbase_Property_MappingResults $argumentsMappingResults
         * @return void
-        * @author Christopher Hlubek <hlubek@networkteam.com>
         * @internal
         */
        public function setArgumentsMappingResults(Tx_Extbase_Property_MappingResults $argumentsMappingResults) {
@@ -143,7 +136,6 @@ class Tx_Extbase_MVC_Controller_ControllerContext {
         * Get the arguments mapping results of the controller
         *
         * @return Tx_Extbase_Property_MappingResults
-        * @author Christopher Hlubek <hlubek@networkteam.com>
         */
        public function getArgumentsMappingResults() {
                return $this->argumentsMappingResults;
@@ -152,7 +144,6 @@ class Tx_Extbase_MVC_Controller_ControllerContext {
        /**
         * Tx_Extbase_MVC_Web_Routing_URIBuilder $URIBuilder
         * @return void
-        * @author Bastian Waidelich <bastian@typo3.org>
         * @internal
         */
        public function setURIBuilder(Tx_Extbase_MVC_Web_Routing_URIBuilder $URIBuilder) {
@@ -161,7 +152,6 @@ class Tx_Extbase_MVC_Controller_ControllerContext {
 
        /**
         * @return Tx_Extbase_MVC_Web_Routing_URIBuilder
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function getURIBuilder() {
                return $this->URIBuilder;
diff --git a/typo3/sysext/extbase/Classes/Object/Exception.php b/typo3/sysext/extbase/Classes/Object/Exception.php
new file mode 100644 (file)
index 0000000..df0f7d5
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3. 
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * A generic Object Exception
+ *
+ * @package Extbase
+ * @subpackage Object
+ * @version $Id: Exception.php 1811 2009-01-28 12:04:49Z robert $
+ */
+class Tx_Extbase_Object_Exception extends Tx_Extbase_Exception {
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Object/Exception/CannotBuildObject.php b/typo3/sysext/extbase/Classes/Object/Exception/CannotBuildObject.php
new file mode 100644 (file)
index 0000000..7312dcc
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3. 
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * "Cannot build object" Exception
+ *
+ * @package Extbase
+ * @subpackage Object
+ * @version $Id: CannotBuildObject.php 1811 2009-01-28 12:04:49Z robert $
+ */
+class Tx_Extbase_Object_CannotBuildObject extends Tx_Extbase_Object_Exception {
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Object/Exception/CannotReconstituteObject.php b/typo3/sysext/extbase/Classes/Object/Exception/CannotReconstituteObject.php
new file mode 100644 (file)
index 0000000..5d839f8
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3. 
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * "Cannot reconstitute object" Exception
+ *
+ * @package Extbase
+ * @subpackage Object
+ * @version $Id: CannotReconstituteObject.php 1811 2009-01-28 12:04:49Z robert $
+ */
+class Tx_Extbase_Object_Exception_CannotReconstituteObject extends Tx_Extbase_Object_Exception {
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Object/Exception/InvalidClass.php b/typo3/sysext/extbase/Classes/Object/Exception/InvalidClass.php
new file mode 100644 (file)
index 0000000..1c71b90
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3. 
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * "Invalid class" Exception
+ *
+ * @package Extbase
+ * @subpackage Object
+ * @version $Id: InvalidClass.php 1811 2009-01-28 12:04:49Z robert $
+ */
+class Tx_Extbase_Object_InvalidClass extends Tx_Extbase_Object_Exception {
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Object/Exception/InvalidObject.php b/typo3/sysext/extbase/Classes/Object/Exception/InvalidObject.php
new file mode 100644 (file)
index 0000000..e4fcf91
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3. 
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * "Invalid object" Exception
+ *
+ * @package Extbase
+ * @subpackage Object
+ * @version $Id: InvalidObject.php 1811 2009-01-28 12:04:49Z robert $
+ */
+class Tx_Extbase_Object_InvalidObject extends Tx_Extbase_Object_Exception {
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Object/Exception/InvalidObjectConfiguration.php b/typo3/sysext/extbase/Classes/Object/Exception/InvalidObjectConfiguration.php
new file mode 100644 (file)
index 0000000..c5be7d0
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3. 
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * "Invalid Object Configuration" Exception
+ *
+ * @package Extbase
+ * @subpackage Object
+ * @version $Id: InvalidObjectConfiguration.php 1811 2009-01-28 12:04:49Z robert $
+ */
+class Tx_Extbase_Object_InvalidObjectConfiguration extends Tx_Extbase_Object_Exception {
+
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Object/Exception/ObjectAlreadyRegistered.php b/typo3/sysext/extbase/Classes/Object/Exception/ObjectAlreadyRegistered.php
new file mode 100644 (file)
index 0000000..0efc372
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3. 
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * "Object already registered" Exception
+ *
+ * @package Extbase
+ * @subpackage Object
+ * @version $Id: ObjectAlreadyRegistered.php 1811 2009-01-28 12:04:49Z robert $
+ */
+class Tx_Extbase_Object_ObjectAlreadyRegistered extends Tx_Extbase_Object_Exception {
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Object/Exception/UnknownClass.php b/typo3/sysext/extbase/Classes/Object/Exception/UnknownClass.php
new file mode 100644 (file)
index 0000000..ad846d4
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3. 
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * "Unknown Class" Exception
+ *
+ * @package Extbase
+ * @subpackage Object
+ * @version $Id: UnknownClass.php 1811 2009-01-28 12:04:49Z robert $
+ */
+class Tx_Extbase_Object_UnknownClass extends Tx_Extbase_Object_Exception {
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Object/Exception/UnknownInterface.php b/typo3/sysext/extbase/Classes/Object/Exception/UnknownInterface.php
new file mode 100644 (file)
index 0000000..43f549c
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3. 
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * "Unknown Interface" Exception
+ *
+ * @package Extbase
+ * @subpackage Object
+ * @version $Id: UnknownInterface.php 1811 2009-01-28 12:04:49Z robert $
+ */
+class Tx_Extbase_Object_UnknownInterface extends Tx_Extbase_Object_Exception {
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Object/Exception/UnknownObject.php b/typo3/sysext/extbase/Classes/Object/Exception/UnknownObject.php
new file mode 100644 (file)
index 0000000..9402aad
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3. 
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * "Unknown Object" Exception
+ *
+ * @package Extbase
+ * @subpackage Object
+ * @version $Id: UnknownObject.php 1811 2009-01-28 12:04:49Z robert $
+ */
+class Tx_Extbase_Object_UnknownObject extends Tx_Extbase_Object_Exception {
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Object/Exception/UnresolvedDependencies.php b/typo3/sysext/extbase/Classes/Object/Exception/UnresolvedDependencies.php
new file mode 100644 (file)
index 0000000..c689339
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3. 
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * "Unresolved Dependencies" Exception
+ *
+ * @package Extbase
+ * @subpackage Object
+ * @version $Id: UnresolvedDependencies.php 1811 2009-01-28 12:04:49Z robert $
+ */
+class Tx_Extbase_Object_UnresolvedDependencies extends Tx_Extbase_Object_Exception {
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Object/Exception/WrongScope.php b/typo3/sysext/extbase/Classes/Object/Exception/WrongScope.php
new file mode 100644 (file)
index 0000000..0ad491a
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3. 
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * "Wrong Scope" Exception
+ *
+ * @package Extbase
+ * @subpackage Object
+ * @version $Id: WrongScope.php 1811 2009-01-28 12:04:49Z robert $
+ */
+class Tx_Extbase_Object_WrongScope extends Tx_Extbase_Object_Exception {
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Object/Manager.php b/typo3/sysext/extbase/Classes/Object/Manager.php
new file mode 100644 (file)
index 0000000..a036657
--- /dev/null
@@ -0,0 +1,105 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3. 
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Implementation of the default Extbase Object Manager
+ *
+ * @package Extbase
+ * @subpackage Object
+ * @version $Id: Manager.php 2123 2009-04-03 15:04:14Z robert $
+ */
+class Tx_Extbase_Object_Manager implements Tx_Extbase_Object_ManagerInterface, t3lib_Singleton {
+
+       /**
+        * @var Tx_Extbase_Object_RegistryInterface
+        */
+       protected $singletonObjectsRegistry;
+
+       /**
+        * Constructs a new Object Manager
+        */
+       public function __construct() {
+               $this->singletonObjectsRegistry = t3lib_div::makeInstance('Tx_Extbase_Object_TransientRegistry'); // singleton
+       }
+
+       /**
+        * Returns a fresh or existing instance of the object specified by $objectName.
+        *
+        * Important:
+        *
+        * If possible, instances of Prototype objects should always be created with the
+        * Object Factory's create() method and Singleton objects should rather be
+        * injected by some type of Dependency Injection.
+        *
+        * @param string $objectName The name of the object to return an instance of
+        * @return object The object instance
+        * @internal
+        */
+       public function getObject($objectName) {
+               if (in_array('t3lib_Singleton', class_implements($objectName))) {
+                       if ($this->singletonObjectsRegistry->objectExists($objectName)) {
+                               $object = $this->singletonObjectsRegistry->getObject($objectName);
+                       } else {
+                               $arguments = array_slice(func_get_args(), 1);
+                               $object = $this->makeInstance($objectName, $arguments);
+                               $this->singletonObjectsRegistry->putObject($objectName, $object);
+                       }
+               } else {
+                       $arguments = array_slice(func_get_args(), 1);
+                       $object = $this->makeInstance($objectName, $arguments);
+               }
+               return $object;
+       }
+       
+       /**
+        * Speed optimized alternative to ReflectionClass::newInstanceArgs().   
+        * Delegates the instanciation to the makeInstance method of t3lib_div.
+        *
+        * @param string $objectName Name of the object to instantiate
+        * @param array $arguments Arguments to pass to t3lib_div::makeInstance
+        * @return object The object
+        */
+       protected function makeInstance($objectName, array $arguments) {
+               switch (count($arguments)) {
+                       case 0: return t3lib_div::makeInstance($objectName);
+                       case 1: return t3lib_div::makeInstance($objectName, $arguments[0]);
+                       case 2: return t3lib_div::makeInstance($objectName, $arguments[0], $arguments[1]);
+                       case 3: return t3lib_div::makeInstance($objectName, $arguments[0], $arguments[1], $arguments[2]);
+                       case 4: return t3lib_div::makeInstance($objectName, $arguments[0], $arguments[1], $arguments[2], $arguments[3]);
+                       case 5: return t3lib_div::makeInstance($objectName, $arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4]);
+                       case 6: return t3lib_div::makeInstance($objectName, $arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5]);
+                       case 7: return t3lib_div::makeInstance($objectName, $arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5], $arguments[6]);
+                       case 8: return t3lib_div::makeInstance($objectName, $arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5], $arguments[6], $arguments[7]);
+                       case 9: return t3lib_div::makeInstance($objectName, $arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5], $arguments[6], $arguments[7], $arguments[8]);
+               }
+               throw new Tx_Extbase_Object_Exception_CannotBuildObject('Object "' . $objectName . '" has too many arguments.', 1166550023);
+       }
+       
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Object/ManagerInterface.php b/typo3/sysext/extbase/Classes/Object/ManagerInterface.php
new file mode 100644 (file)
index 0000000..4fac108
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3. 
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Interface for the TYPO3 Object Manager
+ *
+ * @package Extbase
+ * @subpackage Object
+ * @version $Id: ManagerInterface.php 1811 2009-01-28 12:04:49Z robert $
+ */
+interface Tx_Extbase_Object_ManagerInterface {
+
+       /**
+        * Returns a fresh or existing instance of the object specified by $objectName.
+        *
+        * Important:
+        *
+        * If possible, instances of Prototype objects should always be created with the
+        * Object Factory's create() method and Singleton objects should rather be
+        * injected by some type of Dependency Injection.
+        *
+        * @param string $objectName The name of the object to return an instance of
+        * @return object The object instance
+        */
+       public function getObject($objectName);
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Object/RegistryInterface.php b/typo3/sysext/extbase/Classes/Object/RegistryInterface.php
new file mode 100644 (file)
index 0000000..810b445
--- /dev/null
@@ -0,0 +1,77 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Object Object Cache Interface
+ *
+ * @package Extbase
+ * @subpackage Object
+ * @version $Id: RegistryInterface.php 2293 2009-05-20 18:14:45Z robert $
+ * @internal
+ */
+interface Tx_Extbase_Object_RegistryInterface {
+
+       /**
+        * Returns an object from the registry. If an instance of the required
+        * object does not exist yet, an exception is thrown.
+        *
+        * @param string $objectName Name of the object to return an object of
+        * @return object The object
+        * @internal
+        */
+       public function getObject($objectName);
+
+       /**
+        * Put an object into the registry.
+        *
+        * @param string $objectName Name of the object the object is made for
+        * @param object $object The object to store in the registry
+        * @return void
+        * @internal
+        */
+       public function putObject($objectName, $object);
+
+       /**
+        * Remove an object from the registry.
+        *
+        * @param string $objectName Name of the object to remove the object for
+        * @return void
+        * @internal
+        */
+       public function removeObject($objectName);
+
+       /**
+        * Checks if an object of the given object already exists in the object registry.
+        *
+        * @param string $objectName Name of the object to check for an object
+        * @return boolean TRUE if an object exists, otherwise FALSE
+        * @internal
+        */
+       public function objectExists($objectName);
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Object/TransientRegistry.php b/typo3/sysext/extbase/Classes/Object/TransientRegistry.php
new file mode 100644 (file)
index 0000000..03aa118
--- /dev/null
@@ -0,0 +1,95 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * A transient Object Object Cache which provides a transient memory-based
+ * registry of objects.
+ *
+ * @package Extbase
+ * @subpackage Object
+ * @version $Id: TransientRegistry.php 2293 2009-05-20 18:14:45Z robert $
+ */
+class Tx_Extbase_Object_TransientRegistry implements Tx_Extbase_Object_RegistryInterface {
+
+       /**
+        * @var array Location where objects are stored
+        */
+       protected $objects = array();
+
+       /**
+        * Returns an object from the registry. If an instance of the required
+        * object does not exist yet, an exception is thrown.
+        *
+        * @param string $objectName Name of the object to return an object of
+        * @return object The object
+        * @internal
+        */
+       public function getObject($objectName) {
+               if (!$this->objectExists($objectName)) throw new RuntimeException('Object "' . $objectName . '" does not exist in the object registry.', 1167917198);
+               return $this->objects[$objectName];
+       }
+
+       /**
+        * Put an object into the registry.
+        *
+        * @param string $objectName Name of the object the object is made for
+        * @param object $object The object to store in the registry
+        * @return void
+        * @internal
+        */
+       public function putObject($objectName, $object) {
+               if (!is_string($objectName) || strlen($objectName) === 0) throw new RuntimeException('No valid object name specified.', 1167919564);
+               if (!is_object($object)) throw new RuntimeException('$object must be of type Object', 1167917199);
+               $this->objects[$objectName] = $object;
+       }
+
+       /**
+        * Remove an object from the registry.
+        *
+        * @param string objectName Name of the object to remove the object for
+        * @return void
+        * @internal
+        */
+       public function removeObject($objectName) {
+               if (!$this->objectExists($objectName)) throw new RuntimeException('Object "' . $objectName . '" does not exist in the object registry.', 1167917200);
+               unset ($this->objects[$objectName]);
+       }
+
+       /**
+        * Checks if an object of the given object already exists in the object registry.
+        *
+        * @param string $objectName Name of the object to check for an object
+        * @return boolean TRUE if an object exists, otherwise FALSE
+        * @internal
+        */
+       public function objectExists($objectName) {
+               return isset($this->objects[$objectName]);
+       }
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/Backend.php b/typo3/sysext/extbase/Classes/Persistence/Backend.php
new file mode 100644 (file)
index 0000000..2acb411
--- /dev/null
@@ -0,0 +1,607 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3. 
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * A persistence backend. This backend maps objects to the relational model of the storage backend.
+ * It persists all added, removed and changed objects.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: Backend.php 2183 2009-04-24 14:28:37Z k-fish $
+ */
+class Tx_Extbase_Persistence_Backend implements Tx_Extbase_Persistence_BackendInterface, t3lib_Singleton {
+
+       /**
+        * @var Tx_Extbase_Persistence_Session
+        */
+       protected $session;
+
+       /**
+        * @var Tx_Extbase_Persistence_ObjectStorage
+        */
+       protected $aggregateRootObjects;
+
+       /**
+        * @var Tx_Extbase_Persistence_IdentityMap
+        **/
+       protected $identityMap;
+
+       /**
+        * @var Tx_Extbase_Persistence_QOM_QueryObjectModelFactoryInterface
+        */
+       protected $QOMFactory;
+
+       /**
+        * @var Tx_Extbase_Persistence_ValueFactoryInterface
+        */
+       protected $valueFactory;
+
+       /**
+        * @var Tx_Extbase_Persistence_Storage_BackendInterface
+        */
+       protected $storageBackend;
+
+       /**
+        * @var Tx_Extbase_Persistence_DataMapper
+        */
+       protected $dataMapper;
+
+       /**
+        * The TYPO3 reference index object
+        *
+        * @var t3lib_refindex
+        **/
+       protected $referenceIndex;
+
+       /**
+        * Constructs the backend
+        *
+        * @param Tx_Extbase_Persistence_Session $session The persistence session used to persist data
+        */
+       public function __construct(Tx_Extbase_Persistence_Session $session, Tx_Extbase_Persistence_Storage_BackendInterface $storageBackend) {
+               $this->session = $session;
+               $this->storageBackend = $storageBackend;
+               $this->referenceIndex = t3lib_div::makeInstance('t3lib_refindex');
+               $this->aggregateRootObjects = new Tx_Extbase_Persistence_ObjectStorage();
+               $this->persistenceBackend = $GLOBALS['TYPO3_DB']; // FIXME This is just an intermediate solution
+       }
+
+       /**
+        * Injects the DataMapper to map nodes to objects
+        *
+        * @param Tx_Extbase_Persistence_Mapper_DataMapper $dataMapper
+        * @return void
+        */
+       public function injectDataMapper(Tx_Extbase_Persistence_Mapper_DataMapper $dataMapper) {
+               $this->dataMapper = $dataMapper;
+       }
+
+       /**
+        * Injects the identity map
+        *
+        * @param Tx_Extbase_Persistence_IdentityMap $identityMap
+        * @return void
+        * @internal
+        */
+       public function injectIdentityMap(Tx_Extbase_Persistence_IdentityMap $identityMap) {
+               $this->identityMap = $identityMap;
+       }
+
+       /**
+        * Injects the QueryObjectModelFactory
+        *
+        * @param Tx_Extbase_Persistence_QOM_QueryObjectModelFactoryInterface $dataMapper
+        * @return void
+        */
+       public function injectQOMFactory(Tx_Extbase_Persistence_QOM_QueryObjectModelFactoryInterface $QOMFactory) {
+               $this->QOMFactory = $QOMFactory;
+       }
+
+       /**
+        * Injects the ValueFactory
+        *
+        * @param Tx_Extbase_Persistence_ValueFactoryInterface $valueFactory
+        * @return void
+        */
+       public function injectValueFactory(Tx_Extbase_Persistence_ValueFactoryInterface $valueFactory) {
+               $this->valueFactory = $valueFactory;
+       }
+
+       /**
+        * Returns the repository session
+        *
+        * @return Tx_Extbase_Persistence_Session
+        */
+       public function getSession() {
+               return $this->session;
+       }
+
+       /**
+        * Returns the current QOM factory
+        *
+        * @return Tx_Extbase_Persistence_QOM_QueryObjectModelFactoryInterface
+        * @internal
+        */
+       public function getQOMFactory() {
+               return $this->QOMFactory;
+       }
+
+       /**
+        * Returns the current value factory
+        *
+        * @return Tx_Extbase_Persistence_ValueFactoryInterface
+        * @internal
+        */
+       public function getValueFactory() {
+               return $this->valueFactory;
+       }
+
+       /**
+        * Returns the current identityMap
+        *
+        * @return Tx_Extbase_Persistence_IdentityMap
+        * @internal
+        */
+       public function getIdentityMap() {
+               return $this->identityMap;
+       }
+
+       /**
+        * Returns the (internal) identifier for the object, if it is known to the
+        * backend. Otherwise NULL is returned.
+        *
+        * @param object $object
+        * @return string The identifier for the object if it is known, or NULL
+        */
+       public function getUidByObject($object) {
+               if ($this->identityMap->hasObject($object)) {
+                       return $this->identityMap->getUidByObject($object);
+               } else {
+                       return NULL;
+               }
+       }
+
+       /**
+        * Checks if the given object has ever been persisted.
+        *
+        * @param object $object The object to check
+        * @return boolean TRUE if the object is new, FALSE if the object exists in the repository
+        */
+       public function isNewObject($object) {
+               return ($this->getUidByObject($object) === NULL);
+       }
+
+       /**
+        * Replaces the given object by the second object.
+        *
+        * This method will unregister the existing object at the identity map and
+        * register the new object instead. The existing object must therefore
+        * already be registered at the identity map which is the case for all
+        * reconstituted objects.
+        *
+        * The new object will be identified by the uid which formerly belonged
+        * to the existing object. The existing object looses its uid.
+        *
+        * @param object $existingObject The existing object
+        * @param object $newObject The new object
+        * @return void
+        */
+       public function replaceObject($existingObject, $newObject) {
+               $existingUid = $this->getUidByObject($existingObject);
+               if ($existingUid === NULL) throw new Tx_Extbase_Persistence_Exception_UnknownObject('The given object is unknown to this persistence backend.', 1238070163);
+
+               $this->identityMap->unregisterObject($existingObject);
+               $this->identityMap->registerObject($newObject, $existingUid);
+       }
+
+       /**
+        * Sets the aggregate root objects
+        *
+        * @param Tx_Extbase_Persistence_ObjectStorage $objects
+        * @return void
+        */
+       public function setAggregateRootObjects(Tx_Extbase_Persistence_ObjectStorage $objects) {
+               $this->aggregateRootObjects = $objects;
+       }
+
+       /**
+        * Sets the deleted objects
+        *
+        * @param Tx_Extbase_Persistence_ObjectStorage $objects
+        * @return void
+        */
+       public function setDeletedObjects(Tx_Extbase_Persistence_ObjectStorage $objects) {
+               $this->deletedObjects = $objects;
+       }
+
+       /**
+        * Commits the current persistence session.
+        *
+        * @return void
+        */
+       public function commit() {
+               $this->persistObjects();
+               $this->processDeletedObjects();
+       }
+
+       /**
+        * Traverse and persist all aggregate roots and their object graph.
+        *
+        * @return void
+        */
+       protected function persistObjects() {
+               foreach ($this->aggregateRootObjects as $object) {
+                       $this->persistObject($object);
+               }
+       }
+
+       /**
+        * Inserts an objects corresponding row into the database. If the object is a value object an
+        * existing instance will be looked up.
+        *
+        * @param Tx_Extbase_DomainObject_DomainObjectInterface $object The object to be inserted
+        * @param Tx_Extbase_DomainObject_DomainObjectInterface $parentObject The parent object
+        * @param string $parentPropertyName The name of the property the object is stored in
+        * @return void
+        */
+       protected function persistObject($object, $parentObject = NULL, $parentPropertyName = NULL, $processQueue = TRUE) {
+               $row = array();
+               $queue = array();
+               $className = get_class($object);
+               $dataMap = $this->dataMapper->getDataMap($className);
+               $properties = $object->_getProperties();
+
+               if ($object instanceof Tx_Extbase_DomainObject_AbstractValueObject) {
+                       $this->checkForAlreadyPersistedValueObject($object);
+               }
+
+
+               foreach ($properties as $propertyName => $propertyValue) {
+                       if ($dataMap->isPersistableProperty($propertyName) && ($propertyValue instanceof Tx_Extbase_Persistence_LazyLoadingProxy)) {
+                               continue;
+                       }
+
+                       $columnMap = $dataMap->getColumnMap($propertyName);
+                       $columnName = $columnMap->getColumnName();
+                       if ($object->_isNew() || $object->_isDirty($propertyName)) {
+                               if ($columnMap->isRelation()) {
+                                       if (($columnMap->getTypeOfRelation() === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_MANY) || ($columnMap->getTypeOfRelation() === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY)) {
+                                               $row[$columnName] = count($properties[$propertyName]);
+                                               foreach ($propertyValue as $containedObject) {
+                                                       $queue[] = array($propertyName => $containedObject);
+                                               }
+                                       } elseif ($propertyValue instanceof Tx_Extbase_DomainObject_DomainObjectInterface) {
+                                               // TODO Handle Value Objects different
+                                               if ($propertyValue->_isNew()) {
+                                                       $this->persistObject($propertyValue);
+                                               }
+                                               $row[$columnName] = $propertyValue->getUid();
+                                       }
+                               } else {
+                                       $row[$columnName] = $dataMap->convertPropertyValueToFieldValue($properties[$propertyName], FALSE);
+                               }
+                       }
+               }
+
+               if ($object->_isNew()) {
+                       $this->insertObject($object, $parentObject, $parentPropertyName, $row);
+               } elseif ($object->_isDirty()) {
+                       $this->updateObject($object, $parentObject, $parentPropertyName, $row);
+               }
+
+               if ($parentObject instanceof Tx_Extbase_DomainObject_DomainObjectInterface && !empty($parentPropertyName)) {
+                       $parentClassName = get_class($parentObject);
+                       $parentDataMap = $this->dataMapper->getDataMap($parentClassName);
+                       $parentColumnMap = $parentDataMap->getColumnMap($parentPropertyName);
+
+                       if (($parentColumnMap->getTypeOfRelation()  === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY)) {
+                               $this->insertRelation($object, $parentObject, $parentPropertyName);
+                       }
+               }
+
+               if ($object instanceof Tx_Extbase_DomainObject_AbstractEntity) {
+                       $object->_memorizeCleanState();
+               }
+
+               if ($processQueue === TRUE) {
+                       foreach ($queue as $queuedObjects) {
+                               foreach($queuedObjects as $propertyName => $queuedObject) {
+                                       $this->persistObject($queuedObject, $object, $propertyName);
+                               }
+                       }
+               }
+
+       }
+
+       /*
+        * Tests, if the given Domain Object already exists in the storage backend
+        *
+        * @param Tx_Extbase_DomainObject_AbstractValueObject $object The object to be tested
+        */
+       protected function checkForAlreadyPersistedValueObject(Tx_Extbase_DomainObject_AbstractValueObject $object) {
+               $dataMap = $this->dataMapper->getDataMap(get_class($object));
+               $properties = $object->_getProperties();
+               $result = $this->storageBackend->hasValueObject($properties, $dataMap);
+               if ($result !== FALSE) {
+                       $object->_setProperty('uid', $result);
+               }
+       }
+
+       /**
+        * Inserts an object in the storage
+        * 
+        * @param Tx_Extbase_DomainObject_DomainObjectInterface $object The object to be insterted in the storage
+        * @param Tx_Extbase_DomainObject_AbstractEntity|NULL $parentObject The parent object (if any)
+        * @param string|NULL $parentPropertyName The name of the property
+        * @param array $row The $row
+        */
+       protected function insertObject(Tx_Extbase_DomainObject_DomainObjectInterface $object, Tx_Extbase_DomainObject_AbstractEntity $parentObject = NULL, $parentPropertyName = NULL, array &$row) {
+               $className = get_class($object);
+               $dataMap = $this->dataMapper->getDataMap($className);
+               $tableName = $dataMap->getTableName();
+               $this->addCommonFieldsToRow($object, $parentObject, $parentPropertyName, $row);
+               $uid = $this->storageBackend->addRow(
+                       $tableName,
+                       $row
+                       );
+               $object->_setProperty('uid', $uid);
+               $this->referenceIndex->updateRefIndexTable($tableName, $uid);
+       }
+
+       /**
+        * Inserts mm-relation into a relation table
+        *
+        * @param Tx_Extbase_DomainObject_DomainObjectInterface $relatedObject The related object
+        * @param Tx_Extbase_DomainObject_DomainObjectInterface $parentObject The parent object
+        * @param string $parentPropertyName The name of the parent object's property where the related objects are stored in
+        * @return void
+        */
+       protected function insertRelation(Tx_Extbase_DomainObject_DomainObjectInterface $relatedObject, Tx_Extbase_DomainObject_DomainObjectInterface $parentObject, $parentPropertyName) {
+               $dataMap = $this->dataMapper->getDataMap(get_class($parentObject));
+               $row = array(
+                       'uid_local' => (int)$parentObject->getUid(), // TODO Aliases for relation field names
+                       'uid_foreign' => (int)$relatedObject->getUid(),
+                       'tablenames' => $dataMap->getTableName(),
+                       'sorting' => 9999 // TODO sorting of mm table items
+                       );
+               $tableName = $dataMap->getColumnMap($parentPropertyName)->getRelationTableName();
+               $res = $this->storageBackend->addRow(
+                       $tableName,
+                       $row
+                       );
+               return $res;
+       }
+
+       /**
+        * Updates a given object in the storage
+        * 
+        * @param Tx_Extbase_DomainObject_DomainObjectInterface $object The object to be insterted in the storage
+        * @param Tx_Extbase_DomainObject_AbstractEntity|NULL $parentObject The parent object (if any)
+        * @param string|NULL $parentPropertyName The name of the property
+        * @param array $row The $row
+        */
+       protected function updateObject(Tx_Extbase_DomainObject_DomainObjectInterface $object, $parentObject = NULL, $parentPropertyName = NULL, array &$row) {
+               $className = get_class($object);
+               $dataMap = $this->dataMapper->getDataMap($className);
+               $tableName = $dataMap->getTableName();
+               $this->addCommonFieldsToRow($object, $parentObject, $parentPropertyName, $row);
+               $uid = $object->getUid();
+               $row['uid'] = $uid;
+               $res = $this->storageBackend->updateRow(
+                       $tableName,
+                       $row
+                       );
+               $this->referenceIndex->updateRefIndexTable($tableName, $uid);
+               return $res;
+       }
+
+       /**
+        * Returns a table row to be inserted or updated in the database
+        *
+        * @param Tx_Extbase_Persistence_Mapper_DataMap $dataMap The appropriate data map representing a database table
+        * @param array $properties The properties of the object
+        * @return array A single row to be inserted in the database
+        */
+       protected function addCommonFieldsToRow(Tx_Extbase_DomainObject_DomainObjectInterface $object, $parentObject = NULL, $parentPropertyName = NULL, array &$row) {
+               $className = get_class($object);
+               $dataMap = $this->dataMapper->getDataMap($className);
+               if ($dataMap->hasCreationDateColumn() && $object->_isNew()) {
+                       $row[$dataMap->getCreationDateColumnName()] = time();
+               }
+               if ($dataMap->hasTimestampColumn()) {
+                       $row[$dataMap->getTimestampColumnName()] = time();
+               }
+               if ($dataMap->hasPidColumn()) {
+                       // FIXME Make the settings from $this->cObj available
+                       $row['pid'] = !empty($this->cObj->data['pages']) ? $this->cObj->data['pages'] : $GLOBALS['TSFE']->id;
+               }
+               if ($parentObject instanceof Tx_Extbase_DomainObject_DomainObjectInterface && !empty($parentPropertyName)) {
+                       $parentDataMap = $this->dataMapper->getDataMap(get_class($parentObject));
+                       $parentColumnMap = $parentDataMap->getColumnMap($parentPropertyName);
+                       $parentKeyFieldName = $parentColumnMap->getParentKeyFieldName();
+                       if ($parentKeyFieldName !== NULL) {
+                               $row[$parentKeyFieldName] = $parentObject->getUid();
+                       }
+                       $parentTableFieldName = $parentColumnMap->getParentTableFieldName();
+                       if ($parentTableFieldName !== NULL) {
+                               $row[$parentTableFieldName] = $parentDataMap->getTableName();
+                       }
+               }
+       }
+
+       /**
+        * Inserts and updates all relations of an object. It also inserts and updates data in relation tables.
+        *
+        * @param Tx_Extbase_DomainObject_DomainObjectInterface $object The object for which the relations should be updated
+        * @param string $propertyName The name of the property holding the related child objects
+        * @param array $relations The queued relations
+        * @return void
+        */
+       protected function persistRelations(Tx_Extbase_DomainObject_DomainObjectInterface $object, $propertyName, array $relations) {
+               $dataMap = $this->dataMapper->getDataMap(get_class($object));
+               foreach ($relations as $propertyName => $relatedObjects) {
+                       if (!empty($relatedObjects)) {
+                               $typeOfRelation = $dataMap->getColumnMap($propertyName)->getTypeOfRelation();
+                               foreach ($relatedObjects as $relatedObject) {
+                                       if ($relatedObject->_isNew()) {
+                                               $this->persistObject($relatedObject, $object, $propertyName);
+                                               if ($typeOfRelation === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY) {
+                                                       $this->insertRelationInRelationTable($relatedObject, $object, $propertyName);
+                                               }
+                                       } elseif ($relatedObject->_isDirty()) {
+                                               $this->persistObject($relatedObject, $object, $propertyName);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Iterate over deleted objects and process them
+        *
+        * @return void
+        */
+       protected function processDeletedObjects() {
+               foreach ($this->deletedObjects as $object) {
+                       $this->deleteObject($object);
+                       if ($this->identityMap->hasObject($object)) {
+                               $this->session->registerRemovedObject($object);
+                               $this->identityMap->unregisterObject($object);
+                       }
+               }
+               $this->deletedObjects = new Tx_Extbase_Persistence_ObjectStorage();
+       }
+
+       /**
+        * Deletes an object, it's 1:n related objects, and the m:n relations in relation tables (but not the m:n related objects!)
+        *
+        * @param Tx_Extbase_DomainObject_DomainObjectInterface $object The object to be insterted in the storage
+        * @param Tx_Extbase_DomainObject_AbstractEntity|NULL $parentObject The parent object (if any)
+        * @param string|NULL $parentPropertyName The name of the property
+        * @param bool $markAsDeleted Shold we only mark the row as deleted instead of deleting (TRUE by default)?
+        * @param bool $recurseIntoRelations Shold we delete also dependant aggregates (FALSE by default)?
+        * @return void
+        */
+       protected function deleteObject(Tx_Extbase_DomainObject_DomainObjectInterface $object, $parentObject = NULL, $parentPropertyName = NULL, $markAsDeleted = TRUE, $recurseIntoRelations = FALSE) {
+               // TODO Implement recursive deletions
+               $dataMap = $this->dataMapper->getDataMap(get_class($object));
+               $tableName = $dataMap->getTableName();
+               if ($markAsDeleted === TRUE && $dataMap->hasDeletedColumn()) {
+                       $deletedColumnName = $dataMap->getDeletedColumnName();
+                       $res = $this->storageBackend->updateRow(
+                               $tableName,
+                               array(
+                                       'uid' => $object->getUid(),
+                                       $deletedColumnName => 1
+                                       )
+                               );
+               } else {
+                       $res = $this->storageBackend->removeRow(
+                               $tableName,
+                               $object->getUid()
+                               );
+               }
+               $this->referenceIndex->updateRefIndexTable($tableName, $uid);
+       }
+
+       /**
+        * Deletes all relations of an object.
+        *
+        * @param Tx_Extbase_DomainObject_DomainObjectInterface $object The object for which the relations should be updated
+        * @param string $propertyName The name of the property holding the related child objects
+        * @param array $relations The queued relations
+        * @return void
+        */
+       protected function deleteRelatedObjects(Tx_Extbase_DomainObject_DomainObjectInterface $object, array $relations) {
+               $dataMap = $this->dataMapper->getDataMap(get_class($object));
+               foreach ($relations as $propertyName => $relatedObjects) {
+                       if (is_array($relatedObjects)) {
+                               foreach ($relatedObjects as $relatedObject) {
+                                       $this->deleteObject($relatedObject, $object, $propertyName);
+                                       if ($dataMap->getColumnMap($propertyName)->getTypeOfRelation() === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY) {
+                                               $this->deleteRelationInRelationTable($relatedObject, $object, $propertyName);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Update relations in a relation table
+        *
+        * @param array $relatedObjects An array of related objects
+        * @param Tx_Extbase_DomainObject_DomainObjectInterface $parentObject The parent object
+        * @param string $parentPropertyName The name of the parent object's property where the related objects are stored in
+        * @return void
+        */
+       protected function deleteRelationInRelationTable($relatedObject, Tx_Extbase_DomainObject_DomainObjectInterface $parentObject, $parentPropertyName) {
+               $dataMap = $this->dataMapper->getDataMap(get_class($parentObject));
+               $tableName = $dataMap->getColumnMap($parentPropertyName)->getRelationTableName();
+               // TODO Remove dependency to the t3lib_db instance
+               $res = $this->persistenceBackend->exec_SELECTquery(
+                       'uid_foreign',
+                       $tableName,
+                       'uid_local=' . $parentObject->getUid()
+                       );
+               $existingRelations = array();
+               while($row = $this->persistenceBackend->sql_fetch_assoc($res)) {
+                       $existingRelations[current($row)] = current($row);
+               }
+               $relationsToDelete = $existingRelations;
+               if (is_array($relatedObject)) {
+                       foreach ($relatedObject as $relatedObject) {
+                               $relatedObjectUid = $relatedObject->getUid();
+                               if (array_key_exists($relatedObjectUid, $relationsToDelete)) {
+                                       unset($relationsToDelete[$relatedObjectUid]);
+                               }
+                       }
+               }
+               if (count($relationsToDelete) > 0) {
+                       $relationsToDeleteList = implode(',', $relationsToDelete);
+                       $res = $this->persistenceBackend->exec_DELETEquery(
+                               $tableName,
+                               'uid_local=' . $parentObject->getUid() . ' AND uid_foreign IN (' . $relationsToDeleteList . ')'
+                               );
+               }
+       }
+
+       /**
+        * Delegates the call to the Data Map.
+        * Returns TRUE if the property is persistable (configured in $TCA)
+        *
+        * @param string $className The property name
+        * @param string $propertyName The property name
+        * @return boolean TRUE if the property is persistable (configured in $TCA)
+        */
+       public function isPersistableProperty($className, $propertyName) {
+               $dataMap = $this->dataMapper->getDataMap($className);
+               return $dataMap->isPersistableProperty($propertyName);
+       }
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/BackendInterface.php b/typo3/sysext/extbase/Classes/Persistence/BackendInterface.php
new file mode 100644 (file)
index 0000000..77d5adb
--- /dev/null
@@ -0,0 +1,94 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3. 
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * A persistence backend interface
+ *
+ * @package Extbase
+ * @subpackage extbase
+ * @version $Id: BackendInterface.php 2087 2009-03-26 16:46:14Z sebastian $
+ */
+interface Tx_Extbase_Persistence_BackendInterface {
+
+       /**
+        * Sets the aggregate root objects
+        *
+        * @param Tx_Extbase_Persistence_ObjectStorage $objects
+        * @return void
+        */
+       public function setAggregateRootObjects(Tx_Extbase_Persistence_ObjectStorage $objects);
+
+       /**
+        * Sets the deleted objects
+        *
+        * @param Tx_Extbase_Persistence_ObjectStorage $objects
+        * @return void
+        */
+       public function setDeletedObjects(Tx_Extbase_Persistence_ObjectStorage $objects);
+
+       /**
+        * Commits the current persistence session
+        *
+        * @return void
+        */
+       public function commit();
+
+       /**
+        * Returns the (internal) identifier for the object, if it is known to the
+        * backend. Otherwise NULL is returned.
+        *
+        * @param object $object
+        * @return string The identifier for the object if it is known, or NULL
+        */
+       public function getUidByObject($object);
+
+       /**
+        * Checks if the given object has ever been persisted.
+        *
+        * @param object $object The object to check
+        * @return boolean TRUE if the object is new, FALSE if the object exists in the repository
+        */
+       public function isNewObject($object);
+
+       /**
+        * Replaces the given object by the second object.
+        *
+        * This method will unregister the existing object at the identity map and
+        * register the new object instead. The existing object must therefore
+        * already be registered at the identity map which is the case for all
+        * reconstituted objects.
+        *
+        * The new object will be identified by the uuid which formerly belonged
+        * to the existing object. The existing object looses its uuid.
+        *
+        * @param object $existingObject The existing object
+        * @param object $newObject The new object
+        * @return void
+        */
+       public function replaceObject($existingObject, $newObject);
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/Exception/RepositoryException.php b/typo3/sysext/extbase/Classes/Persistence/Exception/RepositoryException.php
new file mode 100644 (file)
index 0000000..31a7e84
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Main exception thrown by classes in this package. May contain an error
+ * message and/or another nested exception.
+ *
+ * @package PHPCR
+ * @version $Id: RepositoryException.php 1811 2009-01-28 12:04:49Z robert $
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ */
+class Tx_Extbase_Persistence_Extbase_RepositoryException extends RuntimeException {
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/Exception/UnknownObject.php b/typo3/sysext/extbase/Classes/Persistence/Exception/UnknownObject.php
new file mode 100644 (file)
index 0000000..ff2fa70
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3. 
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * An "Unknown Object" exception
+ *
+ * @package Extbase
+ * @subpackage extbase
+ * @version $ID:$
+ */
+class Tx_Extbase_Persistence_Exception_UnknownObject extends Tx_Extbase_Persistence_Exception {
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/Exception/ValueFormatException.php b/typo3/sysext/extbase/Classes/Persistence/Exception/ValueFormatException.php
new file mode 100644 (file)
index 0000000..0b72b63
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Exception thrown when an attempt is made to assign a value to a property
+ * that has an invalid format, given the type of the property. Also thrown
+ * if an attempt is made to read the value of a property using a type-specific
+ * read method of a type into which it is not convertible.
+ *
+ * @package PHPCR
+ * @version $Id: ValueFormatException.php 1811 2009-01-28 12:04:49Z robert $
+ */
+class Tx_Extbase_Persistence_Exception_ValueFormatException extends Tx_Extbase_Persistence_Exception {
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/IteratorInterface.php b/typo3/sysext/extbase/Classes/Persistence/IteratorInterface.php
new file mode 100644 (file)
index 0000000..717ae4d
--- /dev/null
@@ -0,0 +1,75 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * An Iterator interface
+ *
+ * The methods next(), hasNext() and remove() as in java.util.Iterator
+ * append() is something we thought would be nice...
+ *
+ * @package Extbase
+ * @version $Id: IteratorInterface.php 1811 2009-01-28 12:04:49Z robert $
+ */
+interface Tx_Extbase_Persistence_IteratorInterface extends Iterator {
+
+       /**
+        * Returns the next element. Commented as PHP dows not allow overriding methods from extended interfaces...
+        *
+        * @return mixed
+        * @throws OutOfBoundsException if no next element exists
+        */
+       //public function next();
+
+       /**
+        * Returns true if the iteration has more elements.
+        *
+        * This is an alias of valid().
+        *
+        * @return boolean
+        */
+       public function hasNext();
+
+       /**
+        * Removes from the underlying collection the last element returned by the iterator.
+        * This method can be called only once per call to next. The behavior of an iterator
+        * is unspecified if the underlying collection is modified while the iteration is in
+        * progress in any way other than by calling this method.
+        *
+        * @return void
+        * @throws IllegalStateException if the next method has not yet been called, or the remove method has already been called after the last call to the next method.
+        */
+       public function remove();
+
+       /**
+        * Append a new element to the iteration
+        *
+        * @param mixed $element
+        * @return void
+        */
+       public function append($element);
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/LazyLoadingProxy.php b/typo3/sysext/extbase/Classes/Persistence/LazyLoadingProxy.php
new file mode 100644 (file)
index 0000000..3fcc055
--- /dev/null
@@ -0,0 +1,189 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * A proxy that can replace any object and replaces itself in it's parent on
+ * first access (call, get, set, isset, unset).
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: LazyLoadingProxy.php 2591 2009-06-09 19:23:47Z k-fish $
+ */
+ // TODO Implement support for CountableInterface
+class Tx_Extbase_Persistence_LazyLoadingProxy {
+
+       /**
+        * @var Tx_Extbase_Persistence_QueryFactoryInterface
+        */
+       protected $queryFactory;
+
+       /**
+        * The object this property is contained in.
+        *
+        * @var object
+        */
+       private $parentObject;
+
+       /**
+        * The name of the property represented by this proxy.
+        *
+        * @var string
+        */
+       private $propertyName;
+
+       /**
+        *
+        * @var Tx_Extbase_Persistence_Mapper_DataMap
+        */
+       private $dataMap;
+
+       /**
+        * Constructs this proxy instance.
+        *
+        * @param object $parentObject The object instance this proxy is part of
+        * @param string $propertyName The name of the proxied property in it's parent
+        * @param Tx_Extbase_Persistence_Mapper_DataMap $dataMap The corresponding Data Map of the property
+        * @internal
+        */
+       public function __construct($parentObject, $propertyName, Tx_Extbase_Persistence_Mapper_DataMap $dataMap) {
+               $this->queryFactory = t3lib_div::makeInstance('Tx_Extbase_Persistence_QueryFactory');
+               $this->parentObject = $parentObject;
+               $this->propertyName = $propertyName;
+               $this->dataMap = $dataMap;
+       }
+
+       /**
+        * Populate this proxy by asking the $population closure.
+        *
+        * @return object The instance (hopefully) returned
+        * @internal
+        */
+       public function _loadRealInstance() {
+               $result = NULL;
+               $columnMap = $this->dataMap->getColumnMap($this->propertyName);
+               $objectStorage = new Tx_Extbase_Persistence_ObjectStorage();
+               // TODO This if statement should be further encapsulated to follow the DRY principle (see Data Mapper)
+               if ($columnMap->getTypeOfRelation() === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_ONE) {
+                       $query = $this->queryFactory->create($columnMap->getChildClassName());
+                       $result = current($query->matching($query->withUid($row[$columnMap->getColumnName()]))->execute());
+               } elseif ($columnMap->getTypeOfRelation() === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_MANY) {
+                       $objectStorage = new Tx_Extbase_Persistence_ObjectStorage();
+                       $query = $this->queryFactory->create($columnMap->getChildClassName());
+                       $objects = $query->matching($query->equals($columnMap->getParentKeyFieldName(), $this->parentObject->getUid()))->execute();
+                       foreach ($objects as $object) {
+                               $objectStorage->attach($object);
+                       }
+                       $result = $objectStorage;
+               } elseif ($columnMap->getTypeOfRelation() === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY) {
+                       $objectStorage = new Tx_Extbase_Persistence_ObjectStorage();
+                       $relationTableName = $columnMap->getRelationTableName();
+                       $left = $this->QOMFactory->selector($relationTableName);
+                       $childTableName = $columnMap->getChildTableName();
+                       $right = $this->QOMFactory->selector($childTableName);
+                       $joinCondition = $this->QOMFactory->equiJoinCondition($relationTableName, 'uid_foreign', $childTableName, 'uid');
+                       $source = $this->QOMFactory->join(
+                               $left,
+                               $right,
+                               Tx_Extbase_Persistence_QOM_QueryObjectModelConstantsInterface::JCR_JOIN_TYPE_INNER,
+                               $joinCondition
+                               );
+                       $query = $this->queryFactory->create($columnMap->getChildClassName());
+                       $query->setSource($source);
+                       $objects = $query->matching($query->equals('uid_local', $this->parentObject->getUid()))->execute();
+                       foreach ($objects as $object) {
+                               $objectStorage->attach($object);
+                       }
+                       $result = $objectStorage;
+               }
+               $this->parentObject->_setProperty($this->propertyName, $result);
+               $this->parentObject->_memorizeCleanState($this->propertyName);
+               return $result;
+       }
+
+       /**
+        * Magic method call implementation.
+        *
+        * @param string $methodName The name of the property to get
+        * @param array $arguments The arguments given to the call
+        * @return mixed
+        * @internal
+        */
+       public function __call($methodName, $arguments) {
+               $realInstance = $this->_loadRealInstance();
+               return call_user_func_array(array($realInstance, $methodName), $arguments);
+       }
+
+       /**
+        * Magic get call implementation.
+        *
+        * @param string $propertyName The name of the property to get
+        * @return mixed
+        * @internal
+        */
+       public function __get($propertyName) {
+               $realInstance = $this->_loadRealInstance();
+               return $realInstance->$propertyName;
+       }
+
+       /**
+        * Magic set call implementation.
+        *
+        * @param string $propertyName The name of the property to set
+        * @param mixed $value The value for the property to set
+        * @return void
+        * @internal
+        */
+       public function __set($propertyName, $value) {
+               $realInstance = $this->_loadRealInstance();
+               $realInstance->$propertyName = $value;
+       }
+
+       /**
+        * Magic isset call implementation.
+        *
+        * @param string $propertyName The name of the property to check
+        * @return boolean
+        * @internal
+        */
+       public function __isset($propertyName) {
+               $realInstance = $this->_loadRealInstance();
+               return isset($realInstance->$propertyName);
+       }
+
+       /**
+        * Magic unset call implementation.
+        *
+        * @param string $propertyName The name of the property to unset
+        * @return void
+        * @internal
+        */
+       public function __unset($propertyName) {
+               $realInstance = $this->_loadRealInstance();
+               unset($realInstance->$propertyName);
+       }
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/Manager.php b/typo3/sysext/extbase/Classes/Persistence/Manager.php
new file mode 100644 (file)
index 0000000..e74ac40
--- /dev/null
@@ -0,0 +1,121 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * The Extbase Persistence Manager
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: Manager.php 2293 2009-05-20 18:14:45Z robert $
+ *
+ */
+class Tx_Extbase_Persistence_Manager implements Tx_Extbase_Persistence_ManagerInterface, t3lib_Singleton {
+
+       /**
+        * @var Tx_Extbase_Persistence_BackendInterface
+        */
+       protected $backend;
+
+       /**
+        * @var Tx_Extbase_Persistence_Session
+        */
+       protected $session;
+
+       /**
+        * @var Tx_Extbase_Persistence_DataMapper
+        */
+       protected $dataMapper;
+
+       /**
+        * Constructor
+        *
+        * @param Tx_Extbase_Persistence_BackendInterface $backend the backend to use for persistence
+        * @internal
+        */
+       public function __construct(Tx_Extbase_Persistence_BackendInterface $backend) {
+               $this->backend = $backend;
+       }
+
+       /**
+        * Injects the persistence session
+        *
+        * @param Tx_Extbase_Persistence_Session $session The persistence session
+        * @return void
+        * @internal
+        */
+       public function injectSession(Tx_Extbase_Persistence_Session $session) {
+               $this->session = $session;
+       }
+
+       /**
+        * Returns the current persistence session
+        *
+        * @return Tx_Extbase_Persistence_Session
+        * @internal
+        */
+       public function getSession() {
+               return $this->session;
+       }
+
+       /**
+        * Returns the current Data Mapper
+        *
+        * @return Tx_Extbase_Persistence_Mapper_DataMapper
+        * @internal
+        */
+       public function getDataMapper() {
+               return $this->dataMapper;
+       }
+
+       /**
+        * Returns the persistence backend
+        *
+        * @return Tx_Extbase_Persistence_BackendInterface
+        */
+       public function getBackend() {
+               return $this->backend;
+       }
+
+       /**
+        * Commits new objects and changes to objects in the current persistence
+        * session into the backend
+        *
+        * @return void
+        */
+       public function persistAll() {
+               $aggregateRootObjects = new Tx_Extbase_Persistence_ObjectStorage();
+               $aggregateRootObjects->addAll($this->session->getAddedObjects());
+               $aggregateRootObjects->addAll($this->session->getReconstitutedObjects());
+
+               $removedObjects = $this->session->getRemovedObjects();
+
+               $this->backend->setAggregateRootObjects($aggregateRootObjects);
+               $this->backend->setDeletedObjects($removedObjects);
+               $this->backend->commit();
+       }
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/ManagerInterface.php b/typo3/sysext/extbase/Classes/Persistence/ManagerInterface.php
new file mode 100644 (file)
index 0000000..3effa04
--- /dev/null
@@ -0,0 +1,62 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * The Extbase Persistence Manager interface
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: ManagerInterface.php 2293 2009-05-20 18:14:45Z robert $
+ */
+interface Tx_Extbase_Persistence_ManagerInterface {
+
+       /**
+        * Returns the current persistence session
+        *
+        * @return Tx_Extbase_Persistence_Session
+        * @internal
+        */
+       public function getSession();
+
+       /**
+        * Returns the persistence backend
+        *
+        * @return Tx_Extbase_Persistence_BackendInterface
+        * @internal
+        */
+       public function getBackend();
+
+       /**
+        * Commits new objects and changes to objects in the current persistence
+        * session into the backend
+        *
+        * @return void
+        * @internal
+        */
+       public function persistAll();
+}
+?>
\ No newline at end of file
index 2bb7791..9b6806d 100644 (file)
@@ -41,14 +41,10 @@ class Tx_Extbase_Persistence_Mapper_ColumnMap {
        const RELATION_HAS_AND_BELONGS_TO_MANY = 3;
 
        /**
-        * Constants reflecting the type of value
+        * Constants reflecting the loading strategy
         */
-       const TYPE_UNKNOWN = 0;
-       const TYPE_STRING = 1;
-       const TYPE_DATE = 2;
-       const TYPE_INTEGER = 3;
-       const TYPE_FLOAT = 4;
-       const TYPE_BOOLEAN = 5;
+       const STRATEGY_EAGER = 0;
+       const STRATEGY_PROXY = 1;
 
        /**
         * The property name corresponding to the table name
@@ -76,7 +72,7 @@ class Tx_Extbase_Persistence_Mapper_ColumnMap {
         *
         * @var int
         **/
-       protected $typeOfValue;
+       protected $propertyType;
 
        /**
         * The name of the child's class
@@ -155,24 +151,41 @@ class Tx_Extbase_Persistence_Mapper_ColumnMap {
                return $this->typeOfRelation;
        }
 
-       public function setTypeOfValue($typeOfValue) {
-               switch ($typeOfValue) {
-                       case self::TYPE_UNKNOWN;
-                       case self::TYPE_STRING;
-                       case self::TYPE_DATE;
-                       case self::TYPE_INTEGER;
-                       case self::TYPE_FLOAT;
-                       case self::TYPE_BOOLEAN;
-                               $this->typeOfValue = $typeOfValue;
+       public function setPropertyType($propertyType) {
+               switch ($propertyType) {
+                       case Tx_Extbase_Persistence_PropertyType::UNDEFINED;
+                       case Tx_Extbase_Persistence_PropertyType::STRING;
+                       case Tx_Extbase_Persistence_PropertyType::DATE;
+                       case Tx_Extbase_Persistence_PropertyType::LONG;
+                       case Tx_Extbase_Persistence_PropertyType::DOUBLE;
+                       case Tx_Extbase_Persistence_PropertyType::BOOLEAN;
+                       case Tx_Extbase_Persistence_PropertyType::REFERENCE;
+                               $this->propertyType = $propertyType;
                                break;
                        default:
-                               $this->typeOfValue = NULL;
+                               $this->propertyType = NULL; // TODO
                                break;
                }
        }
 
-       public function getTypeOfValue() {
-               return $this->typeOfValue;
+       public function getPropertyType() {
+               return $this->propertyType;
+       }
+
+       public function setLoadingStrategy($loadingStrategy) {
+               switch ($loadingStrategy) {
+                       case self::STRATEGY_PROXY;
+                       // Add more to check for allowed strategies, or-even better-use an interface
+                               $this->loadingStrategy = $loadingStrategy;
+                               break;
+                       default:
+                               $this->loadingStrategy = self::STRATEGY_EAGER;
+                               break;
+               }
+       }
+
+       public function getLoadingStrategy() {
+               return $this->loadingStrategy;
        }
 
        public function setPropertyName($propertyName) {
index 4a2a342..28809c4 100644 (file)
@@ -57,10 +57,13 @@ class Tx_Extbase_Persistence_Mapper_DataMap {
         * @param string $className The class name. This determines the table to fetch the configuration for
         */
        // TODO Refactor to factory pattern (DataMapFactory) and value object (DataMap)  
-       public function __construct($className) {
+       public function __construct($className, $tableName = '') {
                $this->setClassName($className);
-               $this->setTableName($this->determineTableName($className));
-               t3lib_div::loadTCA($this->getTableName());
+               if (empty($tableName)) {
+                       $this->setTableName(strtolower($className));
+               } else {
+                       $this->setTableName($tableName);
+               }
                $this->initialize();
        }
 
@@ -101,17 +104,6 @@ class Tx_Extbase_Persistence_Mapper_DataMap {
        }
        
        /**
-        * Returns the table name for a given class name. If there is an alias defined in the $TCA, it takes the alias name.
-        * Otherwise it converts the class anme to lowercase by default.
-        *
-        * @package default
-        */
-       protected function determineTableName($className) {
-               // TODO Implement table name aliases
-               return strtolower($className);
-       }
-
-       /**
         * Initializes the data map by adding column maps for all the configured columns in the $TCA. 
         * It also resolves the type of values the column is holding and the typo of relation the column 
         * represents.
@@ -119,13 +111,14 @@ class Tx_Extbase_Persistence_Mapper_DataMap {
         * @return void
         */
        protected function initialize() {
+               t3lib_div::loadTCA($this->getTableName());
                $columns = $GLOBALS['TCA'][$this->getTableName()]['columns'];
                $this->addCommonColumns();
                if (is_array($columns)) {
                        foreach ($columns as $columnName => $columnConfiguration) {
                                // TODO convert underscore column names to lowercamelcase
                                $columnMap = new Tx_Extbase_Persistence_Mapper_ColumnMap($columnName, $this);
-                               $this->setTypeOfValue($columnMap, $columnConfiguration);
+                               $this->setPropertyType($columnMap, $columnConfiguration);
                                // TODO support for IRRE
                                // TODO support for MM_insert_fields and MM_match_fields
                                // SK: Discuss the above things
@@ -143,22 +136,22 @@ class Tx_Extbase_Persistence_Mapper_DataMap {
         */
        protected function addCommonColumns() {
                // TODO Decide whether we should add pid and uid columns by default
-               $this->addColumn('uid', Tx_Extbase_Persistence_Mapper_ColumnMap::TYPE_INTEGER);
-               $this->addColumn('pid', Tx_Extbase_Persistence_Mapper_ColumnMap::TYPE_INTEGER);
+               $this->addColumn('uid', Tx_Extbase_Persistence_PropertyType::LONG);
+               $this->addColumn('pid', Tx_Extbase_Persistence_PropertyType::LONG);
                if ($this->hasTimestampColumn()) {
-                       $this->addColumn($this->getTimestampColumnName(), Tx_Extbase_Persistence_Mapper_ColumnMap::TYPE_DATE);
+                       $this->addColumn($this->getTimestampColumnName(), Tx_Extbase_Persistence_PropertyType::DATE);
                }
                if ($this->hasCreationDateColumn()) {
-                       $this->addColumn($this->getCreationDateColumnName(), Tx_Extbase_Persistence_Mapper_ColumnMap::TYPE_DATE);
+                       $this->addColumn($this->getCreationDateColumnName(), Tx_Extbase_Persistence_PropertyType::DATE);
                }
                if ($this->hasCreatorUidColumn()) {
-                       $this->addColumn($this->getCreatorUidColumnName(), Tx_Extbase_Persistence_Mapper_ColumnMap::TYPE_INTEGER);
+                       $this->addColumn($this->getCreatorUidColumnName(), Tx_Extbase_Persistence_PropertyType::LONG);
                }
                if ($this->hasDeletedColumn()) {
-                       $this->addColumn($this->getDeletedColumnName(), Tx_Extbase_Persistence_Mapper_ColumnMap::TYPE_BOOLEAN);
+                       $this->addColumn($this->getDeletedColumnName(), Tx_Extbase_Persistence_PropertyType::BOOLEAN);
                }
                if ($this->hasHiddenColumn()) {
-                       $this->addColumn($this->getHiddenColumnName(), Tx_Extbase_Persistence_Mapper_ColumnMap::TYPE_BOOLEAN);
+                       $this->addColumn($this->getHiddenColumnName(), Tx_Extbase_Persistence_PropertyType::BOOLEAN);
                }
        }
 
@@ -170,18 +163,27 @@ class Tx_Extbase_Persistence_Mapper_DataMap {
         * @param string $columnConfiguration The column configuration from $TCA
         * @return void
         */
-       protected function setTypeOfValue(Tx_Extbase_Persistence_Mapper_ColumnMap &$columnMap, $columnConfiguration) {
+       protected function setPropertyType(Tx_Extbase_Persistence_Mapper_ColumnMap &$columnMap, $columnConfiguration) {
                $evalConfiguration = t3lib_div::trimExplode(',', $columnConfiguration['config']['eval']);
                if (in_array('date', $evalConfiguration) || in_array('datetime', $evalConfiguration)) {
-                       $columnMap->setTypeOfValue(Tx_Extbase_Persistence_Mapper_ColumnMap::TYPE_DATE);
+                       $columnMap->setPropertyType(Tx_Extbase_Persistence_PropertyType::DATE);
                } elseif ($columnConfiguration['config']['type'] === 'check' && empty($columnConfiguration['config']['items'])) {
-                       $columnMap->setTypeOfValue(Tx_Extbase_Persistence_Mapper_ColumnMap::TYPE_BOOLEAN);
+                       $columnMap->setPropertyType(Tx_Extbase_Persistence_PropertyType::BOOLEAN);
                } elseif (in_array('int', $evalConfiguration)) {
-                       $columnMap->setTypeOfValue(Tx_Extbase_Persistence_Mapper_ColumnMap::TYPE_INTEGER);
+                       $columnMap->setPropertyType(Tx_Extbase_Persistence_PropertyType::LONG);
                } elseif (in_array('double2', $evalConfiguration)) {
-                       $columnMap->setTypeOfValue(Tx_Extbase_Persistence_Mapper_ColumnMap::TYPE_FLOAT);
+                       $columnMap->setPropertyType(Tx_Extbase_Persistence_PropertyType::DOUBLE);
                } else {
-                       $columnMap->setTypeOfValue(Tx_Extbase_Persistence_Mapper_ColumnMap::TYPE_STRING);
+                       if (isset($columnConfiguration['config']['foreign_table'])) {
+                               if ($columnConfiguration['config']['loadingStrategy'] === 'proxy') {
+                                       $columnMap->setLoadingStrategy(Tx_Extbase_Persistence_Mapper_ColumnMap::STRATEGY_PROXY);
+                               } else {
+                                       $columnMap->setLoadingStrategy(Tx_Extbase_Persistence_Mapper_ColumnMap::STRATEGY_EAGER);
+                               }
+                               $columnMap->setPropertyType(Tx_Extbase_Persistence_PropertyType::REFERENCE);
+                       } else {
+                               $columnMap->setPropertyType(Tx_Extbase_Persistence_PropertyType::STRING);
+                       }
                }
        }
 
@@ -212,6 +214,7 @@ class Tx_Extbase_Persistence_Mapper_DataMap {
                                $columnMap->setParentKeyFieldName($columnConfiguration['config']['foreign_field']);
                                $columnMap->setParentTableFieldName($columnConfiguration['config']['foreign_table_field']);
                        }
+                       //                      TODO Support MM_match_fields
                } elseif (array_key_exists('MM', $columnConfiguration['config'])) {
                        $columnMap->setTypeOfRelation(Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY);
                        $columnMap->setChildClassName($columnConfiguration['config']['foreign_class']);
@@ -247,13 +250,13 @@ class Tx_Extbase_Persistence_Mapper_DataMap {
         * relation (optional) and adds it to the data map.
         *
         * @param string $columnName The column name
-        * @param string $typeOfValue The type of value (default: string)
+        * @param string $propertyType The type of value (default: string)
         * @param string $typeOfRelation The type of relation (default: none)
         * @return Tx_Extbase_Persistence_Mapper_DataMap Returns itself for a fluent interface
         */
-       public function addColumn($columnName, $typeOfValue = Tx_Extbase_Persistence_Mapper_ColumnMap::TYPE_STRING, $typeOfRelation = Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_NONE) {
+       public function addColumn($columnName, $propertyType = Tx_Extbase_Persistence_PropertyType::STRING, $typeOfRelation = Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_NONE) {
                $columnMap = new Tx_Extbase_Persistence_Mapper_ColumnMap($columnName);
-               $columnMap->setTypeOfValue($typeOfValue);
+               $columnMap->setPropertyType($propertyType);
                $columnMap->setTypeOfRelation($typeOfRelation);
                $this->addColumnMap($columnMap);
                return $this;
@@ -453,27 +456,49 @@ class Tx_Extbase_Persistence_Mapper_DataMap {
        }
 
        /**
-        * Converts a value from a database field type to a property type
+        * Converts a field name to the property name. It respects property name aliases defined in $TCA.
         *
-        * @param string $className The class name
-        * @param string $propertyName The property name
-        * @param mixed $fieldValue The field value
-        * @return mixed The converted value
+        * @param string $fieldName The field name
+        * @return string $propertyName The property name
         */
-       public function convertFieldValueToPropertyValue($propertyName, $fieldValue) {
-               $columnMap = $this->getColumnMap($propertyName);
-               if ($columnMap->getTypeOfValue() === Tx_Extbase_Persistence_Mapper_ColumnMap::TYPE_DATE) {
-                       $convertedValue = new DateTime(strftime('%Y-%m-%d %H:%M:%S', $fieldValue));
-               } elseif ($columnMap->getTypeOfValue() === Tx_Extbase_Persistence_Mapper_ColumnMap::TYPE_BOOLEAN) {
-                       if ($fieldValue === '0') {
-                               $convertedValue = FALSE;
-                       } else {
-                               $convertedValue = TRUE;
-                       }
-               } else {
-                       $convertedValue = $fieldValue;
+       public function convertFieldNameToPropertyName($fieldName) {
+               $propertyName = $fieldName;
+               return $propertyName; // TODO Implement aliases for field names (see also convertPropertyNameToFieldName())
+       }
+
+       /**
+        * Converts a preoperty name to the field name. It respects property name aliases defined in $TCA.
+        *
+        * @param string $fieldName The field name
+        * @return string $propertyName The property name
+        */
+       public function convertPropertyNameToFieldName($propertyName) {
+               $fieldName = $propertyName;
+               return $fieldName;
+       }
+
+       /**
+        * Converts the given string into the given type
+        *
+        * @param integer $type one of the constants defined in Tx_Extbase_Persistence_PropertyType
+        * @param string $string a string representing a value of the given type
+        *
+        * @return string|int|float|DateTime|boolean
+        */
+       public function convertFieldValueToPropertyValue($type, $string) {
+               switch ($type) {
+                       case Tx_Extbase_Persistence_PropertyType::LONG:
+                               return (int) $string;
+                       case Tx_Extbase_Persistence_PropertyType::DOUBLE:
+                       case Tx_Extbase_Persistence_PropertyType::DECIMAL:
+                               return (float) $string;
+                       case Tx_Extbase_Persistence_PropertyType::DATE:
+                               return new DateTime(strftime('%Y-%m-%d %H:%M:%S', $string)); // TODO Check for Time Zone issues
+                       case Tx_Extbase_Persistence_PropertyType::BOOLEAN:
+                               return (boolean) $string;
+                       default:
+                               return $string;
                }
-               return $convertedValue;
        }
 
        /**
@@ -483,7 +508,7 @@ class Tx_Extbase_Persistence_Mapper_DataMap {
         * @param boolean $fullQuoteString TRUE if a field value of type string should be full quoted via $GLOBALS['TYPO3_DB']->fullQuoteStr()
         * @return mixed The converted value
         */
-       public function convertPropertyValueToFieldValue($propertyValue, $fullQuoteString = TRUE) {
+       public function convertPropertyValueToFieldValue($propertyValue, $fullQuoteString = FALSE) {
                if (is_bool($propertyValue)) {
                        $convertedValue = $propertyValue ? 1 : 0;
                } elseif ($propertyValue instanceof Tx_Extbase_DomainObject_AbstractDomainObject) {
@@ -493,6 +518,7 @@ class Tx_Extbase_Persistence_Mapper_DataMap {
                } elseif (is_int($propertyValue)) {
                        $convertedValue = $propertyValue;
                } else {
+                       // FIXME Full quote string does not work with the Typo3DbBackend parsing
                        $convertedValue = $fullQuoteString === TRUE ? $GLOBALS['TYPO3_DB']->fullQuoteStr((string)$propertyValue, '') : $propertyValue;
                }
                return $convertedValue;
diff --git a/typo3/sysext/extbase/Classes/Persistence/Mapper/DataMapper.php b/typo3/sysext/extbase/Classes/Persistence/Mapper/DataMapper.php
new file mode 100644 (file)
index 0000000..faa090f
--- /dev/null
@@ -0,0 +1,305 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * A mapper to map database tables configured in $TCA on domain objects.
+ *
+ * @package Extbase
+ * @subpackage extbase
+ * @version $ID:$
+ */
+class Tx_Extbase_Persistence_Mapper_DataMapper implements t3lib_Singleton {
+
+       /**
+        * @var Tx_Extbase_Persistence_IdentityMap
+        */
+       protected $identityMap;
+
+       /**
+        * @var Tx_Extbase_Persistence_ManagerInterface
+        */
+       protected $persistenceManager;
+
+       /**
+        * A reference to the page select object providing methods to perform language and work space overlays
+        *
+        * @var t3lib_pageSelect
+        **/
+       protected $pageSelectObject;
+
+       /**
+        * Cached data maps
+        *
+        * @var array
+        **/
+       protected $dataMaps = array();
+
+       /**
+        * @var Tx_Extbase_Persistence_QueryFactoryInterface
+        */
+       protected $queryFactory;
+
+       /**
+        * The TYPO3 reference index object
+        *
+        * @var t3lib_refindex
+        **/
+       protected $referenceIndex;
+
+       /**
+        * Constructs a new mapper
+        *
+        */
+       public function __construct() {
+               $this->queryFactory = t3lib_div::makeInstance('Tx_Extbase_Persistence_QueryFactory');
+               $GLOBALS['TSFE']->includeTCA(); // TODO Move this to an appropriate position
+       }
+
+       /**
+        * Injects the identity map
+        *
+        * @param Tx_Extbase_Persistence_IdentityMap $identityMap
+        * @return void
+        */
+       public function injectIdentityMap(Tx_Extbase_Persistence_IdentityMap $identityMap) {
+               $this->identityMap = $identityMap;
+       }
+
+       /**
+        * Injects the persistence manager
+        *
+        * @param Tx_Extbase_Persistence_ManagerInterface $persistenceManager
+        * @return void
+        */
+       public function injectPersistenceManager(Tx_Extbase_Persistence_ManagerInterface $persistenceManager) {
+               $this->persistenceManager = $persistenceManager;
+               $this->QOMFactory = $this->persistenceManager->getBackend()->getQOMFactory();
+       }
+
+       /**
+        * Maps the (aggregate root) rows and registers them as reconstituted
+        * with the session.
+        *
+        * @param Tx_Extbase_Persistence_RowIteratorInterface $rows
+        * @return array
+        */
+       public function map($className, Tx_Extbase_Persistence_RowIteratorInterface $rows) {
+               $objects = array();
+               foreach ($rows as $row) {
+                       $objects[] = $this->mapSingleRow($className, $row);
+               }
+               return $objects;
+       }
+
+       /**
+        * Maps a single node into the object it represents
+        *
+        * @param Tx_Extbase_Persistence_RowInterface $node
+        * @return object
+        */
+       protected function mapSingleRow($className, Tx_Extbase_Persistence_RowInterface $row) {
+               if ($this->identityMap->hasUid($className, $row['uid'])) {
+                       $object = $this->identityMap->getObjectByUid($className, $row['uid']);
+               } else {
+                       $object = $this->createEmptyObject($className);
+                       $this->thawProperties($object, $row);
+                       $this->identityMap->registerObject($object, $object->getUid());
+                       $object->_memorizeCleanState();
+               }
+               return $object;
+       }
+
+       /**
+        * Creates a skeleton of the specified object
+        *
+        * @param string $className Name of the class to create a skeleton for
+        * @return object The object skeleton
+        * @internal
+        */
+       protected function createEmptyObject($className) {
+               // Note: The class_implements() function also invokes autoload to assure that the interfaces
+               // and the class are loaded. Would end up with __PHP_Incomplete_Class without it.
+               if (!in_array('Tx_Extbase_DomainObject_DomainObjectInterface', class_implements($className))) throw new Tx_Extbase_Object_Exception_CannotReconstituteObject('Cannot create empty instance of the class "' . $className . '" because it does not implement the Tx_Extbase_DomainObject_DomainObjectInterface.', 1234386924);
+               $object = unserialize('O:' . strlen($className) . ':"' . $className . '":0:{};');
+               return $object;
+       }
+
+       /**
+        * Sets the given properties on the object.
+        *
+        * @param Tx_Extbase_DomainObject_DomainObjectInterface $object The object to set properties on
+        * @param Tx_Extbase_Persistence_RowInterface $row
+        * @return void
+        */
+       protected function thawProperties(Tx_Extbase_DomainObject_DomainObjectInterface $object, Tx_Extbase_Persistence_RowInterface $row) {
+               $className = get_class($object);
+               $dataMap = $this->getDataMap($className);
+               $properties = $object->_getProperties();
+               $object->_setProperty('uid', $row['uid']);
+               foreach ($properties as $propertyName => $propertyValue) {
+                       if (!$dataMap->isPersistableProperty($propertyName)) continue;
+                       $columnMap = $dataMap->getColumnMap($propertyName);
+                       $columnName = $columnMap->getColumnName();
+                       $propertyValue = NULL;
+                       $propertyType = $columnMap->getPropertyType();
+                       switch ($propertyType) {
+                               case Tx_Extbase_Persistence_PropertyType::STRING;
+                               case Tx_Extbase_Persistence_PropertyType::DATE;
+                               case Tx_Extbase_Persistence_PropertyType::LONG;
+                               case Tx_Extbase_Persistence_PropertyType::DOUBLE;
+                               case Tx_Extbase_Persistence_PropertyType::BOOLEAN;
+                                       if (isset($row[$columnName])) {
+                                               $rawPropertyValue = $row[$columnName];
+                                               $propertyValue = $dataMap->convertFieldValueToPropertyValue($propertyType, $rawPropertyValue);
+                                       }
+                               break;
+                               case (Tx_Extbase_Persistence_PropertyType::REFERENCE):
+                                       if (!is_null($row[$propertyName])) {
+                                               $propertyValue = $this->mapRelatedObjects($object, $propertyName, $row, $columnMap);
+                                       } else {
+                                               $propertyValue = NULL;
+                                       }
+                               break;
+                                       // FIXME we have an object to handle... -> exception
+                               default:
+                                       if (isset($row[$propertyName])) {
+                                               $property = $row[$propertyName];
+                                               if (is_object($property)) {
+                                                       $propertyValue = $this->mapObject($property);
+                                               } else {
+                                                       $propertyValue = $this->mapSingleRow($className, $property);
+                                               }
+                                       }
+                               break;
+                       }
+
+                       $object->_setProperty($propertyName, $propertyValue);
+               }
+       }
+
+       /**
+        * Maps related objects to an ObjectStorage
+        *
+        * @param object $parentObject The parent object for the mapping result
+        * @param string $propertyName The target property name for the mapping result
+        * @param Tx_Extbase_Persistence_RowInterface $row The actual database row
+        * @param int $loadingStrategy The loading strategy; one of Tx_Extbase_Persistence_Mapper_ColumnMap::STRATEGY_*
+        * @return array|Tx_Extbase_Persistence_ObjectStorage|Tx_Extbase_Persistence_LazyLoadingProxy|another implementation of a loading strategy
+        */
+       protected function mapRelatedObjects(Tx_Extbase_DomainObject_AbstractEntity $parentObject, $propertyName, Tx_Extbase_Persistence_RowInterface $row, Tx_Extbase_Persistence_Mapper_ColumnMap $columnMap) {
+               $dataMap = $this->getDataMap(get_class($parentObject));
+               $columnMap = $dataMap->getColumnMap($propertyName);
+               if ($columnMap->getLoadingStrategy() === Tx_Extbase_Persistence_Mapper_ColumnMap::STRATEGY_PROXY) {
+                       // TODO Remove dependency to the loading strategy implementation
+                       $result = t3lib_div::makeInstance('Tx_Extbase_Persistence_LazyLoadingProxy', $parentObject, $propertyName, $dataMap);
+               } else {
+                       if ($columnMap->getTypeOfRelation() === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_ONE) {
+                               $query = $this->queryFactory->create($columnMap->getChildClassName());
+                               $result = current($query->matching($query->withUid($row[$columnMap->getColumnName()]))->execute());
+                       } elseif ($columnMap->getTypeOfRelation() === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_MANY) {
+                               $objectStorage = new Tx_Extbase_Persistence_ObjectStorage();
+                               $query = $this->queryFactory->create($columnMap->getChildClassName());
+                               $objects = $query->matching($query->equals($columnMap->getParentKeyFieldName(), $parentObject->getUid()))->execute();
+                               foreach ($objects as $object) {
+                                       $objectStorage->attach($object);
+                               }
+                               $result = $objectStorage;
+                       } elseif ($columnMap->getTypeOfRelation() === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY) {
+                               $objectStorage = new Tx_Extbase_Persistence_ObjectStorage();
+                               $relationTableName = $columnMap->getRelationTableName();
+                               $left = $this->QOMFactory->selector($relationTableName);
+                               $childTableName = $columnMap->getChildTableName();
+                               $right = $this->QOMFactory->selector($childTableName);
+                               $joinCondition = $this->QOMFactory->equiJoinCondition($relationTableName, 'uid_foreign', $childTableName, 'uid');
+                               $source = $this->QOMFactory->join(
+                                       $left,
+                                       $right,
+                                       Tx_Extbase_Persistence_QOM_QueryObjectModelConstantsInterface::JCR_JOIN_TYPE_INNER,
+                                       $joinCondition
+                                       );
+                               $query = $this->queryFactory->create($columnMap->getChildClassName());
+                               $query->setSource($source);
+                               $objects = $query->matching($query->equals('uid_local', $parentObject->getUid()))->execute();
+                               foreach ($objects as $object) {
+                                       $objectStorage->attach($object);
+                               }
+                               $result = $objectStorage;
+                       }
+               }
+
+               return $result;
+       }
+
+       /**
+        * Delegates the call to the Data Map.
+        * Returns TRUE if the property is persistable (configured in $TCA)
+        *
+        * @param string $className The property name
+        * @param string $propertyName The property name
+        * @return boolean TRUE if the property is persistable (configured in $TCA)
+        */
+       public function isPersistableProperty($className, $propertyName) {
+               $dataMap = $this->getDataMap($className);
+               return $dataMap->isPersistableProperty($propertyName);
+       }
+
+       /**
+        * Returns a data map for a given class name
+        *
+        * @return Tx_Extbase_Persistence_Mapper_DataMap The data map
+        */
+       public function getDataMap($className) {
+               global $TCA;
+               if (empty($this->dataMaps[$className])) {
+//                     // TODO This is a little bit costy for table name aliases -> implement a DataMapBuilder (knowing the aliases defined in $TCA)
+//                     $tableName = '';
+//                     if (is_array($TCA[strtolower($className)] && empty($TCA[strtolower($className)]['config']['classes']))) {
+//                             $tableName = strtolower($className);
+//                     } else {
+//                                             debug($TCA);
+//
+//                             foreach ($TCA as $configuredTableName => $tableConfiguration) {
+//                                     if (in_array($className, t3lib_div::trimExplode(',', $tableConfiguration['config']['classes']))) {
+//                                             $tableName = $configuredTableName;
+//                                     }
+//                             }
+//                     }
+                       $dataMap = new Tx_Extbase_Persistence_Mapper_DataMap($className, $tableName);
+                       $this->dataMaps[$className] = $dataMap;
+               }
+               return $this->dataMaps[$className];
+       }
+
+       /**
+        * Returns the selector (table) name for a given class name.
+        *
+        * @param string $className
+        * @return string The selector name
+        */
+       public function convertClassNameToSelectorName($className) {
+               return $this->getDataMap($className)->getTableName();
+       }
+
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/Mapper/ObjectRelationalMapper.php b/typo3/sysext/extbase/Classes/Persistence/Mapper/ObjectRelationalMapper.php
deleted file mode 100644 (file)
index 55d5875..0000000
+++ /dev/null
@@ -1,828 +0,0 @@
-<?php
-/***************************************************************
-*  Copyright notice
-*
-*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
-*  All rights reserved
-*
-*  This script is part of the TYPO3 project. The TYPO3 project is
-*  free software; you can redistribute it and/or modify
-*  it under the terms of the GNU General Public License as published by
-*  the Free Software Foundation; either version 2 of the License, or
-*  (at your option) any later version.
-*
-*  The GNU General Public License can be found at
-*  http://www.gnu.org/copyleft/gpl.html.
-*
-*  This script is distributed in the hope that it will be useful,
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*  GNU General Public License for more details.
-*
-*  This copyright notice MUST APPEAR in all copies of the script!
-***************************************************************/
-
-require_once(PATH_t3lib . 'interfaces/interface.t3lib_singleton.php');
-require_once(PATH_tslib . 'class.tslib_content.php');
-
-/**
- * A mapper to map database tables configured in $TCA on domain objects.
- *
- * @package Extbase
- * @subpackage extbase
- * @version $ID:$
- */
-class Tx_Extbase_Persistence_Mapper_ObjectRelationalMapper implements Tx_Extbase_Persistence_DataMapperInterface, t3lib_Singleton {
-
-       /**
-        * Cached data maps
-        *
-        * @var array
-        **/
-       protected $dataMaps = array();
-
-       /**
-        * The persistence backend
-        *
-        * @var t3lib_DB
-        **/
-       protected $persistenceBackend;
-
-       /**
-        * The TYPO3 reference index object
-        *
-        * @var t3lib_refindex
-        **/
-       protected $referenceIndex;
-
-       /**
-        * The aggregate root objects to be handled by the object relational mapper
-        *
-        * @var Tx_Extbase_Persistence_ObjectStorage
-        **/
-       protected $aggregateRootObjects;
-
-       /**
-        * The deleted objects to be handled by the object relational mapper
-        *
-        * @var Tx_Extbase_Persistence_ObjectStorage
-        **/
-       protected $deletedObjects;
-
-       /**
-        * A first level cache for domain objects by class and uid
-        *
-        * @var array
-        **/
-       protected $identityMap = array();
-
-       /**
-        * A reference to the page select object providing methods to perform language and work space overlays
-        *
-        * @var t3lib_pageSelect
-        **/
-       protected $pageSelectObject;
-
-       /**
-        * Constructs a new mapper
-        *
-        */
-       // TODO Interface for database handle
-       public function __construct(t3lib_DB $persistenceBackend = NULL) {
-               $this->persistenceBackend = $persistenceBackend !== NULL ? $persistenceBackend : $GLOBALS['TYPO3_DB'];
-               $this->referenceIndex = t3lib_div::makeInstance('t3lib_refindex');
-               $this->aggregateRootObjects = new Tx_Extbase_Persistence_ObjectStorage();
-               $this->identityMap = new Tx_Extbase_Persistence_IdentityMap();
-               $GLOBALS['TSFE']->includeTCA();
-       }
-
-       /**
-        * Sets the aggregate root objects
-        *
-        * @param Tx_Extbase_Persistence_ObjectStorage $objects The objects to be registered
-        * @return void
-        */
-       public function setAggregateRootObjects(Tx_Extbase_Persistence_ObjectStorage $objects) {
-               $this->aggregateRootObjects = $objects;
-       }
-
-       /**
-        * Sets the deleted objects
-        *
-        * @param Tx_Extbase_Persistence_ObjectStorage $objects The objects to be deleted
-        * @return void
-        */
-       public function setDeletedObjects(Tx_Extbase_Persistence_ObjectStorage $objects) {
-               $this->deletedObjects = $objects;
-       }
-
-       /**
-        * The build query method is invoked by the Persistence Repository.
-        * Build a query for objects by multiple conditions. Either as SQL parts or query by example.
-        *
-        * The following condition array would find entities with description like the given keyword and
-        * name equal to "foo".
-        *
-        * <pre>
-        * array(
-        *              array('blog_description LIKE ?', $keyword),
-        *              'blogName' => 'Foo'
-        *              )
-        * </pre>
-        *
-        * Note: The SQL part uses the database columns names, the query by example syntax uses
-        * the object property name (camel-cased, without underscore).
-        *
-        * @param array|string $conditions The conditions as an array or SQL string
-        * @return string The query where part for the class and given conditions
-        */
-       public function buildQuery($className, $conditions) {
-               $dataMap = $this->getDataMap($className);
-               if (is_array($conditions)) {
-                       $where = $this->buildQueryByConditions($dataMap, $conditions);
-               } if (is_string($conditions)) {
-                       // FIXME Should we convert the condition before buiding the where clause (DateTime() -> timestamp)?
-                       $where = $conditions;
-               }
-               return $where;
-       }
-
-       /**
-        * Get a where part for conditions by a specific data map. This will
-        * either replace placeholders (index based array) or use the condition
-        * as an example relative to the data map.
-        *
-        * @param Tx_Extbase_Persistence_Mapper_DataMap $dataMap The data map
-        * @param array $conditions The conditions
-        *
-        * @return string The where part
-        */
-       protected function buildQueryByConditions(Tx_Extbase_Persistence_Mapper_DataMap &$dataMap, array $conditions) {
-               $whereParts = array();
-               foreach ($conditions as $key => $condition) {
-                       if (is_array($condition) && isset($condition[0])) {
-                               $sql = $this->replacePlaceholders($dataMap, $condition[0], array_slice($condition, 1));
-                               $whereParts[] = '(' . $sql . ')';
-                       } elseif (is_string($key)) {
-                               $sql = $this->buildQueryByExample($dataMap, $key, $condition);
-                               if (strlen($sql) > 0) {
-                                       $whereParts[] = '(' . $sql . ')';
-                               }
-                       }
-               }
-               return implode(' AND ', $whereParts);
-       }
-
-       /**
-        * Get a where part for an example condition (associative array). This also works
-        * for nested conditions.
-        *
-        * @param Tx_Extbase_Persistence_Mapper_DataMap $dataMap The data map
-        * @param array $propertyName The property name
-        * @param array $example The example condition
-        *
-        * @return string The where part
-        */
-       protected function buildQueryByExample(Tx_Extbase_Persistence_Mapper_DataMap &$dataMap, $propertyName, $example) {
-               $sql = '';
-               $columnMap = $dataMap->getColumnMap($propertyName);
-               if (empty($columnMap)) {
-                       throw new Tx_Extbase_Persistence_Exception_InvalidPropertyType("No columnMap for $propertyName", 1240305176);
-               }
-               if (!is_array($example)) {
-                       $column = $dataMap->getTableName() . '.' . $columnMap->getColumnName();
-                       $sql = $column . ' = ' . $dataMap->convertPropertyValueToFieldValue($example);
-               } else {
-                       $childDataMap = $this->getDataMap($columnMap->getChildClassName());
-                       $sql = $this->buildQueryByConditions($childDataMap, $example);
-               }
-               return $sql;
-       }
-
-       /**
-        * Replace query placeholders in a query part by the given
-        * parameters.
-        *
-        * @param Tx_Extbase_Persistence_Mapper_DataMap $dataMap The data map for conversion
-        * @param string $queryPart The query part with placeholders
-        * @param array $parameters The parameters
-        *
-        * @return string The query part with replaced placeholders
-        */
-       protected function replacePlaceholders(Tx_Extbase_Persistence_Mapper_DataMap &$dataMap, $queryPart, $parameters) {
-               $sql = $queryPart;
-               foreach ($parameters as $parameter) {
-                       $markPosition = strpos($sql, '?');
-                       if ($markPosition !== FALSE) {
-                               $sql = substr($sql, 0, $markPosition) . $dataMap->convertPropertyValueToFieldValue($parameter) . substr($sql, $markPosition + 1);
-                       }
-               }
-               return $sql;
-       }
-
-       /**
-        * Fetches objects from the database by given SQL statement snippets. The where
-        * statement is raw SQL and will not be escaped. It is much safer to use the
-        * generic find method to supply where conditions.
-        *
-        * @param string $className The name of class to be fetched
-        * @param string $where WHERE statement
-        * @param string $from FROM statement will default to the tablename of the given class
-        * @param string $groupBy GROUP BY statement
-        * @param string $orderBy ORDER BY statement
-        * @param string $limit LIMIT statement
-        * @return array The matched objects
-        */
-       public function fetch($className, $where = '', $from = '', $groupBy = '', $orderBy = '', $limit = '', $useEnableFields = TRUE) {
-               if (strlen($where) === 0) {
-                       $where = '1=1';
-               }
-               $dataMap = $this->getDataMap($className);
-               $joinClause = $this->getJoinClause($className);
-               if (!strlen($from)) {
-                       $from = $dataMap->getTableName() . ' ' . $joinClause;
-               }
-               if ($useEnableFields === TRUE) {
-                       $enableFields = $GLOBALS['TSFE']->sys_page->enableFields($dataMap->getTableName());
-                       // TODO CH: add enable fields for joined tables
-               } else {
-                       $enableFields = '';
-               }
-
-               $res = $this->persistenceBackend->exec_SELECTquery(
-                       '*',
-                       $from,
-                       $where . $enableFields,
-                       $groupBy,
-                       $orderBy,
-                       $limit
-                       );
-
-               if ($res) {
-                       $fieldMap = $this->getFieldMapFromResult($res);
-                       $rows = $this->getRowsFromResult($dataMap->getTableName(), $res);
-               }
-
-               $objects = array();
-               if (is_array($rows)) {
-                       if (count($rows) > 0) {
-                               $objects = $this->reconstituteObjects($dataMap, $fieldMap, $rows);
-                       }
-               }
-               return $objects;
-       }
-
-       /**
-        * Fetches and reconstitutes objects from the database by given SQL statement snippets taking a relation 
-        * table into account. The fetch process is delegated.
-        *
-        * @param Tx_Extbase_DomainObject_AbstractEntity $parentObject The 
-        * @param Tx_Extbase_Peristence_Mapper_ColumnMap $columnMap 
-        * @param string $where The WHERE clause
-        * @param string $groupBy The GROUP BY clause
-        * @param string $orderBy The ORDER BY clause
-        * @param string $limit The LIMIT clause
-        * @param boolean $useEnableFields TRUE if enableFields() should be checked (default: TRUE) 
-        * @return array An array if matched objects
-        * @see Tx_Extbase_Persistence_Mapper_ObjectRelationalMapper::fetch()
-        */
-       public function fetchWithRelationTable(Tx_Extbase_DomainObject_AbstractEntity $parentObject, Tx_Extbase_Persistence_Mapper_ColumnMap $columnMap, $where = '', $groupBy = '', $orderBy = '', $limit = '', $useEnableFields = TRUE) {
-               if (strlen($where) === 0) {
-                       $where = '1=1';
-               }
-               $from = $columnMap->getChildTableName() . ', ' . $columnMap->getRelationTableName();
-               $where .= ' AND ' . $columnMap->getChildTableName() . '.uid=' . $columnMap->getRelationTableName() . '.uid_foreign AND ' . $columnMap->getRelationTableName() . '.uid_local=' . t3lib_div::intval_positive($parentObject->getUid());
-               return $this->fetch($columnMap->getChildClassName(), $where, $from, $groupBy, $orderBy, $limit, $useEnableFields);
-       }
-
-       protected function getFieldMapFromResult($res) {
-               $fieldMap = array();
-               if ($res !== FALSE) {
-                       $fieldPosition = 0;
-                       // TODO mysql_fetch_field should be available in t3lib_db (patch core)
-                       while ($field = mysql_fetch_field($res)) {
-                               $fieldMap[$field->table][$field->name] = $fieldPosition;
-                               $fieldPosition++;
-                       }
-               }
-               return $fieldMap;
-       }
-
-       protected function getRowsFromResult($tableName, $res) {
-               $rows = array();
-               while ($row = $this->persistenceBackend->sql_fetch_assoc($res)) {
-                       $row = $this->doLanguageAndWorkspaceOverlay($tableName, $row);
-                       if (is_array($row)) {
-                               $arrayKeys = range(0,count($row));
-                               array_fill_keys($arrayKeys, $row);
-                               $rows[] = $row;
-                       }
-               }
-               $this->persistenceBackend->sql_free_result($res);
-               return $rows;
-       }
-
-       /**
-        * Performs workspace and language overlay on the given row array. The language and workspace id is automatically
-        * detected (depending on FE or BE context). You can also explicitly set the language/workspace id.
-        *
-        * @param Tx_Extbase_Persistence_Mapper_DataMap $dataMap
-        * @param array $row The row array (as reference)
-        * @param string $languageUid The language id
-        * @param string $workspaceUidUid The workspace id
-        * @return void
-        */
-       protected function doLanguageAndWorkspaceOverlay($tableName, array $row, $languageUid = NULL, $workspaceUid = NULL) {
-               if (!($this->pageSelectObject instanceof t3lib_pageSelect)) {
-                       if (TYPO3_MODE == 'FE') {
-                               if (is_object($GLOBALS ['TSFE'])) {
-                                       $this->pageSelectObject = $GLOBALS ['TSFE']->sys_page;
-                                       if ($languageUid === NULL) {
-                                               $languageUid = $GLOBALS ['TSFE']->sys_language_content;
-                                       }
-                               } else {
-                                       require_once(PATH_t3lib . 'class.t3lib_page.php');
-                                       $this->pageSelectObject = t3lib_div::makeInstance('t3lib_pageSelect');
-                                       if ($languageUid === NULL) {
-                                               $languageUid = intval(t3lib_div::_GP('L'));
-                                       }
-                               }
-                               if ($workspaceUid !== NULL) {
-                                       $this->pageSelectObject->versioningWorkspaceId = $workspaceUid;
-                               }
-                       } else {
-                               require_once(PATH_t3lib . 'class.t3lib_page.php');
-                               $this->pageSelectObject = t3lib_div::makeInstance( 't3lib_pageSelect' );
-                               //$this->pageSelectObject->versioningPreview =  TRUE;
-                               if ($workspaceUid === NULL) {
-                                       $workspaceUid = $GLOBALS ['BE_USER']->workspace;
-                               }
-                               $this->pageSelectObject->versioningWorkspaceId = $workspaceUid;
-                       }
-               }
-
-               $this->pageSelectObject->versionOL($tableName, $row, TRUE);
-               $row = $this->pageSelectObject->getRecordOverlay($tableName, $row, $languageUid, ''); //'hideNonTranslated'
-               // TODO Skip if empty languageoverlay (languagevisibility)
-               return $row;
-       }
-
-       /**
-        * Get the join clause for the fetch method for a specific class. This will
-        * eagerly load all has-one relations.
-        *
-        * @param string $className The class name
-        * @return string The join clause
-        */
-       protected function getJoinClause($className) {
-               $dataMap = $this->getDataMap($className);
-               $join = '';
-               foreach ($dataMap->getColumnMaps() as $propertyName => $columnMap) {
-                       if ($columnMap->getTypeOfRelation() == Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_ONE) {
-                               $join .= ' LEFT JOIN ' . $columnMap->getChildTableName() . ' ON ' . $dataMap->getTableName() . '.' . $columnMap->getColumnName() . ' = ' . $columnMap->getChildTableName() . '.uid';
-                               $join .= $this->getJoinClause($columnMap->getChildClassName());
-                       }
-               }
-               return $join;
-       }
-
-       /**
-        * reconstitutes domain objects from $rows (array)
-        *
-        * @param Tx_Extbase_Persistence_Mapper_DataMap $dataMap The data map corresponding to the domain object
-        * @param array $fieldMap An array indexed by the table name and field name to the row index
-        * @param array $rows The rows array fetched from the database (not associative)
-        * @return array An array of reconstituted domain objects
-        */
-       // TODO Check for infinite loops during reconstitution
-       protected function reconstituteObjects(Tx_Extbase_Persistence_Mapper_DataMap $dataMap, array &$fieldMap, array &$rows) {
-               $objects = array();
-               foreach ($rows as $row) {
-                       $properties = $this->getProperties($dataMap, $fieldMap, $row);
-                       $className = $dataMap->getClassName();
-                       if ($this->identityMap->hasUid($className, $properties['uid'])) {
-                               $object = $this->identityMap->getObjectByUid($className, $properties['uid']);
-                       } else {
-                               $object = $this->reconstituteObject($dataMap->getClassName(), $properties);
-                               foreach ($dataMap->getColumnMaps() as $columnMap) {
-                                       if ($columnMap->getTypeOfRelation() === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_ONE) {
-                                               list($relatedObject) = $this->reconstituteObjects($this->getDataMap($columnMap->getChildClassName()), $fieldMap, array($row));
-                                               $object->_reconstituteProperty($columnMap->getPropertyName(), $relatedObject);
-                                       } elseif ($columnMap->getTypeOfRelation() === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_MANY) {
-                                               $where = $columnMap->getParentKeyFieldName() . '=' . intval($object->getUid());
-                                               $relatedObjects = $this->fetch($columnMap->getChildClassName(), $where);
-                                               $object->_reconstituteProperty($columnMap->getPropertyName(), $relatedObjects);
-                                       } elseif ($columnMap->getTypeOfRelation() === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY) {
-                                               $relatedObjects = $this->fetchWithRelationTable($object, $columnMap);
-                                               $object->_reconstituteProperty($columnMap->getPropertyName(), $relatedObjects);
-                                       }
-                               }
-                               $object->_memorizeCleanState();
-                               $this->identityMap->registerObject($object, $properties['uid']);
-                       }
-
-                       $objects[] = $object;
-               }
-               return $objects;
-       }
-
-       /**
-        * Returns an array of properties with the property name as key and the converted property value as value.
-        *
-        * @param Tx_Extbase_Persistence_Mapper_DataMap $dataMap The data map of the target object
-        * @param string $fieldMap the field map of the related database table.
-        * @param array $row The row to be mapped on properties
-        * @return void
-        */
-       protected function getProperties(Tx_Extbase_Persistence_Mapper_DataMap $dataMap, array &$fieldMap, array &$row) {
-               $properties = array();
-               foreach ($dataMap->getColumnMaps() as $columnMap) {
-                       $properties[$columnMap->getPropertyName()] = $dataMap->convertFieldValueToPropertyValue($columnMap->getPropertyName(), $row[$columnMap->getColumnName()]);
-               }
-               return $properties;
-       }
-
-       /**
-        * Reconstitutes the specified object and fills it with the given properties.
-        *
-        * @param string $objectName Name of the object to reconstitute
-        * @param array $properties The names of properties and their values which should be set during the reconstitution
-        * @return object The reconstituted object
-        */
-       public function reconstituteObject($className, array $properties = array()) {
-               // those objects will be fetched from within the __wakeup() method of the object...
-               $GLOBALS['Extbase']['reconstituteObject']['properties'] = $properties;
-               $object = unserialize('O:' . strlen($className) . ':"' . $className . '":0:{};');
-               unset($GLOBALS['Extbase']['reconstituteObject']);
-               return $object;
-       }
-       
-       /**
-        * Replaces the given object by the second object.
-        *
-        * This method will unregister the existing object at the identity map and
-        * register the new object instead. The existing object must therefore
-        * already be registered at the identity map which is the case for all
-        * reconstituted objects.
-        *
-        * The new object will be identified by the uuid which formerly belonged
-        * to the existing object. The existing object looses its uuid.
-        *
-        * @param object $existingObject The existing object
-        * @param object $newObject The new object
-        * @return void
-        */
-       public function replaceObject($existingObject, $newObject) {
-               $existingUID = $existingObject->getUid();
-               if ($existingUID === NULL) throw new Tx_Extbase_Persistence_Exception_UnknownObjectException('The given object is unknown to this persistence backend.', 1238070163);
-
-               $this->identityMap->unregisterObject($existingObject);
-               $this->identityMap->registerObject($newObject, $existingUID);
-       }
-
-       /**
-        * Create a database entry for all aggregate roots first, then traverse object graph.
-        *
-        * @return void
-        */
-       public function persistObjects() {
-               foreach ($this->aggregateRootObjects as $object) {
-                       $this->persistObject($object);
-               }
-       }
-
-       /**
-        * Inserts an object's corresdponding row into the database. If the object is a value object an
-        * existing instance will be looked up.
-        *
-        * @param Tx_Extbase_DomainObject_DomainObjectInterface $object The object to be inserted
-        * @param Tx_Extbase_DomainObject_DomainObjectInterface $parentObject The parent object
-        * @param string $parentPropertyName The name of the property the object is stored in
-        * @return void
-        */
-       protected function persistObject($object, $parentObject = NULL, $parentPropertyName = NULL, $processQueue = TRUE) {
-               $queue = array();
-               $className = get_class($object);
-               $dataMap = $this->getDataMap($className);
-               $properties = $object->_getProperties();
-
-               if ($object instanceof Tx_Extbase_DomainObject_AbstractValueObject) {
-                       $conditions = $properties;
-                       unset($conditions['uid']);
-                       $where = $this->buildQuery($className, $conditions);
-                       $existingValueObjects = $this->fetch($className, $where);
-                       if (count($existingValueObjects) > 0) {
-                               $existingObject = $existingValueObjects[0];
-                               $object->_reconstituteProperty('uid', $existingObject->getUid());
-                       }
-               }
-
-               foreach ($properties as $propertyName => $propertyValue) {
-                       
-                       // if a LazyLoadingProxy has not been activated, it can neither
-                       // be new nor dirty...
-                       if ($propertyValue instanceof Tx_Extbase_Persistence_LazyLoadingProxy) {
-                               continue;
-                       }
-
-                       $columnMap = $dataMap->getColumnMap($propertyName);
-                       $columnName = $columnMap->getColumnName();
-                       if ($dataMap->isPersistableProperty($propertyName) && ($object->_isNew() || $object->_isDirty($propertyName))) {
-                               if ($columnMap->isRelation()) {
-                                       if (($columnMap->getTypeOfRelation() === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_MANY) || ($columnMap->getTypeOfRelation() === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY)) {
-                                               $row[$columnName] = count($properties[$propertyName]);
-                                               foreach ($propertyValue as $containedObject) {
-                                                       $queue[] = array($propertyName => $containedObject);
-                                               }
-                                       } elseif ($columnMap->getTypeOfRelation() === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_ONE) {
-                                               $queue[] = array($propertyName => $propertyValue);
-                                       }
-                               } else {
-                                       $row[$columnName] = $dataMap->convertPropertyValueToFieldValue($properties[$propertyName], FALSE);
-                               }
-                       }
-               }
-
-               if ($object->_isNew()) {
-                       $this->insertObject($object, $parentObject, $parentPropertyName, $row);
-               } elseif ($object->_isDirty()) {
-                       $this->updateObject($object, $parentObject, $parentPropertyName, $row);
-               }
-
-               if ($parentObject instanceof Tx_Extbase_DomainObject_DomainObjectInterface && !empty($parentPropertyName)) {
-                       $parentClassName = get_class($parentObject);
-                       $parentDataMap = $this->getDataMap($parentClassName);
-                       $parentColumnMap = $parentDataMap->getColumnMap($parentPropertyName);
-
-                       if (($parentColumnMap->getTypeOfRelation()  === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY)) {
-                               $this->insertRelation($object, $parentObject, $parentPropertyName);
-                       }
-               }
-
-               if ($object instanceof Tx_Extbase_DomainObject_AbstractEntity) {
-                       $object->_memorizeCleanState();
-               }
-               if ($processQueue === TRUE) {
-                       foreach ($queue as $queuedObjects) {
-                               foreach($queuedObjects as $propertyName => $queuedObject) {
-                                       $this->persistObject($queuedObject, $object, $propertyName);
-                               }
-                       }
-               }
-
-       }
-
-       protected function insertObject(Tx_Extbase_DomainObject_DomainObjectInterface $object, $parentObject = NULL, $parentPropertyName = NULL, array &$row) {
-               $className = get_class($object);
-               $dataMap = $this->getDataMap($className);
-               $tableName = $dataMap->getTableName();
-               $this->addCommonFieldsToRow($object, $parentObject, $parentPropertyName, $row);
-               $res = $this->persistenceBackend->exec_INSERTquery(
-                       $tableName,
-                       $row
-                       );
-               $uid = $this->persistenceBackend->sql_insert_id();
-               $object->_reconstituteProperty('uid', $uid);
-               $this->referenceIndex->updateRefIndexTable($tableName, $uid);
-       }
-
-       /**
-        * Inserts relation into a relation table
-        *
-        * @param Tx_Extbase_DomainObject_DomainObjectInterface $relatedObject The related object
-        * @param Tx_Extbase_DomainObject_DomainObjectInterface $parentObject The parent object
-        * @param string $parentPropertyName The name of the parent object's property where the related objects are stored in
-        * @return void
-        */
-       protected function insertRelation(Tx_Extbase_DomainObject_DomainObjectInterface $relatedObject, Tx_Extbase_DomainObject_DomainObjectInterface $parentObject, $parentPropertyName) {
-               $dataMap = $this->getDataMap(get_class($parentObject));
-               $rowToInsert = array(
-                       'uid_local' => $parentObject->getUid(),
-                       'uid_foreign' => $relatedObject->getUid(),
-                       'tablenames' => $dataMap->getTableName(),
-                       'sorting' => 9999 // TODO sorting of mm table items
-                       );
-               $tableName = $dataMap->getColumnMap($parentPropertyName)->getRelationTableName();
-               $res = $this->persistenceBackend->exec_INSERTquery(
-                       $tableName,
-                       $rowToInsert
-                       );
-       }
-
-       protected function updateObject(Tx_Extbase_DomainObject_DomainObjectInterface $object, $parentObject = NULL, $parentPropertyName = NULL, array &$row) {
-               $className = get_class($object);
-               $dataMap = $this->getDataMap($className);
-               $tableName = $dataMap->getTableName();
-               $this->addCommonFieldsToRow($object, $parentObject, $parentPropertyName, $row);
-               $uid = $object->getUid();
-               $res = $this->persistenceBackend->exec_UPDATEquery(
-                       $tableName,
-                       'uid=' . intval($uid),
-                       $row
-                       );
-               $this->referenceIndex->updateRefIndexTable($tableName, $uid);
-       }
-
-       /**
-        * Returns a table row to be inserted or updated in the database
-        *
-        * @param Tx_Extbase_Persistence_Mapper_DataMap $dataMap The appropriate data map representing a database table
-        * @param array $properties The properties of the object
-        * @return array A single row to be inserted in the database
-        */
-       protected function addCommonFieldsToRow(Tx_Extbase_DomainObject_DomainObjectInterface $object, $parentObject = NULL, $parentPropertyName = NULL, array &$row) {
-               $className = get_class($object);
-               $dataMap = $this->getDataMap($className);
-               if ($dataMap->hasCreationDateColumn()) {
-                       $row[$dataMap->getCreationDateColumnName()] = time();
-               }
-               if ($dataMap->hasTimestampColumn()) {
-                       $row[$dataMap->getTimestampColumnName()] = time();
-               }
-               if ($dataMap->hasPidColumn()) {
-                       // TODO  Should we merge the settings from $this->cObj into the extension settings (in the dispatcher)
-                       $row['pid'] = !empty($this->cObj->data['pages']) ? $this->cObj->data['pages'] : $GLOBALS['TSFE']->id;
-               }
-               if ($parentObject instanceof Tx_Extbase_DomainObject_DomainObjectInterface && !empty($parentPropertyName)) {
-                       $parentDataMap = $this->getDataMap(get_class($parentObject));
-                       $parentColumnMap = $parentDataMap->getColumnMap($parentPropertyName);
-                       $parentKeyFieldName = $parentColumnMap->getParentKeyFieldName();
-                       if ($parentKeyFieldName !== NULL) {
-                               $row[$parentKeyFieldName] = $parentObject->getUid();
-                       }
-                       $parentTableFieldName = $parentColumnMap->getParentTableFieldName();
-                       if ($parentTableFieldName !== NULL) {
-                               $row[$parentTableFieldName] = $parentDataMap->getTableName();
-                       }
-               }
-       }
-
-       /**
-        * Returns all property values holding child objects
-        *
-        * @param Tx_Extbase_Persistence_Mapper_DataMap $dataMap The data map
-        * @param string $properties The object properties
-        * @return array An array of properties with related child objects
-        */
-       protected function getRelations(Tx_Extbase_DomainObject_DomainObjectInterface $object) {
-               $className = get_class($object);
-               $dataMap = $this->getDataMap($className);
-               $properties = $object->_getProperties();
-               $relations = array();
-               foreach ($dataMap->getColumnMaps() as $columnMap) {
-                       $propertyName = $columnMap->getPropertyName();
-                       if ($columnMap->isRelation()) {
-                               $relations[$propertyName] = $properties[$propertyName];
-                       }
-               }
-               return $relations;
-       }
-
-       /**
-        * Inserts and updates all relations of an object. It also inserts and updates data in relation tables.
-        *
-        * @param Tx_Extbase_DomainObject_DomainObjectInterface $object The object for which the relations should be updated
-        * @param string $propertyName The name of the property holding the related child objects
-        * @param array $relations The queued relations
-        * @return void
-        */
-       protected function persistRelations(Tx_Extbase_DomainObject_DomainObjectInterface $object, $propertyName, array $relations) {
-               $dataMap = $this->getDataMap(get_class($object));
-               foreach ($relations as $propertyName => $relatedObjects) {
-                       if (!empty($relatedObjects)) {
-                               $typeOfRelation = $dataMap->getColumnMap($propertyName)->getTypeOfRelation();
-                               foreach ($relatedObjects as $relatedObject) {
-                                       if ($relatedObject->_isNew()) {
-                                               $this->persistObject($relatedObject, $object, $propertyName);
-                                               if ($typeOfRelation === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY) {
-                                                       $this->insertRelationInRelationTable($relatedObject, $object, $propertyName);
-                                               }
-                                       } elseif ($relatedObject->_isDirty()) {
-                                               $this->persistObject($relatedObject, $object, $propertyName);
-                                       }
-                               }
-                       }
-               }
-       }
-
-       public function processDeletedObjects() {
-               foreach ($this->deletedObjects as $object) {
-                       $this->deleteObject($object);
-               }
-       }
-
-       /**
-        * Deletes an object, it's 1:n related objects, and the m:n relations in relation tables (but not the m:n related objects!)
-        *
-        * @return void
-        */
-       protected function deleteObject(Tx_Extbase_DomainObject_DomainObjectInterface $object, $parentObject = NULL, $parentPropertyName = NULL, $recurseIntoRelations = TRUE, $onlySetDeleted = TRUE) {
-               $properties = $object->_getProperties();
-               $dataMap = $this->getDataMap(get_class($object));
-
-               $tableName = $dataMap->getTableName();
-               if ($onlySetDeleted === TRUE && $dataMap->hasDeletedColumn()) {
-                       $deletedColumnName = $dataMap->getDeletedColumnName();
-                       $res = $this->persistenceBackend->exec_UPDATEquery(
-                               $tableName,
-                               'uid=' . intval($object->getUid()), // FIXME If an object is localized the original version gets deleted; this must be solved in the overlay method
-                               array($deletedColumnName => 1)
-                               );
-               } else {
-                       $res = $this->persistenceBackend->exec_DELETEquery(
-                               $tableName,
-                               'uid=' . intval($object->getUid())
-                               );
-               }
-               $this->referenceIndex->updateRefIndexTable($tableName, $uid);
-       }
-
-       /**
-        * Deletes all relations of an object.
-        *
-        * @param Tx_Extbase_DomainObject_DomainObjectInterface $object The object for which the relations should be updated
-        * @param string $propertyName The name of the property holding the related child objects
-        * @param array $relations The queued relations
-        * @return void
-        */
-       protected function deleteRelatedObjects(Tx_Extbase_DomainObject_DomainObjectInterface $object, array $relations) {
-               $dataMap = $this->getDataMap(get_class($object));
-               foreach ($relations as $propertyName => $relatedObjects) {
-                       if (is_array($relatedObjects)) {
-                               foreach ($relatedObjects as $relatedObject) {
-                                       $this->deleteObject($relatedObject, $object, $propertyName);
-                                       if ($dataMap->getColumnMap($propertyName)->getTypeOfRelation() === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY) {
-                                               $this->deleteRelationInRelationTable($relatedObject, $object, $propertyName);
-                                       }
-                               }
-                       }
-               }
-       }
-
-       /**
-        * Update relations in a relation table
-        *
-        * @param array $relatedObjects An array of related objects
-        * @param Tx_Extbase_DomainObject_DomainObjectInterface $parentObject The parent object
-        * @param string $parentPropertyName The name of the parent object's property where the related objects are stored in
-        * @return void
-        */
-       protected function deleteRelationInRelationTable($relatedObject, Tx_Extbase_DomainObject_DomainObjectInterface $parentObject, $parentPropertyName) {
-               $dataMap = $this->getDataMap(get_class($parentObject));
-               $tableName = $dataMap->getColumnMap($parentPropertyName)->getRelationTableName();
-               $res = $this->persistenceBackend->exec_SELECTquery(
-                       'uid_foreign',
-                       $tableName,
-                       'uid_local=' . $parentObject->getUid()
-                       );
-               $existingRelations = array();
-               while($row = $this->persistenceBackend->sql_fetch_assoc($res)) {
-                       $existingRelations[current($row)] = current($row);
-               }
-               $relationsToDelete = $existingRelations;
-               if (is_array($relatedObject)) {
-                       foreach ($relatedObject as $relatedObject) {
-                               $relatedObjectUid = $relatedObject->getUid();
-                               if (array_key_exists($relatedObjectUid, $relationsToDelete)) {
-                                       unset($relationsToDelete[$relatedObjectUid]);
-                               }
-                       }
-               }
-               if (count($relationsToDelete) > 0) {
-                       $relationsToDeleteList = implode(',', $relationsToDelete);
-                       $res = $this->persistenceBackend->exec_DELETEquery(
-                               $tableName,
-                               'uid_local=' . $parentObject->getUid() . ' AND uid_foreign IN (' . $relationsToDeleteList . ')'
-                               );
-               }
-       }
-
-       /**
-        * Delegates the call to the Data Map.
-        * Returns TRUE if the property is persistable (configured in $TCA)
-        *
-        * @param string $className The property name
-        * @param string $propertyName The property name
-        * @return boolean TRUE if the property is persistable (configured in $TCA)
-        */
-       public function isPersistableProperty($className, $propertyName) {
-               $dataMap = $this->getDataMap($className);
-               return $dataMap->isPersistableProperty($propertyName);
-       }
-
-       /**
-        * Returns a data map for a given class name
-        *
-        * @return Tx_Extbase_Persistence_Mapper_DataMap The data map
-        */
-       public function getDataMap($className) {
-               if (empty($this->dataMaps[$className])) {
-                       // TODO This is a little bit costy for table name aliases -> implement a DataMapBuilder (knowing the aliases defined in $TCA)
-                       $dataMap = new Tx_Extbase_Persistence_Mapper_DataMap($className);
-                       $this->dataMaps[$className] = $dataMap;
-               }
-               return $this->dataMaps[$className];
-       }
-
-}
-?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/PreparedQuery.php b/typo3/sysext/extbase/Classes/Persistence/PreparedQuery.php
new file mode 100644 (file)
index 0000000..d479cab
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * A prepared query. A new prepared query is created by calling
+ * QueryManager->createPreparedQuery.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: PreparedQuery.php 2120 2009-04-02 10:06:31Z k-fish $
+ * @scope prototype
+ */
+class Tx_Extbase_Persistence_PreparedQuery extends Tx_Extbase_Persistence_Query implements Tx_Extbase_Persistence_PreparedQueryInterface {
+
+       /**
+        * @var array
+        */
+       protected $boundVariables = array();
+
+       /**
+        * Binds the given value to the variable named $varName.
+        *
+        * @param string $varName name of variable in query
+        * @param Tx_Extbase_Persistence_ValueInterface $value value to bind
+        * @return void
+        * @throws InvalidArgumentException if $varName is not a valid variable in this query.
+        * @throws RepositoryException if an error occurs.
+        */
+       public function bindValue($varName, Tx_Extbase_Persistence_ValueInterface $value) {
+               if (array_key_exists($varName, $this->boundVariables) === FALSE) {
+                       throw new InvalidArgumentException('Invalid variable name "' . $varName . '" given to bindValue.', 1217241834);
+               }
+               $this->boundVariables[$varName] = $value->getString();
+       }
+
+       /**
+        * Returns the values of all bound variables.
+        *
+        * @return array()
+        */
+       public function getBoundVariableValues() {
+               return $this->boundVariables;
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/PreparedQueryInterface.php b/typo3/sysext/extbase/Classes/Persistence/PreparedQueryInterface.php
new file mode 100644 (file)
index 0000000..e7934f4
--- /dev/null
@@ -0,0 +1,51 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * A prepared query. A new prepared query is created by calling
+ * QueryManager->createPreparedQuery.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: PreparedQueryInterface.php 1811 2009-01-28 12:04:49Z robert $
+ */
+interface Tx_Extbase_Persistence_PreparedQueryInterface extends Tx_Extbase_Persistence_QueryInterface {
+
+       /**
+        * Binds the given value to the variable named $varName.
+        *
+        * @param string $varName name of variable in query
+        * @param Tx_Extbase_Persistence_ValueInterface $value value to bind
+        * @return void
+        * @throws InvalidArgumentException if $varName is not a valid variable in this query.
+        * @throws RepositoryException if an error occurs.
+        */
+       public function bindValue($varName, Tx_Extbase_Persistence_ValueInterface $value);
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/PropertyType.php b/typo3/sysext/extbase/Classes/Persistence/PropertyType.php
new file mode 100644 (file)
index 0000000..362428b
--- /dev/null
@@ -0,0 +1,354 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * The property types supported by the JCR standard.
+ *
+ * The STRING property type is used to store strings.
+ * BINARY properties are used to store binary data.
+ * The LONG property type is used to store integers.
+ * The DECIMAL property type is used to store precise decimal numbers.
+ * The DOUBLE property type is used to store floating point numbers.
+ * The DATE property type is used to store time and date information. See 4.2.6.1 Date in the specification.
+ * The BOOLEAN property type is used to store boolean values.
+ * A NAME is a pairing of a namespace and a local name. When read, the namespace is mapped to the current prefix. See 4.2.6.2 Name in the specification.
+ * A PATH property is an ordered list of path elements. A path element is a NAME with an optional index. When read, the NAMEs within the path are mapped to their current prefix. A path may be absolute or relative. See 4.2.6.3 Path in the specification.
+ * A REFERENCE property stores the identifier of a referenceable node (one having type mix:referenceable), which must exist within the same workspace or session as the REFERENCE property. A REFERENCE property enforces this referential integrity by preventing (in level 2 implementations) the removal of its target node. See 4.2.6.4 Reference in the specification.
+ * A WEAKREFERENCE property stores the identifier of a referenceable node (one having type mix:referenceable). A WEAKREFERENCE property does not enforce referential integrity. See 4.2.6.5 Weak Reference in the specification.
+ * A URI property is identical to STRING property except that it only accepts values that conform to the syntax of a URI-reference as defined in RFC 3986. See also 4.2.6.6 URI in the specification.
+ * UNDEFINED can be used within a property definition (see 4.7.5 Property Definitions) to specify that the property in question may be of any type. However, it cannot be the actual type of any property instance. For example it will never be returned by Property.getType() and (in level 2 implementations) it cannot be assigned as the type when creating a new property.
+ *
+ * @package Extbase
+ * @version $Id: PropertyType.php 1818 2009-01-28 16:46:59Z k-fish $
+ */
+final class Tx_Extbase_Persistence_PropertyType {
+
+       /**
+        * This constant can be used within a property definition to specify that
+        * the property in question may be of any type.
+        * However, it cannot be the actual type of any property instance. For
+        * example, it will never be returned by Property#getType and it cannot be
+        * assigned as the type when creating a new property.
+        */
+       const UNDEFINED = 0;
+
+       /**
+        * The STRING property type is used to store strings.
+        */
+       const STRING = 1;
+
+       /**
+        * BINARY properties are used to store binary data.
+        */
+       const BINARY = 2;
+
+       /**
+        * The LONG property type is used to store integers.
+        */
+       const LONG = 3;
+
+       /**
+        * The DOUBLE property type is used to store floating point numbers.
+        */
+       const DOUBLE = 4;
+
+       /**
+        * The DATE property type is used to store time and date information.
+        */
+       const DATE = 5;
+
+       /**
+        * The BOOLEAN property type is used to store boolean values.
+        */
+       const BOOLEAN = 6;
+
+       /**
+        * A NAME is a pairing of a namespace and a local name. When read, the
+        * namespace is mapped to the current prefix.
+        */
+       const NAME = 7;
+
+       /**
+        * A PATH property is an ordered list of path elements. A path element is a
+        * NAME with an optional index. When read, the NAMEs within the path are
+        * mapped to their current prefix. A path may be absolute or relative.
+        */
+       const PATH = 8;
+
+       /**
+        * A REFERENCE property stores the identifier of a referenceable node (one
+        * having type mix:referenceable), which must exist within the same
+        * workspace or session as the REFERENCE property. A REFERENCE property
+        * enforces this referential integrity by preventing the removal of its
+        * target node.
+        */
+       const REFERENCE = 9;
+
+       /**
+        * A WEAKREFERENCE property stores the identifier of a referenceable node
+        * (one having type mix:referenceable). A WEAKREFERENCE property does not
+        * enforce referential integrity.
+        */
+       const WEAKREFERENCE = 10;
+
+       /**
+        * A URI property is identical to STRING property except that it only
+        * accepts values that conform to the syntax of a URI-reference as defined
+        * in RFC 3986.
+        */
+       const URI = 11;
+
+       /**
+        * The DECIMAL property type is used to store precise decimal numbers.
+        */
+       const DECIMAL = 12;
+
+       /**
+        * The INTEGER property type is used to store precise decimal numbers.
+        */
+       const INTEGER = 13;
+
+       /**
+        * String constant for type name as used in serialization.
+        */
+       const TYPENAME_UNDEFINED = 'undefined';
+
+       /**
+        * String constant for type name as used in serialization.
+        */
+       const TYPENAME_STRING = 'String';
+
+       /**
+        * String constant for type name as used in serialization.
+        */
+       const TYPENAME_BINARY = 'Binary';
+
+       /**
+        * String constant for type name as used in serialization.
+        */
+       const TYPENAME_LONG = 'Long';
+
+       /**
+        * String constant for type name as used in serialization.
+        */
+       const TYPENAME_DOUBLE = 'Double';
+
+       /**
+        * String constant for type name as used in serialization.
+        */
+       const TYPENAME_DATE = 'Date';
+
+       /**
+        * String constant for type name as used in serialization.
+        */
+       const TYPENAME_BOOLEAN = 'Boolean';
+
+       /**
+        * String constant for type name as used in serialization.
+        */
+       const TYPENAME_NAME = 'Name';
+
+       /**
+        * String constant for type name as used in serialization.
+        */
+       const TYPENAME_PATH = 'Path';
+
+       /**
+        * String constant for type name as used in serialization.
+        */
+       const TYPENAME_REFERENCE = 'Reference';
+
+       /**
+        * String constant for type name as used in serialization.
+        */
+       const TYPENAME_WEAKREFERENCE = 'WeakReference';
+
+       /**
+        * String constant for type name as used in serialization.
+        */
+       const TYPENAME_URI= 'URI';
+
+       /**
+        * String constant for type name as used in serialization.
+        */
+       const TYPENAME_DECIMAL = 'Decimal';
+
+       /**
+        * String constant for type name as used in serialization.
+        */
+       const TYPENAME_INTEGER = 'Integer';
+
+       /**
+        * Make instantiation impossible...
+        *
+        * @return void
+        */
+       private function __construct() {}
+
+       /**
+        * Returns the name of the specified type, as used in serialization.
+        *
+        * @param integer $type type the property type
+        * @return string  name of the specified type
+        */
+       static public function nameFromValue($type) {
+               switch (intval($type)) {
+                       case self::UNDEFINED :
+                               return self::TYPENAME_UNDEFINED;
+                               break;
+                       case self::STRING :
+                               return self::TYPENAME_STRING;
+                               break;
+                       case self::BINARY :
+                               return self::TYPENAME_BINARY;
+                               break;
+                       case self::BOOLEAN :
+                               return self::TYPENAME_BOOLEAN;
+                               break;
+                       case self::LONG :
+                               return self::TYPENAME_LONG;
+                               break;
+                       case self::DOUBLE :
+                               return self::TYPENAME_DOUBLE;
+                               break;
+                       case self::DECIMAL :
+                               return self::TYPENAME_DECIMAL;
+                               break;
+                       case self::INTEGER :
+                               return self::TYPENAME_INTEGER;
+                               break;
+                       case self::DATE :
+                               return self::TYPENAME_DATE;
+                               break;
+                       case self::NAME :
+                               return self::TYPENAME_NAME;
+                               break;
+                       case self::PATH :
+                               return self::TYPENAME_PATH;
+                               break;
+                       case self::REFERENCE :
+                               return self::TYPENAME_REFERENCE;
+                               break;
+                       case self::WEAKREFERENCE :
+                               return self::TYPENAME_WEAKREFERENCE;
+                               break;
+                       case self::URI :
+                               return self::TYPENAME_URI;
+                               break;
+               }
+       }
+
+
+       /**
+        * Returns the numeric constant value of the type with the specified name.
+        *
+        * @param string $name The name of the property type
+        * @return int The numeric constant value
+        */
+       static public function valueFromName($name) {
+               switch ($name) {
+                       case self::TYPENAME_UNDEFINED :
+                               return self::UNDEFINED;
+                               break;
+                       case self::TYPENAME_STRING :
+                               return self::STRING;
+                               break;
+                       case self::TYPENAME_BINARY :
+                               return self::BINARY;
+                               break;
+                       case self::TYPENAME_LONG :
+                               return self::LONG;
+                               break;
+                       case self::TYPENAME_DOUBLE :
+                               return self::DOUBLE;
+                               break;
+                       case self::TYPENAME_DECIMAL :
+                               return self::DECIMAL;
+                               break;
+                       case self::TYPENAME_INTEGER :
+                               return self::INTEGER;
+                               break;
+                       case self::TYPENAME_DATE :
+                               return self::DATE;
+                               break;
+                       case self::TYPENAME_BOOLEAN :
+                               return self::BOOLEAN;
+                               break;
+                       case self::TYPENAME_NAME :
+                               return self::NAME;
+                               break;
+                       case self::TYPENAME_PATH :
+                               return self::PATH;
+                               break;
+                       case self::TYPENAME_REFERENCE :
+                               return self::REFERENCE;
+                               break;
+                       case self::TYPENAME_WEAKREFERENCE :
+                               return self::WEAKREFERENCE;
+                               break;
+                       case self::TYPENAME_URI :
+                               return self::URI;
+                               break;
+               }
+       }
+
+       /**
+        * Returns the numeric constant value of the type for the given PHP type
+        * name as returned by gettype().
+        *
+        * @param string $type
+        * @return integer
+        */
+       static public function valueFromType($type) {
+               switch (strtolower($type)) {
+                       case 'string':
+                               return Tx_Extbase_Persistence_PropertyType::STRING;
+                               break;
+                       case 'boolean':
+                               return Tx_Extbase_Persistence_PropertyType::BOOLEAN;
+                               break;
+                       case 'integer':
+                               return Tx_Extbase_Persistence_PropertyType::LONG;
+                               break;
+                       case 'float':
+                       case 'double':
+                               return Tx_Extbase_Persistence_PropertyType::DOUBLE;
+                               break;
+                       case 'integer':
+                       case 'int':
+                               return Tx_Extbase_Persistence_PropertyType::INTEGER;
+                               break;
+                       case 'datetime':
+                               return Tx_Extbase_Persistence_PropertyType::DATE;
+                               break;
+                       default:
+                               return Tx_Extbase_Persistence_PropertyType::UNDEFINED;
+               }
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/AndInterface.php b/typo3/sysext/extbase/Classes/Persistence/QOM/AndInterface.php
new file mode 100644 (file)
index 0000000..eecd729
--- /dev/null
@@ -0,0 +1,56 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Performs a logical conjunction of two other constraints.
+ *
+ * To satisfy the And constraint, a node-tuple must satisfy both constraint1 and
+ * constraint2.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: AndInterface.php 1811 2009-01-28 12:04:49Z robert $
+ */
+interface Tx_Extbase_Persistence_QOM_AndInterface extends Tx_Extbase_Persistence_QOM_ConstraintInterface {
+
+       /**
+        * Gets the first constraint.
+        *
+        * @return Tx_Extbase_Persistence_QOM_ConstraintInterface the constraint; non-null
+        */
+       public function getConstraint1();
+
+       /**
+        * Gets the second constraint.
+        *
+        * @return Tx_Extbase_Persistence_QOM_ConstraintInterface the constraint; non-null
+        */
+       public function getConstraint2();
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/BindVariableValue.php b/typo3/sysext/extbase/Classes/Persistence/QOM/BindVariableValue.php
new file mode 100644 (file)
index 0000000..8283cc0
--- /dev/null
@@ -0,0 +1,74 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Evaluates to the value of a bind variable.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: BindVariableValue.php 1877 2009-02-05 11:29:07Z k-fish $
+ * @scope prototype
+ */
+class Tx_Extbase_Persistence_QOM_BindVariableValue extends Tx_Extbase_Persistence_QOM_StaticOperand implements Tx_Extbase_Persistence_QOM_BindVariableValueInterface {
+
+       /**
+        * @var string
+        */
+       protected $variableName;
+
+       /**
+        * Constructs this BindVariableValue instance
+        *
+        * @param string $variableName
+        */
+       public function __construct($variableName) {
+               $this->variableName = $variableName;
+       }
+
+       /**
+        * Fills an array with the names of all bound variables in the operand
+        *
+        * @param array &$boundVariables
+        * @return void
+        */
+       public function collectBoundVariableNames(&$boundVariables) {
+               $boundVariables[$this->variableName] = NULL;
+       }
+
+
+       /**
+        * Gets the name of the bind variable.
+        *
+        * @return string the bind variable name; non-null
+        */
+       public function getBindVariableName() {
+               return $this->variableName;
+       }
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/BindVariableValueInterface.php b/typo3/sysext/extbase/Classes/Persistence/QOM/BindVariableValueInterface.php
new file mode 100644 (file)
index 0000000..98fb88c
--- /dev/null
@@ -0,0 +1,47 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Evaluates to the value of a bind variable.
+ *
+ * @package Extbase
+ * @subpackage PErsistence
+ * @version $Id: BindVariableValueInterface.php 1811 2009-01-28 12:04:49Z robert $
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ */
+interface Tx_Extbase_Persistence_QOM_BindVariableValueInterface extends Tx_Extbase_Persistence_QOM_StaticOperandInterface {
+
+       /**
+        * Gets the name of the bind variable.
+        *
+        * @return string the bind variable name; non-null
+        */
+       public function getBindVariableName();
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/ChildNodeJoinCondition.php b/typo3/sysext/extbase/Classes/Persistence/QOM/ChildNodeJoinCondition.php
new file mode 100644 (file)
index 0000000..5bbb2ab
--- /dev/null
@@ -0,0 +1,84 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Tests whether the childSelector node is a child of the parentSelector node. A
+ * node-tuple satisfies the constraint only if:
+ * childSelectorNode.getParent().isSame(parentSelectorNode)
+ * would return true, where childSelectorNode is the node for childSelector and
+ * parentSelectorNode is the node for parentSelector.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: ChildNodeJoinCondition.php 2011 2009-03-18 14:22:24Z k-fish $
+ * @scope prototype
+ */
+class Tx_Extbase_Persistence_QOM_ChildNodeJoinCondition implements Tx_Extbase_Persistence_QOM_ChildNodeJoinConditionInterface {
+
+       /**
+        * @var string
+        */
+       protected $childSelectorName;
+
+       /**
+        * @var string
+        */
+       protected $parentSelectorName;
+
+       /**
+        * Constructs this ChildNodeJoinCondition instance
+        *
+        * @param Tx_Extbase_Persistence_QOM_DynamicOperandInterface $operand1
+        * @param Tx_Extbase_Persistence_QOM_StaticOperandInterface $operand2
+        */
+       public function __construct($childSelectorName, $parentSelectorName) {
+               $this->childSelectorName = $childSelectorName;
+               $this->parentSelectorName = $parentSelectorName;
+       }
+
+       /**
+        * Gets the name of the child selector.
+        *
+        * @return string the selector name; non-null
+        */
+       public function getChildSelectorName() {
+               return $this->childSelectorName;
+       }
+
+       /**
+        * Gets the name of the parent selector.
+        *
+        * @return string the selector name; non-null
+        */
+       public function getParentSelectorName() {
+               return $this->parentSelectorName;
+       }
+
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/ChildNodeJoinConditionInterface.php b/typo3/sysext/extbase/Classes/Persistence/QOM/ChildNodeJoinConditionInterface.php
new file mode 100644 (file)
index 0000000..57192b7
--- /dev/null
@@ -0,0 +1,57 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Tests whether the childSelector node is a child of the parentSelector node. A
+ * node-tuple satisfies the constraint only if:
+ *  childSelectorNode.getParent().isSame(parentSelectorNode)
+ * would return true, where childSelectorNode is the node for childSelector and
+ * parentSelectorNode is the node for parentSelector.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: ChildNodeJoinConditionInterface.php 1979 2009-03-09 15:44:15Z k-fish $
+ */
+interface Tx_Extbase_Persistence_QOM_ChildNodeJoinConditionInterface extends Tx_Extbase_Persistence_QOM_JoinConditionInterface {
+
+       /**
+        * Gets the name of the child selector.
+        *
+        * @return string the selector name; non-null
+        */
+       public function getChildSelectorName();
+
+       /**
+        * Gets the name of the parent selector.
+        *
+        * @return string the selector name; non-null
+        */
+       public function getParentSelectorName();
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/Comparison.php b/typo3/sysext/extbase/Classes/Persistence/QOM/Comparison.php
new file mode 100644 (file)
index 0000000..820986a
--- /dev/null
@@ -0,0 +1,146 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Filters node-tuples based on the outcome of a binary operation.
+ *
+ * For any comparison, operand2 always evaluates to a scalar value. In contrast,
+ * operand1 may evaluate to an array of values (for example, the value of a multi-valued
+ * property), in which case the comparison is separately performed for each element
+ * of the array, and the Comparison constraint is satisfied as a whole if the
+ * comparison against any element of the array is satisfied.
+ *
+ * If operand1 and operand2 evaluate to values of different property types, the
+ * value of operand2 is converted to the property type of the value of operand1.
+ * If the type conversion fails, the query is invalid.
+ *
+ * If operator is not supported for the property type of operand1, the query is invalid.
+ *
+ * If operand1 evaluates to null (for example, if the operand evaluates the value
+ * of a property which does not exist), the constraint is not satisfied.
+ *
+ * The JCR_OPERATOR_EQUAL_TO operator is satisfied only if the value of operand1
+ * equals the value of operand2.
+ *
+ * The JCR_OPERATOR_NOT_EQUAL_TO operator is satisfied unless the value of
+ * operand1 equals the value of operand2.
+ *
+ * The JCR_OPERATOR_LESSS_THAN operator is satisfied only if the value of
+ * operand1 is ordered before the value of operand2.
+ *
+ * The JCR_OPERATOR_LESS_THAN_OR_EQUAL_TO operator is satisfied unless the value
+ * of operand1 is ordered after the value of operand2.
+ *
+ * The JCR_OPERATOR_GREATER_THAN operator is satisfied only if the value of
+ * operand1 is ordered after the value of operand2.
+ *
+ * The JCR_OPERATOR_GREATER_THAN_OR_EQUAL_TO operator is satisfied unless the
+ * value of operand1 is ordered before the value of operand2.
+ *
+ * The JCR_OPERATOR_LIKE operator is satisfied only if the value of operand1
+ * matches the pattern specified by the value of operand2, where in the pattern:
+ * * the character "%" matches zero or more characters, and
+ * * the character "_" (underscore) matches exactly one character, and
+ * * the string "\x" matches the character "x", and
+ *   all other characters match themselves.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: Comparison.php 2191 2009-05-07 19:49:06Z k-fish $
+ * @scope prototype
+ */
+class Tx_Extbase_Persistence_QOM_Comparison implements Tx_Extbase_Persistence_QOM_ComparisonInterface {
+
+       /**
+        * @var Tx_Extbase_Persistence_QOM_DynamicOperandInterface
+        */
+       protected $operand1;
+
+       /**
+        * @var integer
+        */
+       protected $operator;
+
+       /**
+        * @var Tx_Extbase_Persistence_QOM_StaticOperandInterface
+        */
+       protected $operand2;
+
+       /**
+        * Constructs this Comparison instance
+        *
+        * @param Tx_Extbase_Persistence_QOM_DynamicOperandInterface $operand1
+        * @param unknown_type $operator
+        * @param Tx_Extbase_Persistence_QOM_StaticOperandInterface $operand2
+        */
+       public function __construct(Tx_Extbase_Persistence_QOM_DynamicOperandInterface $operand1, $operator, Tx_Extbase_Persistence_QOM_StaticOperandInterface $operand2) {
+               $this->operand1 = $operand1;
+               $this->operator = $operator;
+               $this->operand2 = $operand2;
+       }
+
+       /**
+        * Fills an array with the names of all bound variables in the operand
+        *
+        * @param array &$boundVariables
+        * @return void
+        */
+       public function collectBoundVariableNames(&$boundVariables) {
+               $this->operand2->collectBoundVariablenames($boundVariables);
+       }
+
+       /**
+        *
+        * Gets the first operand.
+        *
+        * @return Tx_Extbase_Persistence_QOM_DynamicOperandInterface the operand; non-null
+        */
+       public function getOperand1() {
+               return $this->operand1;
+       }
+
+       /**
+        * Gets the operator.
+        *
+        * @return string one of Tx_Extbase_Persistence_QOM_QueryObjectModelConstantsInterface.JCR_OPERATOR_*
+        */
+       public function getOperator() {
+               return $this->operator;
+       }
+
+       /**
+        * Gets the second operand.
+        *
+        * @return Tx_Extbase_Persistence_QOM_StaticOperandInterface the operand; non-null
+        */
+       public function getOperand2() {
+               return $this->operand2;
+       }
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/ComparisonInterface.php b/typo3/sysext/extbase/Classes/Persistence/QOM/ComparisonInterface.php
new file mode 100644 (file)
index 0000000..2f59a97
--- /dev/null
@@ -0,0 +1,102 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Filters node-tuples based on the outcome of a binary operation.
+ *
+ * For any comparison, operand2 always evaluates to a scalar value. In contrast,
+ * operand1 may evaluate to an array of values (for example, the value of a multi-valued
+ * property), in which case the comparison is separately performed for each element
+ * of the array, and the Comparison constraint is satisfied as a whole if the
+ * comparison against any element of the array is satisfied.
+ *
+ * If operand1 and operand2 evaluate to values of different property types, the
+ * value of operand2 is converted to the property type of the value of operand1.
+ * If the type conversion fails, the query is invalid.
+ *
+ * If operator is not supported for the property type of operand1, the query is invalid.
+ *
+ * If operand1 evaluates to null (for example, if the operand evaluates the value
+ * of a property which does not exist), the constraint is not satisfied.
+ *
+ * The JCR_OPERATOR_EQUAL_TO operator is satisfied only if the value of operand1
+ * equals the value of operand2.
+ *
+ * The JCR_OPERATOR_NOT_EQUAL_TO operator is satisfied unless the value of
+ * operand1 equals the value of operand2.
+ *
+ * The JCR_OPERATOR_LESSS_THAN operator is satisfied only if the value of
+ * operand1 is ordered before the value of operand2.
+ *
+ * The JCR_OPERATOR_LESS_THAN_OR_EQUAL_TO operator is satisfied unless the value
+ * of operand1 is ordered after the value of operand2.
+ *
+ * The JCR_OPERATOR_GREATER_THAN operator is satisfied only if the value of
+ * operand1 is ordered after the value of operand2.
+ *
+ * The JCR_OPERATOR_GREATER_THAN_OR_EQUAL_TO operator is satisfied unless the
+ * value of operand1 is ordered before the value of operand2.
+ *
+ * The JCR_OPERATOR_LIKE operator is satisfied only if the value of operand1
+ * matches the pattern specified by the value of operand2, where in the pattern:
+ * * the character "%" matches zero or more characters, and
+ * * the character "_" (underscore) matches exactly one character, and
+ * * the string "\x" matches the character "x", and
+ *   all other characters match themselves.
+ *
+ * @package PHPCR
+ * @subpackage Persistence
+ * @version $Id: ComparisonInterface.php 2191 2009-05-07 19:49:06Z k-fish $
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ */
+interface Tx_Extbase_Persistence_QOM_ComparisonInterface extends Tx_Extbase_Persistence_QOM_ConstraintInterface {
+
+       /**
+        *
+        * Gets the first operand.
+        *
+        * @return Tx_Extbase_Persistence_QOM_DynamicOperandInterface the operand; non-null
+        */
+       public function getOperand1();
+
+       /**
+        * Gets the operator.
+        *
+        * @return string one of Tx_Extbase_Persistence_QueryObjectModelConstantsInterface.OPERATOR_*
+        */
+       public function getOperator();
+
+       /**
+        * Gets the second operand.
+        *
+        * @return Tx_Extbase_Persistence_QOM_StaticOperandInterface the operand; non-null
+        */
+       public function getOperand2();
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/ConstraintInterface.php b/typo3/sysext/extbase/Classes/Persistence/QOM/ConstraintInterface.php
new file mode 100644 (file)
index 0000000..81f2cfd
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Filters the set of tuples formed by evaluating the query's sources and
+ * the joins between them.
+ *
+ * To be included in the query results, a tuple must satisfy the constraint.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: ConstraintInterface.php 1811 2009-01-28 12:04:49Z robert $
+ */
+interface Tx_Extbase_Persistence_QOM_ConstraintInterface {
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/DynamicOperand.php b/typo3/sysext/extbase/Classes/Persistence/QOM/DynamicOperand.php
new file mode 100644 (file)
index 0000000..be5b2a7
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * An operand whose value can only be determined in evaluating the query.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: DynamicOperand.php 1811 2009-01-28 12:04:49Z robert $
+ * @scope prototype
+ */
+class Tx_Extbase_Persistence_QOM_DynamicOperand extends Tx_Extbase_Persistence_QOM_Operand implements Tx_Extbase_Persistence_QOM_DynamicOperandInterface {
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/DynamicOperandInterface.php b/typo3/sysext/extbase/Classes/Persistence/QOM/DynamicOperandInterface.php
new file mode 100644 (file)
index 0000000..977a38e
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * An operand whose value can only be determined in evaluating the query.
+ *
+ * @package PHPCR
+ * @subpackage Query
+ * @version $Id: DynamicOperandInterface.php 1811 2009-01-28 12:04:49Z robert $
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ */
+interface Tx_Extbase_Persistence_QOM_DynamicOperandInterface extends Tx_Extbase_Persistence_QOM_OperandInterface {
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/EquiJoinCondition.php b/typo3/sysext/extbase/Classes/Persistence/QOM/EquiJoinCondition.php
new file mode 100644 (file)
index 0000000..09ee501
--- /dev/null
@@ -0,0 +1,116 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Tests whether the value of a property in a first selector is equal to the value of a
+ * property in a second selector.
+ * A node-tuple satisfies the constraint only if: the selector1Name node has a property named property1Name, and
+ * the selector2Name node has a property named property2Name, and
+ * the value of property property1Name is equal to the value of property property2Name.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: EquiJoinCondition.php 2011 2009-03-18 14:22:24Z k-fish $
+ * @scope prototype
+ */
+class Tx_Extbase_Persistence_QOM_EquiJoinCondition implements Tx_Extbase_Persistence_QOM_JoinConditionInterface {
+
+       /**
+        * @var string
+        */
+       protected $selector1Name;
+
+       /**
+        * @var string
+        */
+       protected $property1Name;
+
+       /**
+        * @var string
+        */
+       protected $selector2Name;
+
+       /**
+        * @var string
+        */
+       protected $property2Name;
+
+       /**
+        * Constructs this EquiJoinCondition instance
+        *
+        * @param string $selector1Name the name of the first selector; non-null
+        * @param string $property1Name the property name in the first selector; non-null
+        * @param string $selector2Name the name of the second selector; non-null
+        * @param string $property2Name the property name in the second selector; non-null
+        */
+       public function __construct($selector1Name, $property1Name, $selector2Name, $property2Name) {
+               // TODO Test for selector1Name = selector2Name -> exception
+               $this->selector1Name = $selector1Name;
+               $this->property1Name = $property1Name;
+               $this->selector2Name = $selector2Name;
+               $this->property2Name = $property2Name;
+       }
+
+       /**
+        * Gets the name of the first selector.
+        *
+        * @return string the selector name; non-null
+        */
+       public function getSelector1Name() {
+               return $this->selector1Name;
+       }
+
+       /**
+        * Gets the name of the first property.
+        *
+        * @return string the property name; non-null
+        */
+       public function getProperty1Name() {
+               return $this->property1Name;
+       }
+
+       /**
+        * Gets the name of the second selector.
+        *
+        * @return string the selector name; non-null
+        */
+       public function getSelector2Name() {
+               return $this->selector2Name;
+       }
+
+       /**
+        * Gets the name of the second property.
+        *
+        * @return string the property name; non-null
+        */
+       public function getProperty2Name() {
+               return $this->property2Name;
+       }
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/EquiJoinConditionInterface.php b/typo3/sysext/extbase/Classes/Persistence/QOM/EquiJoinConditionInterface.php
new file mode 100644 (file)
index 0000000..57192b7
--- /dev/null
@@ -0,0 +1,57 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Tests whether the childSelector node is a child of the parentSelector node. A
+ * node-tuple satisfies the constraint only if:
+ *  childSelectorNode.getParent().isSame(parentSelectorNode)
+ * would return true, where childSelectorNode is the node for childSelector and
+ * parentSelectorNode is the node for parentSelector.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: ChildNodeJoinConditionInterface.php 1979 2009-03-09 15:44:15Z k-fish $
+ */
+interface Tx_Extbase_Persistence_QOM_ChildNodeJoinConditionInterface extends Tx_Extbase_Persistence_QOM_JoinConditionInterface {
+
+       /**
+        * Gets the name of the child selector.
+        *
+        * @return string the selector name; non-null
+        */
+       public function getChildSelectorName();
+
+       /**
+        * Gets the name of the parent selector.
+        *
+        * @return string the selector name; non-null
+        */
+       public function getParentSelectorName();
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/Join.php b/typo3/sysext/extbase/Classes/Persistence/QOM/Join.php
new file mode 100644 (file)
index 0000000..7293382
--- /dev/null
@@ -0,0 +1,111 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Performs a join between two node-tuple sources.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: Join.php 2191 2009-05-07 19:49:06Z k-fish $
+ * @scope prototype
+ */
+class Tx_Extbase_Persistence_QOM_Join implements Tx_Extbase_Persistence_QOM_JoinInterface {
+
+       /**
+        * @var Tx_Extbase_Persistence_QOM_SourceInterface
+        */
+       protected $left;
+
+       /**
+        * @var Tx_Extbase_Persistence_QOM_SourceInterface
+        */
+       protected $right;
+
+       /**
+        * @var integer
+        */
+       protected $joinType;
+
+       /**
+        * @var Tx_Extbase_Persistence_QOM_JoinConditionInterface
+        */
+       protected $joinCondition;
+
+       /**
+        * Constructs the Join instance
+        *
+        * @param Tx_Extbase_Persistence_QOM_SourceInterface $left the left node-tuple source; non-null
+        * @param Tx_Extbase_Persistence_QOM_SourceInterface $right the right node-tuple source; non-null
+        * @param string $joinType one of QueryObjectModelConstants.JCR_JOIN_TYPE_*
+        * @param Tx_Extbase_Persistence_QOM_JoinConditionInterface $join Condition the join condition; non-null
+        */
+       public function __construct(Tx_Extbase_Persistence_QOM_SourceInterface $left, Tx_Extbase_Persistence_QOM_SourceInterface $right, $joinType, Tx_Extbase_Persistence_QOM_JoinConditionInterface $joinCondition) {
+               $this->left = $left;
+               $this->right = $right;
+               $this->joinType = $joinType;
+               $this->joinCondition = $joinCondition;
+       }
+
+       /**
+        * Gets the left node-tuple source.
+        *
+        * @return Tx_Extbase_Persistence_QOM_SourceInterface the left source; non-null
+        */
+       public function getLeft() {
+               return $this->left;
+       }
+
+       /**
+        * Gets the right node-tuple source.
+        *
+        * @return Tx_Extbase_Persistence_QOM_SourceInterface the right source; non-null
+        */
+       public function getRight() {
+               return $this->right;
+       }
+
+       /**
+        * Gets the join type.
+        *
+        * @return string one of QueryObjectModelConstants.JCR_JOIN_TYPE_*
+        */
+       public function getJoinType() {
+               return $this->joinType;
+       }
+
+       /**
+        * Gets the join condition.
+        *
+        * @return JoinCondition the join condition; non-null
+        */
+       public function getJoinCondition() {
+               return $this->joinCondition;
+       }
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/JoinConditionInterface.php b/typo3/sysext/extbase/Classes/Persistence/QOM/JoinConditionInterface.php
new file mode 100644 (file)
index 0000000..7aea0c2
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Filters the set of node-tuples formed from a join.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: JoinConditionInterface.php 1811 2009-01-28 12:04:49Z robert $
+ */
+interface Tx_Extbase_Persistence_QOM_JoinConditionInterface {
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/JoinInterface.php b/typo3/sysext/extbase/Classes/Persistence/QOM/JoinInterface.php
new file mode 100644 (file)
index 0000000..f6307de
--- /dev/null
@@ -0,0 +1,66 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Performs a join between two node-tuple sources.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: JoinInterface.php 2191 2009-05-07 19:49:06Z k-fish $
+ */
+interface Tx_Extbase_Persistence_QOM_JoinInterface extends Tx_Extbase_Persistence_QOM_SourceInterface {
+
+       /**
+        * Gets the left node-tuple source.
+        *
+        * @return Tx_Extbase_Persistence_QOM_SourceInterface the left source; non-null
+        */
+       public function getLeft();
+
+       /**
+        * Gets the right node-tuple source.
+        *
+        * @return Tx_Extbase_Persistence_QOM_SourceInterface the right source; non-null
+        */
+       public function getRight();
+
+       /**
+        * Gets the join type.
+        *
+        * @return string one of QueryObjectModelConstants.JCR_JOIN_TYPE_*
+        */
+       public function getJoinType();
+
+       /**
+        * Gets the join condition.
+        *
+        * @return JoinCondition the join condition; non-null
+        */
+       public function getJoinCondition();
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/Literal.php b/typo3/sysext/extbase/Classes/Persistence/QOM/Literal.php
new file mode 100644 (file)
index 0000000..a3b89b2
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Evaluates to a literal value.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: Literal.php 2011 2009-03-18 14:22:24Z k-fish $
+ * @scope prototype
+ */
+class Tx_Extbase_Persistence_QOM_Literal extends Tx_Extbase_Persistence_QOM_StaticOperand implements Tx_Extbase_Persistence_QOM_LiteralInterface {
+
+       /**
+        * Constructs this Literal instance
+        *
+        * @param string $value
+        */
+       public function __construct($value) {
+               $this->value = $value;
+       }
+
+       /**
+        * Gets the value of the literal.
+        *
+        * @return string the literal value; non-null
+        */
+       public function getLiteralValue() {
+               return $this->value;
+       }
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/LogicalAnd.php b/typo3/sysext/extbase/Classes/Persistence/QOM/LogicalAnd.php
new file mode 100644 (file)
index 0000000..cd5d6ab
--- /dev/null
@@ -0,0 +1,91 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Performs a logical conjunction of two other constraints.
+ *
+ * To satisfy the And constraint, a node-tuple must satisfy both constraint1 and
+ * constraint2.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: LogicalAnd.php 1877 2009-02-05 11:29:07Z k-fish $
+ * @scope prototype
+ */
+class Tx_Extbase_Persistence_QOM_LogicalAnd implements Tx_Extbase_Persistence_QOM_AndInterface {
+
+       /**
+        * @var Tx_Extbase_Persistence_QOM_ConstraintInterface
+        */
+       protected $constraint1;
+
+       /**
+        * @var Tx_Extbase_Persistence_QOM_ConstraintInterface
+        */
+       protected $constraint2;
+
+       /**
+        *
+        * @param Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint1
+        * @param Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint2
+        */
+       public function __construct(Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint1, Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint2) {
+               $this->constraint1 = $constraint1;
+               $this->constraint2 = $constraint2;
+       }
+
+       /**
+        * Fills an array with the names of all bound variables in the constraints
+        *
+        * @param array &$boundVariables
+        * @return void
+        */
+       public function collectBoundVariableNames(&$boundVariables) {
+               $this->constraint1->collectBoundVariableNames($boundVariables);
+               $this->constraint2->collectBoundVariableNames($boundVariables);
+       }
+
+       /**
+        * Gets the first constraint.
+        *
+        * @return Tx_Extbase_Persistence_QOM_ConstraintInterface the constraint; non-null
+        */
+       public function getConstraint1() {
+               return $this->constraint1;
+       }
+
+       /**
+        * Gets the second constraint.
+        *
+        * @return Tx_Extbase_Persistence_QOM_ConstraintInterface the constraint; non-null
+        */
+       public function getConstraint2() {
+               return $this->constraint2;
+       }
+
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/LogicalNot.php b/typo3/sysext/extbase/Classes/Persistence/QOM/LogicalNot.php
new file mode 100644 (file)
index 0000000..4aa483c
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Performs a logical negation of another constraint.
+ *
+ * To satisfy the Not constraint, the node-tuple must not satisfy constraint.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: LogicalNot.php 2011 2009-03-18 14:22:24Z k-fish $
+ * @scope prototype
+ */
+class Tx_Extbase_Persistence_QOM_LogicalNot implements Tx_Extbase_Persistence_QOM_NotInterface {
+
+       /**
+        * @var Tx_Extbase_Persistence_QOM_ConstraintInterface
+        */
+       protected $constraint;
+
+       /**
+        *
+        * @param Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint
+        */
+       public function __construct(Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint) {
+               $this->constraint = $constraint;
+       }
+
+       /**
+        * Fills an array with the names of all bound variables in the constraint
+        *
+        * @param array &$boundVariables
+        * @return void
+        */
+       public function collectBoundVariableNames(&$boundVariables) {
+               $this->constraint->collectBoundVariableNames($boundVariables);
+       }
+
+       /**
+        * Gets the constraint negated by this Not constraint.
+        *
+        * @return Tx_Extbase_Persistence_QOM_ConstraintInterface the constraint; non-null
+        */
+       public function getConstraint() {
+               return $this->constraint;
+       }
+
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/LogicalOr.php b/typo3/sysext/extbase/Classes/Persistence/QOM/LogicalOr.php
new file mode 100644 (file)
index 0000000..c876f11
--- /dev/null
@@ -0,0 +1,93 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Performs a logical disjunction of two other constraints.
+ *
+ * To satisfy the Or constraint, the node-tuple must either:
+ *  satisfy constraint1 but not constraint2, or
+ *  satisfy constraint2 but not constraint1, or
+ *  satisfy both constraint1 and constraint2.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: LogicalOr.php 1877 2009-02-05 11:29:07Z k-fish $
+ * @scope prototype
+ */
+class Tx_Extbase_Persistence_QOM_LogicalOr implements Tx_Extbase_Persistence_QOM_OrInterface {
+
+       /**
+        * @var Tx_Extbase_Persistence_QOM_ConstraintInterface
+        */
+       protected $constraint1;
+
+       /**
+        * @var Tx_Extbase_Persistence_QOM_ConstraintInterface
+        */
+       protected $constraint2;
+
+       /**
+        *
+        * @param Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint1
+        * @param Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint2
+        */
+       public function __construct(Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint1, Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint2) {
+               $this->constraint1 = $constraint1;
+               $this->constraint2 = $constraint2;
+       }
+
+       /**
+        * Fills an array with the names of all bound variables in the constraints
+        *
+        * @param array &$boundVariables
+        * @return void
+        */
+       public function collectBoundVariableNames(&$boundVariables) {
+               $this->constraint1->collectBoundVariablenames($boundVariables);
+               $this->constraint2->collectBoundVariablenames($boundVariables);
+       }
+
+       /**
+        * Gets the first constraint.
+        *
+        * @return Tx_Extbase_Persistence_QOM_ConstraintInterface the constraint; non-null
+        */
+       public function getConstraint1() {
+               return $this->constraint1;
+       }
+
+       /**
+        * Gets the second constraint.
+        *
+        * @return Tx_Extbase_Persistence_QOM_ConstraintInterface the constraint; non-null
+        */
+       public function getConstraint2() {
+               return $this->constraint2;
+       }
+
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/LowerCase.php b/typo3/sysext/extbase/Classes/Persistence/QOM/LowerCase.php
new file mode 100644 (file)
index 0000000..98fa1bd
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Evaluates to the lower-case string value (or values, if multi-valued) of
+ * operand.
+ *
+ * If operand does not evaluate to a string value, its value is first converted
+ * to a string.
+ *
+ * If operand evaluates to null, the LowerCase operand also evaluates to null.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: LowerCase.php 2011 2009-03-18 14:22:24Z k-fish $
+ * @scope prototype
+ */
+class Tx_Extbase_Persistence_QOM_LowerCase implements Tx_Extbase_Persistence_QOM_LowerCaseInterface {
+
+       /**
+        * @var Tx_Extbase_Persistence_QOM_DynamicOperandInterface
+        */
+       protected $operand;
+
+       /**
+        * Constructs this LowerCase instance
+        *
+        * @param Tx_Extbase_Persistence_QOM_DynamicOperandInterface $constraint
+        */
+       public function __construct(Tx_Extbase_Persistence_QOM_DynamicOperandInterface $operand) {
+               $this->operand = $operand;
+       }
+
+       /**
+        * Gets the operand whose value is converted to a lower-case string.
+        *
+        * @return Tx_Extbase_Persistence_QOM_DynamicOperandInterface the operand; non-null
+        */
+       public function getOperand() {
+               return $this->operand;
+       }
+
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/NotInterface.php b/typo3/sysext/extbase/Classes/Persistence/QOM/NotInterface.php
new file mode 100644 (file)
index 0000000..56e29fc
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Performs a logical negation of another constraint.
+ *
+ * To satisfy the Not constraint, the node-tuple must not satisfy constraint.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: NotInterface.php 1811 2009-01-28 12:04:49Z robert $
+ */
+interface Tx_Extbase_Persistence_QOM_NotInterface extends Tx_Extbase_Persistence_QOM_ConstraintInterface {
+
+       /**
+        * Gets the constraint negated by this Not constraint.
+        *
+        * @return Tx_Extbase_Persistence_QOM_ConstraintInterface the constraint; non-null
+        */
+       public function getConstraint();
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/Operand.php b/typo3/sysext/extbase/Classes/Persistence/QOM/Operand.php
new file mode 100644 (file)
index 0000000..c8b6091
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * An operand to a binary operation specified by a Comparison.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: Operand.php 2011 2009-03-18 14:22:24Z k-fish $
+ * @scope prototype
+ */
+class Tx_Extbase_Persistence_QOM_Operand implements Tx_Extbase_Persistence_QOM_OperandInterface {
+
+       /**
+        * Does nothing
+        *
+        * @param array &$boundVariables
+        * @return void
+        */
+       public function collectBoundVariableNames(&$boundVariables) {
+       }
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/OperandInterface.php b/typo3/sysext/extbase/Classes/Persistence/QOM/OperandInterface.php
new file mode 100644 (file)
index 0000000..fc4bab5
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * An operand to a binary operation specified by a Comparison.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: OperandInterface.php 1811 2009-01-28 12:04:49Z robert $
+ */
+interface Tx_Extbase_Persistence_QOM_OperandInterface {
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/OrInterface.php b/typo3/sysext/extbase/Classes/Persistence/QOM/OrInterface.php
new file mode 100644 (file)
index 0000000..7fab643
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Performs a logical disjunction of two other constraints.
+ *
+ * To satisfy the Or constraint, the node-tuple must either:
+ *  satisfy constraint1 but not constraint2, or
+ *  satisfy constraint2 but not constraint1, or
+ *  satisfy both constraint1 and constraint2.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: OrInterface.php 1811 2009-01-28 12:04:49Z robert $
+ */
+interface Tx_Extbase_Persistence_QOM_OrInterface extends Tx_Extbase_Persistence_QOM_ConstraintInterface {
+
+       /**
+        * Gets the first constraint.
+        *
+        * @return Tx_Extbase_Persistence_QOM_ConstraintInterface the constraint; non-null
+        */
+       public function getConstraint1();
+
+       /**
+        * Gets the second constraint.
+        *
+        * @return Tx_Extbase_Persistence_QOM_ConstraintInterface the constraint; non-null
+        */
+       public function getConstraint2();
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/PropertyValue.php b/typo3/sysext/extbase/Classes/Persistence/QOM/PropertyValue.php
new file mode 100644 (file)
index 0000000..2f6f996
--- /dev/null
@@ -0,0 +1,87 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Evaluates to the value (or values, if multi-valued) of a property.
+ *
+ * If, for a node-tuple, the selector node does not have a property named property,
+ * the operand evaluates to null.
+ *
+ * The query is invalid if:
+ *
+ * selector is not the name of a selector in the query, or
+ * property is not a syntactically valid JCR name.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: PropertyValue.php 1811 2009-01-28 12:04:49Z robert $
+ * @scope prototype
+ */
+class Tx_Extbase_Persistence_QOM_PropertyValue extends Tx_Extbase_Persistence_QOM_DynamicOperand implements Tx_Extbase_Persistence_QOM_PropertyValueInterface {
+
+       /**
+        * @var string
+        */
+       protected $selectorName;
+
+       /**
+        * @var string
+        */
+       protected $propertyName;
+
+       /**
+        * Constructs this PropertyValue instance
+        *
+        * @param string $propertyName
+        * @param string $selectorName
+        */
+       public function __construct($propertyName, $selectorName = '') {
+               $this->propertyName = $propertyName;
+               $this->selectorName = $selectorName;
+       }
+
+       /**
+        * Gets the name of the selector against which to evaluate this operand.
+        *
+        * @return string the selector name; non-null
+        */
+       public function getSelectorName() {
+               return $this->selectorName;
+       }
+
+       /**
+        * Gets the name of the property.
+        *
+        * @return string the property name; non-null
+        */
+       public function getPropertyName() {
+               return $this->propertyName;
+       }
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/PropertyValueInterface.php b/typo3/sysext/extbase/Classes/Persistence/QOM/PropertyValueInterface.php
new file mode 100644 (file)
index 0000000..28efb7f
--- /dev/null
@@ -0,0 +1,61 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Evaluates to the value (or values, if multi-valued) of a property.
+ *
+ * If, for a node-tuple, the selector node does not have a property named property,
+ * the operand evaluates to null.
+ *
+ * The query is invalid if:
+ *
+ * selector is not the name of a selector in the query, or
+ * property is not a syntactically valid JCR name.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: PropertyValueInterface.php 1811 2009-01-28 12:04:49Z robert $
+ */
+interface Tx_Extbase_Persistence_QOM_PropertyValueInterface extends Tx_Extbase_Persistence_QOM_DynamicOperandInterface {
+
+       /**
+        * Gets the name of the selector against which to evaluate this operand.
+        *
+        * @return string the selector name; non-null
+        */
+       public function getSelectorName();
+
+       /**
+        * Gets the name of the property.
+        *
+        * @return string the property name; non-null
+        */
+       public function getPropertyName();
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/QueryObjectModel.php b/typo3/sysext/extbase/Classes/Persistence/QOM/QueryObjectModel.php
new file mode 100644 (file)
index 0000000..f7cf1a5
--- /dev/null
@@ -0,0 +1,245 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * A query in the JCR query object model.
+ *
+ * The JCR query object model describes the queries that can be evaluated by a JCR
+ * repository independent of any particular query language, such as SQL.
+ *
+ * A query consists of:
+ *
+ * a source. When the query is evaluated, the source evaluates its selectors and
+ * the joins between them to produce a (possibly empty) set of node-tuples. This
+ * is a set of 1-tuples if the query has one selector (and therefore no joins), a
+ * set of 2-tuples if the query has two selectors (and therefore one join), a set
+ * of 3-tuples if the query has three selectors (two joins), and so forth.
+ * an optional constraint. When the query is evaluated, the constraint filters the
+ * set of node-tuples.
+ * a list of zero or more orderings. The orderings specify the order in which the
+ * node-tuples appear in the query results. The relative order of two node-tuples
+ * is determined by evaluating the specified orderings, in list order, until
+ * encountering an ordering for which one node-tuple precedes the other. If no
+ * orderings are specified, or if for none of the specified orderings does one
+ * node-tuple precede the other, then the relative order of the node-tuples is
+ * implementation determined (and may be arbitrary).
+ * a list of zero or more columns to include in the tabular view of the query
+ * results. If no columns are specified, the columns available in the tabular view
+ * are implementation determined, but minimally include, for each selector, a column
+ * for each single-valued non-residual property of the selector's node type.
+ *
+ * The query object model representation of a query is created by factory methods in the QueryObjectModelFactory.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: QueryObjectModel.php 1877 2009-02-05 11:29:07Z k-fish $
+ * @scope prototype
+ */
+class Tx_Extbase_Persistence_QOM_QueryObjectModel extends Tx_Extbase_Persistence_Query implements Tx_Extbase_Persistence_QOM_QueryObjectModelInterface {
+
+       /**
+        * @var Tx_Extbase_Persistence_QOM_SourceInterface
+        */
+       protected $source;
+
+       /**
+        * @var Tx_Extbase_Persistence_QOM_ConstraintInterface
+        */
+       protected $constraint;
+
+       /**
+        * @var array
+        */
+       protected $orderings;
+
+       /**
+        * @var array
+        */
+       protected $columns;
+
+       /**
+        * @var Tx_Extbase_Persistence_Storage_BackendInterface
+        */
+       protected $storageBackend;
+
+       /**
+        * integer
+        */
+       protected $limit;
+
+       /**
+        * integer
+        */
+       protected $offset;
+
+       /**
+        * @var array
+        */
+       protected $boundVariables = array();
+
+       /**
+        * Constructs this QueryObjectModel instance
+        *
+        * @param Tx_Extbase_Persistence_QOM_SourceInterface $selectorOrSource
+        * @param Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint (null if none)
+        * @param array $orderings
+        * @param array $columns
+        */
+       public function __construct(Tx_Extbase_Persistence_QOM_SourceInterface $selectorOrSource, $constraint, array $orderings, array $columns) {
+               $this->source = $selectorOrSource;
+               $this->constraint = $constraint;
+               $this->orderings = $orderings;
+               $this->columns = $columns;
+
+               if ($this->constraint !== NULL) {
+                       $this->constraint->collectBoundVariableNames($this->boundVariables);
+               }
+       }
+
+       /**
+        * Injects the StorageBackend 
+        *
+        * @param Tx_Extbase_Persistence_Storage_BackendInterface $storageBackend
+        * @return void
+        */
+       public function injectStorageBackend(Tx_Extbase_Persistence_Storage_BackendInterface $storageBackend) {
+               $this->storageBackend = $storageBackend;
+       }
+
+       /**
+        * Injects the Data Mapper to map nodes to objects
+        *
+        * @param Tx_Extbase_Persistence_Mapper_DataMapper $dataMapper
+        * @return void
+        */
+       public function injectDataMapper(Tx_Extbase_Persistence_Mapper_DataMapper $dataMapper) {
+               $this->dataMapper = $dataMapper;
+       }
+
+       /**
+        * Returns the class name the query handles
+        *
+        * @return string The class name
+        */
+       public function getSelectorName() {
+               $this->dataMapper->convertClassNameToSelectorName($this->className);
+       }
+
+       /**
+        * Gets the node-tuple source for this query.
+        *
+        * @return Tx_Extbase_Persistence_QOM_SourceInterface the node-tuple source; non-null
+       */
+       public function getSource() {
+               return $this->source;
+       }
+
+       /**
+        * Gets the constraint for this query.
+        *
+        * @return Tx_Extbase_Persistence_QOM_ConstraintInterface the constraint, or null if none
+       */
+       public function getConstraint() {
+               return $this->constraint;
+       }
+
+       /**
+        * Gets the orderings for this query.
+        *
+        * @return array an array of zero or more Tx_Extbase_Persistence_QOM_OrderingInterface; non-null
+       */
+       public function getOrderings() {
+               return $this->orderings;
+       }
+
+       /**
+        * Gets the columns for this query.
+        *
+        * @return array an array of zero or more Tx_Extbase_Persistence_QOM_ColumnInterface; non-null
+       */
+       public function getColumns() {
+               return $this->columns;
+       }
+
+       /**
+        * Binds the given value to the variable named $varName.
+        *
+        * @param string $varName name of variable in query
+        * @param Tx_Extbase_Persistence_ValueInterface $value value to bind
+        * @return void
+        * @throws InvalidArgumentException if $varName is not a valid variable in this query.
+        * @throws RepositoryException if an error occurs.
+        */
+       public function bindValue($varName, Tx_Extbase_Persistence_ValueInterface $value) {
+               if (array_key_exists($varName, $this->boundVariables) === FALSE) {
+                       throw new InvalidArgumentException('Invalid variable name "' . $varName . '" given to bindValue.', 1217241834);
+               }
+               $this->boundVariables[$varName] = $value->getString();
+       }
+
+       /**
+        * Returns the values of all bound variables.
+        *
+        * @return array()
+        */
+       public function getBoundVariableValues() {
+               return $this->boundVariables;
+       }
+
+       /**
+        * Executes this query and returns a QueryResult object.
+        *
+        * @return Tx_Extbase_Persistence_QueryResultInterface A QueryResult object
+        */
+       public function execute() {
+               return t3lib_div::makeInstance('Tx_Extbase_Persistence_QueryResult', $this->storageBackend->getRows($this));
+       }
+
+       /**
+        * Returns the statement defined for this query.
+        * If the language of this query is string-based (like JCR-SQL2), this method
+        * will return the statement that was used to create this query.
+        *
+        * If the language of this query is JCR-JQOM, this method will return the
+        * JCR-SQL2 equivalent of the JCR-JQOM object tree.
+        *
+        * This is the standard serialization of JCR-JQOM and is also the string stored
+        * in the jcr:statement property if the query is persisted. See storeAsNode($absPath).
+        *
+        * @return string the query statement.
+        */
+       public function getStatement() {
+               throw new Exception('Method not yet implemented, sorry!', 1216897752);
+       }
+
+       
+       public function useEnableFields() {
+               return TRUE; // TODO Make enableFields configurable
+       }
+
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/QueryObjectModelConstantsInterface.php b/typo3/sysext/extbase/Classes/Persistence/QOM/QueryObjectModelConstantsInterface.php
new file mode 100644 (file)
index 0000000..c1d36bf
--- /dev/null
@@ -0,0 +1,99 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Defines constants used in the query object model.
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: QueryObjectModelConstantsInterface.php 2191 2009-05-07 19:49:06Z k-fish $
+ */
+interface Tx_Extbase_Persistence_QOM_QueryObjectModelConstantsInterface {
+
+       /**
+        * An inner join.
+        */
+       const JCR_JOIN_TYPE_INNER = '{http://www.jcp.org/jcr/1.0}joinTypeInner';
+
+       /**
+        * A left-outer join.
+        */
+       const JCR_JOIN_TYPE_LEFT_OUTER = '{http://www.jcp.org/jcr/1.0}joinTypeLeftOuter';
+
+       /**
+        * A right-outer join.
+        */
+       const JCR_JOIN_TYPE_RIGHT_OUTER = '{http://www.jcp.org/jcr/1.0}joinTypeRightOuter';
+
+       /**
+        * The '=' comparison operator.
+        */
+       const JCR_OPERATOR_EQUAL_TO = '{http://www.jcp.org/jcr/1.0}operatorEqualTo';
+
+       /**
+        * The '!=' comparison operator.
+        */
+       const JCR_OPERATOR_NOT_EQUAL_TO = '{http://www.jcp.org/jcr/1.0}operatorNotEqualTo';
+
+       /**
+        * The '<' comparison operator.
+        */
+       const JCR_OPERATOR_LESS_THAN = '{http://www.jcp.org/jcr/1.0}operatorLessThan';
+
+       /**
+        * The '<=' comparison operator.
+        */
+       const JCR_OPERATOR_LESS_THAN_OR_EQUAL_TO = '{http://www.jcp.org/jcr/1.0}operatorLessThanOrEqualTo';
+
+       /**
+        * The '>' comparison operator.
+        */
+       const JCR_OPERATOR_GREATER_THAN = '{http://www.jcp.org/jcr/1.0}operatorGreaterThan';
+
+       /**
+        * The '>=' comparison operator.
+        */
+       const JCR_OPERATOR_GREATER_THAN_OR_EQUAL_TO = '{http://www.jcp.org/jcr/1.0}operatorGreaterThanOrEqualTo';
+
+       /**
+        * The 'like' comparison operator.
+        */
+       const JCR_OPERATOR_LIKE = '{http://www.jcp.org/jcr/1.0}operatorLike';
+
+       /**
+        * Ascending order.
+        */
+       const JCR_ORDER_ASCENDING = '{http://www.jcp.org/jcr/1.0}orderAscending';
+
+       /**
+        * Descending order.
+        */
+       const JCR_ORDER_DESCENDING = '{http://www.jcp.org/jcr/1.0}orderDescending';
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/QueryObjectModelFactory.php b/typo3/sysext/extbase/Classes/Persistence/QOM/QueryObjectModelFactory.php
new file mode 100644 (file)
index 0000000..ce7de12
--- /dev/null
@@ -0,0 +1,463 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * The Query Object Model Factory
+ *
+ * @package Extbase
+ * @subpackage Persistence
+ * @version $Id: QueryObjectModelFactory.php 2191 2009-05-07 19:49:06Z k-fish $
+ * @scope prototype
+ */
+class Tx_Extbase_Persistence_QOM_QueryObjectModelFactory implements Tx_Extbase_Persistence_QOM_QueryObjectModelFactoryInterface {
+
+       /**
+        * @var Tx_Extbase_Persistence_Storage_BackendInterface
+        */
+       protected $storageBackend;
+
+       /**
+        * Constructs the Component Factory
+        *
+        * @param Tx_Extbase_Persistence_Storage_BackendInterfasce $storageBackend
+        * @param Tx_Extbase_Persistence_Mapper_DataMapper $dataMapper
+        */
+       public function __construct(Tx_Extbase_Persistence_Storage_BackendInterface $storageBackend, Tx_Extbase_Persistence_Mapper_DataMapper $dataMapper) {
+               $this->storageBackend = $storageBackend;
+               $this->dataMapper = $dataMapper;
+       }
+
+       /**
+        * Creates a query with one or more selectors.
+        * If source is a selector, that selector is the default selector of the
+        * query. Otherwise the query does not have a default selector.
+        *
+        * If the query is invalid, this method throws an InvalidQueryException.
+        * See the individual QOM factory methods for the validity criteria of each
+        * query element.
+        *
+        * @param mixed $source the Selector or the node-tuple Source; non-null
+        * @param Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint the constraint, or null if none
+        * @param array $orderings zero or more orderings; null is equivalent to a zero-length array
+        * @param array $columns the columns; null is equivalent to a zero-length array
+        * @return Tx_Extbase_Persistence_QOM_QueryObjectModelInterface the query; non-null
+        * @throws \F3\PHPCR\Query\InvalidQueryException if a particular validity test is possible on this method, the implemention chooses to perform that test and the parameters given fail that test. See the individual QOM factory methods for the validity criteria of each query element.
+        * @throws \F3\PHPCR\RepositoryException if another error occurs.
+        */
+       public function createQuery(Tx_Extbase_Persistence_QOM_SourceInterface $selectorOrSource, $constraint, array $orderings, array $columns) {
+               $query =  new Tx_Extbase_Persistence_QOM_QueryObjectModel($selectorOrSource, $constraint, $orderings, $columns);
+               $query->injectStorageBackend($this->storageBackend);
+               $query->injectDataMapper($this->dataMapper);
+               return $query;
+       }
+
+       /**
+        * Selects a subset of the nodes in the repository based on node type.
+        *
+        * @param string $nodeTypeName the name of the required node type; non-null
+        * @param string $selectorName the selector name; optional
+        * @return Tx_Extbase_Persistence_QOM_SelectorInterface the selector
+        * @throws \F3\PHPCR\Query\InvalidQueryException if the query is invalid
+        * @throws \F3\PHPCR\RepositoryException if the operation otherwise fails
+        */
+       public function selector($nodeTypeName, $selectorName = '') {
+               if ($selectorName === '') {
+                       $selectorName = $nodeTypeName;
+               }
+               return t3lib_div::makeInstance('Tx_Extbase_Persistence_QOM_Selector', $selectorName, $nodeTypeName);
+       }
+
+       /**
+        * Performs a join between two node-tuple sources.
+        *
+        * @param Tx_Extbase_Persistence_QOM_SourceInterface $left the left node-tuple source; non-null
+        * @param Tx_Extbase_Persistence_QOM_SourceInterface $right the right node-tuple source; non-null
+        * @param string $joinType one of QueryObjectModelConstants.JCR_JOIN_TYPE_*
+        * @param Tx_Extbase_Persistence_QOM_JoinConditionInterface $join Condition the join condition; non-null
+        * @return Tx_Extbase_Persistence_QOM_JoinInterface the join; non-null