Esempio n. 1
0
 /**
  * Convert the DOM object-id of an inline container to an array.
  * The object-id could look like 'data-parentPageId-tx_mmftest_company-1-employees'.
  * This initializes $this->inlineStructure - used by AJAX entry points
  * There are two keys:
  * - 'stable': Containing full qualified identifiers (table, uid and field)
  * - 'unstable': Containing partly filled data (e.g. only table and possibly field)
  *
  * @param string $domObjectId The DOM object-id
  * @param bool $loadConfig Load the TCA configuration for that level (default: TRUE)
  * @return void
  */
 public function initializeByParsingDomObjectIdString($domObjectId, $loadConfig = TRUE)
 {
     $unstable = array();
     $vector = array('table', 'uid', 'field');
     // Substitute FlexForm addition and make parsing a bit easier
     $domObjectId = str_replace('---', ':', $domObjectId);
     // The starting pattern of an object identifier (e.g. "data-<firstPidValue>-<anything>)
     $pattern = '/^data' . '-' . '(.+?)' . '-' . '(.+)$/';
     if (preg_match($pattern, $domObjectId, $match)) {
         $inlineFirstPid = $match[1];
         $parts = explode('-', $match[2]);
         $partsCnt = count($parts);
         for ($i = 0; $i < $partsCnt; $i++) {
             if ($i > 0 && $i % 3 == 0) {
                 // Load the TCA configuration of the table field and store it in the stack
                 if ($loadConfig) {
                     $unstable['config'] = $GLOBALS['TCA'][$unstable['table']]['columns'][$unstable['field']]['config'];
                     // Fetch TSconfig:
                     $TSconfig = FormEngineUtility::getTSconfigForTableRow($unstable['table'], array('uid' => $unstable['uid'], 'pid' => $inlineFirstPid), $unstable['field']);
                     // Override TCA field config by TSconfig:
                     if (!$TSconfig['disabled']) {
                         $unstable['config'] = FormEngineUtility::overrideFieldConf($unstable['config'], $TSconfig);
                     }
                     $unstable['localizationMode'] = BackendUtility::getInlineLocalizationMode($unstable['table'], $unstable['config']);
                 }
                 // Extract FlexForm from field part (if any)
                 if (strpos($unstable['field'], ':') !== FALSE) {
                     $fieldParts = GeneralUtility::trimExplode(':', $unstable['field']);
                     $unstable['field'] = array_shift($fieldParts);
                     // FlexForm parts start with data:
                     if (count($fieldParts) > 0 && $fieldParts[0] === 'data') {
                         $unstable['flexform'] = $fieldParts;
                     }
                 }
                 $this->inlineStructure['stable'][] = $unstable;
                 $unstable = array();
             }
             $unstable[$vector[$i % 3]] = $parts[$i];
         }
         if (count($unstable)) {
             $this->inlineStructure['unstable'] = $unstable;
         }
     }
 }
Esempio n. 2
0
    /**
     * Get a selector as used for the select type, to select from all available
     * records and to create a relation to the embedding record (e.g. like MM).
     *
     * @param array $selItems Array of all possible records
     * @param array $conf TCA configuration of the parent(!) field
     * @param array $PA An array with additional configuration options
     * @param array $uniqueIds The uids that have already been used and should be unique
     * @return string A HTML <select> box with all possible records
     */
    protected function renderPossibleRecordsSelectorTypeSelect($selItems, $conf, &$PA, $uniqueIds = array())
    {
        $foreign_table = $conf['foreign_table'];
        $foreign_selector = $conf['foreign_selector'];
        $PA = array();
        $PA['fieldConf'] = $GLOBALS['TCA'][$foreign_table]['columns'][$foreign_selector];
        $PA['fieldTSConfig'] = FormEngineUtility::getTSconfigForTableRow($foreign_table, array(), $foreign_selector);
        $config = $PA['fieldConf']['config'];
        $item = '';
        // @todo $disabled is not present - should be read from config?
        $disabled = false;
        if (!$disabled) {
            $nameObject = $this->inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($this->data['inlineFirstPid']);
            // Create option tags:
            $opt = array();
            foreach ($selItems as $p) {
                if (!in_array($p[1], $uniqueIds)) {
                    $opt[] = '<option value="' . htmlspecialchars($p[1]) . '">' . htmlspecialchars($p[0]) . '</option>';
                }
            }
            // Put together the selector box:
            $itemListStyle = isset($config['itemListStyle']) ? ' style="' . htmlspecialchars($config['itemListStyle']) . '"' : '';
            $size = (int) $conf['size'];
            $size = $conf['autoSizeMax'] ? MathUtility::forceIntegerInRange(count($selItems) + 1, MathUtility::forceIntegerInRange($size, 1), $conf['autoSizeMax']) : $size;
            $onChange = 'return inline.importNewRecord(' . GeneralUtility::quoteJSvalue($nameObject . '-' . $conf['foreign_table']) . ')';
            $item = '
				<select id="' . $nameObject . '-' . $conf['foreign_table'] . '_selector" class="form-control"' . ($size ? ' size="' . $size . '"' : '') . ' onchange="' . htmlspecialchars($onChange) . '"' . $PA['onFocus'] . $itemListStyle . ($conf['foreign_unique'] ? ' isunique="isunique"' : '') . '>
					' . implode('', $opt) . '
				</select>';
            if ($size <= 1) {
                // Add a "Create new relation" link for adding new relations
                // This is necessary, if the size of the selector is "1" or if
                // there is only one record item in the select-box, that is selected by default
                // The selector-box creates a new relation on using an onChange event (see some line above)
                if (!empty($conf['appearance']['createNewRelationLinkTitle'])) {
                    $createNewRelationText = $this->getLanguageService()->sL($conf['appearance']['createNewRelationLinkTitle'], true);
                } else {
                    $createNewRelationText = $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:cm.createNewRelation', true);
                }
                $item .= '
				<span class="input-group-btn">
					<a href="#" class="btn btn-default" onclick="' . htmlspecialchars($onChange) . '" title="' . $createNewRelationText . '">
						' . $this->iconFactory->getIcon('actions-document-new', Icon::SIZE_SMALL)->render() . $createNewRelationText . '
					</a>
				</span>';
            } else {
                $item .= '
				<span class="input-group-btn btn"></span>';
            }
            // Wrap the selector and add a spacer to the bottom
            $item = '<div class="input-group form-group t3js-formengine-validation-marker ' . $this->inlineData['config'][$nameObject]['md5'] . '">' . $item . '</div>';
        }
        return $item;
    }
