[BUGFIX] MM language synchronization is ignored on initial localization 04/52004/7
authorOliver Hader <oliver@typo3.org>
Sat, 11 Mar 2017 09:50:11 +0000 (10:50 +0100)
committerBenni Mack <benni@typo3.org>
Sun, 12 Mar 2017 10:58:29 +0000 (11:58 +0100)
The language synchronization of many-to-many fields (MM) is ignored for
the initial localization command, but is considered again when further
changes happen to source/parent elements of a localized element.

Besides fixing the missing 'config' segment on resolving the foreign
table name of the field to be synchronized, the special handling for
language assignments has been added - albeit it might not been used
in fields different to sys_language_uid.

Change-Id: I8bf02ee117fa41cf5b0425d0e535fced84fb72ca
Resolves: #80211
Releases: master
Reviewed-on: https://review.typo3.org/52004
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Susanne Moog <susanne.moog@typo3.org>
Tested-by: Susanne Moog <susanne.moog@typo3.org>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Christian Müllenhagen <christianmuellenhagen@yahoo.de>
Reviewed-by: Benni Mack <benni@typo3.org>
Tested-by: Benni Mack <benni@typo3.org>
typo3/sysext/core/Classes/DataHandling/Localization/DataMapProcessor.php
typo3/sysext/core/Tests/Functional/DataHandling/ManyToMany/AbstractActionTestCase.php
typo3/sysext/core/Tests/Functional/DataHandling/ManyToMany/Modify/ActionTest.php
typo3/sysext/core/Tests/Functional/DataHandling/ManyToMany/Modify/DataSet/localizeContentChainOfRelationNAddCategoryWSynchronization.csv [new file with mode: 0644]
typo3/sysext/core/Tests/Functional/DataHandling/ManyToMany/Modify/DataSet/localizeContentOfRelationNAddCategoryWSynchronization.csv [new file with mode: 0644]
typo3/sysext/core/Tests/Functional/DataHandling/ManyToMany/Modify/DataSet/localizeContentOfRelationWSynchronization.csv [new file with mode: 0644]

index c21e2ba..727b842 100644 (file)
@@ -417,13 +417,14 @@ class DataMapProcessor
         $fromId = $fromRecord['uid'];
         $fromValue = $this->allDataMap[$item->getFromTableName()][$fromId][$fieldName] ?? $fromRecord[$fieldName];
         $configuration = $GLOBALS['TCA'][$item->getFromTableName()]['columns'][$fieldName];
+        $isSpecialLanguageField = ($configuration['config']['special'] ?? null) === 'languages';
 
         // non-MM relations are stored as comma separated values, just use them
         // if values are available in data-map already, just use them as well
         if (
             empty($configuration['config']['MM'])
             || isset($this->allDataMap[$item->getFromTableName()][$fromId][$fieldName])
-            || ($configuration['config']['special'] ?? null) === 'languages'
+            || $isSpecialLanguageField
         ) {
             $this->modifyDataMap(
                 $item->getTableName(),
@@ -432,14 +433,17 @@ class DataMapProcessor
             );
             return;
         }
-
+        // resolve the language special table name
+        if ($isSpecialLanguageField) {
+            $specialTableName = 'sys_language';
+        }
         // fetch MM relations from storage
         $type = $configuration['config']['type'];
         $manyToManyTable = $configuration['config']['MM'];
         if ($type === 'group' && $configuration['config']['internal_type'] === 'db') {
             $tableNames = trim($configuration['config']['allowed'] ?? '');
         } elseif ($configuration['config']['type'] === 'select') {
-            $tableNames = ($configuration['foreign_table'] ?? '');
+            $tableNames = ($specialTableName ?? $configuration['config']['foreign_table'] ?? '');
         } else {
             return;
         }
index 5f0a6d5..a05193a 100644 (file)
@@ -24,14 +24,19 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
     const VALUE_ContentIdFirst = 297;
     const VALUE_ContentIdLast = 298;
     const VALUE_LanguageId = 1;
+    const VALUE_LanguageIdSecond = 2;
     const VALUE_CategoryIdFirst = 28;
     const VALUE_CategoryIdSecond = 29;
+    const VALUE_CategoryIdThird = 30;
+    const VALUE_CategoryIdFourth = 31;
 
     const TABLE_Page = 'pages';
     const TABLE_Content = 'tt_content';
     const TABLE_Category = 'sys_category';
     const TABLE_ContentCategory_ManyToMany = 'sys_category_record_mm';
 
+    const FIELD_Categories = 'categories';
+
     /**
      * @var string
      */
@@ -178,6 +183,42 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
         $this->recordIds['localizedContentId'] = $localizedTableIds[self::TABLE_Content][self::VALUE_ContentIdLast];
     }
 
