[BUGFIX] Edits disappear when published twice 69/26769/7
authorStefan Rotsch <stefan.rotsch@aoemedia.de>
Fri, 10 Jan 2014 09:34:38 +0000 (10:34 +0100)
committerAndreas Wolf <andreas.wolf@typo3.org>
Wed, 5 Aug 2015 21:58:55 +0000 (23:58 +0200)
When accidentally publishing an edit twice, eg. by using multiple
browser tabs, all modifications are reverted and the changes are no
longer visible in the workspace.

In the database, the old workspace version of the record has wsid = 0
and pid = -1 and is thus invisible, but still contains the modified
content.

Resolves: #54924
Releases: master, 6.2
Change-Id: I8805737540f030ae24331d33590b71629c7f3179
Reviewed-on: http://review.typo3.org/26769
Reviewed-by: Daniel Goerz <ervaude@gmail.com>
Tested-by: Daniel Goerz <ervaude@gmail.com>
Reviewed-by: Andreas Wolf <andreas.wolf@typo3.org>
Tested-by: Andreas Wolf <andreas.wolf@typo3.org>
typo3/sysext/workspaces/Classes/ExtDirect/ActionHandler.php
typo3/sysext/workspaces/Tests/Functional/ActionHandler/ActionHandlerTest.php [new file with mode: 0644]
typo3/sysext/workspaces/Tests/Functional/ActionHandler/Fixtures/pages.xml [new file with mode: 0644]
typo3/sysext/workspaces/Tests/Functional/ActionHandler/Fixtures/sys_workspace.xml [new file with mode: 0644]
typo3/sysext/workspaces/Tests/Functional/ActionHandler/Fixtures/tt_content.xml [new file with mode: 0644]

