[TASK] Remove data processing trait in favor of object 04/42904/6
authorHelmut Hummel <helmut.hummel@typo3.org>
Fri, 28 Aug 2015 10:02:54 +0000 (12:02 +0200)
committerWouter Wolters <typo3@wouterwolters.nl>
Sat, 5 Sep 2015 11:50:48 +0000 (13:50 +0200)
The introduced DataProcessingTrait isn't exactly a good prototype
for Trait usage.

It incorporates functionality that isn't easily testable,
it is impossible to provide different implementations as the trait
is directly bound to the class with its concrete implementation.

Use a composite object instead for this functionality.

Resolves: #69386
Releases: master
Change-Id: I39177b441abc7260465c5271bcd711d8636e1d52
Reviewed-on: http://review.typo3.org/42904
Reviewed-by: Alexander Opitz <opitz.alexander@googlemail.com>
Tested-by: Alexander Opitz <opitz.alexander@googlemail.com>
Reviewed-by: Frank N├Ągler <frank.naegler@typo3.org>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
typo3/sysext/frontend/Classes/ContentObject/ContentDataProcessor.php [new file with mode: 0644]
typo3/sysext/frontend/Classes/ContentObject/DataProcessingTrait.php [deleted file]
typo3/sysext/frontend/Classes/ContentObject/FluidTemplateContentObject.php
typo3/sysext/frontend/Classes/DataProcessing/DatabaseQueryProcessor.php
typo3/sysext/frontend/Tests/Unit/ContentObject/ContentDataProcessorTest.php [new file with mode: 0644]
typo3/sysext/frontend/Tests/Unit/ContentObject/Fixtures/DataProcessorFixture.php [new file with mode: 0644]

