[BUGFIX] Determine translations from transOrigPointerField instead of languageField 01/44101/9
authorMathias Schreiber <mathias.schreiber@wmdb.de>
Fri, 16 Oct 2015 10:13:02 +0000 (12:13 +0200)
committerStefan Neufeind <typo3.neufeind@speedpartner.de>
Mon, 19 Oct 2015 07:29:26 +0000 (09:29 +0200)
The decision whether a record is a translation (and thus must overlay
another record is based upon languageField.
This is wrong because the decision must be based upon the field set in
transOrigPointerField.

Resolves: #32252
Releases: master
Change-Id: Ia4d83151ff302108241427873c2b56689c66fc1e
Reviewed-on: http://review.typo3.org/44101
Reviewed-by: Morton Jonuschat <m.jonuschat@mojocode.de>
Tested-by: Morton Jonuschat <m.jonuschat@mojocode.de>
Reviewed-by: Stefan Neufeind <typo3.neufeind@speedpartner.de>
Tested-by: Stefan Neufeind <typo3.neufeind@speedpartner.de>
typo3/sysext/backend/Classes/Form/Container/SingleFieldContainer.php
typo3/sysext/backend/Classes/Form/Element/NoneElement.php
typo3/sysext/backend/Tests/Unit/Form/Element/NoneElementTest.php

index 64cd38e..91dffcf 100644 (file)
@@ -60,20 +60,29 @@ class SingleFieldContainer extends AbstractContainer
         $parameterArray = array();
         $parameterArray['fieldConf'] = $this->data['processedTca']['columns'][$fieldName];
 
-        $languageField = $this->data['processedTca']['ctrl']['languageField'];
+        $isOverlay = false;
+
+        // This field decides whether the current record is an overlay (as opposed to being a standalone record)
+        // Based on this decision we need to trigger field exclusion or special rendering (like readOnly)
+        if (isset($this->data['processedTca']['ctrl']['transOrigPointerField'])
+            && is_array($this->data['processedTca']['columns'][$this->data['processedTca']['ctrl']['transOrigPointerField']])
+            && is_array($row[$this->data['processedTca']['ctrl']['transOrigPointerField']])
+            && $row[$this->data['processedTca']['ctrl']['transOrigPointerField']][0] > 0
+        ) {
+            $isOverlay = true;
+        }
 
         // A couple of early returns in case the field should not be rendered
         // Check if this field is configured and editable according to exclude fields and other configuration
-        if (
-            // Return if BE-user has no access rights to this field, @todo: another user access rights check!
+        if (// Return if BE-user has no access rights to this field, @todo: another user access rights check!
             $parameterArray['fieldConf']['exclude'] && !$backendUser->check('non_exclude_fields', $table . ':' . $fieldName)
             || $parameterArray['fieldConf']['config']['type'] === 'passthrough'
             // @todo: Drop option "showIfRTE" ?
             || !$backendUser->isRTE() && $parameterArray['fieldConf']['config']['showIfRTE']
             // Return if field should not be rendered in translated records
-            || $languageField && !$parameterArray['fieldConf']['l10n_display'] && $parameterArray['fieldConf']['l10n_mode'] === 'exclude' && is_array($row[$languageField]) && $row[$languageField][0] > 0
+            || $isOverlay && !$parameterArray['fieldConf']['l10n_display'] && $parameterArray['fieldConf']['l10n_mode'] === 'exclude'
             // @todo: localizationMode still needs handling!
-            || $languageField && $this->data['localizationMode'] && $this->data['localizationMode'] !== $parameterArray['fieldConf']['l10n_cat']
+            || $isOverlay && $this->data['localizationMode'] && $this->data['localizationMode'] !== $parameterArray['fieldConf']['l10n_cat']
             || $this->inlineFieldShouldBeSkipped()
         ) {
             return $resultArray;
@@ -100,7 +109,7 @@ class SingleFieldContainer extends AbstractContainer
         // Set field to read-only if configured for translated records to show default language content as readonly
         if ($parameterArray['fieldConf']['l10n_display']
             && GeneralUtility::inList($parameterArray['fieldConf']['l10n_display'], 'defaultAsReadonly')
-            && is_array($row[$languageField]) && $row[$languageField][0] > 0
+            && $isOverlay
         ) {
             $parameterArray['fieldConf']['config']['readOnly'] = true;
             $parameterArray['itemFormElValue'] = $this->data['defaultLanguageData'][$table . ':' . $row['uid']][$fieldName];
@@ -113,8 +122,7 @@ class SingleFieldContainer extends AbstractContainer
         }
         // Create a JavaScript code line which will ask the user to save/update the form due to changing the element.
         // This is used for eg. "type" fields and others configured with "requestUpdate"
-        if (
-            !empty($this->data['processedTca']['ctrl']['type'])
+        if (!empty($this->data['processedTca']['ctrl']['type'])
             && $fieldName === $typeField
             || !empty($this->data['processedTca']['ctrl']['requestUpdate'])
             && GeneralUtility::inList(str_replace(' ', '', $this->data['processedTca']['ctrl']['requestUpdate']), $fieldName)
@@ -176,8 +184,7 @@ class SingleFieldContainer extends AbstractContainer
 
         // Add language + diff
         $renderLanguageDiff = true;
-        if (
-            $parameterArray['fieldConf']['l10n_display'] && (GeneralUtility::inList($parameterArray['fieldConf']['l10n_display'], 'hideDiff')
+        if ($parameterArray['fieldConf']['l10n_display'] && (GeneralUtility::inList($parameterArray['fieldConf']['l10n_display'], 'hideDiff')
             || GeneralUtility::inList($parameterArray['fieldConf']['l10n_display'], 'defaultAsReadonly'))
         ) {
             $renderLanguageDiff = false;
@@ -494,15 +501,15 @@ class SingleFieldContainer extends AbstractContainer
      * A request could look like the following:
      *
      * $searchArray = array(
-     *   '%AND'        => array(
-     *     'key1'      => 'value1',
-     *     'key2'      => 'value2',
-     *     '%OR'       => array(
+     *   '%AND' => array(
+     *     'key1' => 'value1',
+     *     'key2' => 'value2',
+     *     '%OR' => array(
      *       'subarray' => array(
      *         'subkey' => 'subvalue'
      *       ),
-     *       'key3'    => 'value3',
-     *       'key4'    => 'value4'
+     *       'key3' => 'value3',
+     *       'key4' => 'value4'
      *     )
      *   )
      * );
index 3f0aff3..437e448 100644 (file)
@@ -104,25 +104,25 @@ class NoneElement extends AbstractFormElement
                 break;
             case 'datetime':
                 // compatibility with "eval" (type "input")
-                if ($itemValue !== '') {
+                if ($itemValue !== '' && !is_null($itemValue)) {
                     $itemValue = date('H:i d-m-Y', (int)$itemValue);
                 }
                 break;
             case 'time':
                 // compatibility with "eval" (type "input")
-                if ($itemValue !== '') {
+                if ($itemValue !== '' && !is_null($itemValue)) {
                     $itemValue = date('H:i', (int)$itemValue);
                 }
                 break;
             case 'timesec':
                 // compatibility with "eval" (type "input")
-                if ($itemValue !== '') {
+                if ($itemValue !== '' && !is_null($itemValue)) {
                     $itemValue = date('H:i:s', (int)$itemValue);
                 }
                 break;
             case 'year':
                 // compatibility with "eval" (type "input")
-                if ($itemValue !== '') {
+                if ($itemValue !== '' && !is_null($itemValue)) {
                     $itemValue = date('Y', (int)$itemValue);
                 }
                 break;
index 227a9f9..ed96a4d 100644 (file)
@@ -91,6 +91,13 @@ class NoneElementTest extends UnitTestCase
                 '',
                 ''
             ),
+            'format to datetime with null value' => array(
+                array(
+                    'format' => 'datetime',
+                ),
+                null,
+                ''
+            ),
             'format to time' => array(
                 array(
                     'format' => 'time',
@@ -105,6 +112,13 @@ class NoneElementTest extends UnitTestCase
                 '',
                 ''
             ),
+            'format to time with null value' => array(
+                array(
+                    'format' => 'time',
+                ),
+                null,
+                ''
+            ),
             'format to timesec' => array(
                 array(
                     'format' => 'timesec',
@@ -119,6 +133,13 @@ class NoneElementTest extends UnitTestCase
                 '',
                 ''
             ),
+            'format to timesec with null value' => array(
+                array(
+                    'format' => 'timesec',
+                ),
+                null,
+                ''
+            ),
             'format to year' => array(
                 array(
                     'format' => 'year',
@@ -126,6 +147,20 @@ class NoneElementTest extends UnitTestCase
                 '1412358894',
                 '2014'
             ),
+            'format to year with empty value' => array(
+                array(
+                    'format' => 'year',
+                ),
+                '',
+                ''
+            ),
+            'format to year with null value' => array(
+                array(
+                    'format' => 'year',
+                ),
+                null,
+                ''
+            ),
             'format to int' => array(
                 array(
                     'format' => 'int',