Esempio n. 3
0
 /**
  * Determine the configuration and the type of a record selector.
  * This is a helper method for inline / IRRE handling
  *
  * @param array $conf TCA configuration of the parent(!) field
  * @param string $field Field name
  * @return array Associative array with the keys 'PA' and 'type', both are FALSE if the selector was not valid.
  * @internal
  */
 public static function getInlinePossibleRecordsSelectorConfig($conf, $field = '')
 {
     $foreign_table = $conf['foreign_table'];
     $foreign_selector = $conf['foreign_selector'];
     $PA = false;
     $type = false;
     $table = false;
     $selector = false;
     if ($field) {
         $PA = array();
         $PA['fieldConf'] = $GLOBALS['TCA'][$foreign_table]['columns'][$field];
         if ($PA['fieldConf'] && $conf['foreign_selector_fieldTcaOverride']) {
             ArrayUtility::mergeRecursiveWithOverrule($PA['fieldConf'], $conf['foreign_selector_fieldTcaOverride']);
         }
         $PA['fieldTSConfig'] = FormEngineUtility::getTSconfigForTableRow($foreign_table, array(), $field);
         $config = $PA['fieldConf']['config'];
         // Determine type of Selector:
         $type = static::getInlinePossibleRecordsSelectorType($config);
         // Return table on this level:
         $table = $type === 'select' ? $config['foreign_table'] : $config['allowed'];
         // Return type of the selector if foreign_selector is defined and points to the same field as in $field:
         if ($foreign_selector && $foreign_selector == $field && $type) {
             $selector = $type;
         }
     }
     return array('PA' => $PA, 'type' => $type, 'table' => $table, 'selector' => $selector);
 }
 /**
  * Determine label of a single field (not a palette label)
  *
  * @param string $fieldName The field name to calculate the label for
  * @param string $labelFromShowItem Given label, typically from show item configuration
  * @return string Field label
  */
 protected function getSingleFieldLabel($fieldName, $labelFromShowItem)
 {
     $languageService = $this->getLanguageService();
     $table = $this->globalOptions['table'];
     $label = $labelFromShowItem;
     if (!empty($GLOBALS['TCA'][$table]['columns'][$fieldName]['label'])) {
         $label = $GLOBALS['TCA'][$table]['columns'][$fieldName]['label'];
     }
     if (!empty($labelFromShowItem)) {
         $label = $labelFromShowItem;
     }
     $fieldTSConfig = FormEngineUtility::getTSconfigForTableRow($table, $this->globalOptions['databaseRow'], $fieldName);
     if (!empty($fieldTSConfig['label'])) {
         $label = $fieldTSConfig['label'];
     }
     if (!empty($fieldTSConfig['label.'][$languageService->lang])) {
         $label = $fieldTSConfig['label.'][$languageService->lang];
     }
     return $languageService->sL($label);
 }
Esempio n. 5
0
 /**
  * Modify a single FlexForm sheet according to given configuration
  *
  * @param array $sheet Flexform sheet to manipulate
  * @param string $table The table name
  * @param string $tableField The field name
  * @param array $tableRow The record data
  * @param array $sheetConf Sheet configuration
  * @param array $nonExcludeFields Non-exclude-fields for this sheet
  * @return array Modified sheet
  * @see \TYPO3\CMS\Backend\Form\FlexFormsHelper::modifyFlexFormDS()
  */
 public function modifySingleFlexFormSheet(array $sheet, $table, $tableField, array $tableRow, array $sheetConf, array $nonExcludeFields)
 {
     if (empty($sheet) || empty($table) || empty($tableField) || empty($tableRow)) {
         return $sheet;
     }
     // Modify fields
     foreach ($sheet as $fieldName => $field) {
         // Remove excluded fields
         if (!$GLOBALS['BE_USER']->isAdmin() && !empty($field['TCEforms']['exclude']) && empty($nonExcludeFields[$fieldName])) {
             unset($sheet[$fieldName]);
             continue;
         }
         // Stop here if no TSConfig was found for this field
         if (empty($sheetConf[$fieldName]) || !is_array($sheetConf[$fieldName])) {
             continue;
         }
         // Remove disabled fields
         if (!empty($sheetConf[$fieldName]['disabled'])) {
             unset($sheet[$fieldName]);
             continue;
         }
         $fieldConf = $sheetConf[$fieldName];
         $removeItems = !empty($fieldConf['removeItems']) ? GeneralUtility::trimExplode(',', $fieldConf['removeItems'], TRUE) : array();
         $keepItems = !empty($fieldConf['keepItems']) ? GeneralUtility::trimExplode(',', $fieldConf['keepItems'], TRUE) : array();
         $renameItems = !empty($fieldConf['altLabels']) && is_array($fieldConf['altLabels']) ? $fieldConf['altLabels'] : array();
         $changeIcons = !empty($fieldConf['altIcons']) && is_array($fieldConf['altIcons']) ? $fieldConf['altIcons'] : array();
         $addItems = !empty($fieldConf['addItems']) && is_array($fieldConf['addItems']) ? $fieldConf['addItems'] : array();
         unset($fieldConf['removeItems']);
         unset($fieldConf['keepItems']);
         unset($fieldConf['altLabels']);
         unset($fieldConf['altIcons']);
         unset($fieldConf['addItems']);
         // Manipulate field
         if (!empty($field['TCEforms']) && is_array($field['TCEforms'])) {
             $sheet[$fieldName]['TCEforms'] = $field['TCEforms'];
             ArrayUtility::mergeRecursiveWithOverrule($sheet[$fieldName]['TCEforms'], $fieldConf);
         }
         // Manipulate only select fields, other field types will stop here
         if (empty($field['TCEforms']['config']['type']) || $field['TCEforms']['config']['type'] != 'select' || $field['TCEforms']['config']['renderMode'] === 'tree') {
             continue;
         }
         // Getting the selector box items from system
         $selItems = FormEngineUtility::addSelectOptionsToItemArray(FormEngineUtility::initItemArray($field['TCEforms']), $field['TCEforms'], FormEngineUtility::getTSconfigForTableRow($table, $tableRow), $tableField);
         // Possibly filter some items
         $selItems = ArrayUtility::keepItemsInArray($selItems, $keepItems, function ($value) {
             return $value[1];
         });
         // Possibly add some items
         $selItems = FormEngineUtility::addItems($selItems, $addItems);
         // Process items by a user function
         if (!empty($field['TCEforms']['config']['itemsProcFunc'])) {
             $dataPreprocessor = GeneralUtility::makeInstance(DataPreprocessor::class);
             $selItems = $dataPreprocessor->procItems($selItems, $fieldConf['config'], $field['TCEforms']['config'], $table, $tableRow, $tableField);
         }
         // Remove special configuration options after creating items to prevent double parsing
         foreach ($this->removeSelectConfig as $option) {
             unset($sheet[$fieldName]['TCEforms']['config'][$option]);
         }
         // Rename and remove items or change item icon in select
         if ((!empty($removeItems) || !empty($renameItems) || !empty($changeIcons)) && !empty($selItems) && is_array($selItems)) {
             foreach ($selItems as $itemKey => $itemConf) {
                 // Option has no key, no manipulation possible
                 if (!isset($itemConf[1])) {
                     continue;
                 }
                 // Remove
                 foreach ($removeItems as $removeKey => $removeValue) {
                     if (strcasecmp($removeValue, $itemConf[1]) == 0) {
                         unset($selItems[$itemKey]);
                         unset($removeItems[$removeKey]);
                     }
                 }
                 // Rename
                 foreach ($renameItems as $renameKey => $renameValue) {
                     if (strcasecmp($renameKey, $itemConf[1]) == 0) {
                         $selItems[$itemKey][0] = htmlspecialchars($renameValue);
                         unset($renameItems[$renameKey]);
                     }
                 }
                 // Change icon
                 foreach ($changeIcons as $iconKey => $iconValue) {
                     if (strcasecmp($iconKey, $itemConf[1]) == 0) {
                         $selItems[$itemKey][2] = $iconValue;
                         unset($changeIcons[$iconKey]);
                     }
                 }
             }
         }
         $sheet[$fieldName]['TCEforms']['config']['items'] = $selItems;
     }
     return $sheet;
 }
