From 9a4f71bce482e03c51847d4540eb3c1ca9003f60 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Fri, 21 May 2021 18:16:33 +0200 Subject: [PATCH] Allow copy of pages Pages can not be copied by administrators as DataHandler will copy all pages, including tx_tracking_* tables. Those are not allowed on tables which will result in error messages. A test is added to simulate the action and ensure it doesn't fail with errors. Results: #52 --- Classes/Hooks/DataHandler.php | 63 +++++++++++++ .../CopyPasteContainingRecords.csv | 10 ++ .../Typo3FeaturesTest/PageWithRecords.xml | 20 ++++ Tests/Functional/Typo3FeaturesTest.php | 91 +++++++++++++++++++ ext_localconf.php | 3 + phpcs.xml.dist | 3 + 6 files changed, 190 insertions(+) create mode 100644 Classes/Hooks/DataHandler.php create mode 100644 Tests/Functional/ExpectedResults/Typo3FeaturesTest/CopyPasteContainingRecords.csv create mode 100644 Tests/Functional/Fixtures/Typo3FeaturesTest/PageWithRecords.xml create mode 100644 Tests/Functional/Typo3FeaturesTest.php create mode 100644 ext_localconf.php diff --git a/Classes/Hooks/DataHandler.php b/Classes/Hooks/DataHandler.php new file mode 100644 index 0000000..596b961 --- /dev/null +++ b/Classes/Hooks/DataHandler.php @@ -0,0 +1,63 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +use TYPO3\CMS\Core\DataHandling\DataHandler as Typo3DataHandler; +use TYPO3\CMS\Core\Utility\ArrayUtility; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Core\Utility\StringUtility; + +class DataHandler +{ + public function processCmdmap_beforeStart(Typo3DataHandler $dataHandler): void + { + $this->preventCopyOfTrackingTables($dataHandler); + } + + public static function register(): void + { + ArrayUtility::mergeRecursiveWithOverrule($GLOBALS['TYPO3_CONF_VARS'], [ + 'SC_OPTIONS' => [ + 't3lib/class.t3lib_tcemain.php' => [ + 'processCmdmapClass' => [ + 'tracking' => self::class, + ], + ], + ], + ]); + } + + private function preventCopyOfTrackingTables(Typo3DataHandler $dataHandler): void + { + $copyWhichTables = $dataHandler->compileAdminTables(); + + if ($dataHandler->copyWhichTables !== '*') { + $copyWhichTables = GeneralUtility::trimExplode(',', $dataHandler->copyWhichTables, true); + } + + $copyWhichTables = array_filter($copyWhichTables, function (string $tableName) { + return StringUtility::beginsWith($tableName, 'tx_tracking_') === false; + }); + + $dataHandler->copyWhichTables = implode(',', $copyWhichTables); + } +} diff --git a/Tests/Functional/ExpectedResults/Typo3FeaturesTest/CopyPasteContainingRecords.csv b/Tests/Functional/ExpectedResults/Typo3FeaturesTest/CopyPasteContainingRecords.csv new file mode 100644 index 0000000..83eb8e1 --- /dev/null +++ b/Tests/Functional/ExpectedResults/Typo3FeaturesTest/CopyPasteContainingRecords.csv @@ -0,0 +1,10 @@ +pages +,"uid","pid" +,1,0 +,2,1 +tx_tracking_pageview +,"uid","pid" +,1,1 +tx_tracking_recordview +,"uid","pid" +,1,1 diff --git a/Tests/Functional/Fixtures/Typo3FeaturesTest/PageWithRecords.xml b/Tests/Functional/Fixtures/Typo3FeaturesTest/PageWithRecords.xml new file mode 100644 index 0000000..6167f58 --- /dev/null +++ b/Tests/Functional/Fixtures/Typo3FeaturesTest/PageWithRecords.xml @@ -0,0 +1,20 @@ + + + + 0 + 1 + + + + 1 + 1 + https://example.com/path + Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36 + + + + 1 + 1 + https://example.com/path + + diff --git a/Tests/Functional/Typo3FeaturesTest.php b/Tests/Functional/Typo3FeaturesTest.php new file mode 100644 index 0000000..ab30ae9 --- /dev/null +++ b/Tests/Functional/Typo3FeaturesTest.php @@ -0,0 +1,91 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +use DanielSiepmann\Tracking\Functional\CopyingPageWithRecordsWorks; +use TYPO3\CMS\Core\DataHandling\DataHandler; +use TYPO3\CMS\Core\Localization\LanguageServiceFactory; +use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase as TestCase; + +/** + * @covers \DanielSiepmann\Tracking\Functional\CopyingPageWithRecordsWorks + * @testdox This extension works with TYPO3 feature: + */ +class Typo3FeaturesTest extends TestCase +{ + protected $testExtensionsToLoad = [ + 'typo3conf/ext/tracking', + ]; + + /** + * @test + * @testdox Copy pages. Tracking records will not be copied. + */ + public function copyContainingRecords(): void + { + $this->importDataSet('EXT:tracking/Tests/Functional/Fixtures/Typo3FeaturesTest/PageWithRecords.xml'); + $this->setUpBackendUserFromFixture(1); + $GLOBALS['LANG'] = $this->getContainer()->get(LanguageServiceFactory::class)->create('default'); + + $dataHandler = new DataHandler(); + $dataHandler->start([], [ + 'pages' => [ + 1 => [ + 'copy' => 1, + ], + ], + ]); + $dataHandler->process_cmdmap(); + + self::assertCount(0, $dataHandler->errorLog, 'Failed with errors: ' . implode(PHP_EOL, $dataHandler->errorLog)); + $this->assertCSVDataSet( + 'EXT:tracking/Tests/Functional/ExpectedResults/Typo3FeaturesTest/CopyPasteContainingRecords.csv' + ); + } + + /** + * @test + * @testdox Copy individual tables, but always exclude tracking tables. + */ + public function copyCustomTablesViaDataHandler(): void + { + $this->importDataSet('EXT:tracking/Tests/Functional/Fixtures/Typo3FeaturesTest/PageWithRecords.xml'); + $this->setUpBackendUserFromFixture(1); + $GLOBALS['LANG'] = $this->getContainer()->get(LanguageServiceFactory::class)->create('default'); + + $dataHandler = new DataHandler(); + $dataHandler->copyWhichTables = 'pages,tx_tracking_pageview,tx_tracking_recordview'; + $dataHandler->start([], [ + 'pages' => [ + 1 => [ + 'copy' => 1, + ], + ], + ]); + $dataHandler->process_cmdmap(); + + self::assertCount(0, $dataHandler->errorLog, 'Failed with errors: ' . implode(PHP_EOL, $dataHandler->errorLog)); + $this->assertCSVDataSet( + 'EXT:tracking/Tests/Functional/ExpectedResults/Typo3FeaturesTest/CopyPasteContainingRecords.csv' + ); + } +} diff --git a/ext_localconf.php b/ext_localconf.php new file mode 100644 index 0000000..df41943 --- /dev/null +++ b/ext_localconf.php @@ -0,0 +1,3 @@ + /Tests/* + + /Classes/Hooks/DataHandler.php +