+    public function localizeContentOfRelationWithLanguageSynchronization()
+    {
+        $GLOBALS['TCA'][self::TABLE_Content]['columns'][self::FIELD_Categories]['config']['behaviour']['allowLanguageSynchronization'] = true;
+        $localizedTableIds = $this->actionService->localizeRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_LanguageId);
+        $this->recordIds['localizedContentId'] = $localizedTableIds[self::TABLE_Content][self::VALUE_ContentIdLast];
+    }
+
+    public function localizeContentOfRelationAndAddCategoryWithLanguageSynchronization()
+    {
+        self::localizeContentOfRelationWithLanguageSynchronization();
+        $this->actionService->modifyReferences(
+            self::TABLE_Content,
+            self::VALUE_ContentIdLast,
+            self::FIELD_Categories,
+            [self::VALUE_CategoryIdSecond, self::VALUE_CategoryIdThird, self::VALUE_CategoryIdFourth]
+        );
+    }
+
+    public function localizeContentChainOfRelationAndAddCategoryWithLanguageSynchronization()
+    {
+        self::localizeContentOfRelationWithLanguageSynchronization();
+        $localizedTableIds = $this->actionService->localizeRecord(self::TABLE_Content, $this->recordIds['localizedContentId'], self::VALUE_LanguageIdSecond);
+        $this->recordIds['localizedContentIdSecond'] = $localizedTableIds[self::TABLE_Content][$this->recordIds['localizedContentId']];
+        $this->actionService->modifyRecord(
+            self::TABLE_Content,
+            $this->recordIds['localizedContentIdSecond'],
+            ['l10n_state' => [self::FIELD_Categories => 'source']]
+        );
+        $this->actionService->modifyReferences(
+            self::TABLE_Content,
+            self::VALUE_ContentIdLast,
+            self::FIELD_Categories,
+            [self::VALUE_CategoryIdSecond, self::VALUE_CategoryIdThird, self::VALUE_CategoryIdFourth]
+        );
+    }
+
     /**
      * @test
      * @see DataSet/localizeCategoryRecordOfCategoryRelation.csv
index 4d4f067..f2a0f0b 100644 (file)
@@ -229,6 +229,51 @@ class ActionTest extends \TYPO3\CMS\Core\Tests\Functional\DataHandling\ManyToMan
 
     /**
      * @test
+     * @see DataSet/localizeContentOfRelationWSynchronization.csv
+     */
+    public function localizeContentOfRelationWithLanguageSynchronization()
+    {
+        parent::localizeContentOfRelationWithLanguageSynchronization();
+        $this->assertAssertionDataSet('localizeContentOfRelationWSynchronization');
+
+        $responseSections = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageId)->getResponseSections();
+        $this->assertThat($responseSections, $this->getRequestSectionStructureHasRecordConstraint()
+            ->setRecordIdentifier(self::TABLE_Content . ':' . self::VALUE_ContentIdLast)->setRecordField('categories')
+            ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
+    }
+
+    /**
+     * @test
+     * @see DataSet/localizeContentOfRelationNAddCategoryWSynchronization.csv
+     */
+    public function localizeContentOfRelationAndAddCategoryWithLanguageSynchronization()
+    {
+        parent::localizeContentOfRelationAndAddCategoryWithLanguageSynchronization();
+        $this->assertAssertionDataSet('localizeContentOfRelationNAddCategoryWSynchronization');
+
+        $responseSections = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageId)->getResponseSections();
+        $this->assertThat($responseSections, $this->getRequestSectionStructureHasRecordConstraint()
+            ->setRecordIdentifier(self::TABLE_Content . ':' . self::VALUE_ContentIdLast)->setRecordField('categories')
+            ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C', 'Category A.A'));
+    }
+
+    /**
+     * @test
+     * @see DataSet/localizeContentChainOfRelationNAddCategoryWSynchronization.csv
+     */
+    public function localizeContentChainOfRelationAndAddCategoryWithLanguageSynchronization()
+    {
+        parent::localizeContentChainOfRelationAndAddCategoryWithLanguageSynchronization();
+        $this->assertAssertionDataSet('localizeContentChainOfRelationNAddCategoryWSynchronization');
+
+        $responseSections = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageIdSecond)->getResponseSections();
+        $this->assertThat($responseSections, $this->getRequestSectionStructureHasRecordConstraint()
+            ->setRecordIdentifier(self::TABLE_Content . ':' . self::VALUE_ContentIdLast)->setRecordField('categories')
+            ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C', 'Category A.A'));
+    }
+
+    /**
+     * @test
      * @see DataSet/localizeCategoryRecordOfCategoryRelation.csv
      */
     public function localizeCategoryOfRelation()
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/ManyToMany/Modify/DataSet/localizeContentChainOfRelationNAddCategoryWSynchronization.csv b/typo3/sysext/core/Tests/Functional/DataHandling/ManyToMany/Modify/DataSet/localizeContentChainOfRelationNAddCategoryWSynchronization.csv
new file mode 100644 (file)
index 0000000..e773418
--- /dev/null
@@ -0,0 +1,25 @@
+sys_category
+,uid,pid,sorting,deleted,sys_language_uid,l10n_parent,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,title,parent,items
+,28,0,256,0,0,0,0,0,0,0,0,0,"Category A",0,0
+,29,0,512,0,0,0,0,0,0,0,0,0,"Category B",0,0
+,30,0,768,0,0,0,0,0,0,0,0,0,"Category C",0,0
+,31,0,1024,0,0,0,0,0,0,0,0,0,"Category A.A",28,0
+sys_category_record_mm
+,uid_local,uid_foreign,tablenames,sorting,sorting_foreign,fieldname
+,28,297,tt_content,0,1,categories
+,29,297,tt_content,0,2,categories
+,29,298,tt_content,0,1,categories
+,30,298,tt_content,0,2,categories
+,29,299,tt_content,0,1,categories
+,30,299,tt_content,0,2,categories
+,29,300,tt_content,0,1,categories
+,30,300,tt_content,0,2,categories
+,31,298,tt_content,0,3,categories
+,31,299,tt_content,0,3,categories
+,31,300,tt_content,0,3,categories
+tt_content
+,uid,pid,sorting,deleted,sys_language_uid,l18n_parent,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,header,image,categories,l10n_state
+,297,89,256,0,0,0,0,0,0,0,0,0,"Regular Element #1",0,2,\NULL
+,298,89,512,0,0,0,0,0,0,0,0,0,"Regular Element #2",0,3,\NULL
+,299,89,768,0,1,298,298,0,0,0,0,0,"[Translate to Dansk:] Regular Element #2",0,3,"{""categories"":""parent""}"
+,300,89,1024,0,2,298,299,0,0,0,0,0,"[Translate to Deutsch:] [Translate to Dansk:] Regular Element #2",0,3,"{""categories"":""source""}"
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/ManyToMany/Modify/DataSet/localizeContentOfRelationNAddCategoryWSynchronization.csv b/typo3/sysext/core/Tests/Functional/DataHandling/ManyToMany/Modify/DataSet/localizeContentOfRelationNAddCategoryWSynchronization.csv
new file mode 100644 (file)
index 0000000..ed73676
--- /dev/null
@@ -0,0 +1,21 @@
+sys_category
+,uid,pid,sorting,deleted,sys_language_uid,l10n_parent,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,title,parent,items
+,28,0,256,0,0,0,0,0,0,0,0,0,"Category A",0,0
+,29,0,512,0,0,0,0,0,0,0,0,0,"Category B",0,0
+,30,0,768,0,0,0,0,0,0,0,0,0,"Category C",0,0
+,31,0,1024,0,0,0,0,0,0,0,0,0,"Category A.A",28,0
+sys_category_record_mm
+,uid_local,uid_foreign,tablenames,sorting,sorting_foreign,fieldname
+,28,297,tt_content,0,1,categories
+,29,297,tt_content,0,2,categories
+,29,298,tt_content,0,1,categories
+,30,298,tt_content,0,2,categories
+,31,298,tt_content,0,3,categories
+,29,299,tt_content,0,1,categories
+,30,299,tt_content,0,2,categories
+,31,299,tt_content,0,3,categories
+tt_content
+,uid,pid,sorting,deleted,sys_language_uid,l18n_parent,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,header,image,categories,l10n_state
+,297,89,256,0,0,0,0,0,0,0,0,0,"Regular Element #1",0,2,\NULL
+,298,89,512,0,0,0,0,0,0,0,0,0,"Regular Element #2",0,3,\NULL
+,299,89,768,0,1,298,298,0,0,0,0,0,"[Translate to Dansk:] Regular Element #2",0,3,"{""categories"":""parent""}"
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/ManyToMany/Modify/DataSet/localizeContentOfRelationWSynchronization.csv b/typo3/sysext/core/Tests/Functional/DataHandling/ManyToMany/Modify/DataSet/localizeContentOfRelationWSynchronization.csv
new file mode 100644 (file)
index 0000000..24a0853
--- /dev/null
@@ -0,0 +1,19 @@
+sys_category
+,uid,pid,sorting,deleted,sys_language_uid,l10n_parent,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,title,parent,items
+,28,0,256,0,0,0,0,0,0,0,0,0,"Category A",0,0
+,29,0,512,0,0,0,0,0,0,0,0,0,"Category B",0,0
+,30,0,768,0,0,0,0,0,0,0,0,0,"Category C",0,0
+,31,0,1024,0,0,0,0,0,0,0,0,0,"Category A.A",28,0
+sys_category_record_mm
+,uid_local,uid_foreign,tablenames,sorting,sorting_foreign,fieldname
+,28,297,tt_content,0,1,categories
+,29,297,tt_content,0,2,categories
+,29,298,tt_content,0,1,categories
+,30,298,tt_content,0,2,categories
+,29,299,tt_content,0,1,categories
+,30,299,tt_content,0,2,categories
+tt_content
+,uid,pid,sorting,deleted,sys_language_uid,l18n_parent,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,header,image,categories,l10n_state
+,297,89,256,0,0,0,0,0,0,0,0,0,"Regular Element #1",0,2,\NULL
+,298,89,512,0,0,0,0,0,0,0,0,0,"Regular Element #2",0,2,\NULL
+,299,89,768,0,1,298,298,0,0,0,0,0,"[Translate to Dansk:] Regular Element #2",0,2,"{""categories"":""parent""}"