Extbase:
authorJochen Rau <j.rau@web.de>
Mon, 13 Jul 2009 08:45:19 +0000 (08:45 +0000)
committerJochen Rau <j.rau@web.de>
Mon, 13 Jul 2009 08:45:19 +0000 (08:45 +0000)
* Fixed internal method _memorizeCleanState($propertyName); nothing was memorized if $property name was set
* Removed call to $GLOBASL['TYPO3_DB']->fullQuoteString() as this should be the job of the persistence backend
* Fixed Query and Query Object Model Factory (patch contributed by Frans van der Veen); Resolves #3879
* Removed obsolete commit() method in Session
* Fixed invalid SQL without enableFields; Resolves #3826
* First step taken to implement the parsing of Orderings

typo3/sysext/extbase/Classes/Dispatcher.php
typo3/sysext/extbase/Classes/DomainObject/AbstractEntity.php
typo3/sysext/extbase/Classes/Persistence/Backend.php
typo3/sysext/extbase/Classes/Persistence/Mapper/DataMap.php
typo3/sysext/extbase/Classes/Persistence/QOM/QueryObjectModel.php
typo3/sysext/extbase/Classes/Persistence/QOM/QueryObjectModelFactory.php
typo3/sysext/extbase/Classes/Persistence/Query.php
typo3/sysext/extbase/Classes/Persistence/Repository.php
typo3/sysext/extbase/Classes/Persistence/Session.php
typo3/sysext/extbase/Classes/Persistence/Storage/Typo3DbBackend.php

index 0a68f5b..1a5e861 100644 (file)
@@ -56,7 +56,7 @@ class Tx_Extbase_Dispatcher {
                $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');
+               $storageBackend = t3lib_div::makeInstance('Tx_Extbase_Persistence_Storage_Typo3DbBackend'); // singleton
                $dataMapper = t3lib_div::makeInstance('Tx_Extbase_Persistence_Mapper_DataMapper');
 
                $persistenceBackend = t3lib_div::makeInstance('Tx_Extbase_Persistence_Backend', $persistenceSession, $storageBackend); // singleton
index addab49..688c2f7 100644 (file)
@@ -48,7 +48,7 @@ abstract class Tx_Extbase_DomainObject_AbstractEntity extends Tx_Extbase_DomainO
        public function _memorizeCleanState($propertyName = NULL) {
                // TODO Remove dependency to $dataMapper
                if ($propertyName !== NULL) {
-                       // SK: The if part is missing here! Can it be removed?
+                       $this->_memorizePropertyCleanState($propertyName);
                } else {
                        $dataMapper = t3lib_div::makeInstance('Tx_Extbase_Persistence_Mapper_DataMapper'); // singleton
                        $this->_cleanProperties = array();
@@ -76,7 +76,7 @@ abstract class Tx_Extbase_DomainObject_AbstractEntity extends Tx_Extbase_DomainO
                }
                if (is_object($propertyValue)) {
                        // SK: Is "clone" semantically correct here? Discussion needed.
-                       // If you see "getDirtyProperties", there you compare with ===, so cloned objects will return a different value I think (but needs to be verified)
+                       // FIXME If you see "getDirtyProperties", there you compare with ===, so cloned objects will return a different value I think (but needs to be verified)
                        $this->_cleanProperties[$propertyName] = clone($propertyValue);
                } else {
                        $this->_cleanProperties[$propertyName] = $propertyValue;
index a04358d..18ccce0 100644 (file)
@@ -305,8 +305,7 @@ class Tx_Extbase_Persistence_Backend implements Tx_Extbase_Persistence_BackendIn
                                        }
                                } else {
                                        // Not an relation, this means it is a simple type such as STRING or Integer
-                                       // SK: I think that the second option $fullQuoteString is NOT needed here, as this should be the job of the persistence backend.
-                                       $row[$columnName] = $dataMap->convertPropertyValueToFieldValue($properties[$propertyName], FALSE);
+                                       $row[$columnName] = $dataMap->convertPropertyValueToFieldValue($properties[$propertyName]);
                                }
                        }
                }
