/** * Renders the display of default language record content around current field. * Will render content if any is found in the internal array, $this->defaultLanguageData, * depending on registerDefaultLanguageData() being called prior to this. * * @param string $table Table name of the record being edited * @param string $field Field name represented by $item * @param array $row Record array of the record being edited * @param string $item 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 renderDefaultLanguageContent($table, $field, $row, $item) { if (is_array($this->globalOptions['defaultLanguageData'][$table . ':' . $row['uid']])) { $defaultLanguageValue = BackendUtility::getProcessedValue($table, $field, $this->globalOptions['defaultLanguageData'][$table . ':' . $row['uid']][$field], 0, 1, FALSE, $this->globalOptions['defaultLanguageData'][$table . ':' . $row['uid']]['uid']); $fieldConfig = $GLOBALS['TCA'][$table]['columns'][$field]; // Don't show content if it's for IRRE child records: if ($fieldConfig['config']['type'] !== 'inline') { if ($defaultLanguageValue !== '') { $item .= '<div class="t3-form-original-language">' . FormEngineUtility::getLanguageIcon($table, $row, 0) . $this->getMergeBehaviourIcon($fieldConfig['l10n_mode']) . $this->previewFieldValue($defaultLanguageValue, $fieldConfig, $field) . '</div>'; } $additionalPreviewLanguages = $this->globalOptions['additionalPreviewLanguages']; foreach ($additionalPreviewLanguages as $previewLanguage) { $defaultLanguageValue = BackendUtility::getProcessedValue($table, $field, $this->globalOptions['additionalPreviewLanguageData'][$table . ':' . $row['uid']][$previewLanguage['uid']][$field], 0, 1); if ($defaultLanguageValue !== '') { $item .= '<div class="t3-form-original-language">' . FormEngineUtility::getLanguageIcon($table, $row, 'v' . $previewLanguage['ISOcode']) . $this->getMergeBehaviourIcon($fieldConfig['l10n_mode']) . $this->previewFieldValue($defaultLanguageValue, $fieldConfig, $field) . '</div>'; } } } } return $item; }
/** * Entry method * * @return array As defined in initializeResultArray() of AbstractNode */ public function render() { $table = $this->globalOptions['table']; $row = $this->globalOptions['databaseRow']; $fieldName = $this->globalOptions['fieldName']; $flexFormDataStructureArray = $this->globalOptions['flexFormDataStructureArray']; $flexFormRowData = $this->globalOptions['flexFormRowData']; $flexFormCurrentLanguage = $this->globalOptions['flexFormCurrentLanguage']; $flexFormNoEditDefaultLanguage = $this->globalOptions['flexFormNoEditDefaultLanguage']; $flexFormFormPrefix = $this->globalOptions['flexFormFormPrefix']; $parameterArray = $this->globalOptions['parameterArray']; $languageService = $this->getLanguageService(); $resultArray = $this->initializeResultArray(); foreach ($flexFormDataStructureArray as $flexFormFieldName => $flexFormFieldArray) { if (!is_array($flexFormFieldArray) || !isset($flexFormFieldArray['type']) && !is_array($flexFormFieldArray['TCEforms']['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->globalOptions; $options['flexFormDataStructureArray'] = $flexFormFieldArray['el']; $options['flexFormRowData'] = is_array($flexFormRowData[$flexFormFieldName]['el']) ? $flexFormRowData[$flexFormFieldName]['el'] : array(); $options['flexFormSectionType'] = $flexFormFieldName; $options['flexFormSectionTitle'] = $sectionTitle; $options['renderType'] = 'flexFormSectionContainer'; /** @var NodeFactory $nodeFactory */ $nodeFactory = $this->globalOptions['nodeFactory']; $sectionContainerResult = $nodeFactory->create($options)->render(); $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $sectionContainerResult); } else { // Single element $vDEFkey = 'vDEF'; $displayConditionResult = TRUE; if (!empty($flexFormFieldArray['TCEforms']['displayCond'])) { $conditionData = is_array($flexFormRowData) ? $flexFormRowData : array(); $conditionData['parentRec'] = $row; /** @var $elementConditionMatcher ElementConditionMatcher */ $elementConditionMatcher = GeneralUtility::makeInstance(ElementConditionMatcher::class); $displayConditionResult = $elementConditionMatcher->match($flexFormFieldArray['TCEforms']['displayCond'], $conditionData, $vDEFkey); } if (!$displayConditionResult) { continue; } // On-the-fly migration for flex form "TCA" // @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8. This can be removed *if* no additional TCA migration is added with CMS 8, see class TcaMigration $dummyTca = array('dummyTable' => array('columns' => array('dummyField' => $flexFormFieldArray['TCEforms']))); $tcaMigration = GeneralUtility::makeInstance(TcaMigration::class); $migratedTca = $tcaMigration->migrate($dummyTca); $messages = $tcaMigration->getMessages(); if (!empty($messages)) { $context = 'FormEngine did an on-the-fly migration of a flex form data structure. This is deprecated and will be removed' . ' with TYPO3 CMS 8. Merge the following changes into the flex form definition of table ' . $table . ' in field ' . $fieldName . ':'; array_unshift($messages, $context); GeneralUtility::deprecationLog(implode(LF, $messages)); } $flexFormFieldArray['TCEforms'] = $migratedTca['dummyTable']['columns']['dummyField']; // Set up options for single element $fakeParameterArray = array('fieldConf' => array('label' => $languageService->sL(trim($flexFormFieldArray['TCEforms']['label'])), 'config' => $flexFormFieldArray['TCEforms']['config'], 'defaultExtras' => $flexFormFieldArray['TCEforms']['defaultExtras'], 'onChange' => $flexFormFieldArray['TCEforms']['onChange'])); // Force a none field if default language can not be edited if ($flexFormNoEditDefaultLanguage && $flexFormCurrentLanguage === 'lDEF') { $fakeParameterArray['fieldConf']['config'] = array('type' => 'none', 'rows' => 2); } $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 = 'if (confirm(TBE_EDITOR.labels.onChangeAlert) && TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm() };'; } 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 . '][' . $vDEFkey . ']'; $fakeParameterArray['itemFormElID'] = $fakeParameterArray['itemFormElName']; if (isset($flexFormRowData[$flexFormFieldName][$vDEFkey])) { $fakeParameterArray['itemFormElValue'] = $flexFormRowData[$flexFormFieldName][$vDEFkey]; } else { $fakeParameterArray['itemFormElValue'] = $fakeParameterArray['fieldConf']['config']['default']; } $options = $this->globalOptions; $options['parameterArray'] = $fakeParameterArray; $options['elementBaseName'] = $this->globalOptions['elementBaseName'] . $flexFormFormPrefix . '[' . $flexFormFieldName . '][' . $vDEFkey . ']'; if (!empty($flexFormFieldArray['TCEforms']['config']['renderType'])) { $options['renderType'] = $flexFormFieldArray['TCEforms']['config']['renderType']; } else { // Fallback to type if no renderType is given $options['renderType'] = $flexFormFieldArray['TCEforms']['config']['type']; } /** @var NodeFactory $nodeFactory */ $nodeFactory = $this->globalOptions['nodeFactory']; $childResult = $nodeFactory->create($options)->render(); $theTitle = htmlspecialchars($fakeParameterArray['fieldConf']['label']); $defInfo = array(); if (!$flexFormNoEditDefaultLanguage) { $previewLanguages = $this->globalOptions['additionalPreviewLanguages']; foreach ($previewLanguages as $previewLanguage) { $defInfo[] = '<div class="t3-form-original-language">'; $defInfo[] = FormEngineUtility::getLanguageIcon($table, $row, 'v' . $previewLanguage['ISOcode']); $defInfo[] = $this->previewFieldValue($flexFormRowData[$flexFormFieldName]['v' . $previewLanguage['ISOcode']], $fakeParameterArray['fieldConf'], $fieldName); $defInfo[] = '</div>'; } } $languageIcon = ''; if ($vDEFkey !== 'vDEF') { $languageIcon = FormEngineUtility::getLanguageIcon($table, $row, $vDEFkey); } // 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 = array(); $html[] = '<div class="form-section">'; $html[] = '<div class="form-group t3js-formengine-palette-field t3js-formengine-validation-marker">'; $html[] = '<label class="t3js-formengine-label">'; $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], $vDEFkey); $html[] = '</div>'; $html[] = '</div>'; $html[] = '</div>'; $resultArray['html'] .= implode(LF, $html); $childResult['html'] = ''; $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $childResult); } } return $resultArray; }
/** * Entry method * * @return array As defined in initializeResultArray() of AbstractNode */ public function render() { $table = $this->globalOptions['table']; $row = $this->globalOptions['databaseRow']; $flexFormDataStructureArray = $this->globalOptions['flexFormDataStructureArray']; $flexFormRowData = $this->globalOptions['flexFormRowData']; // Determine available languages $langChildren = (bool) $flexFormDataStructureArray['meta']['langChildren']; $langDisabled = (bool) $flexFormDataStructureArray['meta']['langDisable']; $flexFormRowData['meta']['currentLangId'] = array(); // Look up page language overlays $checkPageLanguageOverlay = $this->getBackendUserAuthentication()->getTSConfigVal('options.checkPageLanguageOverlay') ? TRUE : FALSE; $pageOverlays = array(); if ($checkPageLanguageOverlay) { $whereClause = 'pid=' . (int) $row['pid'] . BackendUtility::deleteClause('pages_language_overlay') . BackendUtility::versioningPlaceholderClause('pages_language_overlay'); $pageOverlays = $this->getDatabaseConnection()->exec_SELECTgetRows('*', 'pages_language_overlay', $whereClause, '', '', '', 'sys_language_uid'); } $languages = $this->getAvailableLanguages(); foreach ($languages as $langInfo) { if ($this->getBackendUserAuthentication()->checkLanguageAccess($langInfo['uid']) && (!$checkPageLanguageOverlay || $langInfo['uid'] <= 0 || is_array($pageOverlays[$langInfo['uid']]))) { $flexFormRowData['meta']['currentLangId'][] = $langInfo['ISOcode']; } } if (!is_array($flexFormRowData['meta']['currentLangId']) || !count($flexFormRowData['meta']['currentLangId'])) { $flexFormRowData['meta']['currentLangId'] = array('DEF'); } $flexFormRowData['meta']['currentLangId'] = array_unique($flexFormRowData['meta']['currentLangId']); $flexFormNoEditDefaultLanguage = FALSE; if ($langChildren || $langDisabled) { $availableLanguages = array('DEF'); } else { if (!in_array('DEF', $flexFormRowData['meta']['currentLangId'])) { array_unshift($flexFormRowData['meta']['currentLangId'], 'DEF'); $flexFormNoEditDefaultLanguage = TRUE; } $availableLanguages = $flexFormRowData['meta']['currentLangId']; } // Tabs or no tabs - that's the question $hasTabs = FALSE; if (is_array($flexFormDataStructureArray['sheets'])) { $hasTabs = TRUE; } $resultArray = $this->initializeResultArray(); foreach ($availableLanguages as $lKey) { // Add language as header if (!$langChildren && !$langDisabled) { $resultArray['html'] .= LF . '<strong>' . FormEngineUtility::getLanguageIcon($table, $row, 'v' . $lKey) . $lKey . ':</strong>'; } // Default language "lDEF", other options are "lUK" or whatever country code $flexFormCurrentLanguage = 'l' . $lKey; $options = $this->globalOptions; $options['flexFormCurrentLanguage'] = $flexFormCurrentLanguage; $options['flexFormNoEditDefaultLanguage'] = $flexFormNoEditDefaultLanguage; if (!$hasTabs) { $options['renderType'] = 'flexFormNoTabsContainer'; /** @var NodeFactory $nodeFactory */ $nodeFactory = $this->globalOptions['nodeFactory']; $flexFormNoTabsResult = $nodeFactory->create($options)->render(); $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $flexFormNoTabsResult); } else { $options['renderType'] = 'flexFormTabsContainer'; /** @var NodeFactory $nodeFactory */ $nodeFactory = $this->globalOptions['nodeFactory']; $flexFormTabsContainerResult = $nodeFactory->create($options)->render(); $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $flexFormTabsContainerResult); } } $resultArray['requireJsModules'][] = 'TYPO3/CMS/Backend/FormEngineFlexForm'; return $resultArray; }