diff --git a/typo3/sysext/frontend/Classes/ContentObject/ContentDataProcessor.php b/typo3/sysext/frontend/Classes/ContentObject/ContentDataProcessor.php
new file mode 100644 (file)
index 0000000..42ee985
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+namespace TYPO3\CMS\Frontend\ContentObject;
+
+/*
+ * 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\Core\TypoScript\TemplateService;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+
+/**
+ * A class that contains methods that can be used to use the dataProcessing functionality
+ */
+class ContentDataProcessor {
+
+       /**
+        * Check for the availability of processors, defined in TypoScript, and use them for data processing
+        *
+        * @param ContentObjectRenderer $cObject
+        * @param array $configuration Configuration array
+        * @param array $variables the variables to be processed
+        * @return array the processed data and variables as key/value store
+        * @throws \UnexpectedValueException If a processor class does not exist
+        */
+       public function process(ContentObjectRenderer $cObject, array $configuration, array $variables) {
+               if (
+                       !empty($configuration['dataProcessing.'])
+                       && is_array($configuration['dataProcessing.'])
+               ) {
+                       $processors = $configuration['dataProcessing.'];
+                       $processorKeys = TemplateService::sortedKeyList($processors);
+
+                       foreach ($processorKeys as $key) {
+                               $className = $processors[$key];
+                               if (!class_exists($className)) {
+                                       throw new \UnexpectedValueException('Processor class name "' . $className . '" does not exist!',  1427455378);
+                               }
+
+                               if (!in_array(DataProcessorInterface::class, class_implements($className), TRUE)) {
+                                       throw new \UnexpectedValueException(
+                                               'Processor with class name "' . $className . '" ' .
+                                               'must implement interface "' . DataProcessorInterface::class . '"',
+                                               1427455377
+                                       );
+                               }
+
+                               $processorConfiguration = isset($processors[$key . '.']) ? $processors[$key . '.'] : array();
+
+                               $variables = GeneralUtility::makeInstance($className)->process(
+                                       $cObject,
+                                       $configuration,
+                                       $processorConfiguration,
+                                       $variables
+                               );
+                       }
+               }
+
+               return $variables;
+       }
+
+}
diff --git a/typo3/sysext/frontend/Classes/ContentObject/DataProcessingTrait.php b/typo3/sysext/frontend/Classes/ContentObject/DataProcessingTrait.php
deleted file mode 100644 (file)
index 94f0035..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-<?php
-namespace TYPO3\CMS\Frontend\ContentObject;
-
-/*
- * 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\Core\TypoScript\TemplateService;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-
-/**
- * A trait that contains methods that can be used to use the dataProcessing functionality
- */
-trait DataProcessingTrait {
-
-       /**
-        * Check for the availability of processors, defined in TypoScript, and use them for data processing
-        *
-        * @param ContentObjectRenderer $cObject
-        * @param array $configuration Configuration array
-        * @param array $variables the variables to be processed
-        * @return array the processed data and variables as key/value store
-        */
-       protected function processData(ContentObjectRenderer $cObject, array $configuration, array $variables) {
-               if (
-                       !empty($configuration['dataProcessing.'])
-                       && is_array($configuration['dataProcessing.'])
-               ) {
-                       $processors = $configuration['dataProcessing.'];
-                       $processorKeys = TemplateService::sortedKeyList($processors);
-
-                       foreach ($processorKeys as $key) {
-                               $className = $processors[$key];
-                               $processor = GeneralUtility::makeInstance($className);
-
-                               if (!$processor instanceof DataProcessorInterface) {
-                                       throw new \UnexpectedValueException(
-                                               '$processor with class name "' . $className . '" ' .
-                                               'must implement interface "' . DataProcessorInterface::class . '"',
-                                               1427455377
-                                       );
-                               }
-
-                               $processorConfiguration = isset($processors[$key . '.']) ? $processors[$key . '.'] : array();
-
-                               $variables = $processor->process(
-                                       $cObject,
-                                       $configuration,
-                                       $processorConfiguration,
-                                       $variables
-                               );
-                       }
-               }
-
-               return $variables;
-       }
-
-}
index af2766f..18ec6eb 100644 (file)
@@ -22,7 +22,6 @@ use TYPO3\CMS\Fluid\View\StandaloneView;
  * Contains FLUIDTEMPLATE class object
  */
 class FluidTemplateContentObject extends AbstractContentObject {
-       use DataProcessingTrait;
 
        /**
         * @var StandaloneView
@@ -30,6 +29,26 @@ class FluidTemplateContentObject extends AbstractContentObject {
        protected $view = NULL;
 
        /**
+        * @var ContentDataProcessor
+        */
+       protected $contentDataProcessor;
+
+       /**
+        * @param ContentObjectRenderer $cObj
+        */
+       public function __construct(ContentObjectRenderer $cObj) {
+               parent::__construct($cObj);
+               $this->contentDataProcessor = GeneralUtility::makeInstance(ContentDataProcessor::class);
+       }
+
+       /**
+        * @param ContentDataProcessor $contentDataProcessor
+        */
+       public function setContentDataProcessor($contentDataProcessor) {
+               $this->contentDataProcessor = $contentDataProcessor;
+       }
+
+       /**
         * Rendering the cObject, FLUIDTEMPLATE
         *
         * Configuration properties:
@@ -72,7 +91,7 @@ class FluidTemplateContentObject extends AbstractContentObject {
                $this->setExtbaseVariables($conf);
                $this->assignSettings($conf);
                $variables = $this->getContentObjectVariables($conf);
-               $variables = $this->processData($this->cObj, $conf, $variables);
+               $variables = $this->contentDataProcessor->process($this->cObj, $conf, $variables);
 
                $this->view->assignMultiple($variables);
 
index 7f48b33..9593d64 100644 (file)
@@ -15,9 +15,9 @@ namespace TYPO3\CMS\Frontend\DataProcessing;
  */
 
 use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Frontend\ContentObject\ContentDataProcessor;
 use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
 use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;
-use TYPO3\CMS\Frontend\ContentObject\DataProcessingTrait;
 
 /**
  * Fetch records from the database, using the default .select syntax from TypoScript.
@@ -44,7 +44,25 @@ use TYPO3\CMS\Frontend\ContentObject\DataProcessingTrait;
  * where "as" means the variable to be containing the result-set from the DB query.
  */
 class DatabaseQueryProcessor implements DataProcessorInterface {
-       use DataProcessingTrait;
+
+       /**
+        * @var ContentDataProcessor
+        */
+       protected $contentDataProcessor;
+
+       /**
+        * @param ContentObjectRenderer $cObj
+        */
+       public function __construct(ContentObjectRenderer $cObj) {
+               $this->contentDataProcessor = GeneralUtility::makeInstance(ContentDataProcessor::class);
+       }
+
+       /**
+        * @param ContentDataProcessor $contentDataProcessor
+        */
+       public function setContentDataProcessor($contentDataProcessor) {
+               $this->contentDataProcessor = $contentDataProcessor;
+       }
 
        /**
         * Fetches records from the database as an array
@@ -84,7 +102,7 @@ class DatabaseQueryProcessor implements DataProcessorInterface {
                        $recordContentObjectRenderer = GeneralUtility::makeInstance(ContentObjectRenderer::class);
                        $recordContentObjectRenderer->start($record, $tableName);
                        $processedRecordVariables[$key] = array('data' => $record);
-                       $processedRecordVariables[$key] = $this->processData($recordContentObjectRenderer, $processorConfiguration, $processedRecordVariables[$key]);
+                       $processedRecordVariables[$key] = $this->contentDataProcessor->process($recordContentObjectRenderer, $processorConfiguration, $processedRecordVariables[$key]);
                }
 
                $processedData[$targetVariableName] = $processedRecordVariables;
diff --git a/typo3/sysext/frontend/Tests/Unit/ContentObject/ContentDataProcessorTest.php b/typo3/sysext/frontend/Tests/Unit/ContentObject/ContentDataProcessorTest.php
new file mode 100644 (file)
index 0000000..1da64a4
--- /dev/null
@@ -0,0 +1,86 @@
+<?php
+namespace TYPO3\CMS\Frontend\Tests\Unit\ContentObject;
+
+/*
+ * 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\Core\Tests\UnitTestCase;
+use TYPO3\CMS\Frontend\ContentObject\ContentDataProcessor;
+use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
+use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;
+use TYPO3\CMS\Frontend\Tests\Unit\ContentObject\Fixtures\DataProcessorFixture;
+
+/**
+ * Testcase for TYPO3\CMS\Frontend\ContentObject\ContentDataProcessor
+ */
+class ContentDataProcessorTest extends UnitTestCase {
+
+       /**
+        * @var ContentDataProcessor
+        */
+       protected $contentDataProcessor = NULL;
+
+       /**
+        * Set up
+        */
+       protected function setUp() {
+               $this->contentDataProcessor = new ContentDataProcessor();
+       }
+
+       /**
+        * @test
+        * @expectedException \UnexpectedValueException
+        * @expectedExceptionCode 1427455378
+        */
+       public function throwsExceptionIfProcessorClassDoesNotExist() {
+               $contentObjectRendererStub = new ContentObjectRenderer();
+               $config = [
+                       'dataProcessing.' => [
+                               '10' => 'fooClass'
+                       ]
+               ];
+               $variables = [];
+               $this->contentDataProcessor->process($contentObjectRendererStub, $config, $variables);
+       }
+
+       /**
+        * @test
+        * @expectedException \UnexpectedValueException
+        * @expectedExceptionCode 1427455377
+        */
+       public function throwsExceptionIfProcessorClassDoesNotImplementInterface() {
+               $contentObjectRendererStub = new ContentObjectRenderer();
+               $config = [
+                       'dataProcessing.' => [
+                               '10' => get_class($this)
+                       ]
+               ];
+               $variables = [];
+               $this->contentDataProcessor->process($contentObjectRendererStub, $config, $variables);
+       }
+
+       /**
+        * @test
+        */
+       public function processorIsCalled() {
+               $contentObjectRendererStub = new ContentObjectRenderer();
+               $config = [
+                       'dataProcessing.' => [
+                               '10' => DataProcessorFixture::class,
+                               '10.' => ['foo' => 'bar'],
+                       ]
+               ];
+               $variables = [];
+               $this->assertSame(['foo' => 'bar'], $this->contentDataProcessor->process($contentObjectRendererStub, $config, $variables));
+       }
+
+}
diff --git a/typo3/sysext/frontend/Tests/Unit/ContentObject/Fixtures/DataProcessorFixture.php b/typo3/sysext/frontend/Tests/Unit/ContentObject/Fixtures/DataProcessorFixture.php
new file mode 100644 (file)
index 0000000..7b98e9b
--- /dev/null
@@ -0,0 +1,36 @@
+<?php
+namespace TYPO3\CMS\Frontend\Tests\Unit\ContentObject\Fixtures;
+
+/*
+ * 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\Frontend\ContentObject\ContentObjectRenderer;
+use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;
+
+/**
+ * Fixture for TYPO3\CMS\Frontend\ContentObject\ContentDataProcessor
+ */
+class DataProcessorFixture implements DataProcessorInterface {
+
+       /**
+        * @param ContentObjectRenderer $cObj
+        * @param array $contentObjectConfiguration
+        * @param array $processorConfiguration
+        * @param array $processedData
+        * @return array
+        */
+       public function process(ContentObjectRenderer $cObj, array $contentObjectConfiguration, array $processorConfiguration, array $processedData) {
+               return $processorConfiguration;
+       }
+
+
+}