index 707b6dc..00ce88e 100644 (file)
@@ -508,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 = FALSE) {
+       public function convertPropertyValueToFieldValue($propertyValue) {
                if (is_bool($propertyValue)) {
                        $convertedValue = $propertyValue ? 1 : 0;
                } elseif ($propertyValue instanceof Tx_Extbase_DomainObject_AbstractDomainObject) {
@@ -519,7 +519,7 @@ class Tx_Extbase_Persistence_Mapper_DataMap {
                        $convertedValue = $propertyValue;
                } else {
                        // FIXME Full quote string does not work with the Typo3DbBackend parsing
-                       $convertedValue = $fullQuoteString === TRUE ? $GLOBALS['TYPO3_DB']->fullQuoteStr((string)$propertyValue, '') : $propertyValue;
+                       $convertedValue = $propertyValue;
                }
                return $convertedValue;
        }
index 8286db4..a7ee944 100644 (file)
@@ -241,10 +241,5 @@ class Tx_Extbase_Persistence_QOM_QueryObjectModel extends Tx_Extbase_Persistence
                throw new Exception('Method not yet implemented, sorry!', 1216897752);
        }
 
-       
-       public function useEnableFields() {
-               return TRUE; // TODO Make enableFields configurable
-       }
-
 }
 ?>
\ No newline at end of file
index fd998ba..8d33b27 100644 (file)
@@ -171,7 +171,7 @@ class Tx_Extbase_Persistence_QOM_QueryObjectModelFactory implements Tx_Extbase_P
         * @throws Tx_Extbase_Persistence_Exception_RepositoryException if the operation otherwise fails
         */
        public function _and(Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint1, Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint2) {
-               return t3lib_div::makeInstance('Tx_Extbase_Persistence_QOM_And', $constraint1, $constraint2);
+               return t3lib_div::makeInstance('Tx_Extbase_Persistence_QOM_LogicalAnd', $constraint1, $constraint2);
        }
 
        /**
@@ -184,7 +184,7 @@ class Tx_Extbase_Persistence_QOM_QueryObjectModelFactory implements Tx_Extbase_P
         * @throws Tx_Extbase_Persistence_Exception_RepositoryException if the operation otherwise fails
         */
        public function _or(Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint1, Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint2) {
-               return t3lib_div::makeInstance('Tx_Extbase_Persistence_QOM_Or', $constraint1, $constraint2);
+               return t3lib_div::makeInstance('Tx_Extbase_Persistence_QOM_LogicalOr', $constraint1, $constraint2);
        }
 
        /**
@@ -196,7 +196,7 @@ class Tx_Extbase_Persistence_QOM_QueryObjectModelFactory implements Tx_Extbase_P
         * @throws Tx_Extbase_Persistence_Exception_RepositoryException if the operation otherwise fails
         */
        public function not(Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint) {
-               return t3lib_div::makeInstance('Tx_Extbase_Persistence_QOM_Not', $constraint);
+               return t3lib_div::makeInstance('Tx_Extbase_Persistence_QOM_LogicalNot', $constraint);
        }
 
        /**
@@ -460,4 +460,4 @@ class Tx_Extbase_Persistence_QOM_QueryObjectModelFactory implements Tx_Extbase_P
        }
 
 }
-?>
\ No newline at end of file
+?>
index aafa55e..34b7efd 100644 (file)
@@ -5,7 +5,7 @@
 *  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
 *  All rights reserved
 *
-*  This class is a backport of the corresponding class of FLOW3. 
+*  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
@@ -135,7 +135,7 @@ class Tx_Extbase_Persistence_Query implements Tx_Extbase_Persistence_QueryInterf
        public function getClassName() {
                $this->className;
        }
-       
+
        /**
         * Sets the source to fetch the result from
         *
@@ -189,6 +189,7 @@ class Tx_Extbase_Persistence_Query implements Tx_Extbase_Persistence_QueryInterf
         */
        public function setOrderings(array $orderings) {
                $this->orderings = $orderings;
+               return $this;
        }
 
        /**
@@ -214,6 +215,7 @@ class Tx_Extbase_Persistence_Query implements Tx_Extbase_Persistence_QueryInterf
        public function setOffset($offset) {
                if (!is_int($offset) || $offset < 0) throw new InvalidArgumentException('The limit must be a positive integer', 1245071872);
                $this->offset = $offset;
+               return $this;
        }
 
        /**
@@ -298,8 +300,9 @@ class Tx_Extbase_Persistence_Query implements Tx_Extbase_Persistence_QueryInterf
                // TODO $sourceSelectorName might not be initialized
 
                if (is_object($operand) && !($operand instanceof DateTime)) {
+                       // FIXME This branch of if-then-else is not fully backported and non functional by now
                        $operand = $this->persistenceManager->getBackend()->getUidByObject($operand);
-                       $left = $this->getSource();
+                       $left = $source;
                        $columnMap = $this->dataMapper->getDataMap($this->className)->getColumnMap($propertyName);
                        $childSelectorName = $columnMap->getChildTableName();
                        $right = $this->QOMFactory->selector($childSelectorName);
@@ -354,9 +357,15 @@ class Tx_Extbase_Persistence_Query implements Tx_Extbase_Persistence_QueryInterf
         * @return Tx_Extbase_Persistence_QOM_ComparisonInterface
         */
        public function like($propertyName, $operand) {
+               $source = $this->getSource();
+               if ($source instanceof Tx_Extbase_Persistence_QOM_SelectorInterface) {
+                       $sourceSelectorName = $this->getSource()->getSelectorName();
+               }
+               // TODO $sourceSelectorName might not be initialized
+
                $this->operands[$propertyName] = $operand;
                return $this->QOMFactory->comparison(
-                       $this->QOMFactory->propertyValue($propertyName, $this->getSource()),
+                       $this->QOMFactory->propertyValue($propertyName, $sourceSelectorName),
                        Tx_Extbase_Persistence_QOM_QueryObjectModelConstantsInterface::JCR_OPERATOR_LIKE,
                        $this->QOMFactory->bindVariable($propertyName)
                        );
@@ -431,4 +440,4 @@ class Tx_Extbase_Persistence_Query implements Tx_Extbase_Persistence_QueryInterf
        }
 
 }
