Commit e7217da4 authored by Oliver Hader's avatar Oliver Hader Committed by Oliver Hader
Browse files

[BUGFIX] Add allowLanguageSynchronization chain resolving

Currently the localization behavior does not consider localization
chains concerning field values to be synchronized over multiple
localization hops that use the relative l10n_state "source".

Imagine the following scenario of content elements:
* { uid:10, sys_language_uid:0, l18n_parent:0, l10n_source:0,
    header:Value, l10n_state:null }
* { uid:11, sys_language_uid:1, l18n_parent:10, l10n_source:10,
    header:Value, l10n_state:{header:parent} }
* { uid:12, sys_language_uid:2, l18n_parent:10, l10n_source:11,
    header:Value, l10n_state:{header:source} }

Now if the record of the default language (uid:10) will be updated and
the header value set to "Modified", only direct dependents would be
synchronized. The automated update of the direct-child localization
record (uid:11) does not trigger another update for the grand-child
localization (uid:12).
To achieve this, the data-map processor has been extended to collect
new modifications to the data-map caused by synchronization processes
- as long as modifications could be determined, another synchronization
round is triggered for the modified items.
This way the localization chain is completely synchronized if required,
depending on the according l10n_state settings.

Change-Id: Ic08460f3ed0071f3dca6c6d1666031895bc3d832
Resolves: #80141
Releases: master
Reviewed-on: https://review.typo3.org/51952