Esempio n. 6
0
    /**
     * Main function, rendering the document with the iFrame with the RTE in.
     *
     * @return void
     */
    public function main()
    {
        // Translate id to the workspace version:
        if ($versionedRecord = BackendUtility::getWorkspaceVersionOfRecord($this->getBackendUserAuthentication()->workspace, $this->P['table'], $this->P['uid'], 'uid')) {
            $this->P['uid'] = $versionedRecord['uid'];
        }
        // If all parameters are available:
        if ($this->P['table'] && $this->P['field'] && $this->P['uid'] && $this->checkEditAccess($this->P['table'], $this->P['uid'])) {
            // Getting the raw record (we need only the pid-value from here...)
            $rawRecord = BackendUtility::getRecord($this->P['table'], $this->P['uid']);
            BackendUtility::fixVersioningPid($this->P['table'], $rawRecord);
            // override the default jumpToUrl
            $this->doc->JScodeArray['jumpToUrl'] = '
		function jumpToUrl(URL,formEl) {
			if (document.editform) {
				if (!TBE_EDITOR.isFormChanged()) {
					window.location.href = URL;
				} else if (formEl) {
					if (formEl.type=="checkbox") formEl.checked = formEl.checked ? 0 : 1;
				}
			} else {
				window.location.href = URL;
			}
		}
';
            // Setting JavaScript of the pid value for viewing:
            if ($this->popView) {
                $this->doc->JScode = $this->doc->wrapScriptTags(BackendUtility::viewOnClick($rawRecord['pid'], '', BackendUtility::BEgetRootLine($rawRecord['pid'])));
            }
            // Initialize FormEngine - for rendering the field:
            /** @var FormEngine $formEngine */
            $formEngine = GeneralUtility::makeInstance(FormEngine::class);
            // SPECIAL: Disables all wizards - we are NOT going to need them.
            $formEngine->disableWizards = 1;
            // Fetching content of record:
            /** @var DataPreprocessor $dataPreprocessor */
            $dataPreprocessor = GeneralUtility::makeInstance(DataPreprocessor::class);
            $dataPreprocessor->lockRecords = 1;
            $dataPreprocessor->fetchRecord($this->P['table'], $this->P['uid'], '');
            // Getting the processed record content out:
            $processedRecord = reset($dataPreprocessor->regTableItems_data);
            $processedRecord['uid'] = $this->P['uid'];
            $processedRecord['pid'] = $rawRecord['pid'];
            // TSconfig, setting width:
            $fieldTSConfig = FormEngineUtility::getTSconfigForTableRow($this->P['table'], $processedRecord, $this->P['field']);
            if ((string) $fieldTSConfig['RTEfullScreenWidth'] !== '') {
                $width = $fieldTSConfig['RTEfullScreenWidth'];
            } else {
                $width = '100%';
            }
            // Get the form field and wrap it in the table with the buttons:
            $formContent = $formEngine->getSoloField($this->P['table'], $processedRecord, $this->P['field']);
            $formContent = '

			<!-- RTE wizard: -->
				<table border="0" cellpadding="0" cellspacing="0" width="' . $width . '" id="typo3-rtewizard">
					<tr>
						<td width="' . $width . '" colspan="2" id="c-formContent">' . $formContent . '</td>
						<td></td>
					</tr>
				</table>';
            // Adding hidden fields:
            $formContent .= '<input type="hidden" name="redirect" value="' . htmlspecialchars($this->R_URI) . '" />
						<input type="hidden" name="_serialNumber" value="' . md5(microtime()) . '" />' . FormEngine::getHiddenTokenField('tceAction');
            // Finally, add the whole setup:
            $this->content .= $formEngine->printNeededJSFunctions_top() . $formContent . $formEngine->printNeededJSFunctions();
        } else {
            // ERROR:
            $this->content .= $this->doc->section($this->getLanguageService()->getLL('forms_title'), '<span class="text-danger">' . $this->getLanguageService()->getLL('table_noData', TRUE) . '</span>', 0, 1);
        }
        // Setting up the buttons and markers for docHeader
        $docHeaderButtons = $this->getButtons();
        $markers['CONTENT'] = $this->content;
        // Build the <body> for the module
        $this->content = $this->doc->startPage('');
        $this->content .= $this->doc->moduleBody(array(), $docHeaderButtons, $markers);
        $this->content .= $this->doc->endPage();
        $this->content = $this->doc->insertStylesAndJS($this->content);
    }
 /**
  * Entry method
  *
  * @return array As defined in initializeResultArray() of AbstractNode
  */
 public function render()
 {
     $backendUser = $this->getBackendUserAuthentication();
     $languageService = $this->getLanguageService();
     $resultArray = $this->initializeResultArray();
     $table = $this->globalOptions['table'];
     $row = $this->globalOptions['databaseRow'];
     $fieldName = $this->globalOptions['fieldName'];
     if (!is_array($GLOBALS['TCA'][$table]['columns'][$fieldName])) {
         return $resultArray;
     }
     $parameterArray = array();
     $parameterArray['fieldConf'] = $GLOBALS['TCA'][$table]['columns'][$fieldName];
     // Overlay fieldConf with possible defined columnsOverrides of given record type
     $recordTypeValue = $this->globalOptions['recordTypeValue'];
     // Hint: 0 is a valid $recordTypeValue, !empty() does not work here
     if (trim($recordTypeValue) !== '' && is_array($GLOBALS['TCA'][$table]['types'][$recordTypeValue]['columnsOverrides'][$fieldName])) {
         // Merge columnsOverrides of this field over existing field configuration
         ArrayUtility::mergeRecursiveWithOverrule($parameterArray['fieldConf'], $GLOBALS['TCA'][$table]['types'][$recordTypeValue]['columnsOverrides'][$fieldName]);
     }
     // A couple of early returns in case the field should not be rendered
     // Check if this field is configured and editable according to exclude fields and other configuration
     if ($parameterArray['fieldConf']['exclude'] && !$backendUser->check('non_exclude_fields', $table . ':' . $fieldName) || $parameterArray['fieldConf']['config']['type'] === 'passthrough' || !$backendUser->isRTE() && $parameterArray['fieldConf']['config']['showIfRTE'] || $GLOBALS['TCA'][$table]['ctrl']['languageField'] && !$parameterArray['fieldConf']['l10n_display'] && $parameterArray['fieldConf']['l10n_mode'] === 'exclude' && $row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] > 0 || $GLOBALS['TCA'][$table]['ctrl']['languageField'] && $this->globalOptions['localizationMode'] && $this->globalOptions['localizationMode'] !== $parameterArray['fieldConf']['l10n_cat'] || $this->inlineFieldShouldBeSkipped()) {
         return $resultArray;
     }
     // Evaluate display condition
     if ($parameterArray['fieldConf']['displayCond'] && is_array($row)) {
         // @todo: isn't $row = array() safe somewhere above already?
         /** @var $elementConditionMatcher ElementConditionMatcher */
         $elementConditionMatcher = GeneralUtility::makeInstance(ElementConditionMatcher::class);
         if (!$elementConditionMatcher->match($parameterArray['fieldConf']['displayCond'], $row)) {
             return $resultArray;
         }
     }
     // Fetching the TSconfig for the current table/field. This includes the $row which means that
     $parameterArray['fieldTSConfig'] = FormEngineUtility::getTSconfigForTableRow($table, $row, $fieldName);
     if ($parameterArray['fieldTSConfig']['disabled']) {
         return $resultArray;
     }
     // Override fieldConf by fieldTSconfig:
     $parameterArray['fieldConf']['config'] = FormEngineUtility::overrideFieldConf($parameterArray['fieldConf']['config'], $parameterArray['fieldTSConfig']);
     $parameterArray['itemFormElName'] = 'data[' . $table . '][' . $row['uid'] . '][' . $fieldName . ']';
     $parameterArray['itemFormElID'] = 'data_' . $table . '_' . $row['uid'] . '_' . $fieldName;
     $newElementBaseName = $this->globalOptions['elementBaseName'] . '[' . $table . '][' . $row['uid'] . '][' . $fieldName . ']';
     // The value to show in the form field.
     $parameterArray['itemFormElValue'] = $row[$fieldName];
     // Set field to read-only if configured for translated records to show default language content as readonly
     if ($parameterArray['fieldConf']['l10n_display'] && GeneralUtility::inList($parameterArray['fieldConf']['l10n_display'], 'defaultAsReadonly') && $row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] > 0) {
         $parameterArray['fieldConf']['config']['readOnly'] = TRUE;
         $parameterArray['itemFormElValue'] = $this->globalOptions['defaultLanguageData'][$table . ':' . $row['uid']][$fieldName];
     }
     if (strpos($GLOBALS['TCA'][$table]['ctrl']['type'], ':') === FALSE) {
         $typeField = $GLOBALS['TCA'][$table]['ctrl']['type'];
     } else {
         $typeField = substr($GLOBALS['TCA'][$table]['ctrl']['type'], 0, strpos($GLOBALS['TCA'][$table]['ctrl']['type'], ':'));
     }
     // Create a JavaScript code line which will ask the user to save/update the form due to changing the element.
     // This is used for eg. "type" fields and others configured with "requestUpdate"
     if (!empty($GLOBALS['TCA'][$table]['ctrl']['type']) && $fieldName === $typeField || !empty($GLOBALS['TCA'][$table]['ctrl']['requestUpdate']) && GeneralUtility::inList(str_replace(' ', '', $GLOBALS['TCA'][$table]['ctrl']['requestUpdate']), $fieldName)) {
         if ($backendUser->jsConfirmation(1)) {
             $alertMsgOnChange = 'if (confirm(TBE_EDITOR.labels.onChangeAlert) && TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm() };';
         } else {
             $alertMsgOnChange = 'if (TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm() };';
         }
     } else {
         $alertMsgOnChange = '';
     }
     if (in_array($fieldName, $this->globalOptions['hiddenFieldListArray'], TRUE)) {
         // Render as a hidden field if this field had a forced value in overrideVals
         // @todo: This is an ugly concept ... search for overrideVals and defVals for a full picture of this madness
         $resultArray = $this->initializeResultArray();
         // This hidden field can not just be returned as casual html since upper containers will then render a label and wrapping stuff - this is not wanted here
         $resultArray['additionalHiddenFields'][] = '<input type="hidden" name="' . $parameterArray['itemFormElName'] . '" value="' . htmlspecialchars($parameterArray['itemFormElValue']) . '" />';
     } else {
         // JavaScript code for event handlers:
         $parameterArray['fieldChangeFunc'] = array();
         $parameterArray['fieldChangeFunc']['TBE_EDITOR_fieldChanged'] = 'TBE_EDITOR.fieldChanged(' . GeneralUtility::quoteJSvalue($table) . ',' . GeneralUtility::quoteJSvalue($row['uid']) . ',' . GeneralUtility::quoteJSvalue($fieldName) . ',' . GeneralUtility::quoteJSvalue($parameterArray['itemFormElName']) . ');';
         $parameterArray['fieldChangeFunc']['alert'] = $alertMsgOnChange;
         // If this is the child of an inline type and it is the field creating the label
         if ($this->isInlineChildAndLabelField($table, $fieldName)) {
             /** @var InlineStackProcessor $inlineStackProcessor */
             $inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class);
             $inlineStackProcessor->initializeByGivenStructure($this->globalOptions['inlineStructure']);
             $inlineDomObjectId = $inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($this->globalOptions['inlineFirstPid']);
             $inlineObjectId = implode('-', array($inlineDomObjectId, $table, $row['uid']));
             $parameterArray['fieldChangeFunc']['inline'] = 'inline.handleChangedField(' . GeneralUtility::quoteJSvalue($parameterArray['itemFormElName']) . ',' . GeneralUtility::quoteJSvalue($inlineObjectId) . ');';
         }
         // Based on the type of the item, call a render function on a child element
         $options = $this->globalOptions;
         $options['parameterArray'] = $parameterArray;
         $options['elementBaseName'] = $newElementBaseName;
         if (!empty($parameterArray['fieldConf']['config']['renderType'])) {
             $options['renderType'] = $parameterArray['fieldConf']['config']['renderType'];
         } else {
             // Fallback to type if no renderType is given
             $options['renderType'] = $parameterArray['fieldConf']['config']['type'];
         }
         /** @var NodeFactory $nodeFactory */
         $nodeFactory = $this->globalOptions['nodeFactory'];
         $resultArray = $nodeFactory->create($options)->render();
         $html = $resultArray['html'];
         // @todo: the language handling, the null and the placeholder stuff should be embedded in the single
         // @todo: element classes. Basically, this method should return here and have the element classes
         // @todo: decide on language stuff and other wraps already.
         // Add language + diff
         $renderLanguageDiff = TRUE;
         if ($parameterArray['fieldConf']['l10n_display'] && (GeneralUtility::inList($parameterArray['fieldConf']['l10n_display'], 'hideDiff') || GeneralUtility::inList($parameterArray['fieldConf']['l10n_display'], 'defaultAsReadonly'))) {
             $renderLanguageDiff = FALSE;
         }
         if ($renderLanguageDiff) {
             $html = $this->renderDefaultLanguageContent($table, $fieldName, $row, $html);
             $html = $this->renderDefaultLanguageDiff($table, $fieldName, $row, $html);
         }
         $fieldItemClasses = array('t3js-formengine-field-item');
         // NULL value and placeholder handling
         $nullControlNameAttribute = ' name="' . htmlspecialchars('control[active][' . $table . '][' . $row['uid'] . '][' . $fieldName . ']') . '"';
         if (!empty($parameterArray['fieldConf']['config']['eval']) && GeneralUtility::inList($parameterArray['fieldConf']['config']['eval'], 'null') && (empty($parameterArray['fieldConf']['config']['mode']) || $parameterArray['fieldConf']['config']['mode'] !== 'useOrOverridePlaceholder')) {
             // This field has eval=null set, but has no useOverridePlaceholder defined.
             // Goal is to have a field that can distinct between NULL and empty string in the database.
             // A checkbox and an additional hidden field will be created, both with the same name
             // and prefixed with "control[active]". If the checkbox is set (value 1), the value from the casual
             // input field will be written to the database. If the checkbox is not set, the hidden field
             // transfers value=0 to DataHandler, the value of the input field will then be reset to NULL by the
             // DataHandler at an early point in processing, so NULL will be written to DB as field value.
             // If the value of the field *is* NULL at the moment, an additional class is set
             // @todo: This does not work well at the moment, but is kept for now. see input_14 of ext:styleguide as example
             $checked = ' checked="checked"';
             if ($this->globalOptions['databaseRow'][$fieldName] === NULL) {
                 $fieldItemClasses[] = 'disabled';
                 $checked = '';
             }
             $formElementName = 'data[' . $table . '][' . $row['uid'] . '][' . $fieldName . ']';
             $onChange = htmlspecialchars('typo3form.fieldSetNull(' . GeneralUtility::quoteJSvalue($formElementName) . ', !this.checked)');
             $nullValueWrap = array();
             $nullValueWrap[] = '<div class="' . implode(' ', $fieldItemClasses) . '">';
             $nullValueWrap[] = '<div class="t3-form-field-disable"></div>';
             $nullValueWrap[] = '<div class="checkbox">';
             $nullValueWrap[] = '<label>';
             $nullValueWrap[] = '<input type="hidden"' . $nullControlNameAttribute . ' value="0" />';
             $nullValueWrap[] = '<input type="checkbox"' . $nullControlNameAttribute . ' value="1" onchange="' . $onChange . '"' . $checked . ' /> &nbsp;';
             $nullValueWrap[] = '</label>';
             $nullValueWrap[] = $html;
             $nullValueWrap[] = '</div>';
             $nullValueWrap[] = '</div>';
             $html = implode(LF, $nullValueWrap);
         } elseif (isset($parameterArray['fieldConf']['config']['mode']) && $parameterArray['fieldConf']['config']['mode'] === 'useOrOverridePlaceholder') {
             // This field has useOverridePlaceholder set.
             // Here, a value from a deeper DB structure can be "fetched up" as value, and can also be overridden by a
             // local value. This is used in FAL, where eg. the "title" field can have the default value from sys_file_metadata,
             // the title field of sys_file_reference is then set to NULL. Or the "override" checkbox is set, and a string
             // or an empty string is then written to the field of sys_file_reference.
             // The situation is similar to the NULL handling above, but additionally a "default" value should be shown.
             // To achieve this, again a hidden control[hidden] field is added together with a checkbox with the same name
             // to transfer the information whether the default value should be used or not: Checkbox checked transfers 1 as
             // value in control[active], meaning the overridden value should be used.
             // Additionally to the casual input field, a second field is added containing the "placeholder" value. This
             // field has no name attribute and is not transferred at all. Those two are then hidden / shown depending
             // on the state of the above checkbox in via JS.
             $placeholder = $this->getPlaceholderValue($table, $parameterArray['fieldConf']['config'], $row);
             $onChange = 'typo3form.fieldTogglePlaceholder(' . GeneralUtility::quoteJSvalue($parameterArray['itemFormElName']) . ', !this.checked)';
             $checked = $parameterArray['itemFormElValue'] === NULL ? '' : ' checked="checked"';
             $resultArray['additionalJavaScriptPost'][] = 'typo3form.fieldTogglePlaceholder(' . GeneralUtility::quoteJSvalue($parameterArray['itemFormElName']) . ', ' . ($checked ? 'false' : 'true') . ');';
             // Renders a input or textarea field depending on type of "parent"
             $options = array();
             $options['databaseRow'] = array();
             $options['table'] = '';
             $options['parameterArray'] = $parameterArray;
             $options['parameterArray']['itemFormElValue'] = GeneralUtility::fixed_lgd_cs($placeholder, 30);
             $options['renderType'] = 'none';
             /** @var NodeFactory $nodeFactory */
             $nodeFactory = $this->globalOptions['nodeFactory'];
             $noneElementResult = $nodeFactory->create($options)->render();
             $noneElementHtml = $noneElementResult['html'];
             $placeholderWrap = array();
             $placeholderWrap[] = '<div class="' . implode(' ', $fieldItemClasses) . '">';
             $placeholderWrap[] = '<div class="t3-form-field-disable"></div>';
             $placeholderWrap[] = '<div class="checkbox">';
             $placeholderWrap[] = '<label>';
             $placeholderWrap[] = '<input type="hidden"' . $nullControlNameAttribute . ' value="0" />';
             $placeholderWrap[] = '<input type="checkbox"' . $nullControlNameAttribute . ' value="1" id="tce-forms-textfield-use-override-' . $fieldName . '-' . $row['uid'] . '" onchange="' . htmlspecialchars($onChange) . '"' . $checked . ' />';
             $placeholderWrap[] = sprintf($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.placeholder.override'), BackendUtility::getRecordTitlePrep($placeholder, 20));
             $placeholderWrap[] = '</label>';
             $placeholderWrap[] = '</div>';
             $placeholderWrap[] = '<div class="t3js-formengine-placeholder-placeholder">';
             $placeholderWrap[] = $noneElementHtml;
             $placeholderWrap[] = '</div>';
             $placeholderWrap[] = '<div class="t3js-formengine-placeholder-formfield">';
             $placeholderWrap[] = $html;
             $placeholderWrap[] = '</div>';
             $placeholderWrap[] = '</div>';
             $html = implode(LF, $placeholderWrap);
         } elseif ($parameterArray['fieldConf']['config']['type'] !== 'user' || empty($parameterArray['fieldConf']['config']['noTableWrapping'])) {
             // Add a casual wrap if the field is not of type user with no wrap requested.
             $standardWrap = array();
             $standardWrap[] = '<div class="' . implode(' ', $fieldItemClasses) . '">';
             $standardWrap[] = '<div class="t3-form-field-disable"></div>';
             $standardWrap[] = $html;
             $standardWrap[] = '</div>';
             $html = implode(LF, $standardWrap);
         }
         $resultArray['html'] = $html;
     }
     return $resultArray;
 }
Esempio n. 8
0
 /**
  * If the select field is build by a foreign_table the related UIDs
  * will be returned.
  *
  * Otherwise the label of the currently selected value will be written
  * to the alternativeFieldValue class property.
  *
  * @param array $fieldConfig The "config" section of the TCA for the current select field.
  * @param string $fieldName The name of the select field.
  * @param string $value The current value in the local record, usually a comma separated list of selected values.
  * @return array Array of related UIDs.
  */
 protected function getRelatedSelectFieldUids(array $fieldConfig, $fieldName, $value)
 {
     $relatedUids = array();
     $isTraversable = FALSE;
     if (isset($fieldConfig['foreign_table'])) {
         $isTraversable = TRUE;
         // if a foreign_table is used we pre-filter the records for performance
         $fieldConfig['foreign_table_where'] .= ' AND ' . $fieldConfig['foreign_table'] . '.uid IN (' . $value . ')';
     }
     $PA = array();
     $PA['fieldConf']['config'] = $fieldConfig;
     $PA['fieldTSConfig'] = FormEngineUtility::getTSconfigForTableRow($this->currentTable, $this->currentRow, $fieldName);
     $PA['fieldConf']['config'] = FormEngineUtility::overrideFieldConf($PA['fieldConf']['config'], $PA['fieldTSConfig']);
     $selectItemArray = FormEngineUtility::getSelectItems($this->currentTable, $fieldName, $this->currentRow, $PA);
     if ($isTraversable && !empty($selectItemArray)) {
         $this->currentTable = $fieldConfig['foreign_table'];
         $relatedUids = $this->getSelectedValuesFromSelectItemArray($selectItemArray, $value);
     } else {
         $selectedLabels = $this->getSelectedValuesFromSelectItemArray($selectItemArray, $value, 1, TRUE);
         if (count($selectedLabels) === 1) {
             $this->alternativeFieldValue = $selectedLabels[0];
             $this->forceAlternativeFieldValueUse = TRUE;
         }
     }
     return $relatedUids;
 }