-?>
\ No newline at end of file
+?>
index cd7d7a6..6cf3b7f 100644 (file)
 *  This copyright notice MUST APPEAR in all copies of the script!
 ***************************************************************/
 
-// TODO Remove if autoloader is active
-require_once(PATH_t3lib . 'interfaces/interface.t3lib_singleton.php');
-require_once(PATH_tslib . 'class.tslib_content.php');
-// SK: Remove these require statements as we have the autoloader
-
 /**
  * The base repository - will usually be extended by a more concrete repository.
  *
@@ -56,6 +51,7 @@ class Tx_Extbase_Persistence_Repository implements Tx_Extbase_Persistence_Reposi
        public function __construct() {
                $this->queryFactory = t3lib_div::makeInstance('Tx_Extbase_Persistence_QueryFactory');
                $this->persistenceManager = t3lib_div::makeInstance('Tx_Extbase_Persistence_Manager'); // singleton; must have been initialized before (constructor argument)
+               // FIXME This does not work for itemProcFunc()
        }
 
        /**
@@ -65,8 +61,7 @@ class Tx_Extbase_Persistence_Repository implements Tx_Extbase_Persistence_Reposi
         * @return void
         */
        public function add($object) {
-               // SK: see the following comment, I think this needs to be added again
-               // if (!($object instanceof $this->aggregateRootClassName)) throw new Tx_Extbase_Persistence_Exception_InvalidClass('The class "' . get_class($object) . '" is not supported by the repository.');
+//             if (!is_object($object) || !($object instanceof $this->aggregateRootClassName)) throw new Tx_Extbase_Persistence_Exception_InvalidClass('The class "' . get_class($object) . '" is not supported by the repository.');
                $this->persistenceManager->getSession()->registerAddedObject($object);
        }
 
@@ -77,8 +72,7 @@ class Tx_Extbase_Persistence_Repository implements Tx_Extbase_Persistence_Reposi
         * @return void
         */
        public function remove($object) {
-               // SK: see the following comment, I think this needs to be added again
-               // if (!($object instanceof $this->aggregateRootClassName)) throw new Tx_Extbase_Persistence_Exception_InvalidClass('The class "' . get_class($object) . '" is not supported by the repository.');
+//             if (!is_object($object) || !($object instanceof $this->aggregateRootClassName)) throw new Tx_Extbase_Persistence_Exception_InvalidClass('The class "' . get_class($object) . '" is not supported by the repository.');
                $this->persistenceManager->getSession()->registerRemovedObject($object);
        }
 
index e497d82..973c1d7 100644 (file)
@@ -280,34 +280,5 @@ class Tx_Extbase_Persistence_Session implements t3lib_singleton {
                return $this->aggregateRootClassNames;
        }
 
-       /**
-        * Commits the current persistence session.
-        *
-        * @return void
-        */
-       public function commit() {
-               // SK: This is old code, which needs to be removed.
-               $aggregateRootObjects = new Tx_Extbase_Persistence_ObjectStorage();
-               $aggregateRootObjects->addAll($this->getAddedObjects());
-               $aggregateRootObjects->addAll($this->getReconstitutedObjects());
-
-               // hand in only aggregate roots, leaving handling of subobjects to
-               // the underlying storage layer
-               $dataMapper = t3lib_div::makeInstance('Tx_Extbase_Persistence_Mapper_DataMapper'); // singleton
-               $dataMapper->setAggregateRootObjects($aggregateRootObjects);
-               $dataMapper->setDeletedObjects($this->getRemovedObjects());
-               $dataMapper->persistObjects();
-               $dataMapper->processDeletedObjects();
-
-               // this needs to unregister more than just those, as at least some of
-               // the subobjects are supposed to go away as well...
-               // OTOH those do no harm, changes to the unused ones should not happen,
-               // so all they do is eat some memory.
-               foreach($this->getRemovedObjects() as $removedObject) {
-                       $this->unregisterObject($removedObject);
-               }
-               
-       }
-
 }
 ?>