index 56472bf..da1b853 100644 (file)
@@ -549,11 +549,11 @@ class ActionHandler extends AbstractHandler {
         * t3ver_oid
         * uid
         * nextStage
-        * receipients: array with uids
+        * recipients: array with uids
         * additional: string
         * comments: string
         *
-        * @param stdClass $parameters
+        * @param \stdClass $parameters
         * @return array
         */
        public function sendToSpecificStageExecute(\stdClass $parameters) {
@@ -562,7 +562,13 @@ class ActionHandler extends AbstractHandler {
                $comments = $parameters->comments;
                $elements = $parameters->affects->elements;
                $recipients = $this->getRecipientList($parameters->receipients, $parameters->additional, $setStageId);
-               foreach ($elements as $key => $element) {
+               foreach ($elements as $element) {
+                       // Avoid any action on records that have already been published to live
+                       $elementRecord = BackendUtility::getRecord($element->table, $element->uid);
+                       if ((int)$elementRecord['t3ver_wsid'] === 0) {
+                               continue;
+                       }
+
                        if ($setStageId == StagesService::STAGE_PUBLISH_EXECUTE_ID) {
                                $cmdArray[$element->table][$element->t3ver_oid]['version']['action'] = 'swap';
                                $cmdArray[$element->table][$element->t3ver_oid]['version']['swapWith'] = $element->uid;
diff --git a/typo3/sysext/workspaces/Tests/Functional/ActionHandler/ActionHandlerTest.php b/typo3/sysext/workspaces/Tests/Functional/ActionHandler/ActionHandlerTest.php
new file mode 100644 (file)
index 0000000..cb5699f
--- /dev/null
@@ -0,0 +1,85 @@
+<?php
+namespace TYPO3\CMS\Workspaces\Tests\Functional\ActionHandler;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Backend\Utility\BackendUtility;
+
+/**
+ * Action handler test
+ */
+class ActionHandlerTest extends \TYPO3\CMS\Core\Tests\FunctionalTestCase {
+
+       protected $coreExtensionsToLoad = array('version', 'workspaces');
+
+       /**
+        * Set up
+        *
+        * @return void
+        */
+       public function setUp() {
+               parent::setUp();
+               $this->setUpBackendUserFromFixture(1);
+               \TYPO3\CMS\Core\Core\Bootstrap::getInstance()->initializeLanguageObject();
+       }
+
+       /**
+        * @test
+        */
+       public function sendToSpecificStageExecuteIgnoresDoublePublishes() {
+               $actionHandler = new \TYPO3\CMS\Workspaces\ExtDirect\ActionHandler();
+
+               $this->importDataSet(__DIR__ . '/Fixtures/pages.xml');
+               $this->importDataSet(__DIR__ . '/Fixtures/sys_workspace.xml');
+               $this->importDataSet(__DIR__ . '/Fixtures/tt_content.xml');
+
+               // Prepare parameter
+               $parameter = new \stdClass();
+               $parameter->additional = '';
+               $parameter->receipients = array();
+               $parameter->comments = '';
+
+               // Send to LIVE
+               $parameter->affects = new \stdClass();
+               $parameter->affects->nextStage = -20;
+               $parameter->affects->elements = array();
+
+               // First and only affected element
+               $elementOne = new \stdClass();
+               $elementOne->table = 'tt_content';
+               $elementOne->uid = 2;
+               $elementOne->t3ver_oid = 1;
+               $parameter->affects->elements[] = $elementOne;
+
+               $recordBeforePublish = BackendUtility::getRecord('tt_content', 2);
+               $this->assertEquals($recordBeforePublish['header'], 'Workspace version of original content');
+
+               // First publish
+               $result = $actionHandler->sendToSpecificStageExecute($parameter);
+               $this->assertTrue($result['success']);
+               $recordAfterFirstPublish = BackendUtility::getRecord('tt_content', 2);
+
+               $this->assertEquals($recordAfterFirstPublish['t3ver_wsid'], 0);
+               $this->assertEquals($recordAfterFirstPublish['header'], 'Original content');
+
+               // Second publish
+               $result = $actionHandler->sendToSpecificStageExecute($parameter);
+               $this->assertTrue($result['success']);
+               $recordAfterSecondPublish = BackendUtility::getRecord('tt_content', 2);
+
+               // In case of an error, this will again be "Workspace version of original content"
+               $this->assertEquals($recordAfterSecondPublish['t3ver_wsid'], 0);
+               $this->assertEquals($recordAfterSecondPublish['header'], 'Original content');
+       }
+}
diff --git a/typo3/sysext/workspaces/Tests/Functional/ActionHandler/Fixtures/pages.xml b/typo3/sysext/workspaces/Tests/Functional/ActionHandler/Fixtures/pages.xml
new file mode 100644 (file)
index 0000000..b2f6e23
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<dataset>
+       <pages>
+               <uid>1</uid>
+               <pid>0</pid>
+               <title>Root</title>
+               <deleted>0</deleted>
+               <perms_everybody>15</perms_everybody>
+       </pages>
+       <pages>
+               <uid>2</uid>
+               <pid>1</pid>
+               <title>Dummy 1-2</title>
+               <deleted>0</deleted>
+               <perms_everybody>15</perms_everybody>
+       </pages>
+</dataset>
\ No newline at end of file
diff --git a/typo3/sysext/workspaces/Tests/Functional/ActionHandler/Fixtures/sys_workspace.xml b/typo3/sysext/workspaces/Tests/Functional/ActionHandler/Fixtures/sys_workspace.xml
new file mode 100644 (file)
index 0000000..fc2e75f
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<dataset>
+       <sys_workspace>
+               <uid>90</uid>
+               <pid>0</pid>
+               <title>Empty Workspace</title>
+       </sys_workspace>
+       <sys_workspace>
+               <uid>91</uid>
+               <pid>0</pid>
+               <title>Filled Workspace #1</title>
+       </sys_workspace>
+       <sys_workspace>
+               <uid>92</uid>
+               <pid>0</pid>
+               <title>Filled Workspace #2</title>
+       </sys_workspace>
+</dataset>
\ No newline at end of file
diff --git a/typo3/sysext/workspaces/Tests/Functional/ActionHandler/Fixtures/tt_content.xml b/typo3/sysext/workspaces/Tests/Functional/ActionHandler/Fixtures/tt_content.xml
new file mode 100644 (file)
index 0000000..f95b39d
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<dataset>
+       <tt_content>
+               <uid>1</uid>
+               <pid>2</pid>
+               <header>Original content</header>
+               <deleted>0</deleted>
+               <t3ver_oid>0</t3ver_oid>
+               <t3ver_wsid>0</t3ver_wsid>
+       </tt_content>
+       <tt_content>
+               <uid>2</uid>
+               <pid>-1</pid>
+               <header>Workspace version of original content</header>
+               <deleted>0</deleted>
+               <t3ver_oid>1</t3ver_oid>
+               <t3ver_wsid>91</t3ver_wsid>
+               <t3ver_stage>1</t3ver_stage>
+       </tt_content>
+</dataset>
\ No newline at end of file