Tested-by: default avatarTYPO3com <no-reply@typo3.com>
Tested-by: Susanne Moog's avatarSusanne Moog <susanne.moog@typo3.org>
Reviewed-by: Susanne Moog's avatarSusanne Moog <susanne.moog@typo3.org>
Reviewed-by: Oliver Hader's avatarOliver Hader <oliver.hader@typo3.org>
Tested-by: Oliver Hader's avatarOliver Hader <oliver.hader@typo3.org>
parent 3f35a3c1
......@@ -24,6 +24,7 @@ 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_ElementIdFirst = 1;
const VALUE_ElementIdSecond = 2;
const VALUE_ElementIdThird = 3;
......@@ -219,7 +220,7 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
public function localizeContentOfRelationWithLanguageSynchronization()
{
$GLOBALS['TCA']['tt_content']['columns']['tx_testdatahandler_group']['config']['behaviour']['allowLanguageSynchronization'] = true;
$GLOBALS['TCA']['tt_content']['columns'][self::FIELD_ContentElement]['config']['behaviour']['allowLanguageSynchronization'] = true;
$newTableIds = $this->actionService->localizeRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_LanguageId);
$this->recordIds['localizedContentId'] = $newTableIds[self::TABLE_Content][self::VALUE_ContentIdLast];
$this->actionService->modifyReferences(
......@@ -227,6 +228,23 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
);
}
public function localizeContentChainOfRelationWithLanguageSynchronizationSource()
{
$GLOBALS['TCA']['tt_content']['columns'][self::FIELD_ContentElement]['config']['behaviour']['allowLanguageSynchronization'] = true;
$newTableIds = $this->actionService->localizeRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_LanguageId);
$this->recordIds['localizedContentIdFirst'] = $newTableIds[self::TABLE_Content][self::VALUE_ContentIdLast];
$newTableIds = $this->actionService->localizeRecord(self::TABLE_Content, $this->recordIds['localizedContentIdFirst'], self::VALUE_LanguageIdSecond);
$this->recordIds['localizedContentIdSecond'] = $newTableIds[self::TABLE_Content][$this->recordIds['localizedContentIdFirst']];
$this->actionService->modifyRecord(
self::TABLE_Content,
$this->recordIds['localizedContentIdSecond'],
['l10n_state' => [self::FIELD_ContentElement => 'source']]
);
$this->actionService->modifyReferences(
self::TABLE_Content, self::VALUE_ContentIdLast, self::FIELD_ContentElement, [self::VALUE_ElementIdFirst, self::VALUE_ElementIdSecond]
);
}
/**
* @test
* @see DataSet/localizeElementOfRelation.csv
......
......@@ -301,6 +301,21 @@ class ActionTest extends \TYPO3\CMS\Core\Tests\Functional\DataHandling\Group\Abs
->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2'));
}
/**
* @test
* @see DataSet/localizeContentChainOfRelationWSynchronizationSource.csv
*/
public function localizeContentChainOfRelationWithLanguageSynchronizationSource()
{
parent::localizeContentChainOfRelationWithLanguageSynchronizationSource();
$this->assertAssertionDataSet('localizeContentChainOfRelationWSynchronizationSource');
$responseSections = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageId)->getResponseSections();
$this->assertThat($responseSections, $this->getRequestSectionStructureHasRecordConstraint()
->setRecordIdentifier(self::TABLE_Content . ':' . self::VALUE_ContentIdLast)->setRecordField(self::FIELD_ContentElement)
->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2'));
}
/**
* @test
* @see DataSet/localizeElementOfRelation.csv
......
pages
,uid,pid,sorting,deleted,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,title
,1,0,256,0,0,0,0,0,0,0,FunctionalTest
,88,1,256,0,0,0,0,0,0,0,DataHandlerTest
,89,88,256,0,0,0,0,0,0,0,Relations
,90,88,512,0,0,0,0,0,0,0,Target
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,tx_testdatahandler_group,l10n_state
,297,89,256,0,0,0,0,0,0,0,0,0,"Regular Element #1","1,2",
,298,89,512,0,0,0,0,0,0,0,0,0,"Regular Element #2","1,2",
,299,89,768,0,1,298,298,0,0,0,0,0,"[Translate to Dansk:] Regular Element #2","1,2","{""tx_testdatahandler_group"":""parent""}"
,300,89,1024,0,2,298,299,0,0,0,0,0,"[Translate to Deutsch:] [Translate to Dansk:] Regular Element #2","1,2","{""tx_testdatahandler_group"":""source""}"
tx_testdatahandler_element
,uid,pid,sorting,deleted,sys_language_uid,l10n_parent,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,title
,1,89,256,0,0,0,0,0,0,0,0,0,"Element #1"
,2,89,512,0,0,0,0,0,0,0,0,0,"Element #2"
,3,89,768,0,0,0,0,0,0,0,0,0,"Element #3"
"pages",,,,,,,,,,,,,,
,"uid","pid","sorting","deleted","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","t3ver_move_id","title",,,
,1,0,256,0,0,0,0,0,0,0,"FunctionalTest",,,
,88,1,256,0,0,0,0,0,0,0,"DataHandlerTest",,,
,89,88,256,0,0,0,0,0,0,0,"Relations",,,
,90,88,512,0,0,0,0,0,0,0,"Target",,,
"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","tx_testdatahandler_group"
,297,89,256,0,0,0,0,0,0,0,0,0,"Regular Element #1","1,2"
,298,89,512,0,0,0,0,0,0,0,0,0,"Regular Element #2","1,2"
,299,89,768,0,1,298,298,0,0,0,0,0,"[Translate to Dansk:] Regular Element #2","1,2"
"tx_testdatahandler_element",,,,,,,,,,,,,,
,"uid","pid","sorting","deleted","sys_language_uid","l10n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","t3ver_move_id","title",
,1,89,256,0,0,0,0,0,0,0,0,0,"Element #1",
,2,89,512,0,0,0,0,0,0,0,0,0,"Element #2",
,3,89,768,0,0,0,0,0,0,0,0,0,"Element #3",
pages
,uid,pid,sorting,deleted,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,title
,1,0,256,0,0,0,0,0,0,0,FunctionalTest
,88,1,256,0,0,0,0,0,0,0,DataHandlerTest
,89,88,256,0,0,0,0,0,0,0,Relations
,90,88,512,0,0,0,0,0,0,0,Target
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,tx_testdatahandler_group,l10n_state
,297,89,256,0,0,0,0,0,0,0,0,0,"Regular Element #1","1,2",\NULL
,298,89,512,0,0,0,0,0,0,0,0,0,"Regular Element #2","1,2",\NULL
,299,89,768,0,1,298,298,0,0,0,0,0,"[Translate to Dansk:] Regular Element #2","1,2","{""tx_testdatahandler_group"":""parent""}"
tx_testdatahandler_element
,uid,pid,sorting,deleted,sys_language_uid,l10n_parent,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,title
,1,89,256,0,0,0,0,0,0,0,0,0,"Element #1"
,2,89,512,0,0,0,0,0,0,0,0,0,"Element #2"
,3,89,768,0,0,0,0,0,0,0,0,0,"Element #3"
......@@ -28,6 +28,7 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
const VALUE_HotelIdSecond = 4;
const VALUE_HotelIdThird = 5;
const VALUE_LanguageId = 1;
const VALUE_LanguageIdSecond = 2;
const TABLE_Page = 'pages';
const TABLE_PageOverlay = 'pages_language_overlay';
......@@ -223,6 +224,33 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
);
}
/**
* @see DataSet/localizeParentContentWAllChildrenSelect.csv
*/
public function localizeParentContentChainWithAllChildrenInSelectModeAndLanguageSynchronizationSource()
{
$GLOBALS['TCA'][self::TABLE_Content]['columns'][self::FIELD_ContentHotel]['config']['behaviour']['localizationMode'] = 'select';
$GLOBALS['TCA'][self::TABLE_Content]['columns'][self::FIELD_ContentHotel]['config']['behaviour']['allowLanguageSynchronization'] = true;
$GLOBALS['TCA'][self::TABLE_Content]['columns'][self::FIELD_ContentHotel]['config']['behaviour']['localizeChildrenAtParentLocalization'] = true;
$GLOBALS['TCA'][self::TABLE_Hotel]['columns'][self::FIELD_HotelOffer]['config']['behaviour']['localizeChildrenAtParentLocalization'] = true;
$newTableIds = $this->actionService->localizeRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_LanguageId);
$this->recordIds['localizedContentIdFirst'] = $newTableIds[self::TABLE_Content][self::VALUE_ContentIdLast];
$newTableIds = $this->actionService->localizeRecord(self::TABLE_Content, $this->recordIds['localizedContentIdFirst'], self::VALUE_LanguageIdSecond);
$this->recordIds['localizedContentIdSecond'] = $newTableIds[self::TABLE_Content][$this->recordIds['localizedContentIdFirst']];
$this->actionService->modifyRecord(
self::TABLE_Content,
$this->recordIds['localizedContentIdSecond'],
['l10n_state' => [self::FIELD_ContentHotel => 'source']]
);
$this->actionService->modifyRecords(
self::VALUE_PageId,
[
self::TABLE_Content => ['uid' => self::VALUE_ContentIdLast, self::FIELD_ContentHotel => '5,__nextUid'],
self::TABLE_Hotel => ['uid' => '__NEW', 'title' => 'Hotel #2'],
]
);
}
/**
* @see DataSet/changeParentContentRecordSorting.csv
*/
......
......@@ -243,6 +243,21 @@ class ActionTest extends \TYPO3\CMS\Core\Tests\Functional\DataHandling\IRRE\Fore
->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #1', '[Translate to Dansk:] Hotel #2'));
}
/**
* @test
* @see DataSet/localizeParentContentChainWAllChildrenSelectNLanguageSynchronizationSource.csv
*/
public function localizeParentContentChainWithAllChildrenInSelectModeAndLanguageSynchronizationSource()
{
parent::localizeParentContentChainWithAllChildrenInSelectModeAndLanguageSynchronizationSource();
$this->assertAssertionDataSet('localizeParentContentChainWAllChildrenSelectNLanguageSynchronizationSource');
$responseSections = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageIdSecond)->getResponseSections('Default', 'Extbase:list()');
$this->assertThat($responseSections, $this->getRequestSectionStructureHasRecordConstraint()
->setRecordIdentifier(self::TABLE_Content . ':' . self::VALUE_ContentIdLast)->setRecordField(self::FIELD_ContentHotel)
->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Deutsch:] [Translate to Dansk:] Hotel #1', '[Translate to Deutsch:] [Translate to Dansk:] Hotel #2'));
}
/**
* @test
* @see DataSet/changeParentContentRecordSorting.csv
......
tt_content
,uid,pid,sorting,deleted,sys_language_uid,l18n_parent,l10n_source,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,header,tx_irretutorial_1nff_hotels,l10n_state
,297,89,256,0,0,0,0,0,0,0,0,0,0,"Regular Element #1",2,
,298,89,512,0,0,0,0,0,0,0,0,0,0,"Regular Element #2",2,
,299,89,768,0,1,298,298,298,0,0,0,0,0,"[Translate to Dansk:] Regular Element #2",2,"{""tx_irretutorial_1nff_hotels"":""parent""}"
,300,89,1024,0,2,298,299,299,0,0,0,0,0,"[Translate to Deutsch:] [Translate to Dansk:] Regular Element #2",2,"{""tx_irretutorial_1nff_hotels"":""source""}"
tx_irretutorial_1nff_hotel
,uid,pid,sorting,deleted,sys_language_uid,l18n_parent,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,title,parentid,parenttable,parentidentifier,offers
,2,89,1280,0,0,0,0,0,0,0,0,0,"Hotel #0",89,pages,,0
,3,89,1536,0,0,0,0,0,0,0,0,0,"Hotel #1",297,tt_content,,2
,4,89,2048,0,0,0,0,0,0,0,0,0,"Hotel #2",297,tt_content,,1
,5,89,1,0,0,0,0,0,0,0,0,0,"Hotel #1",298,tt_content,,1
,6,89,1,0,1,5,5,0,0,0,0,0,"[Translate to Dansk:] Hotel #1",299,tt_content,,1
,7,89,1,0,2,5,6,0,0,0,0,0,"[Translate to Deutsch:] [Translate to Dansk:] Hotel #1",300,tt_content,,1
,8,89,2,0,0,0,0,0,0,0,0,0,"Hotel #2",298,tt_content,,0
,9,89,2,0,1,8,0,0,0,0,0,0,"[Translate to Dansk:] Hotel #2",299,tt_content,,0
,10,89,2,0,2,8,0,0,0,0,0,0,"[Translate to Deutsch:] [Translate to Dansk:] Hotel #2",300,tt_content,,0
tx_irretutorial_1nff_offer
,uid,pid,sorting,deleted,sys_language_uid,l18n_parent,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,title,parentid,parenttable,parentidentifier,prices
,5,89,512,0,0,0,0,0,0,0,0,0,"Offer #1.1",3,tx_irretutorial_1nff_hotel,,3
,6,89,1536,0,0,0,0,0,0,0,0,0,"Offer #1.2",3,tx_irretutorial_1nff_hotel,,2
,7,89,768,0,0,0,0,0,0,0,0,0,"Offer #2.1",4,tx_irretutorial_1nff_hotel,,1
,8,89,1024,0,0,0,0,0,0,0,0,0,"Offer #1.1",5,tx_irretutorial_1nff_hotel,,1
,9,89,1,0,1,8,8,0,0,0,0,0,"[Translate to Dansk:] Offer #1.1",6,tx_irretutorial_1nff_hotel,,1
,10,89,1,0,2,8,9,0,0,0,0,0,"[Translate to Deutsch:] [Translate to Dansk:] Offer #1.1",7,tx_irretutorial_1nff_hotel,,1
tx_irretutorial_1nff_price
,uid,pid,sorting,deleted,sys_language_uid,l18n_parent,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,title,parentid,parenttable,parentidentifier
,7,89,512,0,0,0,0,0,0,0,0,0,"Price #1.1.1",5,tx_irretutorial_1nff_offer,
,8,89,1792,0,0,0,0,0,0,0,0,0,"Price #1.1.2",5,tx_irretutorial_1nff_offer,
,9,89,2304,0,0,0,0,0,0,0,0,0,"Price #1.1.3",5,tx_irretutorial_1nff_offer,
,10,89,768,0,0,0,0,0,0,0,0,0,"Price #1.2.1",6,tx_irretutorial_1nff_offer,
,11,89,2048,0,0,0,0,0,0,0,0,0,"Price #1.2.2",6,tx_irretutorial_1nff_offer,
,12,89,1024,0,0,0,0,0,0,0,0,0,"Price #2.1.1",7,tx_irretutorial_1nff_offer,
,13,89,1280,0,0,0,0,0,0,0,0,0,"Price #1.1.1",8,tx_irretutorial_1nff_offer,
,14,89,1,0,1,13,13,0,0,0,0,0,"[Translate to Dansk:] Price #1.1.1",9,tx_irretutorial_1nff_offer,
,15,89,1,0,2,13,14,0,0,0,0,0,"[Translate to Deutsch:] [Translate to Dansk:] Price #1.1.1",10,tx_irretutorial_1nff_offer,
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,tx_irretutorial_1nff_hotels
,297,89,256,0,0,0,0,0,0,0,0,0,"Regular Element #1",2
,298,89,512,0,0,0,0,0,0,0,0,0,"Regular Element #2",2
,299,89,768,0,1,298,298,0,0,0,0,0,"[Translate to Dansk:] Regular Element #2",2
,uid,pid,sorting,deleted,sys_language_uid,l18n_parent,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,header,tx_irretutorial_1nff_hotels,l10n_state
,297,89,256,0,0,0,0,0,0,0,0,0,"Regular Element #1",2,\NULL
,298,89,512,0,0,0,0,0,0,0,0,0,"Regular Element #2",2,\NULL
,299,89,768,0,1,298,298,0,0,0,0,0,"[Translate to Dansk:] Regular Element #2",2,"{""tx_irretutorial_1nff_hotels"":""parent""}"
tx_irretutorial_1nff_hotel
,uid,pid,sorting,deleted,sys_language_uid,l18n_parent,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,title,parentid,parenttable,parentidentifier,offers
,2,89,1024,0,0,0,0,0,0,0,0,0,"Hotel #0",89,pages,,0
......
......@@ -172,6 +172,15 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
$this->actionService->modifyRecord(self::TABLE_Content, self::VALUE_ContentIdThird, ['header' => 'Testing #1']);
}
public function localizeContentFromNonDefaultLanguageWithLanguageSynchronizationSource()
{
$GLOBALS['TCA']['tt_content']['columns']['header']['config']['behaviour']['allowLanguageSynchronization'] = true;
$localizedTableIds = $this->actionService->localizeRecord(self::TABLE_Content, self::VALUE_ContentIdThirdLocalized, self::VALUE_LanguageIdSecond);
$this->recordIds['localizedContentId'] = $localizedTableIds[self::TABLE_Content][self::VALUE_ContentIdThirdLocalized];
$this->actionService->modifyRecord(self::TABLE_Content, $this->recordIds['localizedContentId'], ['l10n_state' => ['header' => 'source']]);
$this->actionService->modifyRecord(self::TABLE_Content, self::VALUE_ContentIdThird, ['header' => 'Testing #1']);
}
/**
* @see DataSet/changeContentRecordSorting.csv
*/
......
......@@ -223,6 +223,21 @@ class ActionTest extends \TYPO3\CMS\Core\Tests\Functional\DataHandling\Regular\A
->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Deutsch:] [Translate to Dansk:] Regular Element #1', 'Testing #1'));
}
/**
* @test
* @see DataSet/localizeContentFromNonDefaultLanguageWSynchronizationSource.csv
*/
public function localizeContentFromNonDefaultLanguageWithLanguageSynchronizationSource()
{
parent::localizeContentFromNonDefaultLanguageWithLanguageSynchronizationSource();
$this->assertAssertionDataSet('localizeContentFromNonDefaultLanguageWSynchronizationSource');
$responseSections = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageIdSecond)->getResponseSections();
$this->assertThat($responseSections, $this->getRequestSectionHasRecordConstraint()
->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Deutsch:] [Translate to Dansk:] Regular Element #1', 'Testing #1'));
}
/**
* @test
* @see DataSet/changeContentRecordSorting.csv
......
......@@ -3,7 +3,7 @@ tt_content,,,,,,,,,,,,,,
,297,89,256,0,0,0,0,0,0,0,0,0,0,Regular Element #1,
,298,89,512,0,0,0,0,0,0,0,0,0,0,Regular Element #2,
,299,89,768,0,0,0,0,0,0,0,0,0,0,Testing #1,
,300,89,1024,0,1,299,299,299,0,0,0,0,0,Testing #1,\NULL
,300,89,1024,0,1,299,299,299,0,0,0,0,0,Testing #1,"{""header"":""parent""}"
,301,89,384,0,1,297,297,297,0,0,0,0,0,[Translate to Dansk:] Regular Element #1,
,302,89,448,0,2,297,301,301,0,0,0,0,0,[Translate to Deutsch:] [Translate to Dansk:] Regular Element #1,
,303,89,1280,0,2,299,300,300,0,0,0,0,0,Testing #1,"{""header"":""parent""}"
tt_content,,,,,,,,,,,,,,
,uid,pid,sorting,deleted,sys_language_uid,l18n_parent,l10n_source,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,header,l10n_state
,297,89,256,0,0,0,0,0,0,0,0,0,0,Regular Element #1,
,298,89,512,0,0,0,0,0,0,0,0,0,0,Regular Element #2,
,299,89,768,0,0,0,0,0,0,0,0,0,0,Testing #1,
,300,89,1024,0,1,299,299,299,0,0,0,0,0,Testing #1,"{""header"":""parent""}"
,301,89,384,0,1,297,297,297,0,0,0,0,0,[Translate to Dansk:] Regular Element #1,
,302,89,448,0,2,297,301,301,0,0,0,0,0,[Translate to Deutsch:] [Translate to Dansk:] Regular Element #1,
,303,89,1280,0,2,299,300,300,0,0,0,0,0,Testing #1,"{""header"":""source""}"
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment