Initial commit

This commit is contained in:
2018-04-02 08:07:38 +02:00
commit 7330c1ed3e
2054 changed files with 405203 additions and 0 deletions

View File

@@ -0,0 +1,227 @@
<?php
namespace TYPO3\CMS\Compatibility6\Form\Container;
/*
* 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\Form\Container\AbstractContainer;
use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Lang\LanguageService;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Type\Bitmask\JsConfirmation;
use TYPO3\CMS\Backend\Utility\BackendUtility;
/**
* The container handles single elements.
*
* This one is called by FlexFormTabsContainer, FlexFormNoTabsContainer or FlexFormContainerContainer.
* For single fields, the code is similar to SingleFieldContainer, processing will end up in single
* element classes depending on specific type of an element. Additionally, it determines if a
* section is handled and hands over to FlexFormSectionContainer in this case.
*/
class FlexFormElementContainer extends AbstractContainer
{
/**
* Entry method
*
* @return array As defined in initializeResultArray() of AbstractNode
*/
public function render()
{
$table = $this->data['tableName'];
$row = $this->data['databaseRow'];
$flexFormDataStructureArray = $this->data['flexFormDataStructureArray'];
$flexFormRowData = $this->data['flexFormRowData'];
$flexFormFormPrefix = $this->data['flexFormFormPrefix'];
$parameterArray = $this->data['parameterArray'];
$metaData = $this->data['parameterArray']['fieldConf']['config']['ds']['meta'];
$languageService = $this->getLanguageService();
/** @var IconFactory $iconFactory */
$iconFactory = GeneralUtility::makeInstance(IconFactory::class);
$resultArray = $this->initializeResultArray();
foreach ($flexFormDataStructureArray as $flexFormFieldName => $flexFormFieldArray) {
if (
// No item array found at all
!is_array($flexFormFieldArray)
// Not a section or container and not a list of single items
|| (!isset($flexFormFieldArray['type']) && !is_array($flexFormFieldArray['config']))
) {
continue;
}
if ($flexFormFieldArray['type'] === 'array') {
// Section
if (empty($flexFormFieldArray['section'])) {
$resultArray['html'] = LF . 'Section expected at ' . $flexFormFieldName . ' but not found';
continue;
}
$sectionTitle = '';
if (!empty($flexFormFieldArray['title'])) {
$sectionTitle = $languageService->sL($flexFormFieldArray['title']);
}
$options = $this->data;
$options['flexFormDataStructureArray'] = $flexFormFieldArray['el'];
$options['flexFormRowData'] = is_array($flexFormRowData[$flexFormFieldName]['el']) ? $flexFormRowData[$flexFormFieldName]['el'] : array();
$options['flexFormSectionType'] = $flexFormFieldName;
$options['flexFormSectionTitle'] = $sectionTitle;
$options['renderType'] = 'flexFormSectionContainer';
$sectionContainerResult = $this->nodeFactory->create($options)->render();
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $sectionContainerResult);
} else {
if (is_array($metaData) && isset($metaData['langChildren']) && isset($metaData['languagesOnElement'])) {
$lkeys = $metaData['languagesOnElement'];
array_walk($lkeys, function (&$value) {
$value = 'v' . $value;
});
} else {
$lkeys = array('vDEF');
}
$html = array();
foreach ($lkeys as $lkey) {
// Set up options for single element
$fakeParameterArray = array(
'fieldConf' => array(
'label' => $languageService->sL(trim($flexFormFieldArray['label'])),
'config' => $flexFormFieldArray['config'],
'defaultExtras' => $flexFormFieldArray['defaultExtras'],
'onChange' => $flexFormFieldArray['onChange'],
),
);
$alertMsgOnChange = '';
if (
$fakeParameterArray['fieldConf']['onChange'] === 'reload'
|| !empty($GLOBALS['TCA'][$table]['ctrl']['type']) && $GLOBALS['TCA'][$table]['ctrl']['type'] === $flexFormFieldName
|| !empty($GLOBALS['TCA'][$table]['ctrl']['requestUpdate']) && GeneralUtility::inList($GLOBALS['TCA'][$table]['ctrl']['requestUpdate'], $flexFormFieldName)
) {
if ($this->getBackendUserAuthentication()->jsConfirmation(JsConfirmation::TYPE_CHANGE)) {
$alertMsgOnChange = 'top.TYPO3.Modal.confirm(TBE_EDITOR.labels.refreshRequired.title, TBE_EDITOR.labels.refreshRequired.content).on("button.clicked", function(e) { if (e.target.name == "ok" && TBE_EDITOR.checkSubmit(-1)) { TBE_EDITOR.submitForm() } top.TYPO3.Modal.dismiss(); });';
} else {
$alertMsgOnChange = 'if (TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm();}';
}
}
$fakeParameterArray['fieldChangeFunc'] = $parameterArray['fieldChangeFunc'];
if ($alertMsgOnChange) {
$fakeParameterArray['fieldChangeFunc']['alert'] = $alertMsgOnChange;
}
$fakeParameterArray['onFocus'] = $parameterArray['onFocus'];
$fakeParameterArray['label'] = $parameterArray['label'];
$fakeParameterArray['itemFormElName'] = $parameterArray['itemFormElName'] . $flexFormFormPrefix . '[' . $flexFormFieldName . '][' . $lkey . ']';
$fakeParameterArray['itemFormElID'] = $fakeParameterArray['itemFormElName'];
if (isset($flexFormRowData[$flexFormFieldName][$lkey])) {
$fakeParameterArray['itemFormElValue'] = $flexFormRowData[$flexFormFieldName][$lkey];
} else {
$fakeParameterArray['itemFormElValue'] = $fakeParameterArray['fieldConf']['config']['default'];
}
$options = $this->data;
$options['parameterArray'] = $fakeParameterArray;
$options['elementBaseName'] = $this->data['elementBaseName'] . $flexFormFormPrefix . '[' . $flexFormFieldName . '][' . $lkey . ']';
if (!empty($flexFormFieldArray['config']['renderType'])) {
$options['renderType'] = $flexFormFieldArray['config']['renderType'];
} else {
// Fallback to type if no renderType is given
$options['renderType'] = $flexFormFieldArray['config']['type'];
}
$childResult = $this->nodeFactory->create($options)->render();
$theTitle = htmlspecialchars($fakeParameterArray['fieldConf']['label']);
$defInfo = array();
// Possible line breaks in the label through xml: \n => <br/>, usage of nl2br() not possible, so it's done through str_replace (?!)
$processedTitle = str_replace('\\n', '<br />', $theTitle);
// @todo: Similar to the processing within SingleElementContainer ... use it from there?!
$html[] = '<div class="form-group t3js-formengine-palette-field t3js-formengine-validation-marker">';
$html[] = '<label class="t3js-formengine-label">';
if (is_array($metaData) && isset($metaData['langChildren']) && $metaData['langChildren']) {
// Find language uid of this iso code
$languageUid = 0;
$lKeyWithoutV = substr($lkey, 1);
if ($lKeyWithoutV !== 'DEF') {
foreach ($this->data['systemLanguageRows'] as $systemLanguageRow) {
if ($systemLanguageRow['iso'] === $lKeyWithoutV) {
$languageUid = $systemLanguageRow['uid'];
break;
}
}
}
$languageIcon = $iconFactory->getIcon($this->data['systemLanguageRows'][$languageUid]['flagIconIdentifier'], Icon::SIZE_SMALL)->render();
$html[] = $languageIcon;
}
$html[] = BackendUtility::wrapInHelp($parameterArray['_cshKey'], $flexFormFieldName, $processedTitle);
$html[] = '</label>';
$html[] = '<div class="t3js-formengine-field-item">';
$html[] = $childResult['html'];
$html[] = implode(LF, $defInfo);
$html[] = $this->renderVDEFDiff($flexFormRowData[$flexFormFieldName], $lkey);
$html[] = '</div>';
$html[] = '</div>';
}
if (!empty($html)) {
$resultArray['html'] .= '<div class="form-section">' . implode(LF, $html) . '</div>';
}
$childResult['html'] = '';
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $childResult);
}
}
return $resultArray;
}
/**
* Renders the diff-view of vDEF fields in flex forms
*
* @param array $vArray Record array of the record being edited
* @param string $vDEFkey HTML of the form field. This is what we add the content to.
* @return string Item string returned again, possibly with the original value added to.
*/
protected function renderVDEFDiff($vArray, $vDEFkey)
{
$item = null;
if (
$GLOBALS['TYPO3_CONF_VARS']['BE']['flexFormXMLincludeDiffBase'] && isset($vArray[$vDEFkey . '.vDEFbase'])
&& (string)$vArray[$vDEFkey . '.vDEFbase'] !== (string)$vArray['vDEF'][0]
) {
// Create diff-result:
$diffUtility = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Utility\DiffUtility::class);
$diffres = $diffUtility->makeDiffDisplay($vArray[$vDEFkey . '.vDEFbase'], $vArray['vDEF']);
$item = '<div class="typo3-TCEforms-diffBox">' . '<div class="typo3-TCEforms-diffBox-header">'
. htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:compatibility6/Resources/Private/Language/locallang.xlf:labels.changeInOrig')) . ':</div>' . $diffres . '</div>';
}
return $item;
}
/**
* @return LanguageService
*/
protected function getLanguageService()
{
return $GLOBALS['LANG'];
}
/**
* @return BackendUserAuthentication
*/
protected function getBackendUserAuthentication()
{
return $GLOBALS['BE_USER'];
}
}

View File

@@ -0,0 +1,94 @@
<?php
namespace TYPO3\CMS\Compatibility6\Form\Container;
/*
* 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\Form\Container\AbstractContainer;
use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Entry container to a flex form element. This container is created by
* SingleFieldContainer if a type='flex' field is rendered.
*
* It either forks a FlexFormTabsContainer or a FlexFormNoTabsContainer.
*
* This container additionally handles flex form languages on sheet level.
*/
class FlexFormEntryContainer extends AbstractContainer
{
/**
* Entry method
*
* @return array As defined in initializeResultArray() of AbstractNode
*/
public function render()
{
$flexFormDataStructureArray = $this->data['parameterArray']['fieldConf']['config']['ds'];
$flexFormRowData = $this->data['parameterArray']['itemFormElValue'];
/** @var IconFactory $iconFactory */
$iconFactory = GeneralUtility::makeInstance(IconFactory::class);
// Tabs or no tabs - that's the question
$hasTabs = false;
if (count($flexFormDataStructureArray['sheets']) > 1) {
$hasTabs = true;
}
$resultArray = $this->initializeResultArray();
foreach ($flexFormDataStructureArray['meta']['languagesOnSheetLevel'] as $lKey) {
// Add language as header
if (!$flexFormDataStructureArray['meta']['langChildren'] && !$flexFormDataStructureArray['meta']['langDisable']) {
// Find language uid of this iso code
$languageUid = 0;
if ($lKey !== 'DEF') {
foreach ($this->data['systemLanguageRows'] as $systemLanguageRow) {
if ($systemLanguageRow['iso'] === $lKey) {
$languageUid = $systemLanguageRow['uid'];
break;
}
}
}
$resultArray['html'] .= LF
. '<strong>'
. $iconFactory->getIcon($this->data['systemLanguageRows'][$languageUid]['flagIconIdentifier'], Icon::SIZE_SMALL)->render()
. htmlspecialchars($this->data['systemLanguageRows'][$languageUid]['title'])
. '</strong>';
}
// Default language "lDEF", other options are "lUK" or whatever country code
$flexFormCurrentLanguage = 'l' . $lKey;
$options = $this->data;
$options['flexFormCurrentLanguage'] = $flexFormCurrentLanguage;
$options['flexFormDataStructureArray'] = $flexFormDataStructureArray;
$options['flexFormRowData'] = $flexFormRowData;
if (!$hasTabs) {
$options['renderType'] = 'flexFormNoTabsContainer';
$flexFormNoTabsResult = $this->nodeFactory->create($options)->render();
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $flexFormNoTabsResult);
} else {
$options['renderType'] = 'flexFormTabsContainer';
$flexFormTabsContainerResult = $this->nodeFactory->create($options)->render();
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $flexFormTabsContainerResult);
}
}
$resultArray['requireJsModules'][] = 'TYPO3/CMS/Backend/FormEngineFlexForm';
return $resultArray;
}
}

View File

@@ -0,0 +1,77 @@
<?php
namespace TYPO3\CMS\Compatibility6\Form\Container;
/*
* 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\Form\Container\AbstractContainer;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Handle a flex form that has no tabs.
*
* This container is called by FlexFormEntryContainer if only a default sheet
* exists. It evaluates the display condition and hands over rendering of single
* fields to FlexFormElementContainer.
*/
class FlexFormNoTabsContainer extends AbstractContainer
{
/**
* Entry method
*
* @return array As defined in initializeResultArray() of AbstractNode
*/
public function render()
{
$table = $this->data['tableName'];
$row = $this->data['databaseRow'];
$fieldName = $this->data['fieldName']; // field name of the flex form field in DB
$parameterArray = $this->data['parameterArray'];
$flexFormDataStructureArray = $this->data['flexFormDataStructureArray'];
$flexFormCurrentLanguage = $this->data['flexFormCurrentLanguage'];
$flexFormRowData = $this->data['flexFormRowData'];
$resultArray = $this->initializeResultArray();
// Flex ds was normalized in flex provider to always have a sheet.
// Determine this single sheet name, most often it ends up with sDEF, except if only one sheet was defined
$sheetName = array_pop(array_keys($flexFormDataStructureArray['sheets']));
$flexFormRowDataSubPart = $flexFormRowData['data'][$sheetName][$flexFormCurrentLanguage];
// That was taken from GeneralUtility::resolveSheetDefInDS - no idea if it is important
unset($flexFormDataStructureArray['meta']);
if (!is_array($flexFormDataStructureArray['sheets'][$sheetName]['ROOT']['el'])) {
$resultArray['html'] = 'Data Structure ERROR: No [\'ROOT\'][\'el\'] element found in flex form definition.';
return $resultArray;
}
// Assemble key for loading the correct CSH file
// @todo: what is that good for? That is for the title of single elements ... see FlexFormElementContainer!
$dsPointerFields = GeneralUtility::trimExplode(',', $GLOBALS['TCA'][$table]['columns'][$fieldName]['config']['ds_pointerField'], true);
$parameterArray['_cshKey'] = $table . '.' . $fieldName;
foreach ($dsPointerFields as $key) {
if ((string)$row[$key] !== '') {
$parameterArray['_cshKey'] .= '.' . $row[$key];
}
}
$options = $this->data;
$options['flexFormDataStructureArray'] = $flexFormDataStructureArray['sheets'][$sheetName]['ROOT']['el'];
$options['flexFormRowData'] = $flexFormRowDataSubPart;
$options['flexFormFormPrefix'] = '[data][' . $sheetName . '][' . $flexFormCurrentLanguage . ']';
$options['parameterArray'] = $parameterArray;
$options['renderType'] = 'flexFormElementContainer';
return $this->nodeFactory->create($options)->render();
}
}

View File

@@ -0,0 +1,110 @@
<?php
namespace TYPO3\CMS\Compatibility6\Form\Container;
/*
* 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\Form\Container\AbstractContainer;
use TYPO3\CMS\Backend\Template\DocumentTemplate;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Lang\LanguageService;
/**
* Handle flex forms that have tabs (multiple "sheets").
*
* This container is called by FlexFormEntryContainer. It resolves each
* sheet and hands rendering of single sheet content over to FlexFormElementContainer.
*/
class FlexFormTabsContainer extends AbstractContainer
{
/**
* Entry method
*
* @return array As defined in initializeResultArray() of AbstractNode
*/
public function render()
{
$languageService = $this->getLanguageService();
$table = $this->data['tableName'];
$row = $this->data['databaseRow'];
$fieldName = $this->data['fieldName']; // field name of the flex form field in DB
$parameterArray = $this->data['parameterArray'];
$flexFormDataStructureArray = $this->data['flexFormDataStructureArray'];
$flexFormCurrentLanguage = $this->data['flexFormCurrentLanguage'];
$flexFormRowData = $this->data['flexFormRowData'];
$resultArray = $this->initializeResultArray();
$resultArray['requireJsModules'][] = 'TYPO3/CMS/Backend/Tabs';
$domIdPrefix = 'DTM-' . GeneralUtility::shortMD5($this->data['parameterArray']['itemFormElName'] . $flexFormCurrentLanguage);
$tabCounter = 0;
$tabElements = array();
foreach ($flexFormDataStructureArray['sheets'] as $sheetName => $sheetDataStructure) {
$flexFormRowSheetDataSubPart = $flexFormRowData['data'][$sheetName][$flexFormCurrentLanguage];
if (!is_array($sheetDataStructure['ROOT']['el'])) {
$resultArray['html'] .= LF . 'No Data Structure ERROR: No [\'ROOT\'][\'el\'] found for sheet "' . $sheetName . '".';
continue;
}
$tabCounter ++;
// Assemble key for loading the correct CSH file
// @todo: what is that good for? That is for the title of single elements ... see FlexFormElementContainer!
$dsPointerFields = GeneralUtility::trimExplode(',', $GLOBALS['TCA'][$table]['columns'][$fieldName]['config']['ds_pointerField'], true);
$parameterArray['_cshKey'] = $table . '.' . $fieldName;
foreach ($dsPointerFields as $key) {
if ((string)$row[$key] !== '') {
$parameterArray['_cshKey'] .= '.' . $row[$key];
}
}
$options = $this->data;
$options['flexFormDataStructureArray'] = $sheetDataStructure['ROOT']['el'];
$options['flexFormRowData'] = $flexFormRowSheetDataSubPart;
$options['flexFormFormPrefix'] = '[data][' . $sheetName . '][' . $flexFormCurrentLanguage . ']';
$options['parameterArray'] = $parameterArray;
// Merge elements of this tab into a single list again and hand over to
// palette and single field container to render this group
$options['tabAndInlineStack'][] = array(
'tab',
$domIdPrefix . '-' . $tabCounter,
);
$options['renderType'] = 'flexFormElementContainer';
$childReturn = $this->nodeFactory->create($options)->render();
$tabElements[] = array(
'label' => !empty($sheetDataStructure['ROOT']['sheetTitle']) ? $languageService->sL($sheetDataStructure['ROOT']['sheetTitle']) : $sheetName,
'content' => $childReturn['html'],
'description' => $sheetDataStructure['ROOT']['sheetDescription'] ? $languageService->sL($sheetDataStructure['ROOT']['sheetDescription']) : '',
'linkTitle' => $sheetDataStructure['ROOT']['sheetShortDescr'] ? $languageService->sL($sheetDataStructure['ROOT']['sheetShortDescr']) : '',
);
$childReturn['html'] = '';
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $childReturn);
}
// Feed everything to document template for tab rendering
$resultArray['html'] = $this->renderTabMenu($tabElements, $domIdPrefix);
return $resultArray;
}
/**
* @return LanguageService
*/
protected function getLanguageService()
{
return $GLOBALS['LANG'];
}
}