Skip to content
Snippets Groups Projects
Commit d26b0a55 authored by Benjamin Mack's avatar Benjamin Mack Committed by Helmut Hummel
Browse files

[!!!][TASK] Redesign FluidTemplateDataProcessorInterface

The FluidTemplateDataProcessorInterface introduced with #66907 has been
refactored to DataProcessorInterface.

This decouples it from the Fluid StandaloneView and makes the
ContentObjectRenderer available in the process method so the different
DataProcessor classes do no have to initiate it on their own.

Instead of manipulating the $data property of the ContentObjectRenderer
a new key/value store can be filled/manipulated by the different
dataProcessor classes.

Resolves: #67890
Releases: master
Change-Id: I461dbff039974715e2c8f916efd5d79c159cc8b5
Reviewed-on: http://review.typo3.org/40915


Reviewed-by: default avatarBenjamin Mack <benni@typo3.org>
Tested-by: default avatarBenjamin Mack <benni@typo3.org>
Reviewed-by: default avatarWouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: default avatarMarkus Klein <markus.klein@typo3.org>
Reviewed-by: default avatarHelmut Hummel <helmut.hummel@typo3.org>
Tested-by: default avatarHelmut Hummel <helmut.hummel@typo3.org>
parent af3122d9
Branches
Tags
No related merge requests found
......@@ -6,7 +6,8 @@ Description
===========
cObject FLUIDTEMPLATE has been extended with ``dataProcessing``. This setting can be used to add one or multiple processors to
manipulate the ``$data`` variable of the currently rendered content object, like tt_content or page.
manipulate data of the currently rendered content object, like tt_content or page, and fill a key/value store that will be passed
as variables to the Fluid template, where every key of the key/value store will be available as variable in the Fluid template.
- dataProcessing = array of class references by full namespace
......@@ -40,4 +41,4 @@ Example:
Impact
======
The data processors can be used in all new projects. There is no interference with any part of existing code.
\ No newline at end of file
The data processors can be used in all new projects. There is no interference with any part of existing code.
=========================================================================================
Breaking: #67890 - Redesign FluidTemplateDataProcessorInterface to DataProcessorInterface
=========================================================================================
Description
===========
The ``FluidTemplateDataProcessorInterface`` introduced with #66907 has been refactored to ``DataProcessorInterface``.
This decouples it from the Fluid StandaloneView and makes the ContentObjectRenderer available in the process method so the different DataProcessor classes do no have to initiate it on their own.
Instead of manipulating the $data property of the ContentObjectRenderer a new key/value store can be filled/manipulated by the different dataProcessor classes.
The new interface expects the following ``process()`` method:
.. code-block:: php
/**
* Process content object data
*
* @param ContentObjectRenderer $cObj The data of the content element or page
* @param array $processorConfiguration The configuration of this processor
* @param array $contentObjectConfiguration The configuration of Content Object
* @param array $processedData Key/value store of processed data (e.g. to be passed to a Fluid View)
* @return array the processed data as key/value store
*/
public function process(
ContentObjectRenderer $cObj,
array $contentObjectConfiguration,
array $processorConfiguration,
array $processedData
);
Impact
======
This will break all frontend rendering for TYPO3 7.3 installations that use ``FLUIDTEMPLATE`` ``.dataProcessing``.
Affected Installations
======================
All TYPO3 7.3 installations that already use the new ``FLUIDTEMPLATE`` ``.dataProcessing`` option.
Migration
=========
Change the interface of all DataProcessor classes from ``FluidTemplateDataProcessorInterface`` to the new ``DataProcessorInterface`` and adjust the ``process()`` method to match the new parameters and make sure it returns the processed data as the processed data.
......@@ -14,26 +14,25 @@ namespace TYPO3\CMS\Frontend\ContentObject;
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Fluid\View\StandaloneView;
/**
* Interface for data processor classes with the FLUIDTEMPLATE content object
* Interface for data processor classes processing data from
* ContentObjectRenderer, used e.g. with the FLUIDTEMPLATE content object
*/
interface FluidTemplateDataProcessorInterface {
interface DataProcessorInterface {
/**
* Process data passed to the FLUIDTEMPLATE content object
* Process content object data
*
* @param array $data The data of the content element or page
* @param ContentObjectRenderer $cObj The data of the content element or page
* @param array $processorConfiguration The configuration of this processor
* @param array $configuration The configuration of FLUIDTEMPLATE
* @param \TYPO3\CMS\Fluid\View\StandaloneView $view The view
* @return void
* @param array $contentObjectConfiguration The configuration of Content Object
* @param array $processedData Key/value store of processed data (e.g. to be passed to a Fluid View)
* @return array the processed data as key/value store
*/
public function process(
array &$data,
ContentObjectRenderer $cObj,
array $contentObjectConfiguration,
array $processorConfiguration,
array $configuration,
StandaloneView $view
array $processedData
);
}
......@@ -71,9 +71,10 @@ class FluidTemplateContentObject extends AbstractContentObject {
$this->setPartialRootPath($conf);
$this->setExtbaseVariables($conf);
$this->assignSettings($conf);
$this->assignContentObjectVariables($conf);
$this->processData($conf);
$this->assignContentObjectDataAndCurrent();
$variables = $this->getContentObjectVariables($conf);
$variables = $this->processData($conf, $variables);
$this->view->assignMultiple($variables);
$content = $this->renderFluidView();
$content = $this->applyStandardWrapToRenderedContent($content, $conf);
......@@ -218,61 +219,61 @@ class FluidTemplateContentObject extends AbstractContentObject {
* Check for the availability of processors, defined in TypoScript, and use them for data processing
*
* @param array $configuration Configuration array
* @return void
* @param array $variables the variables to be processed
* @return array the processed data and variables as key/value store
* @throws \UnexpectedValueException
*/
protected function processData(array $configuration) {
protected function processData(array $configuration, array $variables) {
if (
!empty($configuration['dataProcessing.'])
&& is_array($configuration['dataProcessing.'])
) {
$processors = $configuration['dataProcessing.'];
$processorKeys = \TYPO3\CMS\Core\TypoScript\TemplateService::sortedKeyList($processors);
foreach ($processors as $key => $className) {
if (strpos($key, '.') === FALSE && !empty($className)) {
$processor = GeneralUtility::makeInstance($className);
if (!$processor instanceof FluidTemplateDataProcessorInterface) {
throw new \UnexpectedValueException(
'$processor with class name "' . $className . '" ' .
'must implement interface "' . FluidTemplateDataProcessorInterface::class . '"',
1427455377
);
}
$processorConfiguration = isset($processors[$key . '.']) ? $processors[$key . '.'] : array();
foreach ($processorKeys as $key) {
$className = $processors[$key];
$processor = GeneralUtility::makeInstance($className);
$processor->process(
$this->cObj->data,
$processorConfiguration,
$configuration,
$this->view
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(
$this->cObj,
$configuration,
$processorConfiguration,
$variables
);
}
}
return $variables;
}
/**
* Assign rendered content objects in variables array to view
* Compile rendered content objects in variables array ready to assign to the view
*
* @param array $conf Configuration array
* @return void
* @return array the variables to be assigned
* @throws \InvalidArgumentException
*/
protected function assignContentObjectVariables(array $conf) {
protected function getContentObjectVariables(array $conf) {
$variables = array();
$reservedVariables = array('data', 'current');
// Accumulate the variables to be replaced and loop them through cObjGetSingle
$variables = (array)$conf['variables.'];
foreach ($variables as $variableName => $cObjType) {
// Accumulate the variables to be process and loop them through cObjGetSingle
$variablesToProcess = (array)$conf['variables.'];
foreach ($variablesToProcess as $variableName => $cObjType) {
if (is_array($cObjType)) {
continue;
}
if (!in_array($variableName, $reservedVariables)) {
$this->view->assign(
$variableName,
$this->cObj->cObjGetSingle($cObjType, $variables[$variableName . '.'])
);
$variables[$variableName] = $this->cObj->cObjGetSingle($cObjType, $variablesToProcess[$variableName . '.']);
} else {
throw new \InvalidArgumentException(
'Cannot use reserved name "' . $variableName . '" as variable name in FLUIDTEMPLATE.',
......@@ -280,6 +281,9 @@ class FluidTemplateContentObject extends AbstractContentObject {
);
}
}
$variables['data'] = $this->cObj->data;
$variables['current'] = $this->cObj->data[$this->cObj->currentValKey];
return $variables;
}
/**
......@@ -298,16 +302,6 @@ class FluidTemplateContentObject extends AbstractContentObject {
}
}
/**
* Assign content object renderer data and current to view
*
* @return void
*/
protected function assignContentObjectDataAndCurrent() {
$this->view->assign('data', $this->cObj->data);
$this->view->assign('current', $this->cObj->data[$this->cObj->currentValKey]);
}
/**
* Render fluid standalone view
*
......
......@@ -615,9 +615,9 @@ class FluidTemplateContentObjectTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
->method('cObjGetSingle')
->will($this->returnValue('foo'));
$this->standaloneView
->expects($this->at(1))
->method('assign')
->with('aVar', 'foo');
->expects($this->once())
->method('assignMultiple')
->with(array('aVar' => 'foo', 'data' => array(), 'current' => NULL));
$this->subject->render($configuration);
}
......@@ -628,9 +628,9 @@ class FluidTemplateContentObjectTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
$this->addMockViewToSubject();
$this->contentObjectRenderer->data = array('foo');
$this->standaloneView
->expects($this->at(1))
->method('assign')
->with('data', array('foo'));
->expects($this->once())
->method('assignMultiple')
->with(array('data' => array('foo'), 'current' => NULL));
$this->subject->render(array());
}
......@@ -640,11 +640,11 @@ class FluidTemplateContentObjectTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
public function renderAssignsContentObjectRendererCurrentValueToView() {
$this->addMockViewToSubject();
$this->contentObjectRenderer->data = array('currentKey' => 'currentValue');
$this->contentObjectRenderer->currentValKey= 'currentKey';
$this->contentObjectRenderer->currentValKey = 'currentKey';
$this->standaloneView
->expects($this->at(2))
->method('assign')
->with('current', 'currentValue');
->expects($this->once())
->method('assignMultiple')
->with(array('data' => array('currentKey' => 'currentValue'), 'current' => 'currentValue'));
$this->subject->render(array());
}
......
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