\ No newline at end of file
index edff1e0..f4c4ab3 100644 (file)
@@ -33,7 +33,7 @@
  * @version $Id: $
  * @scope prototype
  */
-class Tx_Extbase_Persistence_Storage_Typo3DbBackend implements Tx_Extbase_Persistence_Storage_BackendInterface {
+class Tx_Extbase_Persistence_Storage_Typo3DbBackend implements Tx_Extbase_Persistence_Storage_BackendInterface, t3lib_Singleton {
 
        /**
         * The TYPO3 database object
@@ -130,16 +130,18 @@ class Tx_Extbase_Persistence_Storage_Typo3DbBackend implements Tx_Extbase_Persis
                $parameters = array();
                $tuples = array();
 
-               $this->parseSource($query, $sql, $parameters);
-               if ($query->getConstraint() !== NULL) {
-                       $this->parseConstraint($query->getConstraint(), $sql, $parameters, $query->getBoundVariableValues());
-               }
 
+               $this->parseSource($query, $sql, $parameters);
+               $this->parseConstraint($query->getConstraint(), $sql, $parameters, $query->getBoundVariableValues());
+               $this->parseOrderings($query->getOrderings(), $sql, $parameters, $query->getBoundVariableValues());
 
                $sqlString = 'SELECT ' . implode(',', $sql['fields']) . ' FROM ' . implode(' ', $sql['tables']);
                if (!empty($sql['where'])) {
                        $sqlString .= ' WHERE ' . implode(' AND ', $sql['where']);
                }
+               if (!empty($sql['orderings'])) {
+                       $sqlString .= ' ORDER BY ' . implode(', ', $sql['orderings']);
+               }
                $this->replacePlaceholders($sqlString, $parameters);
                $result = $this->databaseHandle->sql_query($sqlString);
                if ($result) {
@@ -191,9 +193,8 @@ class Tx_Extbase_Persistence_Storage_Typo3DbBackend implements Tx_Extbase_Persis
                        $selectorName = $source->getSelectorName();
                        $sql['fields'][] = $selectorName . '.*';
                        $sql['tables'][] = $selectorName;
-                       if ($query->useEnableFields()) {
-                               $sql['where'][] = $this->getEnableFields($selectorName);
-                       }
+                       // TODO Should we make the usage of enableFields configurable? And how? Because the Query object and even the QOM should be abstracted from the storage backend.
+                       $this->addEnableFieldsStatement($selectorName, $sql);
                } elseif ($source instanceof Tx_Extbase_Persistence_QOM_JoinInterface) {
                        $this->parseJoin($source, $sql, $parameters);
                }
@@ -362,11 +363,34 @@ class Tx_Extbase_Persistence_Storage_Typo3DbBackend implements Tx_Extbase_Persis
 
        /**
         * Returns the enable fields part of a WHERE query
+        * @param string $selectorName The selector name (= database table name)
+        * @param array &$sql The query parts
+        *
+        * @return void
+        */
+       protected function addEnableFieldsStatement($selectorName, array &$sql) {
+               // TODO We have to call the appropriate API method if we are in TYPO3BE mode
+               $statement = substr($GLOBALS['TSFE']->sys_page->enableFields($selectorName), 4);
+               if (!empty($statement)) {
+                       $sql['where'][] = $statement;
+               }
+       }
+
+       /**
+        * Transforms orderings into SQL
         *
-        * @return string WHERE query part
+        * @param array $orderings
+        * @param array &$sql
+        * @param array &$parameters
+        * @param array $boundVariableValues
+        * @return void
         */
-       protected function getEnableFields($selectorName) {
-               return substr($GLOBALS['TSFE']->sys_page->enableFields($selectorName),4);
+       protected function parseOrderings(array $orderings = NULL, array &$sql, array &$parameters, array $boundVariableValues) {
+               if (is_array($orderings)) {
+                       foreach ($orderings as $propertyName => $ordering) {
+                               // TODO Implement
+                       }
+               }
        }
 
        /**