[+BUGFIX] Extbase: Fixed translation handling. You can now show and edit exiting...
authorJochen Rau <j.rau@web.de>
Wed, 14 Apr 2010 13:41:14 +0000 (13:41 +0000)
committerJochen Rau <j.rau@web.de>
Wed, 14 Apr 2010 13:41:14 +0000 (13:41 +0000)
typo3/sysext/extbase/Classes/DomainObject/AbstractDomainObject.php
typo3/sysext/extbase/Classes/Persistence/Backend.php
typo3/sysext/extbase/Classes/Persistence/LazyObjectStorage.php
typo3/sysext/extbase/Classes/Persistence/Mapper/DataMap.php
typo3/sysext/extbase/Classes/Persistence/Mapper/DataMapFactory.php
typo3/sysext/extbase/Classes/Persistence/Mapper/DataMapper.php
typo3/sysext/extbase/Classes/Persistence/Query.php
typo3/sysext/extbase/Classes/Persistence/Storage/Typo3DbBackend.php

index 30f25af..2a5f020 100644 (file)
@@ -39,9 +39,14 @@ abstract class Tx_Extbase_DomainObject_AbstractDomainObject implements Tx_Extbas
        protected $uid;
 
        /**
-        * @var int The uid of the localization parent
+        * @var int The uid of the localized record. In TYPO3 v4.x the property "uid" holds the uid of the record in default language (the translationOrigin).
         */
-       protected $_localizationParentUid;
+       protected $_localizedUid;
+
+       /**
+        * @var int The uid of the language of the object. In TYPO3 v4.x this is the uid of the language record in the table sys_language.
+        */
+       protected $_languageUid;
 
        /**
         * TRUE if the object is a clone
index 57a1261..3fc3a48 100644 (file)
@@ -369,18 +369,16 @@ class Tx_Extbase_Persistence_Backend implements Tx_Extbase_Persistence_BackendIn
                        $propertyType = $propertyMetaData['type'];
                        // FIXME enable property-type check
                        // $this->checkPropertyType($propertyType, $propertyValue);
-                       if (($propertyValue !== NULL) && ($propertyValue instanceof Tx_Extbase_Persistence_ObjectStorage || $propertyType === 'Tx_Extbase_Persistence_ObjectStorage')) {
+                       if (($propertyValue !== NULL) && ($propertyType === 'SplObjectStorage' || $propertyType === 'Tx_Extbase_Persistence_ObjectStorage')) {
                                if ($object->_isNew() || $object->_isDirty($propertyName)) {
                                        $this->persistObjectStorage($propertyValue, $object, $propertyName, $queue, $row);
-                                       if (is_array($propertyValue) || $propertyValue instanceof Iterator) {
-                                               foreach ($propertyValue as $containedObject) {
-                                                       if ($containedObject instanceof Tx_Extbase_DomainObject_AbstractEntity) {
-                                                               $queue[] = $containedObject;
-                                                       }
+                                       foreach ($propertyValue as $containedObject) {
+                                               if ($containedObject instanceof Tx_Extbase_DomainObject_AbstractDomainObject) {
+                                                       $queue[] = $containedObject;
                                                }
                                        }
                                }
-                       } elseif ($propertyValue instanceof Tx_Extbase_DomainObject_DomainObjectInterface) {                            
+                       } elseif ($propertyValue instanceof Tx_Extbase_DomainObject_DomainObjectInterface) {
                                if ($object->_isDirty($propertyName)) {
                                        if ($propertyValue->_isNew()) {
                                                if ($propertyValue instanceof Tx_Extbase_DomainObject_AbstractEntity) {
@@ -661,23 +659,25 @@ class Tx_Extbase_Persistence_Backend implements Tx_Extbase_Persistence_BackendIn
        }
        
        /**
-        * Inserts an object in the storage
+        * Inserts an object in the storage backend
         *
         * @param Tx_Extbase_DomainObject_DomainObjectInterface $object The object to be insterted in the storage
-        * @param array $row The tuple to be inserted
-        * @param Tx_Extbase_DomainObject_AbstractEntity $parentObject The parent object (if any)
-        * @param string $parentPropertyName The name of the property
+        * @return void
         */
