Skip to content

Commit

Permalink
[BUGFIX] Use form specific flexform sheets within the frontend
Browse files Browse the repository at this point in the history
Use contextual flexform sheets to identify ext:form finisher overrides
within the frontend.

Resolves: #88011
Releases: master, 9.5
Change-Id: I0a21deed29419281478f358ff61986d65b26dd0e
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/60604
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Susanne Moog <look@susi.dev>
Reviewed-by: Susanne Moog <look@susi.dev>
  • Loading branch information
waldhacker1 authored and susannemoog committed Apr 27, 2019
1 parent 9f423b4 commit ecc0e0e
Show file tree
Hide file tree
Showing 3 changed files with 318 additions and 21 deletions.
70 changes: 65 additions & 5 deletions typo3/sysext/form/Classes/Controller/FormFrontendController.php
Expand Up @@ -15,6 +15,8 @@
* The TYPO3 project - inspiring people to share!
*/

use TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools;
use TYPO3\CMS\Core\Service\FlexFormService;
use TYPO3\CMS\Core\Utility\ArrayUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
Expand Down Expand Up @@ -91,15 +93,24 @@ public function performAction()
*/
protected function overrideByFlexFormSettings(array $formDefinition): array
{
$flexFormData = GeneralUtility::xml2array($this->configurationManager->getContentObject()->data['pi_flexform'] ?? '');

if (!is_array($flexFormData)) {
return $formDefinition;
}

if (isset($formDefinition['finishers'])) {
$prototypeName = $formDefinition['prototypeName'] ?? 'standard';
$configurationService = $this->objectManager->get(ConfigurationService::class);
$prototypeConfiguration = $configurationService->getPrototypeConfiguration($prototypeName);

foreach ($formDefinition['finishers'] as $index => $formFinisherDefinition) {
$finisherIdentifier = $formFinisherDefinition['identifier'];
$prototypeName = $formDefinition['prototypeName'] ?? 'standard';

if ($this->settings['overrideFinishers'] && isset($this->settings['finishers'][$finisherIdentifier])) {
$configurationService = $this->objectManager->get(ConfigurationService::class);
$prototypeConfiguration = $configurationService->getPrototypeConfiguration($prototypeName);
$flexFormSheetSettings = $this->settings;
$sheetIdentifier = $this->getFlexformSheetIdentifier($formDefinition, $prototypeName, $finisherIdentifier);
$flexFormSheetSettings = $this->getFlexFormSettingsFromSheet($flexFormData, $sheetIdentifier);

if ($this->settings['overrideFinishers'] && isset($flexFormSheetSettings['finishers'][$finisherIdentifier])) {
$prototypeFinisherDefinition = $prototypeConfiguration['finishersDefinition'][$finisherIdentifier] ?? [];
$converterDto = GeneralUtility::makeInstance(
FlexFormFinisherOverridesConverterDto::class,
Expand Down Expand Up @@ -149,4 +160,53 @@ protected function overrideByTypoScriptSettings(array $formDefinition): array
}
return $formDefinition;
}

/**
* @param array $formDefinition
* @param string $prototypeName
* @param string $finisherIdentifier
* @return string
*/
protected function getFlexformSheetIdentifier(
array $formDefinition,
string $prototypeName,
string $finisherIdentifier
): string {
return md5(
implode('', [
$formDefinition['persistenceIdentifier'],
$prototypeName,
$formDefinition['identifier'],
$finisherIdentifier
])
);
}

/**
* @param array $flexForm
* @param string $sheetIdentifier
* @return array
*/
protected function getFlexFormSettingsFromSheet(
array $flexForm,
string $sheetIdentifier
): array {
$sheetData['data'] = array_filter(
$flexForm['data'] ?? [],
function ($key) use ($sheetIdentifier) {
return $key === $sheetIdentifier;
},
ARRAY_FILTER_USE_KEY
);

if (empty($sheetData['data'])) {
return [];
}

$flexFormService = GeneralUtility::makeInstance(FlexFormService::class);
$flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);

$sheetDataXml = $flexFormTools->flexArray2Xml($sheetData);
return $flexFormService->convertFlexFormContentToArray($sheetDataXml)['settings'] ?? [];
}
}
Expand Up @@ -67,14 +67,22 @@ public function __invoke(string $_, $__, array $matches)

// use the option value from the ext:form setup from the current finisher as default value
try {
$optionValue = ArrayUtility::getValueByPath($finisherDefinitionFromSetup['options'], $optionKey, '.');
$optionValue = ArrayUtility::getValueByPath(
$finisherDefinitionFromSetup,
sprintf('options.%s', $optionKey),
'.'
);
} catch (MissingArrayPathException $exception) {
$optionValue = null;
}

// use the option value from the form definition from the current finisher (if exists) as default value
try {
$optionValue = ArrayUtility::getValueByPath($finisherDefinitionFromFormDefinition['options'], $optionKey, '.');
$optionValue = ArrayUtility::getValueByPath(
$finisherDefinitionFromFormDefinition,
sprintf('options.%s', $optionKey),
'.'
);
} catch (MissingArrayPathException $exception) {
}

Expand Down

0 comments on commit ecc0e0e

Please sign in to comment.