Esempio n. 9
0
    /**
     * Rendering wizards for form fields.
     *
     * @param array $itemKinds Array with the real item in the first value, and an alternative item in the second value.
     * @param array $wizConf The "wizard" key from the config array for the field (from TCA)
     * @param string $table Table name
     * @param array $row The record array
     * @param string $field The field name
     * @param array $PA Additional configuration array.
     * @param string $itemName The field name
     * @param array $specConf Special configuration if available.
     * @param bool $RTE Whether the RTE could have been loaded.
     * @return string The new item value.
     */
    protected function renderWizards($itemKinds, $wizConf, $table, $row, $field, $PA, $itemName, $specConf, $RTE = FALSE)
    {
        // Return not changed main item directly if wizards are disabled
        if (!is_array($wizConf) || $this->isWizardsDisabled()) {
            return $itemKinds[0];
        }
        $languageService = $this->getLanguageService();
        $fieldChangeFunc = $PA['fieldChangeFunc'];
        $item = $itemKinds[0];
        $fName = '[' . $table . '][' . $row['uid'] . '][' . $field . ']';
        $md5ID = 'ID' . GeneralUtility::shortmd5($itemName);
        $fieldConfig = $PA['fieldConf']['config'];
        $prefixOfFormElName = 'data[' . $table . '][' . $row['uid'] . '][' . $field . ']';
        $flexFormPath = '';
        if (GeneralUtility::isFirstPartOfStr($PA['itemFormElName'], $prefixOfFormElName)) {
            $flexFormPath = str_replace('][', '/', substr($PA['itemFormElName'], strlen($prefixOfFormElName) + 1, -1));
        }
        // Manipulate the field name (to be the TRUE form field name) and remove
        // a suffix-value if the item is a selector box with renderMode "singlebox":
        $listFlag = '_list';
        if ($PA['fieldConf']['config']['type'] == 'select') {
            // Single select situation:
            if ($PA['fieldConf']['config']['maxitems'] <= 1) {
                $listFlag = '';
            } elseif ($PA['fieldConf']['config']['renderMode'] == 'singlebox') {
                $itemName .= '[]';
                $listFlag = '';
            }
        }
        // Contains wizard identifiers enabled for this record type, see "special configuration" docs
        $wizardsEnabledByType = $specConf['wizards']['parameters'];
        $buttonWizards = array();
        $otherWizards = array();
        foreach ($wizConf as $wizardIdentifier => $wizardConfiguration) {
            // If an identifier starts with "_", this is a configuration option like _POSITION and not a wizard
            if ($wizardIdentifier[0] === '_') {
                continue;
            }
            // Sanitize wizard type
            $wizardConfiguration['type'] = (string) $wizardConfiguration['type'];
            // Wizards can be shown based on selected "type" of record. If this is the case, the wizard configuration
            // is set to enableByTypeConfig = 1, and the wizardIdentifier is found in $wizardsEnabledByType
            $wizardIsEnabled = TRUE;
            if (isset($wizardConfiguration['enableByTypeConfig']) && (bool) $wizardConfiguration['enableByTypeConfig'] && (!is_array($wizardsEnabledByType) || !in_array($wizardIdentifier, $wizardsEnabledByType))) {
                $wizardIsEnabled = FALSE;
            }
            // Disable if wizard is for RTE fields only and the handled field is no RTE field or RTE can not be loaded
            if (isset($wizardConfiguration['RTEonly']) && (bool) $wizardConfiguration['RTEonly'] && !$RTE) {
                $wizardIsEnabled = FALSE;
            }
            // Disable if wizard is for not-new records only and we're handling a new record
            if (isset($wizardConfiguration['notNewRecords']) && $wizardConfiguration['notNewRecords'] && !MathUtility::canBeInterpretedAsInteger($row['uid'])) {
                $wizardIsEnabled = FALSE;
            }
            // Wizard types script, colorbox and popup must contain a module name configuration
            if (!isset($wizardConfiguration['module']['name']) && in_array($wizardConfiguration['type'], array('script', 'colorbox', 'popup'), TRUE)) {
                $wizardIsEnabled = FALSE;
            }
            if (!$wizardIsEnabled) {
                continue;
            }
            // Title / icon:
            $iTitle = htmlspecialchars($languageService->sL($wizardConfiguration['title']));
            if (isset($wizardConfiguration['icon'])) {
                $icon = FormEngineUtility::getIconHtml($wizardConfiguration['icon'], $iTitle, $iTitle);
            } else {
                $icon = $iTitle;
            }
            switch ($wizardConfiguration['type']) {
                case 'userFunc':
                    $params = array();
                    $params['fieldConfig'] = $fieldConfig;
                    $params['params'] = $wizardConfiguration['params'];
                    $params['exampleImg'] = $wizardConfiguration['exampleImg'];
                    $params['table'] = $table;
                    $params['uid'] = $row['uid'];
                    $params['pid'] = $row['pid'];
                    $params['field'] = $field;
                    $params['flexFormPath'] = $flexFormPath;
                    $params['md5ID'] = $md5ID;
                    $params['returnUrl'] = $this->getReturnUrl();
                    $params['formName'] = 'editform';
                    $params['itemName'] = $itemName;
                    $params['hmac'] = GeneralUtility::hmac($params['formName'] . $params['itemName'], 'wizard_js');
                    $params['fieldChangeFunc'] = $fieldChangeFunc;
                    $params['fieldChangeFuncHash'] = GeneralUtility::hmac(serialize($fieldChangeFunc));
                    $params['item'] =& $item;
                    $params['icon'] = $icon;
                    $params['iTitle'] = $iTitle;
                    $params['wConf'] = $wizardConfiguration;
                    $params['row'] = $row;
                    $formEngineDummy = new FormEngine();
                    $otherWizards[] = GeneralUtility::callUserFunction($wizardConfiguration['userFunc'], $params, $formEngineDummy);
                    break;
                case 'script':
                    $params = array();
                    // Including the full fieldConfig from TCA may produce too long an URL
                    if ($wizardIdentifier != 'RTE') {
                        $params['fieldConfig'] = $fieldConfig;
                    }
                    $params['params'] = $wizardConfiguration['params'];
                    $params['exampleImg'] = $wizardConfiguration['exampleImg'];
                    $params['table'] = $table;
                    $params['uid'] = $row['uid'];
                    $params['pid'] = $row['pid'];
                    $params['field'] = $field;
                    $params['flexFormPath'] = $flexFormPath;
                    $params['md5ID'] = $md5ID;
                    $params['returnUrl'] = $this->getReturnUrl();
                    // Resolving script filename and setting URL.
                    $urlParameters = array();
                    if (isset($wizardConfiguration['module']['urlParameters']) && is_array($wizardConfiguration['module']['urlParameters'])) {
                        $urlParameters = $wizardConfiguration['module']['urlParameters'];
                    }
                    $wScript = BackendUtility::getModuleUrl($wizardConfiguration['module']['name'], $urlParameters, '');
                    $url = $wScript . (strstr($wScript, '?') ? '' : '?') . GeneralUtility::implodeArrayForUrl('', array('P' => $params));
                    $buttonWizards[] = '<a class="btn btn-default" href="' . htmlspecialchars($url) . '" onclick="this.blur(); return !TBE_EDITOR.isFormChanged();">' . $icon . '</a>';
                    break;
                case 'popup':
                    $params = array();
                    $params['fieldConfig'] = $fieldConfig;
                    $params['params'] = $wizardConfiguration['params'];
                    $params['exampleImg'] = $wizardConfiguration['exampleImg'];
                    $params['table'] = $table;
                    $params['uid'] = $row['uid'];
                    $params['pid'] = $row['pid'];
                    $params['field'] = $field;
                    $params['flexFormPath'] = $flexFormPath;
                    $params['md5ID'] = $md5ID;
                    $params['returnUrl'] = $this->getReturnUrl();
                    $params['formName'] = 'editform';
                    $params['itemName'] = $itemName;
                    $params['hmac'] = GeneralUtility::hmac($params['formName'] . $params['itemName'], 'wizard_js');
                    $params['fieldChangeFunc'] = $fieldChangeFunc;
                    $params['fieldChangeFuncHash'] = GeneralUtility::hmac(serialize($fieldChangeFunc));
                    // Resolving script filename and setting URL.
                    $urlParameters = array();
                    if (isset($wizardConfiguration['module']['urlParameters']) && is_array($wizardConfiguration['module']['urlParameters'])) {
                        $urlParameters = $wizardConfiguration['module']['urlParameters'];
                    }
                    $wScript = BackendUtility::getModuleUrl($wizardConfiguration['module']['name'], $urlParameters, '');
                    $url = $wScript . (strstr($wScript, '?') ? '' : '?') . GeneralUtility::implodeArrayForUrl('', array('P' => $params));
                    $onlyIfSelectedJS = '';
                    if (isset($wizardConfiguration['popup_onlyOpenIfSelected']) && $wizardConfiguration['popup_onlyOpenIfSelected']) {
                        $notSelectedText = $languageService->sL('LLL:EXT:lang/locallang_core.xlf:mess.noSelItemForEdit');
                        $onlyIfSelectedJS = 'if (!TBE_EDITOR.curSelected(' . GeneralUtility::quoteJSvalue($itemName . $listFlag) . ')){' . 'alert(' . GeneralUtility::quoteJSvalue($notSelectedText) . ');' . 'return false;' . '}';
                    }
                    $aOnClick = 'this.blur();' . $onlyIfSelectedJS . 'vHWin=window.open(' . GeneralUtility::quoteJSvalue($url) . '+\'&P[currentValue]=\'+TBE_EDITOR.rawurlencode(' . 'document.editform[' . GeneralUtility::quoteJSvalue($itemName) . '].value,200' . ')' . '+\'&P[currentSelectedValues]=\'+TBE_EDITOR.curSelected(' . GeneralUtility::quoteJSvalue($itemName . $listFlag) . '),' . GeneralUtility::quoteJSvalue('popUp' . $md5ID) . ',' . GeneralUtility::quoteJSvalue($wizardConfiguration['JSopenParams']) . ');' . 'vHWin.focus();' . 'return false;';
                    $buttonWizards[] = '<a class="btn btn-default" href="#" onclick="' . htmlspecialchars($aOnClick) . '">' . $icon . '</a>';
                    break;
                case 'colorbox':
                    $params = array();
                    $params['fieldConfig'] = $fieldConfig;
                    $params['params'] = $wizardConfiguration['params'];
                    $params['exampleImg'] = $wizardConfiguration['exampleImg'];
                    $params['table'] = $table;
                    $params['uid'] = $row['uid'];
                    $params['pid'] = $row['pid'];
                    $params['field'] = $field;
                    $params['flexFormPath'] = $flexFormPath;
                    $params['md5ID'] = $md5ID;
                    $params['returnUrl'] = $this->getReturnUrl();
                    $params['formName'] = 'editform';
                    $params['itemName'] = $itemName;
                    $params['hmac'] = GeneralUtility::hmac($params['formName'] . $params['itemName'], 'wizard_js');
                    $params['fieldChangeFunc'] = $fieldChangeFunc;
                    $params['fieldChangeFuncHash'] = GeneralUtility::hmac(serialize($fieldChangeFunc));
                    // Resolving script filename and setting URL.
                    $urlParameters = array();
                    if (isset($wizardConfiguration['module']['urlParameters']) && is_array($wizardConfiguration['module']['urlParameters'])) {
                        $urlParameters = $wizardConfiguration['module']['urlParameters'];
                    }
                    $wScript = BackendUtility::getModuleUrl($wizardConfiguration['module']['name'], $urlParameters, '');
                    $url = $wScript . (strstr($wScript, '?') ? '' : '?') . GeneralUtility::implodeArrayForUrl('', array('P' => $params));
                    $aOnClick = 'this.blur();' . 'vHWin=window.open(' . GeneralUtility::quoteJSvalue($url) . '+\'&P[currentValue]=\'+TBE_EDITOR.rawurlencode(' . 'document.editform[' . GeneralUtility::quoteJSvalue($itemName) . '].value,200' . ')' . '+\'&P[currentSelectedValues]=\'+TBE_EDITOR.curSelected(' . GeneralUtility::quoteJSvalue($itemName . $listFlag) . '),' . GeneralUtility::quoteJSvalue('popUp' . $md5ID) . ',' . GeneralUtility::quoteJSvalue($wizardConfiguration['JSopenParams']) . ');' . 'vHWin.focus();' . 'return false;';
                    $otherWizards[] = '<a id="' . $md5ID . '" class="btn btn-default" href="#" onclick="' . htmlspecialchars($aOnClick) . '"><span class="t3-icon fa fa-eyedropper"></span></a>';
                    break;
                case 'slider':
                    $params = array();
                    $params['fieldConfig'] = $fieldConfig;
                    $params['field'] = $field;
                    $params['flexFormPath'] = $flexFormPath;
                    $params['md5ID'] = $md5ID;
                    $params['itemName'] = $itemName;
                    $params['fieldChangeFunc'] = $fieldChangeFunc;
                    $params['wConf'] = $wizardConfiguration;
                    $params['row'] = $row;
                    /** @var ValueSliderWizard $wizard */
                    $wizard = GeneralUtility::makeInstance(ValueSliderWizard::class);
                    $otherWizards[] = $wizard->renderWizard($params);
                    break;
                case 'select':
                    $fieldValue = array('config' => $wizardConfiguration);
                    $TSconfig = FormEngineUtility::getTSconfigForTableRow($table, $row);
                    $TSconfig[$field] = $TSconfig[$field]['wizards.'][$wizardIdentifier . '.'];
                    $selItems = FormEngineUtility::addSelectOptionsToItemArray(FormEngineUtility::initItemArray($fieldValue), $fieldValue, $TSconfig, $field);
                    // Process items by a user function:
                    if (!empty($wizardConfiguration['itemsProcFunc'])) {
                        $funcConfig = !empty($wizardConfiguration['itemsProcFunc.']) ? $wizardConfiguration['itemsProcFunc.'] : array();
                        $dataPreprocessor = GeneralUtility::makeInstance(DataPreprocessor::class);
                        $selItems = $dataPreprocessor->procItems($selItems, $funcConfig, $wizardConfiguration, $table, $row, $field);
                    }
                    $options = array();
                    $options[] = '<option>' . $iTitle . '</option>';
                    foreach ($selItems as $p) {
                        $options[] = '<option value="' . htmlspecialchars($p[1]) . '">' . htmlspecialchars($p[0]) . '</option>';
                    }
                    if ($wizardConfiguration['mode'] == 'append') {
                        $assignValue = 'document.editform[' . GeneralUtility::quoteJSvalue($itemName) . '].value=\'\'+this.options[this.selectedIndex].value+document.editform[' . GeneralUtility::quoteJSvalue($itemName) . '].value';
                    } elseif ($wizardConfiguration['mode'] == 'prepend') {
                        $assignValue = 'document.editform[' . GeneralUtility::quoteJSvalue($itemName) . '].value+=\'\'+this.options[this.selectedIndex].value';
                    } else {
                        $assignValue = 'document.editform[' . GeneralUtility::quoteJSvalue($itemName) . '].value=this.options[this.selectedIndex].value';
                    }
                    $otherWizards[] = '<select' . ' id="' . str_replace('.', '', uniqid('tceforms-select-', TRUE)) . '"' . ' class="form-control tceforms-select tceforms-wizardselect"' . ' name="_WIZARD' . $fName . '"' . ' onchange="' . htmlspecialchars($assignValue . ';this.blur();this.selectedIndex=0;' . implode('', $fieldChangeFunc)) . '"' . '>' . implode('', $options) . '</select>';
                    break;
                case 'suggest':
                    if (!empty($PA['fieldTSConfig']['suggest.']['default.']['hide'])) {
                        break;
                    }
                    /** @var SuggestWizard $suggestWizard */
                    $suggestWizard = GeneralUtility::makeInstance(SuggestWizard::class);
                    $otherWizards[] = $suggestWizard->renderSuggestSelector($PA['itemFormElName'], $table, $field, $row, $PA);
                    break;
            }
            // Hide the real form element?
            if (is_array($wizardConfiguration['hideParent']) || $wizardConfiguration['hideParent']) {
                // Setting the item to a hidden-field.
                $item = $itemKinds[1];
                if (is_array($wizardConfiguration['hideParent'])) {
                    $options = $this->globalOptions;
                    $options['parameterArray'] = array('fieldConf' => array('config' => $wizardConfiguration['hideParent']), 'itemFormElValue' => $PA['itemFormElValue']);
                    $options['renderType'] = 'none';
                    /** @var NodeFactory $nodeFactory */
                    $nodeFactory = $this->globalOptions['nodeFactory'];
                    $noneElementResult = $nodeFactory->create($options)->render();
                    $item .= $noneElementResult['html'];
                }
            }
        }
        // For each rendered wizard, put them together around the item.
        if (!empty($buttonWizards) || !empty($otherWizards)) {
            if ($wizConf['_HIDDENFIELD']) {
                $item = $itemKinds[1];
            }
            $innerContent = '';
            if (!empty($buttonWizards)) {
                $innerContent .= '<div class="btn-group' . ($wizConf['_VERTICAL'] ? ' btn-group-vertical' : '') . '">' . implode('', $buttonWizards) . '</div>';
            }
            $innerContent .= implode(' ', $otherWizards);
            // Position
            $classes = array('form-wizards-wrap');
            if ($wizConf['_POSITION'] === 'left') {
                $classes[] = 'form-wizards-aside';
                $innerContent = '<div class="form-wizards-items">' . $innerContent . '</div><div class="form-wizards-element">' . $item . '</div>';
            } elseif ($wizConf['_POSITION'] === 'top') {
                $classes[] = 'form-wizards-top';
                $innerContent = '<div class="form-wizards-items">' . $innerContent . '</div><div class="form-wizards-element">' . $item . '</div>';
            } elseif ($wizConf['_POSITION'] === 'bottom') {
                $classes[] = 'form-wizards-bottom';
                $innerContent = '<div class="form-wizards-element">' . $item . '</div><div class="form-wizards-items">' . $innerContent . '</div>';
            } else {
                $classes[] = 'form-wizards-aside';
                $innerContent = '<div class="form-wizards-element">' . $item . '</div><div class="form-wizards-items">' . $innerContent . '</div>';
            }
            $item = '
				<div class="' . implode(' ', $classes) . '">
					' . $innerContent . '
				</div>';
        }
        return $item;
    }