-       protected function insertObject(Tx_Extbase_DomainObject_DomainObjectInterface $object, array $row = array()) {
-               $tableName = $this->dataMapper->getDataMap(get_class($object))->getTableName();
+       protected function insertObject(Tx_Extbase_DomainObject_DomainObjectInterface $object) {
+               $row = array();
+               $dataMap = $this->dataMapper->getDataMap(get_class($object));
                $this->addCommonFieldsToRow($object, $row);
+               if($dataMap->getLanguageIdColumnName() !== NULL) {
+                       $row[$dataMap->getLanguageIdColumnName()] = -1;
+               }
                $uid = $this->storageBackend->addRow(
-                       $tableName,
+                       $dataMap->getTableName(),
                        $row
                        );
                $object->_setProperty('uid', (int)$uid);
                if ($this->extbaseSettings['persistence']['updateReferenceIndex'] === '1') {
-                       $this->referenceIndex->updateRefIndexTable($tableName, $uid);
+                       $this->referenceIndex->updateRefIndexTable($dataMap->getTableName(), $uid);
                }
                $this->identityMap->registerObject($object, $uid);
        }
@@ -781,17 +781,22 @@ class Tx_Extbase_Persistence_Backend implements Tx_Extbase_Persistence_BackendIn
         * @param string|NULL $parentPropertyName The name of the property
         * @param array $row The $row
         */
-       protected function updateObject(Tx_Extbase_DomainObject_DomainObjectInterface $object, array &$row) {
-               $tableName = $this->dataMapper->getDataMap(get_class($object))->getTableName();
+       protected function updateObject(Tx_Extbase_DomainObject_DomainObjectInterface $object, array $row) {
+               $dataMap = $this->dataMapper->getDataMap(get_class($object));
                $this->addCommonFieldsToRow($object, $row);
-               $uid = $object->getUid();
-               $row['uid'] = $uid;
+               if($dataMap->getLanguageIdColumnName() !== NULL) {
+                       $row[$dataMap->getLanguageIdColumnName()] = $object->_getProperty('_languageUid');
+                       $row['uid'] = $object->_getProperty('_localizedUid');
+                       // $row[$dataMap->getTranslationOriginColumnName()] = $object->_getProperty('_languageUid');
+               } else {
+                       $row['uid'] = $object->getUid();
+               }
                $res = $this->storageBackend->updateRow(
-                       $tableName,
+                       $dataMap->getTableName(),
                        $row
                        );
                if ($this->extbaseSettings['persistence']['updateReferenceIndex'] === '1') {
-                       $this->referenceIndex->updateRefIndexTable($tableName, $uid);
+                       $this->referenceIndex->updateRefIndexTable($dataMap->getTableName(), $row['uid']);
                }
                return $res;
        }
index 04c6cbf..0d67503 100644 (file)
@@ -83,7 +83,7 @@ class Tx_Extbase_Persistence_LazyObjectStorage extends Tx_Extbase_Persistence_Ob
        protected function initializeStorage() {
                if (!$this->isInitialized) {
                        $dataMapper = Tx_Extbase_Dispatcher::getPersistenceManager()->getBackend()->getDataMapper();
-                       $objects = $dataMapper->fetchRelated($this->parentObject, $this->propertyName, $this->fieldValue, FALSE, FALSE);
+                       $objects = $dataMapper->fetchRelated($this->parentObject, $this->propertyName, $this->fieldValue, FALSE);
                        $storage = array();
                        foreach ($objects as $object) {
                                $storage[spl_object_hash($object)] = $object;
index 7251011..3d5b7bb 100644 (file)
@@ -60,6 +60,16 @@ class Tx_Extbase_Persistence_Mapper_DataMap {
        /**
         * @var string
         **/
+       protected $languageIdColumnName;
+
+       /**
+        * @var string
+        **/
+       protected $translationOriginColumnName;
+
+       /**
+        * @var string
+        **/
        protected $modificationDateColumnName;
 
        /**
@@ -193,7 +203,44 @@ class Tx_Extbase_Persistence_Mapper_DataMap {
                return $this->pageIdColumnName;
        }
        
-
+       /**
+        * Sets the name of a column holding the language id of the record
+        *
+        * @param string $languageIdColumnName The field name
+        * @return void
+        */
+       public function setLanguageIdColumnName($languageIdColumnName) {
+               $this->languageIdColumnName = $languageIdColumnName;
+       }
+               
+       /**
+        * Returns the name of a column holding the language id of the record.
+        *
+        * @return string The field name
+        */
+       public function getLanguageIdColumnName() {
+               return $this->languageIdColumnName;
+       }
+       
+       /**
+        * Sets the name of a column holding the the uid of the record which this record is a translation of.
+        *
+        * @param string $translationOriginColumnName The field name
+        * @return void
+        */
+       public function setTranslationOriginColumnName($translationOriginColumnName) {
+               $this->translationOriginColumnName = $translationOriginColumnName;
+       }
+               
+       /**
+        * Returns the name of a column holding the the uid of the record which this record is a translation of.
+        *
+        * @return string The field name
+        */
+       public function getTranslationOriginColumnName() {
+               return $this->translationOriginColumnName;
+       }
+       
        /**
         * Sets the name of a column holding the timestamp the record was modified
         *
index f7ddc9c..983587c 100644 (file)
@@ -105,6 +105,8 @@ class Tx_Extbase_Persistence_Mapper_DataMapFactory {
                if (isset($controlSection['crdate'])) $dataMap->setCreationDateColumnName($controlSection['crdate']);
                if (isset($controlSection['cruser_id'])) $dataMap->setCreatorColumnName($controlSection['cruser_id']);
                if (isset($controlSection['delete'])) $dataMap->setDeletedFlagColumnName($controlSection['delete']);
+               if (isset($controlSection['languageField'])) $dataMap->setLanguageIdColumnName($controlSection['languageField']);
+               if (isset($controlSection['transOrigPointerField'])) $dataMap->setTranslationOriginColumnName($controlSection['transOrigPointerField']);
                if (isset($controlSection['enablecolumns']['disabled'])) $dataMap->setDisabledFlagColumnName($controlSection['enablecolumns']['disabled']);
                if (isset($controlSection['enablecolumns']['starttime'])) $dataMap->setStartTimeColumnName($controlSection['enablecolumns']['starttime']);
                if (isset($controlSection['enablecolumns']['endtime'])) $dataMap->setEndTimeColumnName($controlSection['enablecolumns']['endtime']);
index e37b802..9f5f4dc 100644 (file)
@@ -190,14 +190,16 @@ class Tx_Extbase_Persistence_Mapper_DataMapper implements t3lib_Singleton {
        protected function thawProperties(Tx_Extbase_DomainObject_DomainObjectInterface $object, array $row) {
                $className = get_class($object);
                $dataMap = $this->getDataMap($className);
-               $properties = $object->_getProperties();
-               $localizedUid = $row['_LOCALIZED_UID'];
-               if ($localizedUid !== NULL) {
-                       $object->_setProperty('uid', $localizedUid);
-                       $object->_setProperty('_localizationParentUid', $row['uid']);
-               } else {
-                       $object->_setProperty('uid', $row['uid']);
+               $object->_setProperty('uid', intval($row['uid']));
+               if ($dataMap->getLanguageIdColumnName() !== NULL) {
+                       $object->_setProperty('_languageUid', intval($row[$dataMap->getLanguageIdColumnName()]));
+                       if (isset($row['_LOCALIZED_UID'])) {
+                               $object->_setProperty('_localizedUid', intval($row['_LOCALIZED_UID']));
+                       } else {
+                               $object->_setProperty('_localizedUid', intval($row['uid']));
+                       }
                }
+               $properties = $object->_getProperties();
                foreach ($properties as $propertyName => $propertyValue) {
                        if (!$dataMap->isPersistableProperty($propertyName)) continue;
                        $columnMap = $dataMap->getColumnMap($propertyName);
@@ -267,7 +269,7 @@ class Tx_Extbase_Persistence_Mapper_DataMapper implements t3lib_Singleton {
         * @param bool $performLanguageOverlay A flag indication if the related objects should be localized
         * @return mixed The result
         */
-       public function fetchRelated(Tx_Extbase_DomainObject_DomainObjectInterface $parentObject, $propertyName, $fieldValue = '', $enableLazyLoading = TRUE, $performLanguageOverlay = TRUE) {
+       public function fetchRelated(Tx_Extbase_DomainObject_DomainObjectInterface $parentObject, $propertyName, $fieldValue = '', $enableLazyLoading = TRUE) {
                $columnMap = $this->getDataMap(get_class($parentObject))->getColumnMap($propertyName);
                $propertyMetaData = $this->reflectionService->getClassSchema(get_class($parentObject))->getProperty($propertyName);
                if ($enableLazyLoading === TRUE && $propertyMetaData['lazy']) {
@@ -281,7 +283,7 @@ class Tx_Extbase_Persistence_Mapper_DataMapper implements t3lib_Singleton {
                                }
                        }
                } else {
-                       $result = $this->fetchRelatedEager($parentObject, $propertyName, $fieldValue, $performLanguageOverlay);
+                       $result = $this->fetchRelatedEager($parentObject, $propertyName, $fieldValue);
                }
                return $result;
        }
@@ -295,10 +297,9 @@ class Tx_Extbase_Persistence_Mapper_DataMapper implements t3lib_Singleton {
         * @param bool $performLanguageOverlay A flag indication if the related objects should be localized
         * @return void
         */
-       protected function fetchRelatedEager(Tx_Extbase_DomainObject_DomainObjectInterface $parentObject, $propertyName, $fieldValue = '', $performLanguageOverlay = TRUE) {
+       protected function fetchRelatedEager(Tx_Extbase_DomainObject_DomainObjectInterface $parentObject, $propertyName, $fieldValue = '') {
                if ($fieldValue === '') return array();
                $query = $this->getPreparedQuery($parentObject, $propertyName, $fieldValue);
-               $query->getQuerySettings()->setRespectSysLanguage($performLanguageOverlay);
                return $query->execute();
        }
        
@@ -318,9 +319,9 @@ class Tx_Extbase_Persistence_Mapper_DataMapper implements t3lib_Singleton {
                if ($columnMap->getTypeOfRelation() === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_ONE) {
                        $query = $queryFactory->create($this->getType(get_class($parentObject), $propertyName));
                        if (isset($parentKeyFieldName)) {
-                               $query->matching($query->equals($parentKeyFieldName, $parentObject->getUid()));
+                               $query->matching($query->equals($parentKeyFieldName, $parentObject));
                        } else {
-                               $query->matching($query->withUid(intval($fieldValue)));
+                               $query->matching($query->equals('uid', intval($fieldValue)));
                        }
                } elseif ($columnMap->getTypeOfRelation() === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_MANY) {
                        $query = $queryFactory->create($this->getElementType(get_class($parentObject), $propertyName));
@@ -331,7 +332,7 @@ class Tx_Extbase_Persistence_Mapper_DataMapper implements t3lib_Singleton {
                                $query->setOrderings(array($childSortByFieldName => Tx_Extbase_Persistence_QueryInterface::ORDER_ASCENDING));
                        }
                        if (isset($parentKeyFieldName)) {
-                               $query->matching($query->equals($parentKeyFieldName, $parentObject->getUid()));
+                               $query->matching($query->equals($parentKeyFieldName, $parentObject));
                        } else {
                                $query->matching($query->in('uid', t3lib_div::intExplode(',', $fieldValue)));                                   
                        }
@@ -369,7 +370,7 @@ class Tx_Extbase_Persistence_Mapper_DataMapper implements t3lib_Singleton {
                        $query->matching($conditions);
                        
                } else {
-                       throw new Tx_Extbase_Persistence_Exception('Could not determine type of relation. This is mainly caused by a missing type declaration above the property definition.', 1252502725);
+                       throw new Tx_Extbase_Persistence_Exception('Could not determine type of relation for the property "' . $propertyName . '". This is mainly caused by a missing type declaration above the property definition.', 1252502725);
                }
                return $query;
        }
index e4c5eef..45405cd 100644 (file)
@@ -333,7 +333,6 @@ class Tx_Extbase_Persistence_Query implements Tx_Extbase_Persistence_QueryInterf
         * Gets the constraint for this query.
         *
         * @return Tx_Extbase_Persistence_QOM_Constraint the constraint, or null if none
-        * @author Karsten Dambekalns <karsten@typo3.org>
         * @api
        */
        public function getConstraint() {
@@ -411,7 +410,7 @@ class Tx_Extbase_Persistence_Query implements Tx_Extbase_Persistence_QueryInterf
         *
         * @param int $uid The uid to match against
         * @return Tx_Extbase_Persistence_QOM_ComparisonInterface
-        * @deprecated since Extbase 2.0; was removed in FLOW3; will be removed in Extbase 3.0; use equals() ínstead
+        * @deprecated since Extbase 1.2.0; was removed in FLOW3; will be removed in Extbase 1.3.0; use equals() instead
         */
        public function withUid($operand) {
                t3lib_div::logDeprecatedFunction();
index 272b426..75d578e 100644 (file)
@@ -877,6 +877,7 @@ class Tx_Extbase_Persistence_Storage_Typo3DbBackend implements Tx_Extbase_Persis
                        if (is_object($GLOBALS['TSFE'])) {
                                if ($languageUid === NULL) {
                                        $languageUid = $GLOBALS['TSFE']->sys_language_uid;
+                                       $languageMode = $GLOBALS['TSFE']->sys_language_mode;
                                }
                                if ($workspaceUid !== NULL) {
                                        $this->pageSelectObject->versioningWorkspaceId = $workspaceUid;
@@ -898,10 +899,13 @@ class Tx_Extbase_Persistence_Storage_Typo3DbBackend implements Tx_Extbase_Persis
                        $this->pageSelectObject->versionOL($tableName, $row, TRUE);
                        if(isset($GLOBALS['TCA'][$tableName]['ctrl']['languageField']) && $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] !== '') {
                                if (in_array($row[$GLOBALS['TCA'][$tableName]['ctrl']['languageField']], array(-1,0))) {
-                                       $row = $this->pageSelectObject->getRecordOverlay($tableName, $row, $languageUid);
+                                       $overlayMode = ($languageMode === 'strict') ? 'hideNonTranslated' : '';
+                                       $row = $this->pageSelectObject->getRecordOverlay($tableName, $row, $languageUid, $overlayMode);
                                }
                        }
-                       $overlayedRows[] = $row;
+                       if ($row !== NULL) {
+                               $overlayedRows[] = $row;
+                       }
                }
                return $overlayedRows;
        }