[!!!][TASK] Move old mailform to compatibility6 79/36479/6
authorBenjamin Mack <benni@typo3.org>
Fri, 30 Jan 2015 21:34:48 +0000 (22:34 +0100)
committerChristian Kuhn <lolli@schwarzbu.ch>
Sat, 31 Jan 2015 13:20:46 +0000 (14:20 +0100)
Due to the replacement of the better
EXT:form logic, the fallback and default
mailform when EXT:form is not installed,
is moved to compatibility6.

There are certain parts that are migrated
as well and therefore removed from the
main core installation.

 * Various methods in ContentObjectRenderer,
and especially TypoScriptFrontendRenderer
which specifically served the purpose.
 * The FORM Content Object
 * The TCA tt_content mailform configuration
 * The TypoScript from css styled content
 * The newContentElement wizard configuration
 * Related tests to the form-related methods
 * The preview functionality for a mailform in "Web"=>"Page"

The submission class (DataSubmissionController)
has been moved and renamed as well, and now
hooks into the checkDataSubmission of TSFE.

Additionally, the related tests to the methods
have been removed.

Resolves: #64668
Releases: master
Change-Id: Iefbaf11322678f811d5c38d82f7d81be56b1d378
Reviewed-on: http://review.typo3.org/36479
Reviewed-by: Jan Helke <typo3@helke.de>
Tested-by: Jan Helke <typo3@helke.de>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
40 files changed:
typo3/sysext/backend/Classes/Controller/Wizard/FormsController.php [deleted file]
typo3/sysext/backend/Classes/View/PageLayoutView.php
typo3/sysext/backend/Modules/Wizards/FormsWizard/conf.php [deleted file]
typo3/sysext/backend/Modules/Wizards/FormsWizard/index.php [deleted file]
typo3/sysext/backend/Resources/Private/Templates/wizard_forms.html [deleted file]
typo3/sysext/backend/ext_tables.php
typo3/sysext/cms/ext_localconf.php
typo3/sysext/compatibility6/Classes/ContentObject/FormContentObject.php [new file with mode: 0644]
typo3/sysext/compatibility6/Classes/Controller/FormDataSubmissionController.php [new file with mode: 0644]
typo3/sysext/compatibility6/Classes/Controller/Wizard/FormsController.php [new file with mode: 0644]
typo3/sysext/compatibility6/Classes/Hooks/PageLayoutView/MailformPreviewRenderer.php [new file with mode: 0644]
typo3/sysext/compatibility6/Classes/Utility/FormUtility.php [new file with mode: 0644]
typo3/sysext/compatibility6/Configuration/TCA/Overrides/tt_content.php [new file with mode: 0644]
typo3/sysext/compatibility6/Configuration/TypoScript/Form/constants.txt [new file with mode: 0644]
typo3/sysext/compatibility6/Configuration/TypoScript/Form/setup.txt [new file with mode: 0644]
typo3/sysext/compatibility6/Migrations/Code/ClassAliasMap.php
typo3/sysext/compatibility6/Migrations/Code/LegacyClassesForIde.php
typo3/sysext/compatibility6/Modules/Wizards/FormsWizard/conf.php [new file with mode: 0644]
typo3/sysext/compatibility6/Modules/Wizards/FormsWizard/index.php [new file with mode: 0644]
typo3/sysext/compatibility6/Resources/Private/Templates/Wizard/Forms.html [new file with mode: 0644]
typo3/sysext/compatibility6/Resources/Public/JavaScript/jsfunc.validateform.js [new file with mode: 0644]
typo3/sysext/compatibility6/ext_localconf.php
typo3/sysext/compatibility6/ext_tables.php
typo3/sysext/core/Configuration/DefaultConfiguration.php
typo3/sysext/core/Documentation/Changelog/master/Breaking-64668-MailformMovedToLegacyExtension.rst [new file with mode: 0644]
typo3/sysext/css_styled_content/static/setup.txt
typo3/sysext/form/Classes/Hooks/PageLayoutView/MailformPreviewRenderer.php [new file with mode: 0644]
typo3/sysext/form/Classes/Utility/ValidatorUtility.php
typo3/sysext/form/Configuration/TCA/Overrides/tt_content.php
typo3/sysext/form/ext_localconf.php
typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php
typo3/sysext/frontend/Classes/ContentObject/FormContentObject.php [deleted file]
typo3/sysext/frontend/Classes/Controller/DataSubmissionController.php [deleted file]
typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php
typo3/sysext/frontend/Configuration/TCA/tt_content.php
typo3/sysext/frontend/Resources/Public/JavaScript/jsfunc.validateform.js [deleted file]
typo3/sysext/frontend/Tests/Unit/ContentObject/ContentObjectRendererTest.php
typo3/sysext/frontend/Tests/Unit/Controller/DataSubmissionControllerTest.php [deleted file]
typo3/sysext/frontend/Tests/Unit/Controller/TypoScriptFrontendControllerTest.php
typo3/sysext/frontend/ext_localconf.php

diff --git a/typo3/sysext/backend/Classes/Controller/Wizard/FormsController.php b/typo3/sysext/backend/Classes/Controller/Wizard/FormsController.php
deleted file mode 100644 (file)
index 229970d..0000000
+++ /dev/null
@@ -1,871 +0,0 @@
-<?php
-namespace TYPO3\CMS\Backend\Controller\Wizard;
-
-/*
- * 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\Utility\BackendUtility;
-use TYPO3\CMS\Backend\Utility\IconUtility;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-
-/**
- * API comments:
- *
- * The form wizard can help you to create forms - it allows you to create almost any kind of HTML form elements and in any order and amount.
- *
- * The format for the resulting configuration code can be either a line-based configuration. That can look like this:
- *
- * Your name: | *name=input | (input your name here!)
- * Your Email: | *email=input
- * Your address: | address=textarea,40,10
- * Your Haircolor: | hair=radio |
- * upload | attachment=file
- * | quoted_printable=hidden | 0
- * | formtype_mail=submit | Send form
- * | html_enabled=hidden
- * | subject=hidden | This is the subject
- *
- *
- * Alternatively it can be XML. The same configuration from above looks like this in XML:
- *
- * <T3FormWizard>
- * <n2>
- * <type>input</type>
- * <label>Your name:</label>
- * <required>1</required>
- * <fieldname>name</fieldname>
- * <size></size>
- * <max></max>
- * <default>(input your name here!)</default>
- * </n2>
- * <n4>
- * <type>input</type>
- * <label>Your Email:</label>
- * <required>1</required>
- * <fieldname>email</fieldname>
- * <size></size>
- * <max></max>
- * <default></default>
- * </n4>
- * <n6>
- * <type>textarea</type>
- * <label>Your address:</label>
- * <fieldname>address</fieldname>
- * <cols>40</cols>
- * <rows>10</rows>
- * <default></default>
- * </n6>
- * <n8>
- * <type>radio</type>
- * <label>Your Haircolor:</label>
- * <fieldname>hair</fieldname>
- * <options></options>
- * </n8>
- * <n10>
- * <type>file</type>
- * <label>upload</label>
- * <fieldname>attachment</fieldname>
- * <size></size>
- * </n10>
- * <n12>
- * <type>hidden</type>
- * <label></label>
- * <fieldname>quoted_printable</fieldname>
- * <default>0</default>
- * </n12>
- * <n2000>
- * <fieldname>formtype_mail</fieldname>
- * <type>submit</type>
- * <default>Send form</default>
- * </n2000>
- * <n2002>
- * <fieldname>html_enabled</fieldname>
- * <type>hidden</type>
- * </n2002>
- * <n2004>
- * <fieldname>subject</fieldname>
- * <type>hidden</type>
- * <default>This is the subject</default>
- * </n2004>
- * <n20>
- * <content></content>
- * </n20>
- * </T3FormWizard>
- *
- *
- * The XML/phpArray structure is the internal format of the wizard.
- *
- * @author Kasper Skårhøj <kasperYYYY@typo3.com>
- */
-class FormsController extends AbstractWizardController {
-
-       /**
-        * document template object
-        *
-        * @var \TYPO3\CMS\Backend\Template\DocumentTemplate
-        */
-       public $doc;
-
-       /**
-        * Content accumulation for the module.
-        *
-        * @var string
-        */
-       public $content;
-
-       /**
-        * Used to numerate attachments automatically.
-        *
-        * @var int
-        */
-       public $attachmentCounter = 0;
-
-       /**
-        * If set, the string version of the content is interpreted/written as XML instead of
-        * the original linebased kind. This variable still needs binding to the wizard parameters
-        * - but support is ready!
-        *
-        * @var int
-        */
-       public $xmlStorage = 0;
-
-       /**
-        * Wizard parameters, coming from TCEforms linking to the wizard.
-        *
-        * @var array
-        */
-       public $P;
-
-       /**
-        * The array which is constantly submitted by the multidimensional form of this wizard.
-        *
-        * @var array
-        */
-       public $FORMCFG;
-
-       /**
-        * Indicates if the form is of a dedicated type, like "formtype_mail" (for tt_content element "Form")
-        *
-        * @var string
-        */
-       public $special;
-
-       /**
-        * Constructor
-        */
-       public function __construct() {
-               $this->getLanguageService()->includeLLFile('EXT:lang/locallang_wizards.xlf');
-               $GLOBALS['SOBE'] = $this;
-
-               $this->init();
-       }
-
-       /**
-        * Initialization the class
-        *
-        * @return void
-        */
-       protected function init() {
-               // GPvars:
-               $this->P = GeneralUtility::_GP('P');
-               $this->special = GeneralUtility::_GP('special');
-               $this->FORMCFG = GeneralUtility::_GP('FORMCFG');
-               // Setting options:
-               $this->xmlStorage = $this->P['params']['xmlOutput'];
-               // Document template object:
-               $this->doc = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Template\DocumentTemplate::class);
-               $this->doc->backPath = $this->getBackPath();
-               $this->doc->setModuleTemplate('EXT:backend/Resources/Private/Templates/wizard_forms.html');
-               // Setting form tag:
-               list($rUri) = explode('#', GeneralUtility::getIndpEnv('REQUEST_URI'));
-               $this->doc->form = '<form action="' . htmlspecialchars($rUri) . '" method="post" name="wizardForm">';
-       }
-
-       /**
-        * Main function for rendering the form wizard HTML
-        *
-        * @return void
-        */
-       public function main() {
-               if ($this->P['table'] && $this->P['field'] && $this->P['uid']) {
-                       $this->content .= $this->doc->section($this->getLanguageService()->getLL('forms_title'), $this->formsWizard(), 0, 1);
-               } else {
-                       $this->content .= $this->doc->section($this->getLanguageService()->getLL('forms_title'), '<span class="typo3-red">' . $this->getLanguageService()->getLL('table_noData', 1) . '</span>', 0, 1);
-               }
-               // Setting up the buttons and markers for docheader
-               $docHeaderButtons = $this->getButtons();
-               $markers['CSH'] = $docHeaderButtons['csh'];
-               $markers['CONTENT'] = $this->content;
-               // Build the <body> for the module
-               $this->content = $this->doc->startPage('Form Wizard');
-               $this->content .= $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $markers);
-               $this->content .= $this->doc->endPage();
-               $this->content = $this->doc->insertStylesAndJS($this->content);
-       }
-
-       /**
-        * Outputting the accumulated content to screen
-        *
-        * @return void
-        */
-       public function printContent() {
-               echo $this->content;
-       }
-
-       /**
-        * Create the panel of buttons for submitting the form or otherwise perform operations.
-        *
-        * @return array All available buttons as an assoc. array
-        */
-       protected function getButtons() {
-               $buttons = array(
-                       'csh' => '',
-                       'csh_buttons' => '',
-                       'close' => '',
-                       'save' => '',
-                       'save_close' => '',
-                       'reload' => ''
-               );
-               if ($this->P['table'] && $this->P['field'] && $this->P['uid']) {
-                       // CSH
-                       $buttons['csh'] = BackendUtility::cshItem('xMOD_csh_corebe', 'wizard_forms_wiz');
-                       // CSH Buttons
-                       $buttons['csh_buttons'] = BackendUtility::cshItem('xMOD_csh_corebe', 'wizard_forms_wiz_buttons');
-                       // Close
-                       $buttons['close'] = '<a href="#" onclick="' . htmlspecialchars(('jumpToUrl(unescape(\'' . rawurlencode(GeneralUtility::sanitizeLocalUrl($this->P['returnUrl'])) . '\')); return false;')) . '">' . IconUtility::getSpriteIcon('actions-document-close', array('title' => $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:rm.closeDoc', TRUE))) . '</a>';
-                       // Save
-                       $buttons['save'] = '<input type="image" class="c-inputButton" name="savedok"' . IconUtility::skinImg($this->doc->backPath, 'gfx/savedok.gif') . ' title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveDoc', TRUE) . '" />';
-                       // Save & Close
-                       $buttons['save_close'] = '<input type="image" class="c-inputButton" name="saveandclosedok"' . IconUtility::skinImg($this->doc->backPath, 'gfx/saveandclosedok.gif') . ' title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveCloseDoc', TRUE) . '" />';
-                       // Reload
-                       $buttons['reload'] = '<input type="image" class="c-inputButton" name="_refresh"' . IconUtility::skinImg('', 'gfx/refresh_n.gif') . ' title="' . $this->getLanguageService()->getLL('forms_refresh', TRUE) . '" />';
-               }
-               return $buttons;
-       }
-
-       /**
-        * Draws the form wizard content
-        *
-        * @return string HTML content for the form.
-        */
-       public function formsWizard() {
-               if (!$this->checkEditAccess($this->P['table'], $this->P['uid'])) {
-                       throw new \RuntimeException('Wizard Error: No access', 1385807526);
-               }
-               // First, check the references by selecting the record:
-               $row = BackendUtility::getRecord($this->P['table'], $this->P['uid']);
-               if (!is_array($row)) {
-                       throw new \RuntimeException('Wizard Error: No reference to record', 1294587124);
-               }
-               // This will get the content of the form configuration code field to us - possibly
-               // cleaned up, saved to database etc. if the form has been submitted in the meantime.
-               $formCfgArray = $this->getConfigCode($row);
-               // Generation of the Form Wizards HTML code:
-               $content = $this->getFormHTML($formCfgArray, $row);
-               // Return content:
-               return $content;
-       }
-
-       /****************************
-        *
-        * Helper functions
-        *
-        ***************************/
-       /**
-        * Will get and return the configuration code string
-        * Will also save (and possibly redirect/exit) the content if a save button has been pressed
-        *
-        * @param array $row Current parent record row (passed by value!)
-        * @return array Configuration Array
-        * @access private
-        */
-       public function getConfigCode(&$row) {
-               // If some data has been submitted, then construct
-               if (isset($this->FORMCFG['c'])) {
-                       // Process incoming:
-                       $this->changeFunc();
-                       // Convert to string (either line based or XML):
-                       if ($this->xmlStorage) {
-                               // Convert the input array to XML:
-                               $bodyText = GeneralUtility::array2xml_cs($this->FORMCFG['c'], 'T3FormWizard');
-                               // Setting cfgArr directly from the input:
-                               $cfgArr = $this->FORMCFG['c'];
-                       } else {
-                               // Convert the input array to a string of configuration code:
-                               $bodyText = $this->cfgArray2CfgString($this->FORMCFG['c']);
-                               // Create cfgArr from the string based configuration - that way it is cleaned
-                               // up and any incompatibilities will be removed!
-                               $cfgArr = $this->cfgString2CfgArray($bodyText);
-                       }
-                       // If a save button has been pressed, then save the new field content:
-                       if ($_POST['savedok_x'] || $_POST['saveandclosedok_x']) {
-                               // Make TCEmain object:
-                               $tce = GeneralUtility::makeInstance(\TYPO3\CMS\Core\DataHandling\DataHandler::class);
-                               $tce->stripslashes_values = 0;
-                               // Put content into the data array:
-                               $data = array();
-                               $data[$this->P['table']][$this->P['uid']][$this->P['field']] = $bodyText;
-                               if ($this->special == 'formtype_mail') {
-                                       $data[$this->P['table']][$this->P['uid']]['subheader'] = $this->FORMCFG['recipient'];
-                               }
-                               // Perform the update:
-                               $tce->start($data, array());
-                               $tce->process_datamap();
-                               // Re-load the record content:
-                               $row = BackendUtility::getRecord($this->P['table'], $this->P['uid']);
-                               // If the save/close button was pressed, then redirect the screen:
-                               if ($_POST['saveandclosedok_x']) {
-                                       \TYPO3\CMS\Core\Utility\HttpUtility::redirect(GeneralUtility::sanitizeLocalUrl($this->P['returnUrl']));
-                               }
-                       }
-               } else {
-                       // If nothing has been submitted, load the $bodyText variable from the selected database row:
-                       if ($this->xmlStorage) {
-                               $cfgArr = GeneralUtility::xml2array($row[$this->P['field']]);
-                       } else {
-                               // Regular linebased form configuration:
-                               $cfgArr = $this->cfgString2CfgArray($row[$this->P['field']]);
-                       }
-                       $cfgArr = is_array($cfgArr) ? $cfgArr : array();
-               }
-               // Return configuration code:
-               return $cfgArr;
-       }
-
-       /**
-        * Creates the HTML for the Form Wizard:
-        *
-        * @param string $formCfgArray Form config array
-        * @param array $row Current parent record array
-        * @return string HTML for the form wizard
-        * @access private
-        */
-       public function getFormHTML($formCfgArray, $row) {
-               // Initialize variables:
-               $specParts = array();
-               $hiddenFields = array();
-               $tRows = array();
-               // Set header row:
-               $cells = array(
-                       $this->getLanguageService()->getLL('forms_preview', TRUE) . ':',
-                       $this->getLanguageService()->getLL('forms_element', TRUE) . ':',
-                       $this->getLanguageService()->getLL('forms_config', TRUE) . ':'
-               );
-               $tRows[] = '
-                       <tr class="bgColor2" id="typo3-formWizardHeader">
-                               <td>&nbsp;</td>
-                               <td><strong>' . implode('</strong></td>
-                               <td><strong>', $cells) . '</strong></td>
-                       </tr>';
-               // Traverse the number of form elements:
-               $k = 0;
-               foreach ($formCfgArray as $confData) {
-                       // Initialize:
-                       $cells = array();
-                       // If there is a configuration line which is active, then render it:
-                       if (!isset($confData['comment'])) {
-                               // Special parts:
-                               if ($this->special == 'formtype_mail' && GeneralUtility::inList('formtype_mail,subject,html_enabled', $confData['fieldname'])) {
-                                       $specParts[$confData['fieldname']] = $confData['default'];
-                               } else {
-                                       // Render title/field preview COLUMN
-                                       $cells[] = $confData['type'] != 'hidden' ? '<strong>' . htmlspecialchars($confData['label']) . '</strong>' : '';
-                                       // Render general type/title COLUMN:
-                                       $temp_cells = array();
-                                       // Field type selector:
-                                       $opt = array();
-                                       $opt[] = '<option value=""></option>';
-                                       $types = explode(',', 'input,textarea,select,check,radio,password,file,hidden,submit,property,label');
-                                       foreach ($types as $t) {
-                                               $opt[] = '
-                                                               <option value="' . $t . '"' . ($confData['type'] == $t ? ' selected="selected"' : '') . '>' . $this->getLanguageService()->getLL(('forms_type_' . $t), TRUE) . '</option>';
-                                       }
-                                       $temp_cells[$this->getLanguageService()->getLL('forms_type')] = '
-                                                       <select name="FORMCFG[c][' . ($k + 1) * 2 . '][type]">
-                                                               ' . implode('
-                                                               ', $opt) . '
-                                                       </select>';
-                                       // Title field:
-                                       if (!GeneralUtility::inList('hidden,submit', $confData['type'])) {
-                                               $temp_cells[$this->getLanguageService()->getLL('forms_label')] = '<input type="text"' . $this->doc->formWidth(15) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][label]" value="' . htmlspecialchars($confData['label']) . '" />';
-                                       }
-                                       // Required checkbox:
-                                       if (!GeneralUtility::inList('check,hidden,submit,label', $confData['type'])) {
-                                               $temp_cells[$this->getLanguageService()->getLL('forms_required')] = '<input type="checkbox" name="FORMCFG[c][' . ($k + 1) * 2 . '][required]" value="1"' . ($confData['required'] ? ' checked="checked"' : '') . ' title="' . $this->getLanguageService()->getLL('forms_required', TRUE) . '" />';
-                                       }
-                                       // Put sub-items together into table cell:
-                                       $cells[] = $this->formatCells($temp_cells);
-                                       // Render specific field configuration COLUMN:
-                                       $temp_cells = array();
-                                       // Fieldname
-                                       if ($this->special == 'formtype_mail' && $confData['type'] == 'file') {
-                                               $confData['fieldname'] = 'attachment' . ++$this->attachmentCounter;
-                                       }
-                                       if (!GeneralUtility::inList('label', $confData['type'])) {
-                                               $temp_cells[$this->getLanguageService()->getLL('forms_fieldName')] = '<input type="text"' . $this->doc->formWidth(10) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][fieldname]" value="' . htmlspecialchars($confData['fieldname']) . '" title="' . $this->getLanguageService()->getLL('forms_fieldName', TRUE) . '" />';
-                                       }
-                                       // Field configuration depending on the fields type:
-                                       switch ((string)$confData['type']) {
-                                               case 'textarea':
-                                                       $temp_cells[$this->getLanguageService()->getLL('forms_cols')] = '<input type="text"' . $this->doc->formWidth(5) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][cols]" value="' . htmlspecialchars($confData['cols']) . '" title="' . $this->getLanguageService()->getLL('forms_cols', TRUE) . '" />';
-                                                       $temp_cells[$this->getLanguageService()->getLL('forms_rows')] = '<input type="text"' . $this->doc->formWidth(5) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][rows]" value="' . htmlspecialchars($confData['rows']) . '" title="' . $this->getLanguageService()->getLL('forms_rows', TRUE) . '" />';
-                                                       $temp_cells[$this->getLanguageService()->getLL('forms_extra')] = '<input type="checkbox" name="FORMCFG[c][' . ($k + 1) * 2 . '][extra]" value="OFF"' . ($confData['extra'] == 'OFF' ? ' checked="checked"' : '') . ' title="' . $this->getLanguageService()->getLL('forms_extra', TRUE) . '" />';
-                                                       break;
-                                               case 'input':
-
-                                               case 'password':
-                                                       $temp_cells[$this->getLanguageService()->getLL('forms_size')] = '<input type="text"' . $this->doc->formWidth(5) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][size]" value="' . htmlspecialchars($confData['size']) . '" title="' . $this->getLanguageService()->getLL('forms_size', TRUE) . '" />';
-                                                       $temp_cells[$this->getLanguageService()->getLL('forms_max')] = '<input type="text"' . $this->doc->formWidth(5) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][max]" value="' . htmlspecialchars($confData['max']) . '" title="' . $this->getLanguageService()->getLL('forms_max', TRUE) . '" />';
-                                                       break;
-                                               case 'file':
-                                                       $temp_cells[$this->getLanguageService()->getLL('forms_size')] = '<input type="text"' . $this->doc->formWidth(5) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][size]" value="' . htmlspecialchars($confData['size']) . '" title="' . $this->getLanguageService()->getLL('forms_size', TRUE) . '" />';
-                                                       break;
-                                               case 'select':
-                                                       $temp_cells[$this->getLanguageService()->getLL('forms_size')] = '<input type="text"' . $this->doc->formWidth(5) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][size]" value="' . htmlspecialchars($confData['size']) . '" title="' . $this->getLanguageService()->getLL('forms_size', TRUE) . '" />';
-                                                       $temp_cells[$this->getLanguageService()->getLL('forms_autosize')] = '<input type="checkbox" name="FORMCFG[c][' . ($k + 1) * 2 . '][autosize]" value="1"' . ($confData['autosize'] ? ' checked="checked"' : '') . ' title="' . $this->getLanguageService()->getLL('forms_autosize', TRUE) . '" />';
-                                                       $temp_cells[$this->getLanguageService()->getLL('forms_multiple')] = '<input type="checkbox" name="FORMCFG[c][' . ($k + 1) * 2 . '][multiple]" value="1"' . ($confData['multiple'] ? ' checked="checked"' : '') . ' title="' . $this->getLanguageService()->getLL('forms_multiple', TRUE) . '" />';
-                                                       break;
-                                       }
-                                       // Field configuration depending on the fields type:
-                                       switch ((string)$confData['type']) {
-                                               case 'textarea':
-
-                                               case 'input':
-
-                                               case 'password':
-                                                       if (trim($confData['specialEval']) !== '') {
-                                                               $hiddenFields[] = '<input type="hidden" name="FORMCFG[c][' . ($k + 1) * 2 . '][specialEval]" value="' . htmlspecialchars($confData['specialEval']) . '" />';
-                                                       }
-                                                       break;
-                                       }
-                                       // Default data
-                                       if ($confData['type'] == 'select' || $confData['type'] == 'radio') {
-                                               $temp_cells[$this->getLanguageService()->getLL('forms_options')] = '<textarea ' . $this->doc->formWidth(15) . ' rows="4" name="FORMCFG[c][' . ($k + 1) * 2 . '][options]" title="' . $this->getLanguageService()->getLL('forms_options', TRUE) . '">' . GeneralUtility::formatForTextarea($confData['default']) . '</textarea>';
-                                       } elseif ($confData['type'] == 'check') {
-                                               $temp_cells[$this->getLanguageService()->getLL('forms_checked')] = '<input type="checkbox" name="FORMCFG[c][' . ($k + 1) * 2 . '][default]" value="1"' . (trim($confData['default']) ? ' checked="checked"' : '') . ' title="' . $this->getLanguageService()->getLL('forms_checked', TRUE) . '" />';
-                                       } elseif ($confData['type'] && $confData['type'] != 'file') {
-                                               $temp_cells[$this->getLanguageService()->getLL('forms_default')] = '<input type="text"' . $this->doc->formWidth(15) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][default]" value="' . htmlspecialchars($confData['default']) . '" title="' . $this->getLanguageService()->getLL('forms_default', TRUE) . '" />';
-                                       }
-                                       $cells[] = $confData['type'] ? $this->formatCells($temp_cells) : '';
-                                       // CTRL panel for an item (move up/down/around):
-                                       $ctrl = '';
-                                       $onClick = 'document.wizardForm.action+=\'#ANC_' . (($k + 1) * 2 - 2) . '\';';
-                                       $onClick = ' onclick="' . htmlspecialchars($onClick) . '"';
-                                       // @todo $inputStyle undefined
-                                       $brTag = $inputStyle ? '' : '<br />';
-                                       if ($k != 0) {
-                                               $ctrl .= '<input type="image" name="FORMCFG[row_up][' . ($k + 1) * 2 . ']"' . IconUtility::skinImg($this->doc->backPath, 'gfx/pil2up.gif', '') . $onClick . ' title="' . $this->getLanguageService()->getLL('table_up', TRUE) . '" />' . $brTag;
-                                       } else {
-                                               $ctrl .= '<input type="image" name="FORMCFG[row_bottom][' . ($k + 1) * 2 . ']"' . IconUtility::skinImg($this->doc->backPath, 'gfx/turn_up.gif', '') . $onClick . ' title="' . $this->getLanguageService()->getLL('table_bottom', TRUE) . '" />' . $brTag;
-                                       }
-                                       $ctrl .= '<input type="image" name="FORMCFG[row_remove][' . ($k + 1) * 2 . ']"' . IconUtility::skinImg($this->doc->backPath, 'gfx/garbage.gif', '') . $onClick . ' title="' . $this->getLanguageService()->getLL('table_removeRow', TRUE) . '" />' . $brTag;
-                                       // @todo $tLines undefined
-                                       if ($k + 1 != count($tLines)) {
-                                               $ctrl .= '<input type="image" name="FORMCFG[row_down][' . ($k + 1) * 2 . ']"' . IconUtility::skinImg($this->doc->backPath, 'gfx/pil2down.gif', '') . $onClick . ' title="' . $this->getLanguageService()->getLL('table_down', TRUE) . '" />' . $brTag;
-                                       } else {
-                                               $ctrl .= '<input type="image" name="FORMCFG[row_top][' . ($k + 1) * 2 . ']"' . IconUtility::skinImg($this->doc->backPath, 'gfx/turn_down.gif', '') . $onClick . ' title="' . $this->getLanguageService()->getLL('table_top', TRUE) . '" />' . $brTag;
-                                       }
-                                       $ctrl .= '<input type="image" name="FORMCFG[row_add][' . ($k + 1) * 2 . ']"' . IconUtility::skinImg($this->doc->backPath, 'gfx/add.gif', '') . $onClick . ' title="' . $this->getLanguageService()->getLL('table_addRow', TRUE) . '" />' . $brTag;
-                                       $ctrl = '<span class="c-wizButtonsV">' . $ctrl . '</span>';
-                                       // Finally, put together the full row from the generated content above:
-                                       $bgC = $confData['type'] ? ' class="bgColor5"' : '';
-                                       $tRows[] = '
-                                               <tr' . $bgC . '>
-                                                       <td><a name="ANC_' . ($k + 1) * 2 . '"></a>' . $ctrl . '</td>
-                                                       <td class="bgColor4">' . implode('</td>
-                                                       <td valign="top">', $cells) . '</td>
-                                               </tr>';
-                               }
-                       } else {
-                               $hiddenFields[] = '<input type="hidden" name="FORMCFG[c][' . ($k + 1) * 2 . '][comment]" value="' . htmlspecialchars($confData['comment']) . '" />';
-                       }
-                       // Increment counter:
-                       $k++;
-               }
-               // If the form is of the special type "formtype_mail" (used for tt_content elements):
-               if ($this->special == 'formtype_mail') {
-                       // Blank spacer:
-                       $tRows[] = '
-                               <tr>
-                                       <td colspan="4">&nbsp;</td>
-                               </tr>';
-                       // Header:
-                       $tRows[] = '
-                               <tr>
-                                       <td colspan="2" class="bgColor2">&nbsp;</td>
-                                       <td colspan="2" class="bgColor2"><strong>' . $this->getLanguageService()->getLL('forms_special_eform', TRUE) . ':</strong>' . BackendUtility::cshItem('xMOD_csh_corebe', 'wizard_forms_wiz_formmail_info') . '</td>
-                               </tr>';
-                       // "FORM type":
-                       $tRows[] = '
-                               <tr class="bgColor5">
-                                       <td>&nbsp;</td>
-                                       <td class="bgColor4">&nbsp;</td>
-                                       <td>' . $this->getLanguageService()->getLL('forms_eform_formtype_mail', TRUE) . ':</td>
-                                       <td>
-                                               <input type="hidden" name="FORMCFG[c][' . 1000 * 2 . '][fieldname]" value="formtype_mail" />
-                                               <input type="hidden" name="FORMCFG[c][' . 1000 * 2 . '][type]" value="submit" />
-                                               <input type="text"' . $this->doc->formWidth(15) . ' name="FORMCFG[c][' . 1000 * 2 . '][default]" value="' . htmlspecialchars($specParts['formtype_mail']) . '" />
-                                       </td>
-                               </tr>';
-                       // "Send HTML mail":
-                       $tRows[] = '
-                               <tr class="bgColor5">
-                                       <td>&nbsp;</td>
-                                       <td class="bgColor4">&nbsp;</td>
-                                       <td>' . $this->getLanguageService()->getLL('forms_eform_html_enabled', TRUE) . ':</td>
-                                       <td>
-                                               <input type="hidden" name="FORMCFG[c][' . 1001 * 2 . '][fieldname]" value="html_enabled" />
-                                               <input type="hidden" name="FORMCFG[c][' . 1001 * 2 . '][type]" value="hidden" />
-                                               <input type="checkbox" name="FORMCFG[c][' . 1001 * 2 . '][default]" value="1"' . ($specParts['html_enabled'] ? ' checked="checked"' : '') . ' />
-                                       </td>
-                               </tr>';
-                       // "Subject":
-                       $tRows[] = '
-                               <tr class="bgColor5">
-                                       <td>&nbsp;</td>
-                                       <td class="bgColor4">&nbsp;</td>
-                                       <td>' . $this->getLanguageService()->getLL('forms_eform_subject', TRUE) . ':</td>
-                                       <td>
-                                               <input type="hidden" name="FORMCFG[c][' . 1002 * 2 . '][fieldname]" value="subject" />
-                                               <input type="hidden" name="FORMCFG[c][' . 1002 * 2 . '][type]" value="hidden" />
-                                               <input type="text"' . $this->doc->formWidth(15) . ' name="FORMCFG[c][' . 1002 * 2 . '][default]" value="' . htmlspecialchars($specParts['subject']) . '" />
-                                       </td>
-                               </tr>';
-                       // Recipient:
-                       $tRows[] = '
-                               <tr class="bgColor5">
-                                       <td>&nbsp;</td>
-                                       <td class="bgColor4">&nbsp;</td>
-                                       <td>' . $this->getLanguageService()->getLL('forms_eform_recipient', TRUE) . ':</td>
-                                       <td>
-                                               <input type="text"' . $this->doc->formWidth(15) . ' name="FORMCFG[recipient]" value="' . htmlspecialchars($row['subheader']) . '" />
-                                       </td>
-                               </tr>';
-               }
-               $content = '';
-               // Implode all table rows into a string, wrapped in table tags.
-               $content .= '
-
-                       <!--
-                               Form wizard
-                       -->
-                       <table border="0" cellpadding="1" cellspacing="1" id="typo3-formwizard">
-                               ' . implode('', $tRows) . '
-                       </table>';
-               // Add hidden fields:
-               $content .= implode('', $hiddenFields);
-               // Return content:
-               return $content;
-       }
-
-       /**
-        * Detects if a control button (up/down/around/delete) has been pressed for an item and accordingly it will manipulate the internal FORMCFG array
-        *
-        * @return void
-        * @access private
-        */
-       public function changeFunc() {
-               if ($this->FORMCFG['row_remove']) {
-                       $kk = key($this->FORMCFG['row_remove']);
-                       $cmd = 'row_remove';
-               } elseif ($this->FORMCFG['row_add']) {
-                       $kk = key($this->FORMCFG['row_add']);
-                       $cmd = 'row_add';
-               } elseif ($this->FORMCFG['row_top']) {
-                       $kk = key($this->FORMCFG['row_top']);
-                       $cmd = 'row_top';
-               } elseif ($this->FORMCFG['row_bottom']) {
-                       $kk = key($this->FORMCFG['row_bottom']);
-                       $cmd = 'row_bottom';
-               } elseif ($this->FORMCFG['row_up']) {
-                       $kk = key($this->FORMCFG['row_up']);
-                       $cmd = 'row_up';
-               } elseif ($this->FORMCFG['row_down']) {
-                       $kk = key($this->FORMCFG['row_down']);
-                       $cmd = 'row_down';
-               }
-               if ($cmd && \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($kk)) {
-                       if (substr($cmd, 0, 4) == 'row_') {
-                               switch ($cmd) {
-                                       case 'row_remove':
-                                               unset($this->FORMCFG['c'][$kk]);
-                                               break;
-                                       case 'row_add':
-                                               $this->FORMCFG['c'][$kk + 1] = array();
-                                               break;
-                                       case 'row_top':
-                                               $this->FORMCFG['c'][1] = $this->FORMCFG['c'][$kk];
-                                               unset($this->FORMCFG['c'][$kk]);
-                                               break;
-                                       case 'row_bottom':
-                                               $this->FORMCFG['c'][1000000] = $this->FORMCFG['c'][$kk];
-                                               unset($this->FORMCFG['c'][$kk]);
-                                               break;
-                                       case 'row_up':
-                                               $this->FORMCFG['c'][$kk - 3] = $this->FORMCFG['c'][$kk];
-                                               unset($this->FORMCFG['c'][$kk]);
-                                               break;
-                                       case 'row_down':
-                                               $this->FORMCFG['c'][$kk + 3] = $this->FORMCFG['c'][$kk];
-                                               unset($this->FORMCFG['c'][$kk]);
-                                               break;
-                               }
-                               ksort($this->FORMCFG['c']);
-                       }
-               }
-       }
-
-       /**
-        * Converts the input array to a configuration code string
-        *
-        * @param array $cfgArr Array of form configuration (follows the input structure from the form wizard POST form)
-        * @return string The array converted into a string with line-based configuration.
-        * @see cfgString2CfgArray()
-        */
-       public function cfgArray2CfgString($cfgArr) {
-               // Initialize:
-               $inLines = array();
-               // Traverse the elements of the form wizard and transform the settings into configuration code.
-               foreach ($cfgArr as $vv) {
-                       // If "content" is found, then just pass it over.
-                       if ($vv['comment']) {
-                               $inLines[] = trim($vv['comment']);
-                       } else {
-                               // Begin to put together the single-line configuration code of this field:
-                               // Reset:
-                               $thisLine = array();
-                               // Set Label:
-                               $thisLine[0] = str_replace('|', '', $vv['label']);
-                               // Set Type:
-                               if ($vv['type']) {
-                                       $thisLine[1] = ($vv['required'] ? '*' : '') . str_replace(',', '', (($vv['fieldname'] ? $vv['fieldname'] . '=' : '') . $vv['type']));
-                                       // Default:
-                                       $tArr = array('', '', '', '', '', '');
-                                       switch ((string)$vv['type']) {
-                                               case 'textarea':
-                                                       if ((int)$vv['cols']) {
-                                                               $tArr[0] = (int)$vv['cols'];
-                                                       }
-                                                       if ((int)$vv['rows']) {
-                                                               $tArr[1] = (int)$vv['rows'];
-                                                       }
-                                                       if (trim($vv['extra'])) {
-                                                               $tArr[2] = trim($vv['extra']);
-                                                       }
-                                                       if ($vv['specialEval'] !== '') {
-                                                               // Preset blank default value so position 3 can get a value...
-                                                               $thisLine[2] = '';
-                                                               $thisLine[3] = $vv['specialEval'];
-                                                       }
-                                                       break;
-                                               case 'input':
-                                               case 'password':
-                                                       if ((int)$vv['size']) {
-                                                               $tArr[0] = (int)$vv['size'];
-                                                       }
-                                                       if ((int)$vv['max']) {
-                                                               $tArr[1] = (int)$vv['max'];
-                                                       }
-                                                       if ($vv['specialEval'] !== '') {
-                                                               // Preset blank default value so position 3 can get a value...
-                                                               $thisLine[2] = '';
-                                                               $thisLine[3] = $vv['specialEval'];
-                                                       }
-                                                       break;
-                                               case 'file':
-                                                       if ((int)$vv['size']) {
-                                                               $tArr[0] = (int)$vv['size'];
-                                                       }
-                                                       break;
-                                               case 'select':
-                                                       if ((int)$vv['size']) {
-                                                               $tArr[0] = (int)$vv['size'];
-                                                       }
-                                                       if ($vv['autosize']) {
-                                                               $tArr[0] = 'auto';
-                                                       }
-                                                       if ($vv['multiple']) {
-                                                               $tArr[1] = 'm';
-                                                       }
-                                                       break;
-                                       }
-                                       $tArr = $this->cleanT($tArr);
-                                       if (count($tArr)) {
-                                               $thisLine[1] .= ',' . implode(',', $tArr);
-                                       }
-                                       $thisLine[1] = str_replace('|', '', $thisLine[1]);
-                                       // Default:
-                                       if ($vv['type'] == 'select' || $vv['type'] == 'radio') {
-                                               $options = str_replace(',', '', $vv['options']);
-                                               $options = str_replace(
-                                                       array(CRLF, CR, LF),
-                                                       ', ',
-                                                       $options);
-                                               $thisLine[2] = $options;
-                                       } elseif ($vv['type'] == 'check') {
-                                               if ($vv['default']) {
-                                                       $thisLine[2] = 1;
-                                               }
-                                       } elseif (trim($vv['default']) !== '') {
-                                               $thisLine[2] = $vv['default'];
-                                       }
-                                       if (isset($thisLine[2])) {
-                                               $thisLine[2] = str_replace('|', '', $thisLine[2]);
-                                       }
-                               }
-                               // Compile the final line:
-                               $inLines[] = preg_replace('/[
-
-]*/', '', implode(' | ', $thisLine));
-                       }
-               }
-               // Finally, implode the lines into a string, and return it:
-               return implode(LF, $inLines);
-       }
-
-       /**
-        * Converts the input configuration code string into an array
-        *
-        * @param string $cfgStr Configuration code
-        * @return array Configuration array
-        * @see cfgArray2CfgString()
-        */
-       public function cfgString2CfgArray($cfgStr) {
-               // Traverse the number of form elements:
-               $tLines = explode(LF, $cfgStr);
-               $attachmentCounter = 0;
-               foreach ($tLines as $k => $v) {
-                       // Initialize:
-                       $confData = array();
-                       $val = trim($v);
-                       // Accept a line as configuration if a) it is blank(! - because blank lines indicates new,
-                       // unconfigured fields) or b) it is NOT a comment.
-                       if (!$val || strcspn($val, '#/')) {
-                               // Split:
-                               $parts = GeneralUtility::trimExplode('|', $val);
-                               // Label:
-                               $confData['label'] = trim($parts[0]);
-                               // Field:
-                               $fParts = GeneralUtility::trimExplode(',', $parts[1]);
-                               $fParts[0] = trim($fParts[0]);
-                               if ($fParts[0][0] === '*') {
-                                       $confData['required'] = 1;
-                                       $fParts[0] = substr($fParts[0], 1);
-                               }
-                               $typeParts = GeneralUtility::trimExplode('=', $fParts[0]);
-                               $confData['type'] = trim(strtolower(end($typeParts)));
-                               if ($confData['type']) {
-                                       if (count($typeParts) == 1) {
-                                               $confData['fieldname'] = substr(preg_replace('/[^a-zA-Z0-9_]/', '', str_replace(' ', '_', trim($parts[0]))), 0, 30);
-                                               // Attachment names...
-                                               if ($confData['type'] == 'file') {
-                                                       $confData['fieldname'] = 'attachment' . $attachmentCounter;
-                                                       $attachmentCounter = (int)$attachmentCounter + 1;
-                                               }
-                                       } else {
-                                               $confData['fieldname'] = str_replace(' ', '_', trim($typeParts[0]));
-                                       }
-                                       switch ((string)$confData['type']) {
-                                               case 'select':
-                                               case 'radio':
-                                                       $confData['default'] = implode(LF, GeneralUtility::trimExplode(',', $parts[2]));
-                                                       break;
-                                               default:
-                                                       $confData['default'] = trim($parts[2]);
-                                       }
-                                       // Field configuration depending on the fields type:
-                                       switch ((string)$confData['type']) {
-                                               case 'textarea':
-                                                       $confData['cols'] = $fParts[1];
-                                                       $confData['rows'] = $fParts[2];
-                                                       $confData['extra'] = strtoupper($fParts[3]) == 'OFF' ? 'OFF' : '';
-                                                       $confData['specialEval'] = trim($parts[3]);
-                                                       break;
-                                               case 'input':
-                                               case 'password':
-                                                       $confData['size'] = $fParts[1];
-                                                       $confData['max'] = $fParts[2];
-                                                       $confData['specialEval'] = trim($parts[3]);
-                                                       break;
-                                               case 'file':
-                                                       $confData['size'] = $fParts[1];
-                                                       break;
-                                               case 'select':
-                                                       $confData['size'] = (int)$fParts[1] ? $fParts[1] : '';
-                                                       $confData['autosize'] = strtolower(trim($fParts[1])) === 'auto' ? 1 : 0;
-                                                       $confData['multiple'] = strtolower(trim($fParts[2])) === 'm' ? 1 : 0;
-                                                       break;
-                                       }
-                               }
-                       } else {
-                               // No configuration, only a comment:
-                               $confData = array(
-                                       'comment' => $val
-                               );
-                       }
-                       // Adding config array:
-                       $cfgArr[] = $confData;
-               }
-               // Return cfgArr
-               return $cfgArr;
-       }
-
-       /**
-        * Removes any "trailing elements" in the array which consists of whitespace (little like trim() does for strings, so this does for arrays)
-        *
-        * @param array $tArr Single dim array
-        * @return array Processed array
-        * @access private
-        */
-       public function cleanT($tArr) {
-               for ($a = count($tArr); $a > 0; $a--) {
-                       if ((string)$tArr[$a - 1] !== '') {
-                               break;
-                       } else {
-                               unset($tArr[$a - 1]);
-                       }
-               }
-               return $tArr;
-       }
-
-       /**
-        * Wraps items in $fArr in table cells/rows, displaying them vertically.
-        *
-        * @param array $fArr Array of label/HTML pairs.
-        * @return string HTML table
-        * @access private
-        */
-       public function formatCells($fArr) {
-               // Traverse the elements in $fArr and wrap them in table cells:
-               $lines = array();
-               foreach ($fArr as $l => $c) {
-                       $lines[] = '
-                               <tr>
-                                       <td nowrap="nowrap">' . htmlspecialchars(($l . ':')) . '&nbsp;</td>
-                                       <td>' . $c . '</td>
-                               </tr>';
-               }
-               // Add a cell which will set a minimum width:
-               $lines[] = '
-                       <tr>
-                               <td nowrap="nowrap"><img src="clear.gif" width="70" height="1" alt="" /></td>
-                               <td></td>
-                       </tr>';
-               // Wrap in table and return:
-               return '
-                       <table border="0" cellpadding="0" cellspacing="0">
-                               ' . implode('', $lines) . '
-                       </table>';
-       }
-
-}
index 8da8b3b..fdd3cb9 100644 (file)
@@ -1506,10 +1506,7 @@ class PageLayoutView extends \TYPO3\CMS\Recordlist\RecordList\AbstractDatabaseRe
                                        }
                                        break;
                                case 'bullets':
-
                                case 'table':
-
-                               case 'mailform':
                                        if ($row['bodytext']) {
                                                $out .= $this->linkEditContent($this->renderText($row['bodytext']), $row) . '<br />';
                                        }
diff --git a/typo3/sysext/backend/Modules/Wizards/FormsWizard/conf.php b/typo3/sysext/backend/Modules/Wizards/FormsWizard/conf.php
deleted file mode 100644 (file)
index 9742c33..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<?php
-//required for mod.php
-$MCONF['name'] = 'wizard_forms';
-$MCONF['script'] = '_DISPATCH';
-$MCONF['access'] = '';
diff --git a/typo3/sysext/backend/Modules/Wizards/FormsWizard/index.php b/typo3/sysext/backend/Modules/Wizards/FormsWizard/index.php
deleted file mode 100644 (file)
index c9b1bb8..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-<?php
-/*
- * 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!
- */
-
-/**
- * Wizard to help make forms (fx. for tt_content elements) of type 'form'.
- */
-$formsController = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Controller\Wizard\FormsController::class);
-$formsController->main();
-$formsController->printContent();
diff --git a/typo3/sysext/backend/Resources/Private/Templates/wizard_forms.html b/typo3/sysext/backend/Resources/Private/Templates/wizard_forms.html
deleted file mode 100644 (file)
index 6178b15..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-<!-- ###FULLDOC### begin -->
-<div class="typo3-fullDoc">
-       <div id="typo3-docheader">
-               <div class="typo3-docheader-functions">
-                       <div class="left">###CSH###</div>
-                       <div class="right"></div>
-               </div>
-               <div class="typo3-docheader-buttons">
-                       <div class="left">###BUTTONLIST_LEFT###</div>
-                       <div class="right">###BUTTONLIST_RIGHT###</div>
-               </div>
-       </div>
-
-       <div id="typo3-docbody">
-               <div id="typo3-inner-docbody">
-                       ###CONTENT###
-               </div>
-       </div>
-</div>
-<!-- ###FULLDOC### end -->
-
-<!-- Grouping the icons on top -->
-
-<!-- ###BUTTON_GROUP_WRAP### -->
-<div class="buttongroup">###BUTTONS###</div>
-<!-- ###BUTTON_GROUP_WRAP### -->
-
-<!-- ###BUTTON_GROUPS_LEFT### -->
-<!-- ###BUTTON_GROUP1### -->###CLOSE###<!-- ###BUTTON_GROUP1### -->
-<!-- ###BUTTON_GROUP2### -->###SAVE######SAVE_CLOSE###<!-- ###BUTTON_GROUP2### -->
-<!-- ###BUTTON_GROUPS_LEFT### -->
-
-<!-- ###BUTTON_GROUPS_RIGHT### -->
-<!-- ###BUTTON_GROUP1### -->###RELOAD###<!-- ###BUTTON_GROUP1### -->
-<!-- ###BUTTON_GROUPS_RIGHT### -->
-<!-- ###FULLDOC### begin -->
-<div class="typo3-fullDoc">
-       <div id="typo3-docheader">
-               <div class="typo3-docheader-functions">
-                       <div class="left">###CSH###</div>
-                       <div class="right"></div>
-               </div>
-               <div class="typo3-docheader-buttons">
-                       <div class="left">###BUTTONLIST_LEFT###</div>
-                       <div class="right">###BUTTONLIST_RIGHT###</div>
-               </div>
-       </div>
-
-       <div id="typo3-docbody">
-               <div id="typo3-inner-docbody">
-                       ###CONTENT###
-               </div>
-       </div>
-</div>
-<!-- ###FULLDOC### end -->
-
-<!-- Grouping the icons on top -->
-
-<!-- ###BUTTON_GROUP_WRAP### -->
-<div class="buttongroup">###BUTTONS###</div>
-<!-- ###BUTTON_GROUP_WRAP### -->
-
-<!-- ###BUTTON_GROUPS_LEFT### -->
-<!-- ###BUTTON_GROUP1### -->###CLOSE###<!-- ###BUTTON_GROUP1### -->
-<!-- ###BUTTON_GROUP2### -->###SAVE######SAVE_CLOSE###<!-- ###BUTTON_GROUP2### -->
-<!-- ###BUTTON_GROUPS_LEFT### -->
-
-<!-- ###BUTTON_GROUPS_RIGHT### -->
-<!-- ###BUTTON_GROUP1### -->###RELOAD###<!-- ###BUTTON_GROUP1### -->
-<!-- ###BUTTON_GROUPS_RIGHT### -->
index 0376c15..4e47da3 100644 (file)
@@ -56,12 +56,6 @@ if (TYPO3_MODE === 'BE') {
                \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath($_EXTKEY) . 'Modules/Wizards/TableWizard/'
        );
 
-       // Register forms wizard
-       \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addModulePath(
-               'wizard_forms',
-               \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath($_EXTKEY) . 'Modules/Wizards/FormsWizard/'
-       );
-
        // Register rte wizard
        \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addModulePath(
                'wizard_rte',
index 8fea64b..8ee3f3c 100644 (file)
@@ -133,25 +133,6 @@ mod.wizards.newContentElement {
 
                forms.header = LLL:EXT:cms/layout/locallang_db_new_content_el.xlf:forms
                forms.elements {
-                       mailform {
-                               icon = gfx/c_wiz/mailform.gif
-                               title = LLL:EXT:cms/layout/locallang_db_new_content_el.xlf:forms_mail_title
-                               description = LLL:EXT:cms/layout/locallang_db_new_content_el.xlf:forms_mail_description
-                               tt_content_defValues {
-                                       CType = mailform
-                                       bodytext (
-       # Example content:
-       Name: | *name = input,40 | Enter your name here
-       Email: | *email=input,40 |
-       Address: | address=textarea,40,5 |
-       Contact me: | tv=check | 1
-
-       |formtype_mail = submit | Send form!
-       |html_enabled=hidden | 1
-       |subject=hidden| This is the subject
-                                       )
-                               }
-                       }
                        search {
                                icon = gfx/c_wiz/searchform.gif
                                title = LLL:EXT:cms/layout/locallang_db_new_content_el.xlf:forms_search_title
@@ -161,7 +142,7 @@ mod.wizards.newContentElement {
                                }
                        }
                }
-               forms.show = mailform,search
+               forms.show = search
 
                plugins.header = LLL:EXT:cms/layout/locallang_db_new_content_el.xlf:plugins
                plugins.elements {
diff --git a/typo3/sysext/compatibility6/Classes/ContentObject/FormContentObject.php b/typo3/sysext/compatibility6/Classes/ContentObject/FormContentObject.php
new file mode 100644 (file)
index 0000000..7bb39b2
--- /dev/null
@@ -0,0 +1,661 @@
+<?php
+namespace TYPO3\CMS\Compatibility6\ContentObject;
+
+/*
+ * 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\Core\Utility\GeneralUtility;
+
+/**
+ * Contains FORM class object.
+ *
+ * @author Xavier Perseguers <typo3@perseguers.ch>
+ * @author Steffen Kamper <steffen@typo3.org>
+ */
+class FormContentObject extends \TYPO3\CMS\Frontend\ContentObject\AbstractContentObject {
+
+       /**
+        * Rendering the cObject, FORM
+        *
+        * Note on $formData:
+        * In the optional $formData array each entry represents a line in the ordinary setup.
+        * In those entries each entry (0,1,2...) represents a space normally divided by the '|' line.
+        *
+        * $formData [] = array('Name:', 'name=input, 25 ', 'Default value....');
+        * $formData [] = array('Email:', 'email=input, 25 ', 'Default value for email....');
+        *
+        * - corresponds to the $conf['data'] value being :
+        * Name:|name=input, 25 |Default value....||Email:|email=input, 25 |Default value for email....
+        *
+        * If $formData is an array the value of $conf['data'] is ignored.
+        *
+        * @param array $conf Array of TypoScript properties
+        * @param array $formData Alternative formdata overriding whatever comes from TypoScript
+        * @return string Output
+        */
+       public function render($conf = array(), $formData = '') {
+               $content = '';
+               if (is_array($formData)) {
+                       $dataArray = $formData;
+               } else {
+                       $data = isset($conf['data.']) ? $this->cObj->stdWrap($conf['data'], $conf['data.']) : $conf['data'];
+                       // Clearing dataArr
+                       $dataArray = array();
+                       // Getting the original config
+                       if (trim($data)) {
+                               $data = str_replace(LF, '||', $data);
+                               $dataArray = explode('||', $data);
+                       }
+                       // Adding the new dataArray config form:
+                       if (is_array($conf['dataArray.'])) {
+                               // dataArray is supplied
+                               $sortedKeyArray = \TYPO3\CMS\Core\TypoScript\TemplateService::sortedKeyList($conf['dataArray.'], TRUE);
+                               foreach ($sortedKeyArray as $theKey) {
+                                       $singleKeyArray = $conf['dataArray.'][$theKey . '.'];
+                                       if (is_array($singleKeyArray)) {
+                                               $temp = array();
+                                               $label = isset($singleKeyArray['label.']) ? $this->cObj->stdWrap($singleKeyArray['label'], $singleKeyArray['label.']) : $singleKeyArray['label'];
+                                               list($temp[0]) = explode('|', $label);
+                                               $type = isset($singleKeyArray['type.']) ? $this->cObj->stdWrap($singleKeyArray['type'], $singleKeyArray['type.']) : $singleKeyArray['type'];
+                                               list($temp[1]) = explode('|', $type);
+                                               $required = isset($singleKeyArray['required.']) ? $this->cObj->stdWrap($singleKeyArray['required'], $singleKeyArray['required.']) : $singleKeyArray['required'];
+                                               if ($required) {
+                                                       $temp[1] = '*' . $temp[1];
+                                               }
+                                               $singleValue = isset($singleKeyArray['value.']) ? $this->cObj->stdWrap($singleKeyArray['value'], $singleKeyArray['value.']) : $singleKeyArray['value'];
+                                               list($temp[2]) = explode('|', $singleValue);
+                                               // If value array is set, then implode those values.
+                                               if (is_array($singleKeyArray['valueArray.'])) {
+                                                       $temp_accumulated = array();
+                                                       foreach ($singleKeyArray['valueArray.'] as $singleKey => $singleKey_valueArray) {
+                                                               if (is_array($singleKey_valueArray) && (int)$singleKey . '.' === (string)$singleKey) {
+                                                                       $temp_valueArray = array();
+                                                                       $valueArrayLabel = isset($singleKey_valueArray['label.']) ? $this->cObj->stdWrap($singleKey_valueArray['label'], $singleKey_valueArray['label.']) : $singleKey_valueArray['label'];
+                                                                       list($temp_valueArray[0]) = explode('=', $valueArrayLabel);
+                                                                       $selected = isset($singleKey_valueArray['selected.']) ? $this->cObj->stdWrap($singleKey_valueArray['selected'], $singleKey_valueArray['selected.']) : $singleKey_valueArray['selected'];
+                                                                       if ($selected) {
+                                                                               $temp_valueArray[0] = '*' . $temp_valueArray[0];
+                                                                       }
+                                                                       $singleKeyValue = isset($singleKey_valueArray['value.']) ? $this->cObj->stdWrap($singleKey_valueArray['value'], $singleKey_valueArray['value.']) : $singleKey_valueArray['value'];
+                                                                       list($temp_valueArray[1]) = explode(',', $singleKeyValue);
+                                                               }
+                                                               $temp_accumulated[] = implode('=', $temp_valueArray);
+                                                       }
+                                                       $temp[2] = implode(',', $temp_accumulated);
+                                               }
+                                               $specialEval = isset($singleKeyArray['specialEval.']) ? $this->cObj->stdWrap($singleKeyArray['specialEval'], $singleKeyArray['specialEval.']) : $singleKeyArray['specialEval'];
+                                               list($temp[3]) = explode('|', $specialEval);
+                                               // Adding the form entry to the dataArray
+                                               $dataArray[] = implode('|', $temp);
+                                       }
+                               }
+                       }
+               }
+               $attachmentCounter = '';
+               $hiddenfields = '';
+               $fieldlist = array();
+               $propertyOverride = array();
+               $fieldname_hashArray = array();
+               $counter = 0;
+               $xhtmlStrict = GeneralUtility::inList('xhtml_strict,xhtml_11,xhtml_2', $GLOBALS['TSFE']->xhtmlDoctype);
+               // Formname
+               $formName = isset($conf['formName.']) ? $this->cObj->stdWrap($conf['formName'], $conf['formName.']) : $conf['formName'];
+               $formName = $this->cleanFormName($formName);
+               $formName = $GLOBALS['TSFE']->getUniqueId($formName);
+
+               $fieldPrefix = isset($conf['fieldPrefix.']) ? $this->cObj->stdWrap($conf['fieldPrefix'], $conf['fieldPrefix.']) : $conf['fieldPrefix'];
+               if (isset($conf['fieldPrefix']) || isset($conf['fieldPrefix.'])) {
+                       if ($fieldPrefix) {
+                               $prefix = $this->cleanFormName($fieldPrefix);
+                       } else {
+                               $prefix = '';
+                       }
+               } else {
+                       $prefix = $formName;
+               }
+               foreach ($dataArray as $dataValue) {
+                       $counter++;
+                       $confData = array();
+                       if (is_array($formData)) {
+                               $parts = $dataValue;
+                               // TRUE...
+                               $dataValue = 1;
+                       } else {
+                               $dataValue = trim($dataValue);
+                               $parts = explode('|', $dataValue);
+                       }
+                       if ($dataValue && strcspn($dataValue, '#/')) {
+                               // label:
+                               $confData['label'] = GeneralUtility::removeXSS(trim($parts[0]));
+                               // field:
+                               $fParts = explode(',', $parts[1]);
+                               $fParts[0] = trim($fParts[0]);
+                               if ($fParts[0][0] === '*') {
+                                       $confData['required'] = 1;
+                                       $fParts[0] = substr($fParts[0], 1);
+                               }
+                               $typeParts = explode('=', $fParts[0]);
+                               $confData['type'] = trim(strtolower(end($typeParts)));
+                               if (count($typeParts) == 1) {
+                                       $confData['fieldname'] = $this->cleanFormName($parts[0]);
+                                       if (strtolower(preg_replace('/[^[:alnum:]]/', '', $confData['fieldname'])) == 'email') {
+                                               $confData['fieldname'] = 'email';
+                                       }
+                                       // Duplicate fieldnames resolved
+                                       if (isset($fieldname_hashArray[md5($confData['fieldname'])])) {
+                                               $confData['fieldname'] .= '_' . $counter;
+                                       }
+                                       $fieldname_hashArray[md5($confData['fieldname'])] = $confData['fieldname'];
+                                       // Attachment names...
+                                       if ($confData['type'] == 'file') {
+                                               $confData['fieldname'] = 'attachment' . $attachmentCounter;
+                                               $attachmentCounter = (int)$attachmentCounter + 1;
+                                       }
+                               } else {
+                                       $confData['fieldname'] = str_replace(' ', '_', trim($typeParts[0]));
+                               }
+                               $confData['fieldname'] = htmlspecialchars($confData['fieldname']);
+                               $fieldCode = '';
+                               $wrapFieldName = isset($conf['wrapFieldName']) ? $this->cObj->stdWrap($conf['wrapFieldName'], $conf['wrapFieldName.']) : $conf['wrapFieldName'];
+                               if ($wrapFieldName) {
+                                       $confData['fieldname'] = $this->cObj->wrap($confData['fieldname'], $wrapFieldName);
+                               }
+                               // Set field name as current:
+                               $this->cObj->setCurrentVal($confData['fieldname']);
+                               // Additional parameters
+                               if (trim($confData['type'])) {
+                                       if (isset($conf['params.'][$confData['type']])) {
+                                               $addParams = isset($conf['params.'][$confData['type'] . '.']) ? trim($this->cObj->stdWrap($conf['params.'][$confData['type']], $conf['params.'][$confData['type'] . '.'])) : trim($conf['params.'][$confData['type']]);
+                                       } else {
+                                               $addParams = isset($conf['params.']) ? trim($this->cObj->stdWrap($conf['params'], $conf['params.'])) : trim($conf['params']);
+                                       }
+                                       if ((string)$addParams !== '') {
+                                               $addParams = ' ' . $addParams;
+                                       }
+                               } else {
+                                       $addParams = '';
+                               }
+                               $dontMd5FieldNames = isset($conf['dontMd5FieldNames.']) ? $this->cObj->stdWrap($conf['dontMd5FieldNames'], $conf['dontMd5FieldNames.']) : $conf['dontMd5FieldNames'];
+                               if ($dontMd5FieldNames) {
+                                       $fName = $confData['fieldname'];
+                               } else {
+                                       $fName = md5($confData['fieldname']);
+                               }
+                               // Accessibility: Set id = fieldname attribute:
+                               $accessibility = isset($conf['accessibility.']) ? $this->cObj->stdWrap($conf['accessibility'], $conf['accessibility.']) : $conf['accessibility'];
+                               if ($accessibility || $xhtmlStrict) {
+                                       $elementIdAttribute = ' id="' . $prefix . $fName . '"';
+                               } else {
+                                       $elementIdAttribute = '';
+                               }
+                               // Create form field based on configuration/type:
+                               switch ($confData['type']) {
+                                       case 'textarea':
+                                               $cols = trim($fParts[1]) ? (int)$fParts[1] : 20;
+                                               $compensateFieldWidth = isset($conf['compensateFieldWidth.']) ? $this->cObj->stdWrap($conf['compensateFieldWidth'], $conf['compensateFieldWidth.']) : $conf['compensateFieldWidth'];
+                                               $compWidth = doubleval($compensateFieldWidth ? $compensateFieldWidth : $GLOBALS['TSFE']->compensateFieldWidth);
+                                               $compWidth = $compWidth ? $compWidth : 1;
+                                               $cols = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($cols * $compWidth, 1, 120);
+                                               $rows = trim($fParts[2]) ? \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($fParts[2], 1, 30) : 5;
+                                               $wrap = trim($fParts[3]);
+                                               $noWrapAttr = isset($conf['noWrapAttr.']) ? $this->cObj->stdWrap($conf['noWrapAttr'], $conf['noWrapAttr.']) : $conf['noWrapAttr'];
+                                               if ($noWrapAttr || $wrap === 'disabled') {
+                                                       $wrap = '';
+                                               } else {
+                                                       $wrap = $wrap ? ' wrap="' . $wrap . '"' : ' wrap="virtual"';
+                                               }
+                                               $noValueInsert = isset($conf['noValueInsert.']) ? $this->cObj->stdWrap($conf['noValueInsert'], $conf['noValueInsert.']) : $conf['noValueInsert'];
+                                               $default = $this->getFieldDefaultValue($noValueInsert, $confData['fieldname'], str_replace('\\n', LF, trim($parts[2])));
+                                               $fieldCode = sprintf('<textarea name="%s"%s cols="%s" rows="%s"%s%s>%s</textarea>', $confData['fieldname'], $elementIdAttribute, $cols, $rows, $wrap, $addParams, GeneralUtility::formatForTextarea($default));
+                                               break;
+                                       case 'input':
+
+                                       case 'password':
+                                               $size = trim($fParts[1]) ? (int)$fParts[1] : 20;
+                                               $compensateFieldWidth = isset($conf['compensateFieldWidth.']) ? $this->cObj->stdWrap($conf['compensateFieldWidth'], $conf['compensateFieldWidth.']) : $conf['compensateFieldWidth'];
+                                               $compWidth = doubleval($compensateFieldWidth ? $compensateFieldWidth : $GLOBALS['TSFE']->compensateFieldWidth);
+                                               $compWidth = $compWidth ? $compWidth : 1;
+                                               $size = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($size * $compWidth, 1, 120);
+                                               $noValueInsert = isset($conf['noValueInsert.']) ? $this->cObj->stdWrap($conf['noValueInsert'], $conf['noValueInsert.']) : $conf['noValueInsert'];
+                                               $default = $this->getFieldDefaultValue($noValueInsert, $confData['fieldname'], trim($parts[2]));
+                                               if ($confData['type'] == 'password') {
+                                                       $default = '';
+                                               }
+                                               $max = trim($fParts[2]) ? ' maxlength="' . \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($fParts[2], 1, 1000) . '"' : '';
+                                               $theType = $confData['type'] == 'input' ? 'text' : 'password';
+                                               $fieldCode = sprintf('<input type="%s" name="%s"%s size="%s"%s value="%s"%s />', $theType, $confData['fieldname'], $elementIdAttribute, $size, $max, htmlspecialchars($default), $addParams);
+                                               break;
+                                       case 'file':
+                                               $size = trim($fParts[1]) ? \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($fParts[1], 1, 60) : 20;
+                                               $fieldCode = sprintf('<input type="file" name="%s"%s size="%s"%s />', $confData['fieldname'], $elementIdAttribute, $size, $addParams);
+                                               break;
+                                       case 'check':
+                                               // alternative default value:
+                                               $noValueInsert = isset($conf['noValueInsert.']) ? $this->cObj->stdWrap($conf['noValueInsert'], $conf['noValueInsert.']) : $conf['noValueInsert'];
+                                               $default = $this->getFieldDefaultValue($noValueInsert, $confData['fieldname'], trim($parts[2]));
+                                               $checked = $default ? ' checked="checked"' : '';
+                                               $fieldCode = sprintf('<input type="checkbox" value="%s" name="%s"%s%s%s />', 1, $confData['fieldname'], $elementIdAttribute, $checked, $addParams);
+                                               break;
+                                       case 'select':
+                                               $option = '';
+                                               $valueParts = explode(',', $parts[2]);
+                                               // size
+                                               if (strtolower(trim($fParts[1])) == 'auto') {
+                                                       $fParts[1] = count($valueParts);
+                                               }
+                                               // Auto size set here. Max 20
+                                               $size = trim($fParts[1]) ? \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($fParts[1], 1, 20) : 1;
+                                               // multiple
+                                               $multiple = strtolower(trim($fParts[2])) == 'm' ? ' multiple="multiple"' : '';
+                                               // Where the items will be
+                                               $items = array();
+                                               //RTF
+                                               $defaults = array();
+                                               $pCount = count($valueParts);
+                                               for ($a = 0; $a < $pCount; $a++) {
+                                                       $valueParts[$a] = trim($valueParts[$a]);
+                                                       // Finding default value
+                                                       if ($valueParts[$a][0] === '*') {
+                                                               $sel = 'selected';
+                                                               $valueParts[$a] = substr($valueParts[$a], 1);
+                                                       } else {
+                                                               $sel = '';
+                                                       }
+                                                       // Get value/label
+                                                       $subParts = explode('=', $valueParts[$a]);
+                                                       // Sets the value
+                                                       $subParts[1] = isset($subParts[1]) ? trim($subParts[1]) : trim($subParts[0]);
+                                                       // Adds the value/label pair to the items-array
+                                                       $items[] = $subParts;
+                                                       if ($sel) {
+                                                               $defaults[] = $subParts[1];
+                                                       }
+                                               }
+                                               // alternative default value:
+                                               $noValueInsert = isset($conf['noValueInsert.']) ? $this->cObj->stdWrap($conf['noValueInsert'], $conf['noValueInsert.']) : $conf['noValueInsert'];
+                                               $default = $this->getFieldDefaultValue($noValueInsert, $confData['fieldname'], $defaults);
+                                               if (!is_array($default)) {
+                                                       $defaults = array();
+                                                       $defaults[] = $default;
+                                               } else {
+                                                       $defaults = $default;
+                                               }
+                                               // Create the select-box:
+                                               $iCount = count($items);
+                                               for ($a = 0; $a < $iCount; $a++) {
+                                                       $option .= '<option value="' . $items[$a][1] . '"' . (in_array($items[$a][1], $defaults) ? ' selected="selected"' : '') . '>' . trim($items[$a][0]) . '</option>';
+                                               }
+                                               if ($multiple) {
+                                                       // The fieldname must be prepended '[]' if multiple select. And the reason why it's prepended is, because the required-field list later must also have [] prepended.
+                                                       $confData['fieldname'] .= '[]';
+                                               }
+                                               $fieldCode = sprintf('<select name="%s"%s size="%s"%s%s>%s</select>', $confData['fieldname'], $elementIdAttribute, $size, $multiple, $addParams, $option);
+                                               //RTF
+                                               break;
+                                       case 'radio':
+                                               $option = '';
+                                               $valueParts = explode(',', $parts[2]);
+                                               // Where the items will be
+                                               $items = array();
+                                               $default = '';
+                                               $pCount = count($valueParts);
+                                               for ($a = 0; $a < $pCount; $a++) {
+                                                       $valueParts[$a] = trim($valueParts[$a]);
+                                                       if ($valueParts[$a][0] === '*') {
+                                                               $sel = 'checked';
+                                                               $valueParts[$a] = substr($valueParts[$a], 1);
+                                                       } else {
+                                                               $sel = '';
+                                                       }
+                                                       // Get value/label
+                                                       $subParts = explode('=', $valueParts[$a]);
+                                                       // Sets the value
+                                                       $subParts[1] = isset($subParts[1]) ? trim($subParts[1]) : trim($subParts[0]);
+                                                       // Adds the value/label pair to the items-array
+                                                       $items[] = $subParts;
+                                                       if ($sel) {
+                                                               $default = $subParts[1];
+                                                       }
+                                               }
+                                               // alternative default value:
+                                               $noValueInsert = isset($conf['noValueInsert.']) ? $this->cObj->stdWrap($conf['noValueInsert'], $conf['noValueInsert.']) : $conf['noValueInsert'];
+                                               $default = $this->getFieldDefaultValue($noValueInsert, $confData['fieldname'], $default);
+                                               // Create the select-box:
+                                               $iCount = count($items);
+                                               for ($a = 0; $a < $iCount; $a++) {
+                                                       $optionParts = '';
+                                                       $radioId = $prefix . $fName . $this->cleanFormName($items[$a][0]);
+                                                       if ($accessibility) {
+                                                               $radioLabelIdAttribute = ' id="' . $radioId . '"';
+                                                       } else {
+                                                               $radioLabelIdAttribute = '';
+                                                       }
+                                                       $optionParts .= '<input type="radio" name="' . $confData['fieldname'] . '"' . $radioLabelIdAttribute . ' value="' . $items[$a][1] . '"' . ((string)$items[$a][1] === (string)$default ? ' checked="checked"' : '') . $addParams . ' />';
+                                                       if ($accessibility) {
+                                                               $label = isset($conf['radioWrap.']) ? $this->cObj->stdWrap(trim($items[$a][0]), $conf['radioWrap.']) : trim($items[$a][0]);
+                                                               $optionParts .= '<label for="' . $radioId . '">' . $label . '</label>';
+                                                       } else {
+                                                               $optionParts .= isset($conf['radioWrap.']) ? $this->cObj->stdWrap(trim($items[$a][0]), $conf['radioWrap.']) : trim($items[$a][0]);
+                                                       }
+                                                       $option .= isset($conf['radioInputWrap.']) ? $this->cObj->stdWrap($optionParts, $conf['radioInputWrap.']) : $optionParts;
+                                               }
+                                               if ($accessibility) {
+                                                       $accessibilityWrap = isset($conf['radioWrap.']['accessibilityWrap.']) ? $this->cObj->stdWrap($conf['radioWrap.']['accessibilityWrap'], $conf['radioWrap.']['accessibilityWrap.']) : $conf['radioWrap.']['accessibilityWrap'];
+                                                       if ($accessibilityWrap) {
+                                                               $search = array(
+                                                                       '###RADIO_FIELD_ID###',
+                                                                       '###RADIO_GROUP_LABEL###'
+                                                               );
+                                                               $replace = array(
+                                                                       $elementIdAttribute,
+                                                                       $confData['label']
+                                                               );
+                                                               $accessibilityWrap = str_replace($search, $replace, $accessibilityWrap);
+                                                               $option = $this->cObj->wrap($option, $accessibilityWrap);
+                                                       }
+                                               }
+                                               $fieldCode = $option;
+                                               break;
+                                       case 'hidden':
+                                               $value = trim($parts[2]);
+                                               // If this form includes an auto responder message, include a HMAC checksum field
+                                               // in order to verify potential abuse of this feature.
+                                               if ($value !== '') {
+                                                       if (GeneralUtility::inList($confData['fieldname'], 'auto_respond_msg')) {
+                                                               $hmacChecksum = GeneralUtility::hmac($value, 'content_form');
+                                                               $hiddenfields .= sprintf('<input type="hidden" name="auto_respond_checksum" id="%sauto_respond_checksum" value="%s" />', $prefix, $hmacChecksum);
+                                                       }
+                                                       if (GeneralUtility::inList('recipient_copy,recipient', $confData['fieldname']) && $GLOBALS['TYPO3_CONF_VARS']['FE']['secureFormmail']) {
+                                                               break;
+                                                       }
+                                                       if (GeneralUtility::inList('recipient_copy,recipient', $confData['fieldname'])) {
+                                                               $value = \TYPO3\CMS\Compatibility6\Utility\FormUtility::codeString($value);
+                                                       }
+                                               }
+                                               $hiddenfields .= sprintf('<input type="hidden" name="%s"%s value="%s" />', $confData['fieldname'], $elementIdAttribute, htmlspecialchars($value));
+                                               break;
+                                       case 'property':
+                                               if (GeneralUtility::inList('type,locationData,goodMess,badMess,emailMess', $confData['fieldname'])) {
+                                                       $value = trim($parts[2]);
+                                                       $propertyOverride[$confData['fieldname']] = $value;
+                                                       $conf[$confData['fieldname']] = $value;
+                                               }
+                                               break;
+                                       case 'submit':
+                                               $value = trim($parts[2]);
+                                               if ($conf['image.']) {
+                                                       $this->cObj->data[$this->cObj->currentValKey] = $value;
+                                                       $image = $this->cObj->cObjGetSingle('IMG_RESOURCE', $conf['image.']);
+                                                       $params = $conf['image.']['params'] ? ' ' . $conf['image.']['params'] : '';
+                                                       $params .= $this->cObj->getAltParam($conf['image.'], FALSE);
+                                                       $params .= $addParams;
+                                               } else {
+                                                       $image = '';
+                                               }
+                                               if ($image) {
+                                                       $fieldCode = sprintf('<input type="image" name="%s"%s src="%s"%s />', $confData['fieldname'], $elementIdAttribute, $image, $params);
+                                               } else {
+                                                       $fieldCode = sprintf('<input type="submit" name="%s"%s value="%s"%s />', $confData['fieldname'], $elementIdAttribute, htmlspecialchars($value, ENT_COMPAT, 'UTF-8', FALSE), $addParams);
+                                               }
+                                               break;
+                                       case 'reset':
+                                               $value = trim($parts[2]);
+                                               $fieldCode = sprintf('<input type="reset" name="%s"%s value="%s"%s />', $confData['fieldname'], $elementIdAttribute, htmlspecialchars($value, ENT_COMPAT, 'UTF-8', FALSE), $addParams);
+                                               break;
+                                       case 'label':
+                                               $fieldCode = nl2br(htmlspecialchars(trim($parts[2])));
+                                               break;
+                                       default:
+                                               $confData['type'] = 'comment';
+                                               $fieldCode = trim($parts[2]) . '&nbsp;';
+                               }
+                               if ($fieldCode) {
+                                       // Checking for special evaluation modes:
+                                       if (trim($parts[3]) !== '' && GeneralUtility::inList('textarea,input,password', $confData['type'])) {
+                                               $modeParameters = GeneralUtility::trimExplode(':', $parts[3]);
+                                       } else {
+                                               $modeParameters = array();
+                                       }
+                                       // Adding evaluation based on settings:
+                                       switch ((string)$modeParameters[0]) {
+                                               case 'EREG':
+                                                       $fieldlist[] = '_EREG';
+                                                       $fieldlist[] = $modeParameters[1];
+                                                       $fieldlist[] = $modeParameters[2];
+                                                       $fieldlist[] = $confData['fieldname'];
+                                                       $fieldlist[] = $confData['label'];
+                                                       // Setting this so "required" layout is used.
+                                                       $confData['required'] = 1;
+                                                       break;
+                                               case 'EMAIL':
+                                                       $fieldlist[] = '_EMAIL';
+                                                       $fieldlist[] = $confData['fieldname'];
+                                                       $fieldlist[] = $confData['label'];
+                                                       // Setting this so "required" layout is used.
+                                                       $confData['required'] = 1;
+                                                       break;
+                                               default:
+                                                       if ($confData['required']) {
+                                                               $fieldlist[] = $confData['fieldname'];
+                                                               $fieldlist[] = $confData['label'];
+                                                       }
+                                       }
+                                       // Field:
+                                       $fieldLabel = $confData['label'];
+                                       if ($accessibility && trim($fieldLabel) && !preg_match('/^(label|hidden|comment)$/', $confData['type'])) {
+                                               $fieldLabel = '<label for="' . $prefix . $fName . '">' . $fieldLabel . '</label>';
+                                       }
+                                       // Getting template code:
+                                       if (isset($conf['fieldWrap.'])) {
+                                               $fieldCode = $this->cObj->stdWrap($fieldCode, $conf['fieldWrap.']);
+                                       }
+                                       $labelCode = isset($conf['labelWrap.']) ? $this->cObj->stdWrap($fieldLabel, $conf['labelWrap.']) : $fieldLabel;
+                                       $commentCode = isset($conf['commentWrap.']) ? $this->cObj->stdWrap($confData['label'], $conf['commentWrap.']) : $confData['label'];
+                                       $result = $conf['layout'];
+                                       $req = isset($conf['REQ.']) ? $this->cObj->stdWrap($conf['REQ'], $conf['REQ.']) : $conf['REQ'];
+                                       if ($req && $confData['required']) {
+                                               if (isset($conf['REQ.']['fieldWrap.'])) {
+                                                       $fieldCode = $this->cObj->stdWrap($fieldCode, $conf['REQ.']['fieldWrap.']);
+                                               }
+                                               if (isset($conf['REQ.']['labelWrap.'])) {
+                                                       $labelCode = $this->cObj->stdWrap($fieldLabel, $conf['REQ.']['labelWrap.']);
+                                               }
+                                               $reqLayout = isset($conf['REQ.']['layout.']) ? $this->cObj->stdWrap($conf['REQ.']['layout'], $conf['REQ.']['layout.']) : $conf['REQ.']['layout'];
+                                               if ($reqLayout) {
+                                                       $result = $reqLayout;
+                                               }
+                                       }
+                                       if ($confData['type'] == 'comment') {
+                                               $commentLayout = isset($conf['COMMENT.']['layout.']) ? $this->cObj->stdWrap($conf['COMMENT.']['layout'], $conf['COMMENT.']['layout.']) : $conf['COMMENT.']['layout'];
+                                               if ($commentLayout) {
+                                                       $result = $commentLayout;
+                                               }
+                                       }
+                                       if ($confData['type'] == 'check') {
+                                               $checkLayout = isset($conf['CHECK.']['layout.']) ? $this->cObj->stdWrap($conf['CHECK.']['layout'], $conf['CHECK.']['layout.']) : $conf['CHECK.']['layout'];
+                                               if ($checkLayout) {
+                                                       $result = $checkLayout;
+                                               }
+                                       }
+                                       if ($confData['type'] == 'radio') {
+                                               $radioLayout = isset($conf['RADIO.']['layout.']) ? $this->cObj->stdWrap($conf['RADIO.']['layout'], $conf['RADIO.']['layout.']) : $conf['RADIO.']['layout'];
+                                               if ($radioLayout) {
+                                                       $result = $radioLayout;
+                                               }
+                                       }
+                                       if ($confData['type'] == 'label') {
+                                               $labelLayout = isset($conf['LABEL.']['layout.']) ? $this->cObj->stdWrap($conf['LABEL.']['layout'], $conf['LABEL.']['layout.']) : $conf['LABEL.']['layout'];
+                                               if ($labelLayout) {
+                                                       $result = $labelLayout;
+                                               }
+                                       }
+                                       //RTF
+                                       $content .= str_replace(
+                                               array(
+                                                       '###FIELD###',
+                                                       '###LABEL###',
+                                                       '###COMMENT###'
+                                               ),
+                                               array(
+                                                       $fieldCode,
+                                                       $labelCode,
+                                                       $commentCode
+                                               ),
+                                               $result
+                                       );
+                               }
+                       }
+               }
+               if (isset($conf['stdWrap.'])) {
+                       $content = $this->cObj->stdWrap($content, $conf['stdWrap.']);
+               }
+               // Redirect (external: where to go afterwards. internal: where to submit to)
+               $theRedirect = isset($conf['redirect.']) ? $this->cObj->stdWrap($conf['redirect'], $conf['redirect.']) : $conf['redirect'];
+               // redirect should be set to the page to redirect to after an external script has been used. If internal scripts is used, and if no 'type' is set that dictates otherwise, redirect is used as the url to jump to as long as it's an integer (page)
+               $target = isset($conf['target.']) ? $this->cObj->stdWrap($conf['target'], $conf['target.']) : $conf['target'];
+               // redirect should be set to the page to redirect to after an external script has been used. If internal scripts is used, and if no 'type' is set that dictates otherwise, redirect is used as the url to jump to as long as it's an integer (page)
+               $noCache = isset($conf['no_cache.']) ? $this->cObj->stdWrap($conf['no_cache'], $conf['no_cache.']) : $conf['no_cache'];
+               // redirect should be set to the page to redirect to after an external script has been used. If internal scripts is used, and if no 'type' is set that dictates otherwise, redirect is used as the url to jump to as long as it's an integer (page)
+               $page = $GLOBALS['TSFE']->page;
+               // Internal: Just submit to current page
+               if (!$theRedirect) {
+                       $LD = $GLOBALS['TSFE']->tmpl->linkData($page, $target, $noCache, 'index.php', '', $this->cObj->getClosestMPvalueForPage($page['uid']));
+               } elseif (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($theRedirect)) {
+                       // Internal: Submit to page with ID $theRedirect
+                       $page = $GLOBALS['TSFE']->sys_page->getPage_noCheck($theRedirect);
+                       $LD = $GLOBALS['TSFE']->tmpl->linkData($page, $target, $noCache, 'index.php', '', $this->cObj->getClosestMPvalueForPage($page['uid']));
+               } else {
+                       // External URL, redirect-hidden field is rendered!
+                       $LD = $GLOBALS['TSFE']->tmpl->linkData($page, $target, $noCache, '', '', $this->cObj->getClosestMPvalueForPage($page['uid']));
+                       $LD['totalURL'] = $theRedirect;
+                       $hiddenfields .= '<input type="hidden" name="redirect" value="' . htmlspecialchars($LD['totalURL']) . '" />';
+               }
+               // Formtype (where to submit to!):
+               if ($propertyOverride['type']) {
+                       $formtype = $propertyOverride['type'];
+               } else {
+                       $formtype = isset($conf['type.']) ? $this->cObj->stdWrap($conf['type'], $conf['type.']) : $conf['type'];
+               }
+               // Submit to a specific page
+               if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($formtype)) {
+                       $page = $GLOBALS['TSFE']->sys_page->getPage_noCheck($formtype);
+                       $LD_A = $GLOBALS['TSFE']->tmpl->linkData($page, $target, $noCache, '', '', $this->cObj->getClosestMPvalueForPage($page['uid']));
+                       $action = $LD_A['totalURL'];
+               } elseif ($formtype) {
+                       // Submit to external script
+                       $LD_A = $LD;
+                       $action = $formtype;
+               } elseif (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($theRedirect)) {
+                       $LD_A = $LD;
+                       $action = $LD_A['totalURL'];
+               } else {
+                       // Submit to "nothing" - which is current page
+                       $LD_A = $GLOBALS['TSFE']->tmpl->linkData($GLOBALS['TSFE']->page, $target, $noCache, '', '', $this->cObj->getClosestMPvalueForPage($page['uid']));
+                       $action = $LD_A['totalURL'];
+               }
+               // Recipient:
+               $theEmail = isset($conf['recipient.']) ? $this->cObj->stdWrap($conf['recipient'], $conf['recipient.']) : $conf['recipient'];
+               if ($theEmail && !$GLOBALS['TYPO3_CONF_VARS']['FE']['secureFormmail']) {
+                       $theEmail = \TYPO3\CMS\Compatibility6\Utility\FormUtility::codeString($theEmail);
+                       $hiddenfields .= '<input type="hidden" name="recipient" value="' . htmlspecialchars($theEmail) . '" />';
+               }
+               // location data:
+               $location = isset($conf['locationData.']) ? $this->cObj->stdWrap($conf['locationData'], $conf['locationData.']) : $conf['locationData'];
+               if ($location) {
+                       if ($location == 'HTTP_POST_VARS' && isset($_POST['locationData'])) {
+                               $locationData = GeneralUtility::_POST('locationData');
+                       } else {
+                               // locationData is [the page id]:[tablename]:[uid of record]. Indicates on which page the record (from tablename with uid) is shown. Used to check access.
+                               if (isset($this->data['_LOCALIZED_UID'])) {
+                                       $locationData = $GLOBALS['TSFE']->id . ':' . str_replace($this->data['uid'], $this->data['_LOCALIZED_UID'], $this->cObj->currentRecord);
+                               } else {
+                                       $locationData = $GLOBALS['TSFE']->id . ':' . $this->cObj->currentRecord;
+                               }
+                       }
+                       $hiddenfields .= '<input type="hidden" name="locationData" value="' . htmlspecialchars($locationData) . '" />';
+               }
+               // Hidden fields:
+               if (is_array($conf['hiddenFields.'])) {
+                       foreach ($conf['hiddenFields.'] as $hF_key => $hF_conf) {
+                               if (substr($hF_key, -1) != '.') {
+                                       $hF_value = $this->cObj->cObjGetSingle($hF_conf, $conf['hiddenFields.'][$hF_key . '.'], 'hiddenfields');
+                                       if ((string)$hF_value !== '' && GeneralUtility::inList('recipient_copy,recipient', $hF_key)) {
+                                               if ($GLOBALS['TYPO3_CONF_VARS']['FE']['secureFormmail']) {
+                                                       continue;
+                                               }
+                                               $hF_value = \TYPO3\CMS\Compatibility6\Utility\FormUtility::codeString($hF_value);
+                                       }
+                                       $hiddenfields .= '<input type="hidden" name="' . $hF_key . '" value="' . htmlspecialchars($hF_value) . '" />';
+                               }
+                       }
+               }
+               // Wrap all hidden fields in a div tag (see http://forge.typo3.org/issues/14491)
+               $hiddenfields = isset($conf['hiddenFields.']['stdWrap.']) ? $this->cObj->stdWrap($hiddenfields, $conf['hiddenFields.']['stdWrap.']) : '<div style="display:none;">' . $hiddenfields . '</div>';
+               if ($conf['REQ']) {
+                       $goodMess = isset($conf['goodMess.']) ? $this->cObj->stdWrap($conf['goodMess'], $conf['goodMess.']) : $conf['goodMess'];
+                       $badMess = isset($conf['badMess.']) ? $this->cObj->stdWrap($conf['badMess'], $conf['badMess.']) : $conf['badMess'];
+                       $emailMess = isset($conf['emailMess.']) ? $this->cObj->stdWrap($conf['emailMess'], $conf['emailMess.']) : $conf['emailMess'];
+                       $validateForm = ' onsubmit="return validateForm(' . GeneralUtility::quoteJSvalue($formName) . ',' . GeneralUtility::quoteJSvalue(implode(',', $fieldlist)) . ',' . GeneralUtility::quoteJSvalue($goodMess) . ',' . GeneralUtility::quoteJSvalue($badMess) . ',' . GeneralUtility::quoteJSvalue($emailMess) . ')"';
+                       $GLOBALS['TSFE']->additionalHeaderData['JSFormValidate'] = '<script type="text/javascript" src="' . GeneralUtility::createVersionNumberedFilename(($GLOBALS['TSFE']->absRefPrefix . 'typo3/sysext/compatibility6/Resources/Public/JavaScript/jsfunc.validateform.js')) . '"></script>';
+               } else {
+                       $validateForm = '';
+               }
+               // Create form tag:
+               $theTarget = $theRedirect ? $LD['target'] : $LD_A['target'];
+               $method = isset($conf['method.']) ? $this->cObj->stdWrap($conf['method'], $conf['method.']) : $conf['method'];
+               $content = array(
+                       '<form' . ' action="' . htmlspecialchars($action) . '"' . ' id="' . $formName . '"' . ($xhtmlStrict ? '' : ' name="' . $formName . '"') . ' enctype="' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['form_enctype'] . '"' . ' method="' . ($method ? $method : 'post') . '"' . ($theTarget ? ' target="' . $theTarget . '"' : '') . $validateForm . '>',
+                       $hiddenfields . $content,
+                       '</form>'
+               );
+               $arrayReturnMode = isset($conf['arrayReturnMode.']) ? $this->cObj->stdWrap($conf['arrayReturnMode'], $conf['arrayReturnMode.']) : $conf['arrayReturnMode'];
+               if ($arrayReturnMode) {
+                       $content['validateForm'] = $validateForm;
+                       $content['formname'] = $formName;
+                       return $content;
+               } else {
+                       return implode('', $content);
+               }
+       }
+
+
+       /**
+        * Returns a default value for a form field in the FORM cObject.
+        * Page CANNOT be cached because that would include the inserted value for the current user.
+        *
+        * @param bool $noValueInsert If noValueInsert OR if the no_cache flag for this page is NOT set, the original default value is returned.
+        * @param string $fieldName The POST var name to get default value for
+        * @param string $defaultVal The current default value
+        * @return string The default value, either from INPUT var or the current default, based on whether caching is enabled or not.
+        */
+       protected function getFieldDefaultValue($noValueInsert, $fieldName, $defaultVal) {
+               if (!$GLOBALS['TSFE']->no_cache || !isset($_POST[$fieldName]) && !isset($_GET[$fieldName]) || $noValueInsert) {
+                       return $defaultVal;
+               } else {
+                       return GeneralUtility::_GP($fieldName);
+               }
+       }
+
+       /**
+        * Removes forbidden characters and spaces from name/id attributes in the form tag and formfields
+        *
+        * @param string $name Input string
+        * @return string the cleaned string
+        */
+       protected function cleanFormName($name) {
+               // Turn data[x][y] into data:x:y:
+               $name = preg_replace('/\\[|\\]\\[?/', ':', trim($name));
+               // Remove illegal chars like _
+               return preg_replace('#[^:a-zA-Z0-9]#', '', $name);
+       }
+}
diff --git a/typo3/sysext/compatibility6/Classes/Controller/FormDataSubmissionController.php b/typo3/sysext/compatibility6/Classes/Controller/FormDataSubmissionController.php
new file mode 100644 (file)
index 0000000..0b13266
--- /dev/null
@@ -0,0 +1,450 @@
+<?php
+namespace TYPO3\CMS\Compatibility6\Controller;
+
+/*
+ * 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\Core\Utility;
+
+/**
+ * Formmail class
+ * used to submit data, and hooks into TSFE
+ *
+ * @author Kasper Skårhøj <kasperYYYY@typo3.com>
+ */
+class FormDataSubmissionController {
+
+       /**
+        * @var string
+        */
+       protected $reserved_names = 'recipient,recipient_copy,auto_respond_msg,auto_respond_checksum,redirect,subject,attachment,from_email,from_name,replyto_email,replyto_name,organisation,priority,html_enabled,quoted_printable,submit_x,submit_y';
+
+       /**
+        * Collection of suspicious header data, used for logging
+        *
+        * @var array
+        */
+       protected $dirtyHeaders = array();
+
+       /**
+        * @var string
+        */
+       protected $characterSet;
+
+       /**
+        * @var string
+        */
+       protected $subject;
+
+       /**
+        * @var string
+        */
+       protected $fromName;
+
+       /**
+        * @var string
+        */
+       protected $replyToName;
+
+       /**
+        * @var string
+        */
+       protected $organisation;
+
+       /**
+        * @var string
+        */
+       protected $fromAddress;
+
+       /**
+        * @var string
+        */
+       protected $replyToAddress;
+
+       /**
+        * @var int
+        */
+       protected $priority;
+
+       /**
+        * @var string
+        */
+       protected $autoRespondMessage;
+
+       /**
+        * @var string
+        */
+       protected $encoding = 'quoted-printable';
+
+       /**
+        * @var \TYPO3\CMS\Core\Mail\MailMessage
+        */
+       protected $mailMessage;
+
+       /**
+        * @var string
+        */
+       protected $recipient;
+
+       /**
+        * @var string
+        */
+       protected $plainContent = '';
+
+       /**
+        * @var array Files to clean up at the end (attachments)
+        */
+       protected $temporaryFiles = array();
+
+       /**
+        * @var \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
+        */
+       protected $frontendController = NULL;
+
+       /**
+        * hook to be executed by TypoScriptFrontendController
+        *
+        * @param \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController $frontendController
+        */
+       public function checkDataSubmission($frontendController) {
+               $this->frontendController = $frontendController;
+
+               // Checks if any email-submissions
+               $formtype_mail = isset($_POST['formtype_mail']) || isset($_POST['formtype_mail_x']);
+               if ($formtype_mail) {
+                       $refInfo = parse_url(Utility\GeneralUtility::getIndpEnv('HTTP_REFERER'));
+                       if (Utility\GeneralUtility::getIndpEnv('TYPO3_HOST_ONLY') == $refInfo['host'] || $this->frontendController->TYPO3_CONF_VARS['SYS']['doNotCheckReferer']) {
+                               if ($this->locDataCheck($_POST['locationData'])) {
+                                       if ($formtype_mail) {
+                                               $this->prepareAndSend();
+                                               $GLOBALS['TT']->setTSlogMessage('"Check Data Submission": Return value: email', 0);
+                                       }
+                               }
+                       } else {
+                               $GLOBALS['TT']->setTSlogMessage('"Check Data Submission": HTTP_HOST and REFERER HOST did not match when processing submitted formdata!', 3);
+                       }
+               }
+       }
+
+       /**
+        * Checks if a formmail submission can be sent as email
+        *
+        * @param string $locationData The input from $_POST['locationData']
+        * @return void|int
+        */
+       protected function locDataCheck($locationData) {
+               $locData = explode(':', $locationData);
+               if (!$locData[1] || $this->frontendController->sys_page->checkRecord($locData[1], $locData[2], 1)) {
+                       // $locData[1] -check means that a record is checked only if the locationData has a value for a record else than the page.
+                       if (count($this->frontendController->sys_page->getPage($locData[0]))) {
+                               return 1;
+                       } else {
+                               $GLOBALS['TT']->setTSlogMessage('LocationData Error: The page pointed to by location data (' . $locationData . ') was not accessible.', 2);
+                       }
+               } else {
+                       $GLOBALS['TT']->setTSlogMessage('LocationData Error: Location data (' . $locationData . ') record pointed to was not accessible.', 2);
+               }
+       }
+
+       /**
+        * Sends the emails from the formmail content object.
+        *
+        * @return void
+        */
+       protected function prepareAndSend() {
+               $EMAIL_VARS = Utility\GeneralUtility::_POST();
+               $locationData = $EMAIL_VARS['locationData'];
+               unset($EMAIL_VARS['locationData']);
+               unset($EMAIL_VARS['formtype_mail'], $EMAIL_VARS['formtype_mail_x'], $EMAIL_VARS['formtype_mail_y']);
+               $integrityCheck = $this->frontendController->TYPO3_CONF_VARS['FE']['strictFormmail'];
+               if (!$this->frontendController->TYPO3_CONF_VARS['FE']['secureFormmail']) {
+                       // Check recipient field:
+                       // These two fields are the ones which contain recipient addresses that can be misused to send mail from foreign servers.
+                       $encodedFields = explode(',', 'recipient, recipient_copy');
+                       foreach ($encodedFields as $fieldKey) {
+                               if ((string)$EMAIL_VARS[$fieldKey] !== '') {
+                                       // Decode...
+                                       if ($res = \TYPO3\CMS\Compatibility6\Utility\FormUtility::codeString($EMAIL_VARS[$fieldKey], TRUE)) {
+                                               $EMAIL_VARS[$fieldKey] = $res;
+                                       } elseif ($integrityCheck) {
+                                               // Otherwise abort:
+                                               $GLOBALS['TT']->setTSlogMessage('"Formmail" discovered a field (' . $fieldKey . ') which could not be decoded to a valid string. Sending formmail aborted due to security reasons!', 3);
+                                               return;
+                                       } else {
+                                               $GLOBALS['TT']->setTSlogMessage('"Formmail" discovered a field (' . $fieldKey . ') which could not be decoded to a valid string. The security level accepts this, but you should consider a correct coding though!', 2);
+                                       }
+                               }
+                       }
+               } else {
+                       $locData = explode(':', $locationData);
+                       $record = $this->frontendController->sys_page->checkRecord($locData[1], $locData[2], 1);
+                       $EMAIL_VARS['recipient'] = $record['subheader'];
+                       $EMAIL_VARS['recipient_copy'] = $this->extractRecipientCopy($record['bodytext']);
+               }
+               // Hook for preprocessing of the content for formmails:
+               if (is_array($this->frontendController->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['sendFormmail-PreProcClass'])) {
+                       foreach ($this->frontendController->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['sendFormmail-PreProcClass'] as $_classRef) {
+                               $_procObj = Utility\GeneralUtility::getUserObj($_classRef);
+                               $EMAIL_VARS = $_procObj->sendFormmail_preProcessVariables($EMAIL_VARS, $this);
+                       }
+               }
+               $this->start($EMAIL_VARS);
+               $r = $this->sendtheMail();
+               $GLOBALS['TT']->setTSlogMessage('"Formmail" invoked, sending mail to ' . $EMAIL_VARS['recipient'], 0);
+       }
+
+       /**
+        * Extracts the value of recipient copy field from a formmail CE bodytext
+        *
+        * @param string $bodytext The content of the related bodytext field
+        * @return string The value of the recipient_copy field, or an empty string
+        */
+       protected function extractRecipientCopy($bodytext) {
+               $fdef = array();
+               //|recipient_copy=hidden|karsten@localhost.localdomain
+               preg_match('/^[\\s]*\\|[\\s]*recipient_copy[\\s]*=[\\s]*hidden[\\s]*\\|(.*)$/m', $bodytext, $fdef);
+               return $fdef[1] ?: '';
+       }
+
+       /**
+        * Start function
+        * This class is able to generate a mail in formmail-style from the data in $V
+        * Fields:
+        *
+        * [recipient]:                 email-adress of the one to receive the mail. If array, then all values are expected to be recipients
+        * [attachment]:                ....
+        *
+        * [subject]:                   The subject of the mail
+        * [from_email]:                Sender email. If not set, [email] is used
+        * [from_name]:                 Sender name. If not set, [name] is used
+        * [replyto_email]:             Reply-to email. If not set [from_email] is used
+        * [replyto_name]:              Reply-to name. If not set [from_name] is used
+        * [organisation]:              Organization (header)
+        * [priority]:                  Priority, 1-5, default 3
+        * [html_enabled]:              If mail is sent as html
+        * [use_base64]:                If set, base64 encoding will be used instead of quoted-printable
+        *
+        * @param array $valueList Contains values for the field names listed above (with slashes removed if from POST input)
+        * @param bool $base64 Whether to base64 encode the mail content
+        * @return void
+        */
+       public function start($valueList, $base64 = FALSE) {
+               $this->mailMessage = Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Mail\MailMessage::class);
+               if ($GLOBALS['TSFE']->config['config']['formMailCharset']) {
+                       // Respect formMailCharset if it was set
+                       $this->characterSet = $GLOBALS['TSFE']->csConvObj->parse_charset($GLOBALS['TSFE']->config['config']['formMailCharset']);
+               } elseif ($GLOBALS['TSFE']->metaCharset != $GLOBALS['TSFE']->renderCharset) {
+                       // Use metaCharset for mail if different from renderCharset
+                       $this->characterSet = $GLOBALS['TSFE']->metaCharset;
+               } else {
+                       // Otherwise use renderCharset as default
+                       $this->characterSet = $GLOBALS['TSFE']->renderCharset;
+               }
+               if ($base64 || $valueList['use_base64']) {
+                       $this->encoding = 'base64';
+               }
+               if (isset($valueList['recipient'])) {
+                       // Convert form data from renderCharset to mail charset
+                       $this->subject = $valueList['subject'] ? $valueList['subject'] : 'Formmail on ' . Utility\GeneralUtility::getIndpEnv('HTTP_HOST');
+                       $this->subject = $this->sanitizeHeaderString($this->subject);
+                       $this->fromName = $valueList['from_name'] ? $valueList['from_name'] : ($valueList['name'] ? $valueList['name'] : '');
+                       $this->fromName = $this->sanitizeHeaderString($this->fromName);
+                       $this->replyToName = $valueList['replyto_name'] ? $valueList['replyto_name'] : $this->fromName;
+                       $this->replyToName = $this->sanitizeHeaderString($this->replyToName);
+                       $this->organisation = $valueList['organisation'] ? $valueList['organisation'] : '';
+                       $this->organisation = $this->sanitizeHeaderString($this->organisation);
+                       $this->fromAddress = $valueList['from_email'] ? $valueList['from_email'] : ($valueList['email'] ? $valueList['email'] : '');
+                       if (!Utility\GeneralUtility::validEmail($this->fromAddress)) {
+                               $this->fromAddress = Utility\MailUtility::getSystemFromAddress();
+                               $this->fromName = Utility\MailUtility::getSystemFromName();
+                       }
+                       $this->replyToAddress = $valueList['replyto_email'] ? $valueList['replyto_email'] : $this->fromAddress;
+                       $this->priority = $valueList['priority'] ? Utility\MathUtility::forceIntegerInRange($valueList['priority'], 1, 5) : 3;
+                       // Auto responder
+                       $this->autoRespondMessage = trim($valueList['auto_respond_msg']) && $this->fromAddress ? trim($valueList['auto_respond_msg']) : '';
+                       if ($this->autoRespondMessage !== '') {
+                               // Check if the value of the auto responder message has been modified with evil intentions
+                               $autoRespondChecksum = $valueList['auto_respond_checksum'];
+                               $correctHmacChecksum = Utility\GeneralUtility::hmac($this->autoRespondMessage, 'content_form');
+                               if ($autoRespondChecksum !== $correctHmacChecksum) {
+                                       Utility\GeneralUtility::sysLog('Possible misuse of DataSubmissionController auto respond method. Subject: ' . $valueList['subject'], 'Core', Utility\GeneralUtility::SYSLOG_SEVERITY_ERROR);
+                                       return;
+                               } else {
+                                       $this->autoRespondMessage = $this->sanitizeHeaderString($this->autoRespondMessage);
+                               }
+                       }
+                       $plainTextContent = '';
+                       $htmlContent = '<table border="0" cellpadding="2" cellspacing="2">';
+                       // Runs through $V and generates the mail
+                       if (is_array($valueList)) {
+                               foreach ($valueList as $key => $val) {
+                                       if (!Utility\GeneralUtility::inList($this->reserved_names, $key)) {
+                                               $space = strlen($val) > 60 ? LF : '';
+                                               $val = is_array($val) ? implode($val, LF) : $val;
+                                               // Convert form data from renderCharset to mail charset (HTML may use entities)
+                                               $plainTextValue = $val;
+                                               $HtmlValue = htmlspecialchars($val);
+                                               $plainTextContent .= strtoupper($key) . ':  ' . $space . $plainTextValue . LF . $space;
+                                               $htmlContent .= '<tr><td bgcolor="#eeeeee"><font face="Verdana" size="1"><strong>' . strtoupper($key) . '</strong></font></td><td bgcolor="#eeeeee"><font face="Verdana" size="1">' . nl2br($HtmlValue) . '&nbsp;</font></td></tr>';
+                                       }
+                               }
+                       }
+                       $htmlContent .= '</table>';
+                       $this->plainContent = $plainTextContent;
+                       if ($valueList['html_enabled']) {
+                               $this->mailMessage->setBody($htmlContent, 'text/html', $this->characterSet);
+                               $this->mailMessage->addPart($plainTextContent, 'text/plain', $this->characterSet);
+                       } else {
+                               $this->mailMessage->setBody($plainTextContent, 'text/plain', $this->characterSet);
+                       }
+                       for ($a = 0; $a < 10; $a++) {
+                               $variableName = 'attachment' . ($a ?: '');
+                               if (!isset($_FILES[$variableName])) {
+                                       continue;
+                               }
+
+                               if ($_FILES[$variableName]['error'] !== UPLOAD_ERR_OK) {
+                                       Utility\GeneralUtility::sysLog(
+                                               'Error in uploaded file in DataSubmissionController: temporary file "' .
+                                                       $_FILES[$variableName]['tmp_name'] . '" ("' . $_FILES[$variableName]['name'] . '") Error code: ' .
+                                                       $_FILES[$variableName]['error'],
+                                               'Core',
+                                               Utility\GeneralUtility::SYSLOG_SEVERITY_ERROR
+                                       );
+                                       continue;
+                               }
+
+                               if (!is_uploaded_file($_FILES[$variableName]['tmp_name'])) {
+                                       Utility\GeneralUtility::sysLog(
+                                               'Possible abuse of DataSubmissionController: temporary file "' . $_FILES[$variableName]['tmp_name'] .
+                                                       '" ("' . $_FILES[$variableName]['name'] . '") was not an uploaded file.',
+                                               'Core',
+                                               Utility\GeneralUtility::SYSLOG_SEVERITY_ERROR
+                                       );
+                                       continue;
+                               }
+
+                               $theFile = Utility\GeneralUtility::upload_to_tempfile($_FILES[$variableName]['tmp_name']);
+                               $theName = $_FILES[$variableName]['name'];
+                               if ($theFile && file_exists($theFile)) {
+                                       if (filesize($theFile) < $GLOBALS['TYPO3_CONF_VARS']['FE']['formmailMaxAttachmentSize']) {
+                                               $this->mailMessage->attach(\Swift_Attachment::fromPath($theFile)->setFilename($theName));
+                                       }
+                               }
+                               $this->temporaryFiles[] = $theFile;
+                       }
+                       $from = $this->fromName ? array($this->fromAddress => $this->fromName) : array($this->fromAddress);
+                       $this->recipient = $this->parseAddresses($valueList['recipient']);
+                       $this->mailMessage->setSubject($this->subject)->setFrom($from)->setTo($this->recipient)->setPriority($this->priority);
+                       $replyTo = $this->replyToName ? array($this->replyToAddress => $this->replyToName) : array($this->replyToAddress);
+                       $this->mailMessage->setReplyTo($replyTo);
+                       $this->mailMessage->getHeaders()->addTextHeader('Organization', $this->organisation);
+                       if ($valueList['recipient_copy']) {
+                               $this->mailMessage->setCc($this->parseAddresses($valueList['recipient_copy']));
+                       }
+                       $this->mailMessage->setCharset($this->characterSet);
+                       // Ignore target encoding. This is handled automatically by Swift Mailer and overriding the defaults
+                       // is not worth the trouble
+                       // Log dirty header lines
+                       if ($this->dirtyHeaders) {
+                               Utility\GeneralUtility::sysLog('Possible misuse of DataSubmissionController: see TYPO3 devLog', 'Core', Utility\GeneralUtility::SYSLOG_SEVERITY_ERROR);
+                               if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_DLOG']) {
+                                       Utility\GeneralUtility::devLog('DataSubmissionController: ' . Utility\GeneralUtility::arrayToLogString($this->dirtyHeaders, '', 200), 'Core', 3);
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Checks string for suspicious characters
+        *
+        * @param string $string String to check
+        * @return string Valid or empty string
+        */
+       protected function sanitizeHeaderString($string) {
+               $pattern = '/[\\r\\n\\f\\e]/';
+               if (preg_match($pattern, $string) > 0) {
+                       $this->dirtyHeaders[] = $string;
+                       $string = '';
+               }
+               return $string;
+       }
+
+       /**
+        * Parses mailbox headers and turns them into an array.
+        *
+        * Mailbox headers are a comma separated list of 'name <email@example.org' combinations or plain email addresses (or a mix
+        * of these).
+        * The resulting array has key-value pairs where the key is either a number (no display name in the mailbox header) and the
+        * value is the email address, or the key is the email address and the value is the display name.
+        *
+        * @param string $rawAddresses Comma separated list of email addresses (optionally with display name)
+        * @return array Parsed list of addresses.
+        */
+       protected function parseAddresses($rawAddresses = '') {
+               /** @var $addressParser \TYPO3\CMS\Core\Mail\Rfc822AddressesParser */
+               $addressParser = Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Mail\Rfc822AddressesParser::class, $rawAddresses);
+               $addresses = $addressParser->parseAddressList();
+               $addressList = array();
+               foreach ($addresses as $address) {
+                       if ($address->personal) {
+                               // Item with name found ( name <email@example.org> )
+                               $addressList[$address->mailbox . '@' . $address->host] = $address->personal;
+                       } else {
+                               // Item without name found ( email@example.org )
+                               $addressList[] = $address->mailbox . '@' . $address->host;
+                       }
+               }
+               return $addressList;
+       }
+
+       /**
+        * Sends the actual mail and handles autorespond message
+        *
+        * @return bool
+        */
+       public function sendTheMail() {
+               // Sending the mail requires the recipient and message to be set.
+               if (!$this->mailMessage->getTo() || !trim($this->mailMessage->getBody())) {
+                       return FALSE;
+               }
+               $this->mailMessage->send();
+               // Auto response
+               if ($this->autoRespondMessage) {
+                       $theParts = explode('/', $this->autoRespondMessage, 2);
+                       $theParts[0] = str_replace('###SUBJECT###', $this->subject, $theParts[0]);
+                       $theParts[1] = str_replace(
+                               array('/', '###MESSAGE###'),
+                               array(LF, $this->plainContent),
+                               $theParts[1]
+                       );
+                       /** @var $autoRespondMail \TYPO3\CMS\Core\Mail\MailMessage */
+                       $autoRespondMail = Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Mail\MailMessage::class);
+                       $autoRespondMail->setTo($this->fromAddress)->setSubject($theParts[0])->setFrom($this->recipient)->setBody($theParts[1]);
+                       $autoRespondMail->send();
+               }
+               return $this->mailMessage->isSent();
+       }
+
+       /**
+        * Do some cleanup at the end (deleting attachment files)
+        */
+       public function __destruct() {
+               foreach ($this->temporaryFiles as $file) {
+                       if (Utility\GeneralUtility::isAllowedAbsPath($file) && Utility\GeneralUtility::isFirstPartOfStr($file, PATH_site . 'typo3temp/upload_temp_')) {
+                               Utility\GeneralUtility::unlink_tempfile($file);
+                       }
+               }
+       }
+
+}
diff --git a/typo3/sysext/compatibility6/Classes/Controller/Wizard/FormsController.php b/typo3/sysext/compatibility6/Classes/Controller/Wizard/FormsController.php
new file mode 100644 (file)
index 0000000..97585a1
--- /dev/null
@@ -0,0 +1,871 @@
+<?php
+namespace TYPO3\CMS\Compatibility6\Controller\Wizard;
+
+/*
+ * 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\Utility\BackendUtility;
+use TYPO3\CMS\Backend\Utility\IconUtility;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+
+/**
+ * API comments:
+ *
+ * The form wizard can help you to create forms - it allows you to create almost any kind of HTML form elements and in any order and amount.
+ *
+ * The format for the resulting configuration code can be either a line-based configuration. That can look like this:
+ *
+ * Your name: | *name=input | (input your name here!)
+ * Your Email: | *email=input
+ * Your address: | address=textarea,40,10
+ * Your Haircolor: | hair=radio |
+ * upload | attachment=file
+ * | quoted_printable=hidden | 0
+ * | formtype_mail=submit | Send form
+ * | html_enabled=hidden
+ * | subject=hidden | This is the subject
+ *
+ *
+ * Alternatively it can be XML. The same configuration from above looks like this in XML:
+ *
+ * <T3FormWizard>
+ * <n2>
+ * <type>input</type>
+ * <label>Your name:</label>
+ * <required>1</required>
+ * <fieldname>name</fieldname>
+ * <size></size>
+ * <max></max>
+ * <default>(input your name here!)</default>
+ * </n2>
+ * <n4>
+ * <type>input</type>
+ * <label>Your Email:</label>
+ * <required>1</required>
+ * <fieldname>email</fieldname>
+ * <size></size>
+ * <max></max>
+ * <default></default>
+ * </n4>
+ * <n6>
+ * <type>textarea</type>
+ * <label>Your address:</label>
+ * <fieldname>address</fieldname>
+ * <cols>40</cols>
+ * <rows>10</rows>
+ * <default></default>
+ * </n6>
+ * <n8>
+ * <type>radio</type>
+ * <label>Your Haircolor:</label>
+ * <fieldname>hair</fieldname>
+ * <options></options>
+ * </n8>
+ * <n10>
+ * <type>file</type>
+ * <label>upload</label>
+ * <fieldname>attachment</fieldname>
+ * <size></size>
+ * </n10>
+ * <n12>
+ * <type>hidden</type>
+ * <label></label>
+ * <fieldname>quoted_printable</fieldname>
+ * <default>0</default>
+ * </n12>
+ * <n2000>
+ * <fieldname>formtype_mail</fieldname>
+ * <type>submit</type>
+ * <default>Send form</default>
+ * </n2000>
+ * <n2002>
+ * <fieldname>html_enabled</fieldname>
+ * <type>hidden</type>
+ * </n2002>
+ * <n2004>
+ * <fieldname>subject</fieldname>
+ * <type>hidden</type>
+ * <default>This is the subject</default>
+ * </n2004>
+ * <n20>
+ * <content></content>
+ * </n20>
+ * </T3FormWizard>
+ *
+ *
+ * The XML/phpArray structure is the internal format of the wizard.
+ *
+ * @author Kasper Skårhøj <kasperYYYY@typo3.com>
+ */
+class FormsController extends \TYPO3\CMS\Backend\Controller\Wizard\AbstractWizardController {
+
+       /**
+        * document template object
+        *
+        * @var \TYPO3\CMS\Backend\Template\DocumentTemplate
+        */
+       public $doc;
+
+       /**
+        * Content accumulation for the module.
+        *
+        * @var string
+        */
+       public $content;
+
+       /**
+        * Used to numerate attachments automatically.
+        *
+        * @var int
+        */
+       public $attachmentCounter = 0;
+
+       /**
+        * If set, the string version of the content is interpreted/written as XML instead of
+        * the original linebased kind. This variable still needs binding to the wizard parameters
+        * - but support is ready!
+        *
+        * @var int
+        */
+       public $xmlStorage = 0;
+
+       /**
+        * Wizard parameters, coming from TCEforms linking to the wizard.
+        *
+        * @var array
+        */
+       public $P;
+
+       /**
+        * The array which is constantly submitted by the multidimensional form of this wizard.
+        *
+        * @var array
+        */
+       public $FORMCFG;
+
+       /**
+        * Indicates if the form is of a dedicated type, like "formtype_mail" (for tt_content element "Form")
+        *
+        * @var string
+        */
+       public $special;
+
+       /**
+        * Constructor
+        */
+       public function __construct() {
+               $this->getLanguageService()->includeLLFile('EXT:lang/locallang_wizards.xlf');
+               $GLOBALS['SOBE'] = $this;
+
+               $this->init();
+       }
+
+       /**
+        * Initialization the class
+        *
+        * @return void
+        */
+       protected function init() {
+               // GPvars:
+               $this->P = GeneralUtility::_GP('P');
+               $this->special = GeneralUtility::_GP('special');
+               $this->FORMCFG = GeneralUtility::_GP('FORMCFG');
+               // Setting options:
+               $this->xmlStorage = $this->P['params']['xmlOutput'];
+               // Document template object:
+               $this->doc = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Template\DocumentTemplate::class);
+               $this->doc->backPath = $this->getBackPath();
+               $this->doc->setModuleTemplate('EXT:compatibility6/Resources/Private/Templates/Wizard/Forms.html');
+               // Setting form tag:
+               list($rUri) = explode('#', GeneralUtility::getIndpEnv('REQUEST_URI'));
+               $this->doc->form = '<form action="' . htmlspecialchars($rUri) . '" method="post" name="wizardForm">';
+       }
+
+       /**
+        * Main function for rendering the form wizard HTML
+        *
+        * @return void
+        */
+       public function main() {
+               if ($this->P['table'] && $this->P['field'] && $this->P['uid']) {
+                       $this->content .= $this->doc->section($this->getLanguageService()->getLL('forms_title'), $this->formsWizard(), 0, 1);
+               } else {
+                       $this->content .= $this->doc->section($this->getLanguageService()->getLL('forms_title'), '<span class="typo3-red">' . $this->getLanguageService()->getLL('table_noData', 1) . '</span>', 0, 1);
+               }
+               // Setting up the buttons and markers for docheader
+               $docHeaderButtons = $this->getButtons();
+               $markers['CSH'] = $docHeaderButtons['csh'];
+               $markers['CONTENT'] = $this->content;
+               // Build the <body> for the module
+               $this->content = $this->doc->startPage('Form Wizard');
+               $this->content .= $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $markers);
+               $this->content .= $this->doc->endPage();
+               $this->content = $this->doc->insertStylesAndJS($this->content);
+       }
+
+       /**
+        * Outputting the accumulated content to screen
+        *
+        * @return void
+        */
+       public function printContent() {
+               echo $this->content;
+       }
+
+       /**
+        * Create the panel of buttons for submitting the form or otherwise perform operations.
+        *
+        * @return array All available buttons as an assoc. array
+        */
+       protected function getButtons() {
+               $buttons = array(
+                       'csh' => '',
+                       'csh_buttons' => '',
+                       'close' => '',
+                       'save' => '',
+                       'save_close' => '',
+                       'reload' => ''
+               );
+               if ($this->P['table'] && $this->P['field'] && $this->P['uid']) {
+                       // CSH
+                       $buttons['csh'] = BackendUtility::cshItem('xMOD_csh_corebe', 'wizard_forms_wiz');
+                       // CSH Buttons
+                       $buttons['csh_buttons'] = BackendUtility::cshItem('xMOD_csh_corebe', 'wizard_forms_wiz_buttons');
+                       // Close
+                       $buttons['close'] = '<a href="#" onclick="' . htmlspecialchars(('jumpToUrl(unescape(\'' . rawurlencode(GeneralUtility::sanitizeLocalUrl($this->P['returnUrl'])) . '\')); return false;')) . '">' . IconUtility::getSpriteIcon('actions-document-close', array('title' => $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:rm.closeDoc', TRUE))) . '</a>';
+                       // Save
+                       $buttons['save'] = '<input type="image" class="c-inputButton" name="savedok"' . IconUtility::skinImg($this->doc->backPath, 'gfx/savedok.gif') . ' title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveDoc', TRUE) . '" />';
+                       // Save & Close
+                       $buttons['save_close'] = '<input type="image" class="c-inputButton" name="saveandclosedok"' . IconUtility::skinImg($this->doc->backPath, 'gfx/saveandclosedok.gif') . ' title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveCloseDoc', TRUE) . '" />';
+                       // Reload
+                       $buttons['reload'] = '<input type="image" class="c-inputButton" name="_refresh"' . IconUtility::skinImg('', 'gfx/refresh_n.gif') . ' title="' . $this->getLanguageService()->getLL('forms_refresh', TRUE) . '" />';
+               }
+               return $buttons;
+       }
+
+       /**
+        * Draws the form wizard content
+        *
+        * @return string HTML content for the form.
+        */
+       public function formsWizard() {
+               if (!$this->checkEditAccess($this->P['table'], $this->P['uid'])) {
+                       throw new \RuntimeException('Wizard Error: No access', 1385807526);
+               }
+               // First, check the references by selecting the record:
+               $row = BackendUtility::getRecord($this->P['table'], $this->P['uid']);
+               if (!is_array($row)) {
+                       throw new \RuntimeException('Wizard Error: No reference to record', 1294587124);
+               }
+               // This will get the content of the form configuration code field to us - possibly
+               // cleaned up, saved to database etc. if the form has been submitted in the meantime.
+               $formCfgArray = $this->getConfigCode($row);
+               // Generation of the Form Wizards HTML code:
+               $content = $this->getFormHTML($formCfgArray, $row);
+               // Return content:
+               return $content;
+       }
+
+       /****************************
+        *
+        * Helper functions
+        *
+        ***************************/
+       /**
+        * Will get and return the configuration code string
+        * Will also save (and possibly redirect/exit) the content if a save button has been pressed
+        *
+        * @param array $row Current parent record row (passed by value!)
+        * @return array Configuration Array
+        * @access private
+        */
+       public function getConfigCode(&$row) {
+               // If some data has been submitted, then construct
+               if (isset($this->FORMCFG['c'])) {
+                       // Process incoming:
+                       $this->changeFunc();
+                       // Convert to string (either line based or XML):
+                       if ($this->xmlStorage) {
+                               // Convert the input array to XML:
+                               $bodyText = GeneralUtility::array2xml_cs($this->FORMCFG['c'], 'T3FormWizard');
+                               // Setting cfgArr directly from the input:
+                               $cfgArr = $this->FORMCFG['c'];
+                       } else {
+                               // Convert the input array to a string of configuration code:
+                               $bodyText = $this->cfgArray2CfgString($this->FORMCFG['c']);
+                               // Create cfgArr from the string based configuration - that way it is cleaned
+                               // up and any incompatibilities will be removed!
+                               $cfgArr = $this->cfgString2CfgArray($bodyText);
+                       }
+                       // If a save button has been pressed, then save the new field content:
+                       if ($_POST['savedok_x'] || $_POST['saveandclosedok_x']) {
+                               // Make TCEmain object:
+                               $tce = GeneralUtility::makeInstance(\TYPO3\CMS\Core\DataHandling\DataHandler::class);
+                               $tce->stripslashes_values = 0;
+                               // Put content into the data array:
+                               $data = array();
+                               $data[$this->P['table']][$this->P['uid']][$this->P['field']] = $bodyText;
+                               if ($this->special == 'formtype_mail') {
+                                       $data[$this->P['table']][$this->P['uid']]['subheader'] = $this->FORMCFG['recipient'];
+                               }
+                               // Perform the update:
+                               $tce->start($data, array());
+                               $tce->process_datamap();
+                               // Re-load the record content:
+                               $row = BackendUtility::getRecord($this->P['table'], $this->P['uid']);
+                               // If the save/close button was pressed, then redirect the screen:
+                               if ($_POST['saveandclosedok_x']) {
+                                       \TYPO3\CMS\Core\Utility\HttpUtility::redirect(GeneralUtility::sanitizeLocalUrl($this->P['returnUrl']));
+                               }
+                       }
+               } else {
+                       // If nothing has been submitted, load the $bodyText variable from the selected database row:
+                       if ($this->xmlStorage) {
+                               $cfgArr = GeneralUtility::xml2array($row[$this->P['field']]);
+                       } else {
+                               // Regular linebased form configuration:
+                               $cfgArr = $this->cfgString2CfgArray($row[$this->P['field']]);
+                       }
+                       $cfgArr = is_array($cfgArr) ? $cfgArr : array();
+               }
+               // Return configuration code:
+               return $cfgArr;
+       }
+
+       /**
+        * Creates the HTML for the Form Wizard:
+        *
+        * @param string $formCfgArray Form config array
+        * @param array $row Current parent record array
+        * @return string HTML for the form wizard
+        * @access private
+        */
+       public function getFormHTML($formCfgArray, $row) {
+               // Initialize variables:
+               $specParts = array();
+               $hiddenFields = array();
+               $tRows = array();
+               // Set header row:
+               $cells = array(
+                       $this->getLanguageService()->getLL('forms_preview', TRUE) . ':',
+                       $this->getLanguageService()->getLL('forms_element', TRUE) . ':',
+                       $this->getLanguageService()->getLL('forms_config', TRUE) . ':'
+               );
+               $tRows[] = '
+                       <tr class="bgColor2" id="typo3-formWizardHeader">
+                               <td>&nbsp;</td>
+                               <td><strong>' . implode('</strong></td>
+                               <td><strong>', $cells) . '</strong></td>
+                       </tr>';
+               // Traverse the number of form elements:
+               $k = 0;
+               foreach ($formCfgArray as $confData) {
+                       // Initialize:
+                       $cells = array();
+                       // If there is a configuration line which is active, then render it:
+                       if (!isset($confData['comment'])) {
+                               // Special parts:
+                               if ($this->special == 'formtype_mail' && GeneralUtility::inList('formtype_mail,subject,html_enabled', $confData['fieldname'])) {
+                                       $specParts[$confData['fieldname']] = $confData['default'];
+                               } else {
+                                       // Render title/field preview COLUMN
+                                       $cells[] = $confData['type'] != 'hidden' ? '<strong>' . htmlspecialchars($confData['label']) . '</strong>' : '';
+                                       // Render general type/title COLUMN:
+                                       $temp_cells = array();
+                                       // Field type selector:
+                                       $opt = array();
+                                       $opt[] = '<option value=""></option>';
+                                       $types = explode(',', 'input,textarea,select,check,radio,password,file,hidden,submit,property,label');
+                                       foreach ($types as $t) {
+                                               $opt[] = '
+                                                               <option value="' . $t . '"' . ($confData['type'] == $t ? ' selected="selected"' : '') . '>' . $this->getLanguageService()->getLL(('forms_type_' . $t), TRUE) . '</option>';
+                                       }
+                                       $temp_cells[$this->getLanguageService()->getLL('forms_type')] = '
+                                                       <select name="FORMCFG[c][' . ($k + 1) * 2 . '][type]">
+                                                               ' . implode('
+                                                               ', $opt) . '
+                                                       </select>';
+                                       // Title field:
+                                       if (!GeneralUtility::inList('hidden,submit', $confData['type'])) {
+                                               $temp_cells[$this->getLanguageService()->getLL('forms_label')] = '<input type="text"' . $this->doc->formWidth(15) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][label]" value="' . htmlspecialchars($confData['label']) . '" />';
+                                       }
+                                       // Required checkbox:
+                                       if (!GeneralUtility::inList('check,hidden,submit,label', $confData['type'])) {
+                                               $temp_cells[$this->getLanguageService()->getLL('forms_required')] = '<input type="checkbox" name="FORMCFG[c][' . ($k + 1) * 2 . '][required]" value="1"' . ($confData['required'] ? ' checked="checked"' : '') . ' title="' . $this->getLanguageService()->getLL('forms_required', TRUE) . '" />';
+                                       }
+                                       // Put sub-items together into table cell:
+                                       $cells[] = $this->formatCells($temp_cells);
+                                       // Render specific field configuration COLUMN:
+                                       $temp_cells = array();
+                                       // Fieldname
+                                       if ($this->special == 'formtype_mail' && $confData['type'] == 'file') {
+                                               $confData['fieldname'] = 'attachment' . ++$this->attachmentCounter;
+                                       }
+                                       if (!GeneralUtility::inList('label', $confData['type'])) {
+                                               $temp_cells[$this->getLanguageService()->getLL('forms_fieldName')] = '<input type="text"' . $this->doc->formWidth(10) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][fieldname]" value="' . htmlspecialchars($confData['fieldname']) . '" title="' . $this->getLanguageService()->getLL('forms_fieldName', TRUE) . '" />';
+                                       }
+                                       // Field configuration depending on the fields type:
+                                       switch ((string)$confData['type']) {
+                                               case 'textarea':
+                                                       $temp_cells[$this->getLanguageService()->getLL('forms_cols')] = '<input type="text"' . $this->doc->formWidth(5) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][cols]" value="' . htmlspecialchars($confData['cols']) . '" title="' . $this->getLanguageService()->getLL('forms_cols', TRUE) . '" />';
+                                                       $temp_cells[$this->getLanguageService()->getLL('forms_rows')] = '<input type="text"' . $this->doc->formWidth(5) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][rows]" value="' . htmlspecialchars($confData['rows']) . '" title="' . $this->getLanguageService()->getLL('forms_rows', TRUE) . '" />';
+                                                       $temp_cells[$this->getLanguageService()->getLL('forms_extra')] = '<input type="checkbox" name="FORMCFG[c][' . ($k + 1) * 2 . '][extra]" value="OFF"' . ($confData['extra'] == 'OFF' ? ' checked="checked"' : '') . ' title="' . $this->getLanguageService()->getLL('forms_extra', TRUE) . '" />';
+                                                       break;
+                                               case 'input':
+
+                                               case 'password':
+                                                       $temp_cells[$this->getLanguageService()->getLL('forms_size')] = '<input type="text"' . $this->doc->formWidth(5) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][size]" value="' . htmlspecialchars($confData['size']) . '" title="' . $this->getLanguageService()->getLL('forms_size', TRUE) . '" />';
+                                                       $temp_cells[$this->getLanguageService()->getLL('forms_max')] = '<input type="text"' . $this->doc->formWidth(5) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][max]" value="' . htmlspecialchars($confData['max']) . '" title="' . $this->getLanguageService()->getLL('forms_max', TRUE) . '" />';
+                                                       break;
+                                               case 'file':
+                                                       $temp_cells[$this->getLanguageService()->getLL('forms_size')] = '<input type="text"' . $this->doc->formWidth(5) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][size]" value="' . htmlspecialchars($confData['size']) . '" title="' . $this->getLanguageService()->getLL('forms_size', TRUE) . '" />';
+                                                       break;
+                                               case 'select':
+                                                       $temp_cells[$this->getLanguageService()->getLL('forms_size')] = '<input type="text"' . $this->doc->formWidth(5) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][size]" value="' . htmlspecialchars($confData['size']) . '" title="' . $this->getLanguageService()->getLL('forms_size', TRUE) . '" />';
+                                                       $temp_cells[$this->getLanguageService()->getLL('forms_autosize')] = '<input type="checkbox" name="FORMCFG[c][' . ($k + 1) * 2 . '][autosize]" value="1"' . ($confData['autosize'] ? ' checked="checked"' : '') . ' title="' . $this->getLanguageService()->getLL('forms_autosize', TRUE) . '" />';
+                                                       $temp_cells[$this->getLanguageService()->getLL('forms_multiple')] = '<input type="checkbox" name="FORMCFG[c][' . ($k + 1) * 2 . '][multiple]" value="1"' . ($confData['multiple'] ? ' checked="checked"' : '') . ' title="' . $this->getLanguageService()->getLL('forms_multiple', TRUE) . '" />';
+                                                       break;
+                                       }
+                                       // Field configuration depending on the fields type:
+                                       switch ((string)$confData['type']) {
+                                               case 'textarea':
+
+                                               case 'input':
+
+                                               case 'password':
+                                                       if (trim($confData['specialEval']) !== '') {
+                                                               $hiddenFields[] = '<input type="hidden" name="FORMCFG[c][' . ($k + 1) * 2 . '][specialEval]" value="' . htmlspecialchars($confData['specialEval']) . '" />';
+                                                       }
+                                                       break;
+                                       }
+                                       // Default data
+                                       if ($confData['type'] == 'select' || $confData['type'] == 'radio') {
+                                               $temp_cells[$this->getLanguageService()->getLL('forms_options')] = '<textarea ' . $this->doc->formWidth(15) . ' rows="4" name="FORMCFG[c][' . ($k + 1) * 2 . '][options]" title="' . $this->getLanguageService()->getLL('forms_options', TRUE) . '">' . GeneralUtility::formatForTextarea($confData['default']) . '</textarea>';
+                                       } elseif ($confData['type'] == 'check') {
+                                               $temp_cells[$this->getLanguageService()->getLL('forms_checked')] = '<input type="checkbox" name="FORMCFG[c][' . ($k + 1) * 2 . '][default]" value="1"' . (trim($confData['default']) ? ' checked="checked"' : '') . ' title="' . $this->getLanguageService()->getLL('forms_checked', TRUE) . '" />';
+                                       } elseif ($confData['type'] && $confData['type'] != 'file') {
+                                               $temp_cells[$this->getLanguageService()->getLL('forms_default')] = '<input type="text"' . $this->doc->formWidth(15) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][default]" value="' . htmlspecialchars($confData['default']) . '" title="' . $this->getLanguageService()->getLL('forms_default', TRUE) . '" />';
+                                       }
+                                       $cells[] = $confData['type'] ? $this->formatCells($temp_cells) : '';
+                                       // CTRL panel for an item (move up/down/around):
+                                       $ctrl = '';
+                                       $onClick = 'document.wizardForm.action+=\'#ANC_' . (($k + 1) * 2 - 2) . '\';';
+                                       $onClick = ' onclick="' . htmlspecialchars($onClick) . '"';
+                                       // @todo $inputStyle undefined
+                                       $brTag = $inputStyle ? '' : '<br />';
+                                       if ($k != 0) {
+                                               $ctrl .= '<input type="image" name="FORMCFG[row_up][' . ($k + 1) * 2 . ']"' . IconUtility::skinImg($this->doc->backPath, 'gfx/pil2up.gif', '') . $onClick . ' title="' . $this->getLanguageService()->getLL('table_up', TRUE) . '" />' . $brTag;
+                                       } else {
+                                               $ctrl .= '<input type="image" name="FORMCFG[row_bottom][' . ($k + 1) * 2 . ']"' . IconUtility::skinImg($this->doc->backPath, 'gfx/turn_up.gif', '') . $onClick . ' title="' . $this->getLanguageService()->getLL('table_bottom', TRUE) . '" />' . $brTag;
+                                       }
+                                       $ctrl .= '<input type="image" name="FORMCFG[row_remove][' . ($k + 1) * 2 . ']"' . IconUtility::skinImg($this->doc->backPath, 'gfx/garbage.gif', '') . $onClick . ' title="' . $this->getLanguageService()->getLL('table_removeRow', TRUE) . '" />' . $brTag;
+                                       // @todo $tLines undefined
+                                       if ($k + 1 != count($tLines)) {
+                                               $ctrl .= '<input type="image" name="FORMCFG[row_down][' . ($k + 1) * 2 . ']"' . IconUtility::skinImg($this->doc->backPath, 'gfx/pil2down.gif', '') . $onClick . ' title="' . $this->getLanguageService()->getLL('table_down', TRUE) . '" />' . $brTag;
+                                       } else {
+                                               $ctrl .= '<input type="image" name="FORMCFG[row_top][' . ($k + 1) * 2 . ']"' . IconUtility::skinImg($this->doc->backPath, 'gfx/turn_down.gif', '') . $onClick . ' title="' . $this->getLanguageService()->getLL('table_top', TRUE) . '" />' . $brTag;
+                                       }
+                                       $ctrl .= '<input type="image" name="FORMCFG[row_add][' . ($k + 1) * 2 . ']"' . IconUtility::skinImg($this->doc->backPath, 'gfx/add.gif', '') . $onClick . ' title="' . $this->getLanguageService()->getLL('table_addRow', TRUE) . '" />' . $brTag;
+                                       $ctrl = '<span class="c-wizButtonsV">' . $ctrl . '</span>';
+                                       // Finally, put together the full row from the generated content above:
+                                       $bgC = $confData['type'] ? ' class="bgColor5"' : '';
+                                       $tRows[] = '
+                                               <tr' . $bgC . '>
+                                                       <td><a name="ANC_' . ($k + 1) * 2 . '"></a>' . $ctrl . '</td>
+                                                       <td class="bgColor4">' . implode('</td>
+                                                       <td valign="top">', $cells) . '</td>
+                                               </tr>';
+                               }
+                       } else {
+                               $hiddenFields[] = '<input type="hidden" name="FORMCFG[c][' . ($k + 1) * 2 . '][comment]" value="' . htmlspecialchars($confData['comment']) . '" />';
+                       }
+                       // Increment counter:
+                       $k++;
+               }
+               // If the form is of the special type "formtype_mail" (used for tt_content elements):
+               if ($this->special == 'formtype_mail') {
+                       // Blank spacer:
+                       $tRows[] = '
+                               <tr>
+                                       <td colspan="4">&nbsp;</td>
+                               </tr>';
+                       // Header:
+                       $tRows[] = '
+                               <tr>
+                                       <td colspan="2" class="bgColor2">&nbsp;</td>
+                                       <td colspan="2" class="bgColor2"><strong>' . $this->getLanguageService()->getLL('forms_special_eform', TRUE) . ':</strong>' . BackendUtility::cshItem('xMOD_csh_corebe', 'wizard_forms_wiz_formmail_info') . '</td>
+                               </tr>';
+                       // "FORM type":
+                       $tRows[] = '
+                               <tr class="bgColor5">
+                                       <td>&nbsp;</td>
+                                       <td class="bgColor4">&nbsp;</td>
+                                       <td>' . $this->getLanguageService()->getLL('forms_eform_formtype_mail', TRUE) . ':</td>
+                                       <td>
+                                               <input type="hidden" name="FORMCFG[c][' . 1000 * 2 . '][fieldname]" value="formtype_mail" />
+                                               <input type="hidden" name="FORMCFG[c][' . 1000 * 2 . '][type]" value="submit" />
+                                               <input type="text"' . $this->doc->formWidth(15) . ' name="FORMCFG[c][' . 1000 * 2 . '][default]" value="' . htmlspecialchars($specParts['formtype_mail']) . '" />
+                                       </td>
+                               </tr>';
+                       // "Send HTML mail":
+                       $tRows[] = '
+                               <tr class="bgColor5">
+                                       <td>&nbsp;</td>
+                                       <td class="bgColor4">&nbsp;</td>
+                                       <td>' . $this->getLanguageService()->getLL('forms_eform_html_enabled', TRUE) . ':</td>
+                                       <td>
+                                               <input type="hidden" name="FORMCFG[c][' . 1001 * 2 . '][fieldname]" value="html_enabled" />
+                                               <input type="hidden" name="FORMCFG[c][' . 1001 * 2 . '][type]" value="hidden" />
+                                               <input type="checkbox" name="FORMCFG[c][' . 1001 * 2 . '][default]" value="1"' . ($specParts['html_enabled'] ? ' checked="checked"' : '') . ' />
+                                       </td>
+                               </tr>';
+                       // "Subject":
+                       $tRows[] = '
+                               <tr class="bgColor5">
+                                       <td>&nbsp;</td>
+                                       <td class="bgColor4">&nbsp;</td>
+                                       <td>' . $this->getLanguageService()->getLL('forms_eform_subject', TRUE) . ':</td>
+                                       <td>
+                                               <input type="hidden" name="FORMCFG[c][' . 1002 * 2 . '][fieldname]" value="subject" />
+                                               <input type="hidden" name="FORMCFG[c][' . 1002 * 2 . '][type]" value="hidden" />
+                                               <input type="text"' . $this->doc->formWidth(15) . ' name="FORMCFG[c][' . 1002 * 2 . '][default]" value="' . htmlspecialchars($specParts['subject']) . '" />
+                                       </td>
+                               </tr>';
+                       // Recipient:
+                       $tRows[] = '
+                               <tr class="bgColor5">
+                                       <td>&nbsp;</td>
+                                       <td class="bgColor4">&nbsp;</td>
+                                       <td>' . $this->getLanguageService()->getLL('forms_eform_recipient', TRUE) . ':</td>
+                                       <td>
+                                               <input type="text"' . $this->doc->formWidth(15) . ' name="FORMCFG[recipient]" value="' . htmlspecialchars($row['subheader']) . '" />
+                                       </td>
+                               </tr>';
+               }
+               $content = '';
+               // Implode all table rows into a string, wrapped in table tags.
+               $content .= '
+
+                       <!--
+                               Form wizard
+                       -->
+                       <table border="0" cellpadding="1" cellspacing="1" id="typo3-formwizard">
+                               ' . implode('', $tRows) . '
+                       </table>';
+               // Add hidden fields:
+               $content .= implode('', $hiddenFields);
+               // Return content:
+               return $content;
+       }
+
+       /**
+        * Detects if a control button (up/down/around/delete) has been pressed for an item and accordingly it will manipulate the internal FORMCFG array
+        *
+        * @return void
+        * @access private
+        */
+       public function changeFunc() {
+               if ($this->FORMCFG['row_remove']) {
+                       $kk = key($this->FORMCFG['row_remove']);
+                       $cmd = 'row_remove';
+               } elseif ($this->FORMCFG['row_add']) {
+                       $kk = key($this->FORMCFG['row_add']);
+                       $cmd = 'row_add';
+               } elseif ($this->FORMCFG['row_top']) {
+                       $kk = key($this->FORMCFG['row_top']);
+                       $cmd = 'row_top';
+               } elseif ($this->FORMCFG['row_bottom']) {
+                       $kk = key($this->FORMCFG['row_bottom']);
+                       $cmd = 'row_bottom';
+               } elseif ($this->FORMCFG['row_up']) {
+                       $kk = key($this->FORMCFG['row_up']);
+                       $cmd = 'row_up';
+               } elseif ($this->FORMCFG['row_down']) {
+                       $kk = key($this->FORMCFG['row_down']);
+                       $cmd = 'row_down';
+               }
+               if ($cmd && \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($kk)) {
+                       if (substr($cmd, 0, 4) == 'row_') {
+                               switch ($cmd) {
+                                       case 'row_remove':
+                                               unset($this->FORMCFG['c'][$kk]);
+                                               break;
+                                       case 'row_add':
+                                               $this->FORMCFG['c'][$kk + 1] = array();
+                                               break;
+                                       case 'row_top':
+                                               $this->FORMCFG['c'][1] = $this->FORMCFG['c'][$kk];
+                                               unset($this->FORMCFG['c'][$kk]);
+                                               break;
+                                       case 'row_bottom':
+                                               $this->FORMCFG['c'][1000000] = $this->FORMCFG['c'][$kk];
+                                               unset($this->FORMCFG['c'][$kk]);
+                                               break;
+                                       case 'row_up':
+                                               $this->FORMCFG['c'][$kk - 3] = $this->FORMCFG['c'][$kk];
+                                               unset($this->FORMCFG['c'][$kk]);
+                                               break;
+                                       case 'row_down':
+                                               $this->FORMCFG['c'][$kk + 3] = $this->FORMCFG['c'][$kk];
+                                               unset($this->FORMCFG['c'][$kk]);
+                                               break;
+                               }
+                               ksort($this->FORMCFG['c']);
+                       }
+               }
+       }
+
+       /**
+        * Converts the input array to a configuration code string
+        *
+        * @param array $cfgArr Array of form configuration (follows the input structure from the form wizard POST form)
+        * @return string The array converted into a string with line-based configuration.
+        * @see cfgString2CfgArray()
+        */
+       public function cfgArray2CfgString($cfgArr) {
+               // Initialize:
+               $inLines = array();
+               // Traverse the elements of the form wizard and transform the settings into configuration code.
+               foreach ($cfgArr as $vv) {
+                       // If "content" is found, then just pass it over.
+                       if ($vv['comment']) {
+                               $inLines[] = trim($vv['comment']);
+                       } else {
+                               // Begin to put together the single-line configuration code of this field:
+                               // Reset:
+                               $thisLine = array();
+                               // Set Label:
+                               $thisLine[0] = str_replace('|', '', $vv['label']);
+                               // Set Type:
+                               if ($vv['type']) {
+                                       $thisLine[1] = ($vv['required'] ? '*' : '') . str_replace(',', '', (($vv['fieldname'] ? $vv['fieldname'] . '=' : '') . $vv['type']));
+                                       // Default:
+                                       $tArr = array('', '', '', '', '', '');
+                                       switch ((string)$vv['type']) {
+                                               case 'textarea':
+                                                       if ((int)$vv['cols']) {
+                                                               $tArr[0] = (int)$vv['cols'];
+                                                       }
+                                                       if ((int)$vv['rows']) {
+                                                               $tArr[1] = (int)$vv['rows'];
+                                                       }
+                                                       if (trim($vv['extra'])) {
+                                                               $tArr[2] = trim($vv['extra']);
+                                                       }
+                                                       if ($vv['specialEval'] !== '') {
+                                                               // Preset blank default value so position 3 can get a value...
+                                                               $thisLine[2] = '';
+                                                               $thisLine[3] = $vv['specialEval'];
+                                                       }
+                                                       break;
+                                               case 'input':
+                                               case 'password':
+                                                       if ((int)$vv['size']) {
+                                                               $tArr[0] = (int)$vv['size'];
+                                                       }
+                                                       if ((int)$vv['max']) {
+                                                               $tArr[1] = (int)$vv['max'];
+                                                       }
+                                                       if ($vv['specialEval'] !== '') {
+                                                               // Preset blank default value so position 3 can get a value...
+                                                               $thisLine[2] = '';
+                                                               $thisLine[3] = $vv['specialEval'];
+                                                       }
+                                                       break;
+                                               case 'file':
+                                                       if ((int)$vv['size']) {
+                                                               $tArr[0] = (int)$vv['size'];
+                                                       }
+                                                       break;
+                                               case 'select':
+                                                       if ((int)$vv['size']) {
+                                                               $tArr[0] = (int)$vv['size'];
+                                                       }
+                                                       if ($vv['autosize']) {
+                                                               $tArr[0] = 'auto';
+                                                       }
+                                                       if ($vv['multiple']) {
+                                                               $tArr[1] = 'm';
+                                                       }
+                                                       break;
+                                       }
+                                       $tArr = $this->cleanT($tArr);
+                                       if (count($tArr)) {
+                                               $thisLine[1] .= ',' . implode(',', $tArr);
+                                       }
+                                       $thisLine[1] = str_replace('|', '', $thisLine[1]);
+                                       // Default:
+                                       if ($vv['type'] == 'select' || $vv['type'] == 'radio') {
+                                               $options = str_replace(',', '', $vv['options']);
+                                               $options = str_replace(
+                                                       array(CRLF, CR, LF),
+                                                       ', ',
+                                                       $options);
+                                               $thisLine[2] = $options;
+                                       } elseif ($vv['type'] == 'check') {
+                                               if ($vv['default']) {
+                                                       $thisLine[2] = 1;
+                                               }
+                                       } elseif (trim($vv['default']) !== '') {
+                                               $thisLine[2] = $vv['default'];
+                                       }
+                                       if (isset($thisLine[2])) {
+                                               $thisLine[2] = str_replace('|', '', $thisLine[2]);
+                                       }
+                               }
+                               // Compile the final line:
+                               $inLines[] = preg_replace('/[
+
+]*/', '', implode(' | ', $thisLine));
+                       }
+               }
+               // Finally, implode the lines into a string, and return it:
+               return implode(LF, $inLines);
+       }
+
+       /**
+        * Converts the input configuration code string into an array
+        *
+        * @param string $cfgStr Configuration code
+        * @return array Configuration array
+        * @see cfgArray2CfgString()
+        */
+       public function cfgString2CfgArray($cfgStr) {
+               // Traverse the number of form elements:
+               $tLines = explode(LF, $cfgStr);
+               $attachmentCounter = 0;
+               foreach ($tLines as $k => $v) {
+                       // Initialize:
+                       $confData = array();
+                       $val = trim($v);
+                       // Accept a line as configuration if a) it is blank(! - because blank lines indicates new,
+                       // unconfigured fields) or b) it is NOT a comment.
+                       if (!$val || strcspn($val, '#/')) {
+                               // Split:
+                               $parts = GeneralUtility::trimExplode('|', $val);
+                               // Label:
+                               $confData['label'] = trim($parts[0]);
+                               // Field:
+                               $fParts = GeneralUtility::trimExplode(',', $parts[1]);
+                               $fParts[0] = trim($fParts[0]);
+                               if ($fParts[0][0] === '*') {
+                                       $confData['required'] = 1;
+                                       $fParts[0] = substr($fParts[0], 1);
+                               }
+                               $typeParts = GeneralUtility::trimExplode('=', $fParts[0]);
+                               $confData['type'] = trim(strtolower(end($typeParts)));
+                               if ($confData['type']) {
+                                       if (count($typeParts) == 1) {
+                                               $confData['fieldname'] = substr(preg_replace('/[^a-zA-Z0-9_]/', '', str_replace(' ', '_', trim($parts[0]))), 0, 30);
+                                               // Attachment names...
+                                               if ($confData['type'] == 'file') {
+                                                       $confData['fieldname'] = 'attachment' . $attachmentCounter;
+                                                       $attachmentCounter = (int)$attachmentCounter + 1;
+                                               }
+                                       } else {
+                                               $confData['fieldname'] = str_replace(' ', '_', trim($typeParts[0]));
+                                       }
+                                       switch ((string)$confData['type']) {
+                                               case 'select':
+                                               case 'radio':
+                                                       $confData['default'] = implode(LF, GeneralUtility::trimExplode(',', $parts[2]));
+                                                       break;
+                                               default:
+                                                       $confData['default'] = trim($parts[2]);
+                                       }
+                                       // Field configuration depending on the fields type:
+                                       switch ((string)$confData['type']) {
+                                               case 'textarea':
+                                                       $confData['cols'] = $fParts[1];
+                                                       $confData['rows'] = $fParts[2];
+                                                       $confData['extra'] = strtoupper($fParts[3]) == 'OFF' ? 'OFF' : '';
+                                                       $confData['specialEval'] = trim($parts[3]);
+                                                       break;
+                                               case 'input':
+                                               case 'password':
+                                                       $confData['size'] = $fParts[1];
+                                                       $confData['max'] = $fParts[2];
+                                                       $confData['specialEval'] = trim($parts[3]);
+                                                       break;
+                                               case 'file':
+                                                       $confData['size'] = $fParts[1];
+                                                       break;
+                                               case 'select':
+                                                       $confData['size'] = (int)$fParts[1] ? $fParts[1] : '';
+                                                       $confData['autosize'] = strtolower(trim($fParts[1])) === 'auto' ? 1 : 0;
+                                                       $confData['multiple'] = strtolower(trim($fParts[2])) === 'm' ? 1 : 0;
+                                                       break;
+                                       }
+                               }
+                       } else {
+                               // No configuration, only a comment:
+                               $confData = array(
+                                       'comment' => $val
+                               );
+                       }
+                       // Adding config array:
+                       $cfgArr[] = $confData;
+               }
+               // Return cfgArr
+               return $cfgArr;
+       }
+
+       /**
+        * Removes any "trailing elements" in the array which consists of whitespace (little like trim() does for strings, so this does for arrays)
+        *
+        * @param array $tArr Single dim array
+        * @return array Processed array
+        * @access private
+        */
+       public function cleanT($tArr) {
+               for ($a = count($tArr); $a > 0; $a--) {
+                       if ((string)$tArr[$a - 1] !== '') {
+                               break;
+                       } else {
+                               unset($tArr[$a - 1]);
+                       }
+               }
+               return $tArr;
+       }
+
+       /**
+        * Wraps items in $fArr in table cells/rows, displaying them vertically.
+        *
+        * @param array $fArr Array of label/HTML pairs.
+        * @return string HTML table
+        * @access private
+        */
+       public function formatCells($fArr) {
+               // Traverse the elements in $fArr and wrap them in table cells:
+               $lines = array();
+               foreach ($fArr as $l => $c) {
+                       $lines[] = '
+                               <tr>
+                                       <td nowrap="nowrap">' . htmlspecialchars(($l . ':')) . '&nbsp;</td>
+                                       <td>' . $c . '</td>
+                               </tr>';
+               }
+               // Add a cell which will set a minimum width:
+               $lines[] = '
+                       <tr>
+                               <td nowrap="nowrap"><img src="clear.gif" width="70" height="1" alt="" /></td>
+                               <td></td>
+                       </tr>';
+               // Wrap in table and return:
+               return '
+                       <table border="0" cellpadding="0" cellspacing="0">
+                               ' . implode('', $lines) . '
+                       </table>';
+       }
+
+}
diff --git a/typo3/sysext/compatibility6/Classes/Hooks/PageLayoutView/MailformPreviewRenderer.php b/typo3/sysext/compatibility6/Classes/Hooks/PageLayoutView/MailformPreviewRenderer.php
new file mode 100644 (file)
index 0000000..a22aaf1
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+namespace TYPO3\CMS\Compatibility6\Hooks\PageLayoutView;
+
+/*
+ * 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!
+ */
+
+/**
+ * Contains a preview rendering for the page module of
+ * CType="mailform"
+ */
+class MailformPreviewRenderer implements \TYPO3\CMS\Backend\View\PageLayoutViewDrawItemHookInterface {
+
+       /**
+        * Preprocesses the preview rendering of a content element of type "mailform"
+        *
+        * @param \TYPO3\CMS\Backend\View\PageLayoutView $parentObject Calling parent object
+        * @param bool $drawItem Whether to draw the item using the default functionality
+        * @param string $headerContent Header content
+        * @param string $itemContent Item content
+        * @param array $row Record row of tt_content
+        *
+        * @return void
+        */
+       public function preProcess(\TYPO3\CMS\Backend\View\PageLayoutView &$parentObject, &$drawItem, &$headerContent, &$itemContent, array &$row) {
+               if ($row['CType'] === 'mailform') {
+                       $itemContent = $parentObject->linkEditContent($parentObject->renderText($row['bodytext']), $row) . '<br />';
+                       $drawItem = FALSE;
+               }
+       }
+}
diff --git a/typo3/sysext/compatibility6/Classes/Utility/FormUtility.php b/typo3/sysext/compatibility6/Classes/Utility/FormUtility.php
new file mode 100644 (file)
index 0000000..4aea8ce
--- /dev/null
@@ -0,0 +1,77 @@
+<?php
+namespace TYPO3\CMS\Compatibility6\Utility;
+
+/*
+ * 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!
+ */
+
+/**
+ * Contains some functions that were been previously found
+ * inside TypoScriptFrontendController
+ * but are shared between FormContentObject and TypoScriptFrontendController
+ *
+ */
+class FormUtility {
+
+       /**
+        * En/decodes strings with lightweight encryption and a hash containing the server encryptionKey (salt)
+        * Can be used for authentication of information sent from server generated pages back to the server to establish that the server generated the page. (Like hidden fields with recipient mail addresses)
+        * Encryption is mainly to avoid spam-bots to pick up information.
+        *
+        * @param string $string Input string to en/decode
+        * @param bool $decode If set, string is decoded, not encoded.
+        * @return string encoded/decoded version of $string
+        */
+       public static function codeString($string, $decode = FALSE) {
+               if ($decode) {
+                       list($md5Hash, $str) = explode(':', $string, 2);
+                       $newHash = substr(md5($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] . ':' . $str), 0, 10);
+                       if ($md5Hash === $newHash) {
+                               $str = base64_decode($str);
+                               $str = self::roundTripCryptString($str);
+                               return $str;
+                       } else {
+                               return FALSE;
+                       }
+               } else {
+                       $str = $string;
+                       $str = self::roundTripCryptString($str);
+                       $str = base64_encode($str);
+                       $newHash = substr(md5($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] . ':' . $str), 0, 10);
+                       return $newHash . ':' . $str;
+               }
+       }
+
+       /**
+        * Encrypts a strings by XOR'ing all characters with a key derived from the
+        * TYPO3 encryption key.
+        *
+        * Using XOR means that the string can be decrypted by simply calling the
+        * function again - just like rot-13 works (but in this case for ANY byte
+        * value).
+        *
+        * @param string $string String to crypt, may be empty
+        * @return string binary crypt string, will have the same length as $string
+        */
+       protected static function roundTripCryptString($string) {
+               $out = '';
+               $cleartextLength = strlen($string);
+               $key = sha1($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']);
+               $keyLength = strlen($key);
+               for ($a = 0; $a < $cleartextLength; $a++) {
+                       $xorVal = ord($key[$a % $keyLength]);
+                       $out .= chr(ord($string[$a]) ^ $xorVal);
+               }
+               return $out;
+       }
+
+}
diff --git a/typo3/sysext/compatibility6/Configuration/TCA/Overrides/tt_content.php b/typo3/sysext/compatibility6/Configuration/TCA/Overrides/tt_content.php
new file mode 100644 (file)
index 0000000..d2bad6a
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+defined('TYPO3_MODE') or die();
+
+if (!\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('form')) {
+
+       $GLOBALS['TCA']['tt_content']['ctrl']['typeicon_classes']['mailform'] = 'mimetypes-x-content-form';
+       $GLOBALS['TCA']['tt_content']['ctrl']['typeicons']['mailform'] = 'tt_content_form.gif';
+       $GLOBALS['TCA']['tt_content']['columns']['bodytext']['config']['wizards']['forms'] = array(
+               'notNewRecords' => 1,
+               'enableByTypeConfig' => 1,
+               'type' => 'script',
+               'title' => 'LLL:EXT:cms/locallang_ttc.xlf:bodytext.W.forms',
+               'icon' => 'wizard_forms.gif',
+               'module' => array(
+                       'name' => 'wizard_forms',
+                       'urlParameters' => array(
+                               'special' => 'formtype_mail'
+                       )
+               ),
+               'params' => array(
+                       'xmlOutput' => 0
+               )
+       );
+
+       \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTcaSelectItem('tt_content', 'CType', array(
+                       'LLL:EXT:cms/locallang_ttc.xlf:CType.I.8',
+                       'mailform',
+                       'i/tt_content_form.gif'
+               ),
+               'search',
+               'before'
+       );
+
+       // set up the fields
+       $GLOBALS['TCA']['tt_content']['types']['mailform'] = array(
+               'showitem' => '
+                       --palette--;LLL:EXT:cms/locallang_ttc.xlf:palette.general;general,
+                       --palette--;LLL:EXT:cms/locallang_ttc.xlf:palette.header;header,
+                       bodytext;LLL:EXT:cms/locallang_ttc.xlf:bodytext.ALT.mailform_formlabel;;nowrap:wizards[forms],
+               --div--;LLL:EXT:cms/locallang_ttc.xlf:tabs.appearance,
+                       --palette--;LLL:EXT:cms/locallang_ttc.xlf:palette.frames;frames,
+               --div--;LLL:EXT:cms/locallang_ttc.xlf:tabs.access,
+                       --palette--;LLL:EXT:cms/locallang_ttc.xlf:palette.visibility;visibility,
+                       --palette--;LLL:EXT:cms/locallang_ttc.xlf:palette.access;access,
+               --div--;LLL:EXT:cms/locallang_ttc.xlf:tabs.behaviour,
+                       --palette--;LLL:EXT:cms/locallang_ttc.xlf:palette.mailform;mailform,
+               --div--;LLL:EXT:cms/locallang_ttc.xlf:tabs.extended'
+       );
+       $GLOBALS['TCA']['tt_content']['palettes']['mailform'] = array(
+                       'showitem' => 'pages;LLL:EXT:cms/locallang_ttc.xlf:pages.ALT.mailform, --linebreak--, subheader;LLL:EXT:cms/locallang_ttc.xlf:subheader.ALT.mailform_formlabel',
+                       'canNotCollapse' => 1
+       );
+}
diff --git a/typo3/sysext/compatibility6/Configuration/TypoScript/Form/constants.txt b/typo3/sysext/compatibility6/Configuration/TypoScript/Form/constants.txt
new file mode 100644 (file)
index 0000000..922c787
--- /dev/null
@@ -0,0 +1,7 @@
+styles.content.mailform {
+  target = {$PAGE_TARGET}
+    # cat=content/cMailform; type=; label= Message, Formmail OK: This is the message (if any) that is popped-up (JavaScript) when a user clicks "send" with an email-form
+  goodMess =
+    # cat=content/cMailform; type=; label= Message, Formmail Missing: This is the message that is popped-up when a user has NOT filled required fields in an email-form
+  badMess =
+}
diff --git a/typo3/sysext/compatibility6/Configuration/TypoScript/Form/setup.txt b/typo3/sysext/compatibility6/Configuration/TypoScript/Form/setup.txt
new file mode 100644 (file)
index 0000000..83a4d9d
--- /dev/null
@@ -0,0 +1,56 @@
+# Hide subheader for old style form element (it is used for recipient mail)
+lib.stdheader.20.if {
+       isFalse = 0
+       isFalse.override = 1
+       isFalse.override {
+               if.equals.field = CType
+               if.value = mailform
+       }
+}
+
+# ******************
+# CType: mailform
+# ******************
+tt_content.mailform = COA
+tt_content.mailform.10 = < lib.stdheader
+tt_content.mailform.20 = FORM
+tt_content.mailform.20 {
+       useDefaultContentObject = 1
+       accessibility = 1
+       noWrapAttr = 1
+       formName = mailform
+       dontMd5FieldNames = 1
+       layout = <div class="csc-mailform-field">###LABEL### ###FIELD###</div>
+       labelWrap.wrap = |
+       commentWrap.wrap = |
+       radioWrap.wrap = |<br />
+       radioWrap.accessibilityWrap = <fieldset###RADIO_FIELD_ID###><legend>###RADIO_GROUP_LABEL###</legend>|</fieldset>
+       REQ = 1
+       REQ.labelWrap.wrap = |
+       COMMENT.layout = <div class="csc-mailform-label">###LABEL###</div>
+       RADIO.layout = <div class="csc-mailform-field">###LABEL### <span class="csc-mailform-radio">###FIELD###</span></div>
+       LABEL.layout = <div class="csc-mailform-field">###LABEL### <span class="csc-mailform-label">###FIELD###</span></div>
+       target < lib.parseTarget
+       target =
+       target.override = {$styles.content.mailform.target}
+       goodMess = {$styles.content.mailform.goodMess}
+       badMess = {$styles.content.mailform.badMess}
+       redirect.field = pages
+       redirect.listNum = 0
+       recipient.field = subheader
+       data.field = bodytext
+       locationData = 1
+       hiddenFields.stdWrap.wrap = <div style="display:none;">|</div>
+
+       params.radio = class="csc-mailform-radio"
+       params.check = class="csc-mailform-check"
+       params.submit = class="csc-mailform-submit"
+
+       stdWrap.wrap = <fieldset class="csc-mailform"> | </fieldset>
+       stdWrap {
+               editIcons = tt_content: bodytext, pages, subheader
+               editIcons.iconTitle.data = LLL:EXT:css_styled_content/Resources/Private/Language/locallang.xlf:eIcon.form
+
+               prefixComment = 2 | Mail form inserted:
+       }
+}
index 074f65c..f48df32 100644 (file)
@@ -47,7 +47,7 @@ return array(
        'SC_wizard_add' => \TYPO3\CMS\Backend\Controller\Wizard\AddController::class,
        'SC_wizard_colorpicker' => \TYPO3\CMS\Backend\Controller\Wizard\ColorpickerController::class,
        'SC_wizard_edit' => \TYPO3\CMS\Backend\Controller\Wizard\EditController::class,
-       'SC_wizard_forms' => \TYPO3\CMS\Backend\Controller\Wizard\FormsController::class,
+       'SC_wizard_forms' => \TYPO3\CMS\Compatibility6\Controller\Wizard\FormsController::class,
        'SC_wizard_list' => \TYPO3\CMS\Backend\Controller\Wizard\ListController::class,
        'SC_wizard_rte' => \TYPO3\CMS\Backend\Controller\Wizard\RteController::class,
        'SC_wizard_table' => \TYPO3\CMS\Backend\Controller\Wizard\TableController::class,
@@ -945,7 +945,7 @@ return array(
        'tx_form_View_Wizard_Wizard' => \TYPO3\CMS\Form\View\Wizard\WizardView::class,
        'tslib_feUserAuth' => \TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication::class,
        't3lib_matchCondition_frontend' => \TYPO3\CMS\Frontend\Configuration\TypoScript\ConditionMatching\ConditionMatcher::class,
-       't3lib_formmail' => \TYPO3\CMS\Frontend\Controller\DataSubmissionController::class,
+       't3lib_formmail' => \TYPO3\CMS\Compatibility6\Controller\FormDataSubmissionController::class,
        'tslib_content_Abstract' => \TYPO3\CMS\Frontend\ContentObject\AbstractContentObject::class,
        'tslib_content_Case' => \TYPO3\CMS\Frontend\ContentObject\CaseContentObject::class,
        'tslib_content_ClearGif' => \TYPO3\CMS\Compatibility6\ContentObject\ClearGifContentObject::class,
@@ -967,7 +967,7 @@ return array(
        'tslib_content_Files' => \TYPO3\CMS\Frontend\ContentObject\FilesContentObject::class,
        'tslib_content_FlowPlayer' => \TYPO3\CMS\Frontend\ContentObject\FlowPlayerContentObject::class,
        'tslib_content_FluidTemplate' => \TYPO3\CMS\Frontend\ContentObject\FluidTemplateContentObject::class,
-       'tslib_content_Form' => \TYPO3\CMS\Frontend\ContentObject\FormContentObject::class,
+       'tslib_content_Form' => \TYPO3\CMS\Compatibility6\ContentObject\FormContentObject::class,
        'tslib_content_HierarchicalMenu' => \TYPO3\CMS\Frontend\ContentObject\HierarchicalMenuContentObject::class,
        'tslib_content_HorizontalRuler' => \TYPO3\CMS\Compatibility6\ContentObject\HorizontalRulerContentObject::class,
        'tslib_content_Image' => \TYPO3\CMS\Frontend\ContentObject\ImageContentObject::class,
@@ -1279,5 +1279,8 @@ return array(
        'TYPO3\\CMS\\Frontend\\ContentObject\\ContentTableContentObject' => \TYPO3\CMS\Compatibility6\ContentObject\ContentTableContentObject::class,
        'TYPO3\\CMS\\Frontend\\ContentObject\\OffsetTableContentObject' => \TYPO3\CMS\Compatibility6\ContentObject\OffsetTableContentObject::class,
        'TYPO3\\CMS\\Frontend\\ContentObject\\ColumnsContentObject' => \TYPO3\CMS\Compatibility6\ContentObject\ColumnsContentObject::class,
-       'TYPO3\\CMS\\Frontend\\ContentObject\\HorizontalRulerContentObject' => \TYPO3\CMS\Compatibility6\ContentObject\HorizontalRulerContentObject::class
+       'TYPO3\\CMS\\Frontend\\ContentObject\\HorizontalRulerContentObject' => \TYPO3\CMS\Compatibility6\ContentObject\HorizontalRulerContentObject::class,
+       'TYPO3\\CMS\\Frontend\\ContentObject\\FormContentObject' => \TYPO3\CMS\Compatibility6\ContentObject\FormContentObject::class,
+       'TYPO3\\CMS\\Frontend\\Controller\\Wizard\\FormsController' => \TYPO3\CMS\Compatibility6\Controller\Wizard\FormsController::class,
+       'TYPO3\\CMS\\Frontend\\Controller\\DataSubmissionController' => \TYPO3\CMS\Compatibility6\Controller\FormDataSubmissionController::class
 );
index 8dafca6..0b5e47c 100644 (file)
@@ -244,7 +244,7 @@ class SC_wizard_edit extends \TYPO3\CMS\Backend\Controller\Wizard\EditController
 /**
  * @deprecated since 6.0, removed since 7.0
  */
-class SC_wizard_forms extends \TYPO3\CMS\Backend\Controller\Wizard\FormsController {}
+class SC_wizard_forms extends \TYPO3\CMS\Compatibility6\Controller\Wizard\FormsController {}
 
 /**
  * @deprecated since 6.0, removed since 7.0
@@ -4714,7 +4714,7 @@ class t3lib_matchCondition_frontend extends \TYPO3\CMS\Frontend\Configuration\Ty
 /**
  * @deprecated since 6.0, removed since 7.0
  */
-class t3lib_formmail extends \TYPO3\CMS\Frontend\Controller\DataSubmissionController {}
+class t3lib_formmail extends \TYPO3\CMS\Compatibility6\Controller\FormDataSubmissionController {}
 
 /**
  * @deprecated since 6.0, removed since 7.0
@@ -4824,7 +4824,7 @@ class tslib_content_FluidTemplate extends \TYPO3\CMS\Frontend\ContentObject\Flui
 /**
  * @deprecated since 6.0, removed since 7.0
  */
-class tslib_content_Form extends \TYPO3\CMS\Frontend\ContentObject\FormContentObject {}
+class tslib_content_Form extends \TYPO3\CMS\Compatibility6\ContentObject\FormContentObject {}
 
 /**
  * @deprecated since 6.0, removed since 7.0
diff --git a/typo3/sysext/compatibility6/Modules/Wizards/FormsWizard/conf.php b/typo3/sysext/compatibility6/Modules/Wizards/FormsWizard/conf.php
new file mode 100644 (file)
index 0000000..9742c33
--- /dev/null
@@ -0,0 +1,5 @@
+<?php
+//required for mod.php
+$MCONF['name'] = 'wizard_forms';
+$MCONF['script'] = '_DISPATCH';
+$MCONF['access'] = '';
diff --git a/typo3/sysext/compatibility6/Modules/Wizards/FormsWizard/index.php b/typo3/sysext/compatibility6/Modules/Wizards/FormsWizard/index.php
new file mode 100644 (file)
index 0000000..af4eaf8
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/*
+ * 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!
+ */
+
+/**
+ * Wizard to help make forms (fx. for tt_content elements) of type 'form'.
+ */
+$formsController = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Compatibility6\Controller\Wizard\FormsController::class);
+$formsController->main();
+$formsController->printContent();
diff --git a/typo3/sysext/compatibility6/Resources/Private/Templates/Wizard/Forms.html b/typo3/sysext/compatibility6/Resources/Private/Templates/Wizard/Forms.html
new file mode 100644 (file)
index 0000000..6178b15
--- /dev/null
@@ -0,0 +1,70 @@
+<!-- ###FULLDOC### begin -->
+<div class="typo3-fullDoc">
+       <div id="typo3-docheader">
+               <div class="typo3-docheader-functions">
+                       <div class="left">###CSH###</div>
+                       <div class="right"></div>
+               </div>
+               <div class="typo3-docheader-buttons">
+                       <div class="left">###BUTTONLIST_LEFT###</div>
+                       <div class="right">###BUTTONLIST_RIGHT###</div>
+               </div>
+       </div>
+
+       <div id="typo3-docbody">
+               <div id="typo3-inner-docbody">
+                       ###CONTENT###
+               </div>
+       </div>
+</div>
+<!-- ###FULLDOC### end -->
+
+<!-- Grouping the icons on top -->
+
+<!-- ###BUTTON_GROUP_WRAP### -->
+<div class="buttongroup">###BUTTONS###</div>
+<!-- ###BUTTON_GROUP_WRAP### -->
+
+<!-- ###BUTTON_GROUPS_LEFT### -->
+<!-- ###BUTTON_GROUP1### -->###CLOSE###<!-- ###BUTTON_GROUP1### -->
+<!-- ###BUTTON_GROUP2### -->###SAVE######SAVE_CLOSE###<!-- ###BUTTON_GROUP2### -->
+<!-- ###BUTTON_GROUPS_LEFT### -->
+
+<!-- ###BUTTON_GROUPS_RIGHT### -->
+<!-- ###BUTTON_GROUP1### -->###RELOAD###<!-- ###BUTTON_GROUP1### -->
+<!-- ###BUTTON_GROUPS_RIGHT### -->
+<!-- ###FULLDOC### begin -->
+<div class="typo3-fullDoc">
+       <div id="typo3-docheader">
+               <div class="typo3-docheader-functions">
+                       <div class="left">###CSH###</div>
+                       <div class="right"></div>
+               </div>
+               <div class="typo3-docheader-buttons">
+                       <div class="left">###BUTTONLIST_LEFT###</div>
+                       <div class="right">###BUTTONLIST_RIGHT###</div>
+               </div>
+       </div>
+
+       <div id="typo3-docbody">
+               <div id="typo3-inner-docbody">
+                       ###CONTENT###
+               </div>
+       </div>
+</div>
+<!-- ###FULLDOC### end -->
+
+<!-- Grouping the icons on top -->
+
+<!-- ###BUTTON_GROUP_WRAP### -->
+<div class="buttongroup">###BUTTONS###</div>
+<!-- ###BUTTON_GROUP_WRAP### -->
+
+<!-- ###BUTTON_GROUPS_LEFT### -->
+<!-- ###BUTTON_GROUP1### -->###CLOSE###<!-- ###BUTTON_GROUP1### -->
+<!-- ###BUTTON_GROUP2### -->###SAVE######SAVE_CLOSE###<!-- ###BUTTON_GROUP2### -->
+<!-- ###BUTTON_GROUPS_LEFT### -->
+
+<!-- ###BUTTON_GROUPS_RIGHT### -->
+<!-- ###BUTTON_GROUP1### -->###RELOAD###<!-- ###BUTTON_GROUP1### -->
+<!-- ###BUTTON_GROUPS_RIGHT### -->
diff --git a/typo3/sysext/compatibility6/Resources/Public/JavaScript/jsfunc.validateform.js b/typo3/sysext/compatibility6/Resources/Public/JavaScript/jsfunc.validateform.js
new file mode 100644 (file)
index 0000000..0d810cd
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * 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!
+ */
+
+
+function validateForm(theFormname,theFieldlist,goodMess,badMess,emailMess) {
+       var formObject = document[theFormname];
+       if (!formObject) {
+               formObject = document.getElementById(theFormname);
+       }
+       if (formObject && theFieldlist) {
+               var index=1;
+               var theField = split(theFieldlist, ",", index);
+               var msg="";
+               var theEreg = '';
+               var theEregMsg = '';
+               var specialMode = '';
+               var theLabel, a;
+
+               while (theField) {
+                       theEreg = '';
+                       specialMode = '';
+
+                               // Check special modes:
+                       if (theField == '_EREG')        {       // EREG mode: _EREG,[error msg],[JS ereg],[fieldname],[field Label]
+                               specialMode = theField;
+
+                               index++;
+                               theEregMsg = split(theFieldlist, ",", index);
+                               index++;
+                               theEreg = split(theFieldlist, ",", index);
+                       } else if (theField == '_EMAIL') {
+                               specialMode = theField;
+                       }
+
+                               // Get real field name if special mode has been set:
+                       if (specialMode) {
+                               index++;
+                               theField = split(theFieldlist, ",", index);
+                       }
+
+                       index++;
+                       theLabel = split(theFieldlist, ",", index);
+                       theField = theField;
+                       if (formObject[theField]) {
+                               var fObj = formObject[theField];
+                               var type=fObj.type;
+                               if (!fObj.type) {
+                                       type="radio";
+                               }
+                               var value="";
+                               switch(type) {
+                                       case "text":
+                                       case "textarea":
+                                       case "password":
+                                       case "file":
+                                               value = fObj.value;
+                                       break;
+                                       case "select-one":
+                                               if (fObj.selectedIndex>=0) {
+                                                       value = fObj.options[fObj.selectedIndex].value;
+                                               }
+                                       break;
+                                       case "select-multiple":
+                                               var l=fObj.length;
+                                               for (a=0;a<l;a++) {
+                                                       if (fObj.options[a].selected) {
+                                                                value+= fObj.options[a].value;
+                                                       }
+                                               }
+                                       break;
+                                       case "radio":
+                                       case "checkbox":
+                                               var len=fObj.length;
+                                               if (len) {
+                                                       for (a=0;a<len;a++) {
+                                                               if (fObj[a].checked) {
+                                                                       value = fObj[a].value;
+                                                               }
+                                                       }
+                                               } else {
+                                                       if (fObj.checked) {
+                                                               value = fObj.value;
+                                                       }
+                                               }
+                                       break;
+                                       default:
+                                               value = 1;
+                               }
+
+                               switch(specialMode) {
+                                       case "_EMAIL":
+                                               var theRegEx_notValid = new RegExp("(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)", "gi");
+                                               var theRegEx_isValid = new RegExp("^.+\@[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,4}|[0-9]{1,3})$","");
+                                               if (!theRegEx_isValid.test(value))      {       // This part was supposed to be a part of the condition: " || theRegEx_notValid.test(value)" - but I couldn't make it work (Mozilla Firefox, linux) - Anyone knows why?
+                                                       msg+="\n"+theLabel+' ('+(emailMess ? emailMess : 'Email address not valid!')+')';
+                                               }
+                                       break;
+                                       case "_EREG":
+                                               var theRegEx_isValid = new RegExp(theEreg,"");
+                                               if (!theRegEx_isValid.test(value)) {
+                                                       msg+="\n"+theLabel+' ('+theEregMsg+')';
+                                               }
+                                       break;
+                                       default:
+                                               if (!value) {
+                                                       msg+="\n"+theLabel;
+                                               }
+                               }
+                       }
+                       index++;
+                       theField = split(theFieldlist, ",", index);
+               }
+               if (msg) {
+                       var theBadMess = badMess;
+                       if (!theBadMess) {
+                               theBadMess = "You must fill in these fields:";
+                       }
+                       theBadMess+="\n";
+                       alert(theBadMess+msg);
+                       return false;
+               } else {
+                       var theGoodMess = goodMess;
+                       if (theGoodMess) {
+                               alert(theGoodMess);
+                       }
+                       return true;
+               }
+       }
+}
+function split(theStr1, delim, index) {
+       var theStr = ''+theStr1;
+       var lengthOfDelim = delim.length;
+       var sPos = -lengthOfDelim;
+       var a, ePos;
+       if (index<1) {index=1;}
+       for (a=1; a<index; a++) {
+               sPos = theStr.indexOf(delim, sPos+lengthOfDelim);
+               if (sPos==-1)   {return null;}
+       }
+       ePos = theStr.indexOf(delim, sPos+lengthOfDelim);
+       if(ePos == -1)  {ePos = theStr.length;}
+       return (theStr.substring(sPos+lengthOfDelim,ePos));
+}
index 2368bac..1cb6f84 100644 (file)
@@ -10,4 +10,42 @@ if (TYPO3_MODE === 'FE') {
        $GLOBALS['TYPO3_CONF_VARS']['FE']['ContentObjects']['OTABLE']   = \TYPO3\CMS\Compatibility6\ContentObject\OffsetTableContentObject::class;
        $GLOBALS['TYPO3_CONF_VARS']['FE']['ContentObjects']['COLUMNS']  = \TYPO3\CMS\Compatibility6\ContentObject\ColumnsContentObject::class;
        $GLOBALS['TYPO3_CONF_VARS']['FE']['ContentObjects']['HRULER']   = \TYPO3\CMS\Compatibility6\ContentObject\HorizontalRulerContentObject::class;
+       $GLOBALS['TYPO3_CONF_VARS']['FE']['ContentObjects']['FORM']     = \TYPO3\CMS\Compatibility6\ContentObject\FormContentObject::class;
+
+       // Register a hook for data submission
+       $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['checkDataSubmission']['mailform'] = \TYPO3\CMS\Compatibility6\Controller\FormDataSubmissionController::class;
+}
+
+// Add Default TS for CType "mailform" after default content rendering
+\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTypoScript('compatibility6', 'constants', '<INCLUDE_TYPOSCRIPT: source="FILE:EXT:compatibility6/Configuration/TypoScript/Form/constants.txt">', 'defaultContentRendering');
+\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTypoScript('compatibility6', 'setup',     '<INCLUDE_TYPOSCRIPT: source="FILE:EXT:compatibility6/Configuration/TypoScript/Form/setup.txt">', 'defaultContentRendering');
+
+\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPageTSConfig('
+mod.wizards.newContentElement.wizardItems {
+               forms.header = LLL:EXT:cms/layout/locallang_db_new_content_el.xlf:forms
+               forms.elements.mailform {
+                       icon = gfx/c_wiz/mailform.gif
+                       title = LLL:EXT:cms/layout/locallang_db_new_content_el.xlf:forms_mail_title
+                       description = LLL:EXT:cms/layout/locallang_db_new_content_el.xlf:forms_mail_description
+                       tt_content_defValues {
+                               CType = mailform
+                               bodytext (
+# Example content:
+Name: | *name = input,40 | Enter your name here
+Email: | *email=input,40 |
+Address: | address=textarea,40,5 |
+Contact me: | tv=check | 1
+
+|formtype_mail = submit | Send form!
+|html_enabled=hidden | 1
+|subject=hidden| This is the subject
+                               )
+                       }
+               }
+               forms.show := addToList(mailform)
+       }
 }
+');
+
+// Add a for previewing tt_content elements of CType="mailform"
+$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['tt_content_drawItem']['mailform'] = \TYPO3\CMS\Compatibility6\Hooks\PageLayoutView\MailformPreviewRenderer::class;
index a0601bc..9ba50f3 100644 (file)
@@ -9,4 +9,11 @@ if (TYPO3_MODE === 'BE') {
                'LLL:EXT:compatibility6/Resources/Private/Language/wizards.xlf:mod_wizards'
        );
        \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addLLrefForTCAdescr('_MOD_web_func', 'EXT:compatibility6/Resources/Private/Language/wizards_csh.xlf');
+
+
+       // Register forms wizard
+       \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addModulePath(
+               'wizard_forms',
+               \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('compatibility6', 'Modules/Wizards/FormsWizard/')
+       );
 }
index 739b2bb..4441e65 100644 (file)
@@ -720,9 +720,9 @@ return array(
                'allowedTempPaths' => '',               // Additional paths allowed for temporary images. Used with imgResource. Eg. 'alttypo3temp/,another_temp_dir/';
                'debug' => FALSE,               // Boolean: If set, some debug HTML-comments may be output somewhere. Can also be set by TypoScript.
                'noPHPscriptInclude' => FALSE,          // Boolean: If set, PHP-scripts are not included by TypoScript configurations, unless they reside in the folders typo3/ext/, typo3/sysext/ or typo3conf/ext. This is a security option to ensure that users with template-access do not terrorize
-               'strictFormmail' => TRUE,               // Boolean: If set, the internal "formmail" feature in TYPO3 will send mail ONLY to recipients which has been encoded by the system itself. This protects against spammers misusing the formmailer.
-               'secureFormmail' => TRUE,               // Boolean: If set, the internal "formmail" feature in TYPO3 will send mail ONLY to the recipients that are defined in the form CE record. This protects against spammers misusing the formmailer.
-               'formmailMaxAttachmentSize' => 250000,          // Integer: Sets the maximum allowed size (in bytes) of attachments for the internal "formmail" feature.
+               'strictFormmail' => TRUE,               // Boolean: If set, the internal "formmail" feature in TYPO3 will send mail ONLY to recipients which has been encoded by the system itself. This protects against spammers misusing the formmailer. This option has been marked as deprecated since TYPO3 CMS 7 and will be removed in TYPO3 CMS 8.
+               'secureFormmail' => TRUE,               // Boolean: If set, the internal "formmail" feature in TYPO3 will send mail ONLY to the recipients that are defined in the form CE record. This protects against spammers misusing the formmailer. This option has been marked as deprecated since TYPO3 CMS 7 and will be removed in TYPO3 CMS 8.
+               'formmailMaxAttachmentSize' => 250000,          // Integer: Sets the maximum allowed size (in bytes) of attachments for the internal "formmail" feature.This option has been marked as deprecated since TYPO3 CMS 7 and will be removed in TYPO3 CMS 8.
                'compressionLevel' => 0,                // Integer: Determines output compression of FE output. Makes output smaller but slows down the page generation depending on the compression level. Requires zlib in your PHP installation. Range 1-9, where 1 is least compression and 9 is greatest compression. 'true' as value will set the compression based on the PHP default settings (usually 5). Suggested and most optimal value is 5.
                'pageNotFound_handling' => '',          // <p>How TYPO3 should handle requests for non-existing/accessible pages.</p> <dl><dt>empty (default)</dt><dd>The next visible page upwards in the page tree is shown.</dd> <dt>'true' or '1'</dt><dd>An error message is shown.</dd><dt>String</dt><dd>Static HTML file to show (reads content and outputs with correct headers), e.g. 'notfound.html' or 'http://www.example.org/errors/notfound.html'.</dd> <dt>Prefix "REDIRECT:"</dt><dd> If prefixed with "REDIRECT:" it will redirect to the URL/script after the prefix.</dd><dt>Prefix "READFILE:"</dt><dd>If prefixed with "READFILE" then it will expect the remaining string to be a HTML file which will be read and outputted directly after having the marker "###CURRENT_URL###" substituted with REQUEST_URI and ###REASON### with reason text, for example: "READFILE:fileadmin/notfound.html".</dd> <dt>Prefix "USER_FUNCTION:"</dt><dd> If prefixed with "USER_FUNCTION:" a user function is called, e.g. "USER_FUNCTION:fileadmin/class.user_notfound.php:user_notFound->pageNotFound" where the file must contain a class "user_notFound" with a method "pageNotFound" inside with two parameters $param and $ref.</dd></dl>
                'pageNotFound_handling_statheader' => 'HTTP/1.0 404 Not Found',         // If 'pageNotFound_handling' is enabled, this string will always be sent as header before the actual handling.
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-64668-MailformMovedToLegacyExtension.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-64668-MailformMovedToLegacyExtension.rst
new file mode 100644 (file)
index 0000000..045069a
--- /dev/null
@@ -0,0 +1,50 @@
+=====================================================================
+Breaking: #64668 - Content Element mailform moved to legacy extension
+=====================================================================
+
+Description
+===========
+
+The fallback "mailform" functionality, containing the FORM ContentObject, the submission logic for sending mailform
+and the content element (CType=mailform) has been moved to the legacy extension "compatibility6". This mailform
+was available when the "Form" extension, introduced in TYPO3 CMS 4.7, was not installed.
+
+The following options have been marked for deprecation:
+
+.. code-block:: php
+
+       $TYPO3_CONF_VARS][FE][secureFormmail]
+       $TYPO3_CONF_VARS][FE][strictFormmail]
+       $TYPO3_CONF_VARS][FE][formmailMaxAttachmentSize]
+
+The following methods within TypoScriptFrontendController have been removed:
+
+.. code-block:: php
+
+       protected checkDataSubmission()
+       protected sendFormmail()
+       public extractRecipientCopy()
+       public codeString()
+       protected roundTripCryptString()
+
+
+Impact
+======
+
+Mailform elements are missing and not rendered in the frontend anymore unless the extension compatibility6
+is installed.
+
+
+Affected installations
+======================
+
+Any installation using the fallback "mailform" Content Element, the FrontendDataSubmissionController or the FORM
+Content Object directly will break. Additionally, any third party extension using the TypoScriptFrontendController
+methods directly will stop working with a fatal error.
+
+Migration
+=========
+
+For TYPO3 CMS 7, installing the compatibility6 extension brings back the existing functionality. For the long term
+the affected installations should be migrate to a differently, better suited solution for sending mails and building
+forms.
index 114269e..e75921d 100644 (file)
@@ -281,13 +281,6 @@ lib.stdheader {
                        }
                        value = html5
                        equals.data = TSFE:config|config|doctype
-                       # Hide subheader for old style form element (it is used for recipient mail)
-                       isFalse = 0
-                       isFalse.override = 1
-                       isFalse.override {
-                               if.equals.field = CType
-                               if.value = mailform
-                       }
                }
        }
 
@@ -1609,53 +1602,6 @@ tt_content.media {
        }
 }
 
-# ******************
-# CType: mailform
-# ******************
-tt_content.mailform = COA
-tt_content.mailform.10 = < lib.stdheader
-tt_content.mailform.20 = FORM
-tt_content.mailform.20 {
-       useDefaultContentObject = 1
-       accessibility = 1
-       noWrapAttr=1
-       formName = mailform
-       dontMd5FieldNames = 1
-       layout = <div class="csc-mailform-field">###LABEL### ###FIELD###</div>
-       labelWrap.wrap = |
-       commentWrap.wrap = |
-       radioWrap.wrap = |<br />
-       radioWrap.accessibilityWrap = <fieldset###RADIO_FIELD_ID###><legend>###RADIO_GROUP_LABEL###</legend>|</fieldset>
-       REQ = 1
-       REQ.labelWrap.wrap = |
-       COMMENT.layout = <div class="csc-mailform-label">###LABEL###</div>
-       RADIO.layout = <div class="csc-mailform-field">###LABEL### <span class="csc-mailform-radio">###FIELD###</span></div>
-       LABEL.layout = <div class="csc-mailform-field">###LABEL### <span class="csc-mailform-label">###FIELD###</span></div>
-       target < lib.parseTarget
-       target =
-       target.override = {$styles.content.mailform.target}
-       goodMess = {$styles.content.mailform.goodMess}
-       badMess = {$styles.content.mailform.badMess}
-       redirect.field = pages
-       redirect.listNum = 0
-       recipient.field = subheader
-       data.field = bodytext
-       locationData = 1
-       hiddenFields.stdWrap.wrap = <div style="display:none;">|</div>
-
-       params.radio = class="csc-mailform-radio"
-       params.check = class="csc-mailform-check"
-       params.submit = class="csc-mailform-submit"
-
-       stdWrap.wrap = <fieldset class="csc-mailform"> | </fieldset>
-       stdWrap {
-               editIcons = tt_content: bodytext, pages, subheader
-               editIcons.iconTitle.data = LLL:EXT:css_styled_content/Resources/Private/Language/locallang.xlf:eIcon.form
-
-               prefixComment = 2 | Mail form inserted:
-       }
-}
-
 
 # ******************
 # CType: search
@@ -1731,8 +1677,7 @@ tt_content.search.20 {
        stdWrap.prefixComment = 2 | Search result:
 }
 
-# Form:
-tt_content.search.30 < tt_content.mailform.20
+tt_content.search.30 =< tt_content.mailform.20
 tt_content.search.30 {
        goodMess = {$styles.content.searchform.goodMess}
        redirect >
diff --git a/typo3/sysext/form/Classes/Hooks/PageLayoutView/MailformPreviewRenderer.php b/typo3/sysext/form/Classes/Hooks/PageLayoutView/MailformPreviewRenderer.php
new file mode 100644 (file)
index 0000000..aeb838b
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+namespace TYPO3\CMS\Form\Hooks\PageLayoutView;
+
+/*
+ * 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!
+ */
+
+/**
+ * Contains a preview rendering for the page module of
+ * CType="mailform"
+ */
+class MailformPreviewRenderer implements \TYPO3\CMS\Backend\View\PageLayoutViewDrawItemHookInterface {
+
+       /**
+        * Preprocesses the preview rendering of a content element of type "mailform"
+        *
+        * @param \TYPO3\CMS\Backend\View\PageLayoutView $parentObject Calling parent object
+        * @param bool $drawItem Whether to draw the item using the default functionality
+        * @param string $headerContent Header content
+        * @param string $itemContent Item content
+        * @param array $row Record row of tt_content
+        *
+        * @return void
+        */
+       public function preProcess(\TYPO3\CMS\Backend\View\PageLayoutView &$parentObject, &$drawItem, &$headerContent, &$itemContent, array &$row) {
+               if ($row['CType'] === 'mailform') {
+                       $itemContent = $parentObject->linkEditContent($parentObject->renderText($row['bodytext']), $row) . '<br />';
+                       $drawItem = FALSE;
+               }
+       }
+}
index 455494e..5b7a7cd 100644 (file)
@@ -115,22 +115,24 @@ class ValidatorUtility implements \TYPO3\CMS\Core\SingletonInterface {
                $prefix = $this->getPrefix();
                $this->errors[$prefix] = array();
                $result = TRUE;
-               foreach ($this->rules[$prefix] as $key => $element) {
-                       /* @var $rule AbstractValidator */
-                       $rule = $element['instance'];
-                       $fieldName = $element['fieldName'];
-                       if ($rule->isValid()) {
-                               continue;
-                       }
-                       $result = FALSE;
-                       if (!isset($this->errors[$prefix][$fieldName])) {
-                               $this->errors[$prefix][$fieldName] = array();
-                       }
-                       $error = $rule->getError();
-                       $this->errors[$prefix][$fieldName][$key][$key + 1] = $error['cObj'];
-                       $this->errors[$prefix][$fieldName][$key][($key + 1) . '.'] = $error['cObj.'];
-                       if ($element['breakOnError']) {
-                               break;
+               if (is_array($this->rules[$prefix])) {
+                               foreach ($this->rules[$prefix] as $key => $element) {
+                               /* @var $rule AbstractValidator */
+                               $rule = $element['instance'];
+                               $fieldName = $element['fieldName'];
+                               if ($rule->isValid()) {
+                                       continue;
+                               }
+                               $result = FALSE;
+                               if (!isset($this->errors[$prefix][$fieldName])) {
+                                       $this->errors[$prefix][$fieldName] = array();
+                               }
+                               $error = $rule->getError();
+                               $this->errors[$prefix][$fieldName][$key][$key + 1] = $error['cObj'];
+                               $this->errors[$prefix][$fieldName][$key][($key + 1) . '.'] = $error['cObj.'];
+                               if ($element['breakOnError']) {
+                                       break;
+                               }
                        }
                }
                return $result;
index 7d88d24..fda2b67 100644 (file)
@@ -1,6 +1,22 @@
 <?php
 defined('TYPO3_MODE') or die();
 
+
+// add an CType element if the compatibility6 extension is not taking care of that already
+if (!\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('compatibility6')) {
+       $GLOBALS['TCA']['tt_content']['ctrl']['typeicon_classes']['mailform'] = 'mimetypes-x-content-form';
+       $GLOBALS['TCA']['tt_content']['ctrl']['typeicons']['mailform'] = 'tt_content_form.gif';
+
+       \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTcaSelectItem('tt_content', 'CType', array(
+                       'LLL:EXT:cms/locallang_ttc.xlf:CType.I.8',
+                       'mailform',
+                       'i/tt_content_form.gif'
+               ),
+               'search',
+               'before'
+       );
+}
+
 $GLOBALS['TCA']['tt_content']['columns']['bodytext']['config']['wizards']['forms'] = array(
        'notNewRecords' => 1,
        'enableByTypeConfig' => 1,
@@ -14,6 +30,7 @@ $GLOBALS['TCA']['tt_content']['columns']['bodytext']['config']['wizards']['forms
                'xmlOutput' => 0
        )
 );
+
 $GLOBALS['TCA']['tt_content']['types']['mailform']['showitem'] = '
        --palette--;LLL:EXT:cms/locallang_ttc.xlf:palette.general;general,
        --palette--;LLL:EXT:cms/locallang_ttc.xlf:palette.header;header,
index 0a7d284..1e3eeaa 100644 (file)
@@ -2,3 +2,6 @@
 defined('TYPO3_MODE') or die();
 
 \TYPO3\CMS\Form\Utility\FormUtility::getInstance()->initializeFormObjects()->initializePageTsConfig();
+
+// Add a for previewing tt_content elements of CType="mailform"
+$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['tt_content_drawItem']['mailform'] = \TYPO3\CMS\Form\Hooks\PageLayoutView\MailformPreviewRenderer::class;
index ad291a6..7447bc5 100644 (file)
@@ -1776,8 +1776,10 @@ class ContentObjectRenderer {
         * @param string $name Input string
         * @return string the cleaned string
         * @see FORM()
+        * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8, the method is moved to FormContentObject
         */
        public function cleanFormName($name) {
+               GeneralUtility::logDeprecatedFunction();
                // Turn data[x][y] into data:x:y:
                $name = preg_replace('/\\[|\\]\\[?/', ':', trim($name));
                // Remove illegal chars like _
diff --git a/typo3/sysext/frontend/Classes/ContentObject/FormContentObject.php b/typo3/sysext/frontend/Classes/ContentObject/FormContentObject.php
deleted file mode 100644 (file)
index fc013b8..0000000
+++ /dev/null
@@ -1,648 +0,0 @@
-<?php
-namespace TYPO3\CMS\Frontend\ContentObject;
-
-/*
- * 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\Core\Utility\GeneralUtility;
-
-/**
- * Contains FORM class object.
- *
- * @author Xavier Perseguers <typo3@perseguers.ch>
- * @author Steffen Kamper <steffen@typo3.org>
- */
-class FormContentObject extends AbstractContentObject {
-
-       /**
-        * Rendering the cObject, FORM
-        *
-        * Note on $formData:
-        * In the optional $formData array each entry represents a line in the ordinary setup.
-        * In those entries each entry (0,1,2...) represents a space normally divided by the '|' line.
-        *
-        * $formData [] = array('Name:', 'name=input, 25 ', 'Default value....');
-        * $formData [] = array('Email:', 'email=input, 25 ', 'Default value for email....');
-        *
-        * - corresponds to the $conf['data'] value being :
-        * Name:|name=input, 25 |Default value....||Email:|email=input, 25 |Default value for email....
-        *
-        * If $formData is an array the value of $conf['data'] is ignored.
-        *
-        * @param array $conf Array of TypoScript properties
-        * @param array $formData Alternative formdata overriding whatever comes from TypoScript
-        * @return string Output
-        */
-       public function render($conf = array(), $formData = '') {
-               $content = '';
-               if (is_array($formData)) {
-                       $dataArray = $formData;
-               } else {
-                       $data = isset($conf['data.']) ? $this->cObj->stdWrap($conf['data'], $conf['data.']) : $conf['data'];
-                       // Clearing dataArr
-                       $dataArray = array();
-                       // Getting the original config
-                       if (trim($data)) {
-                               $data = str_replace(LF, '||', $data);
-                               $dataArray = explode('||', $data);
-                       }
-                       // Adding the new dataArray config form:
-                       if (is_array($conf['dataArray.'])) {
-                               // dataArray is supplied
-                               $sortedKeyArray = \TYPO3\CMS\Core\TypoScript\TemplateService::sortedKeyList($conf['dataArray.'], TRUE);
-                               foreach ($sortedKeyArray as $theKey) {
-                                       $singleKeyArray = $conf['dataArray.'][$theKey . '.'];
-                                       if (is_array($singleKeyArray)) {
-                                               $temp = array();
-                                               $label = isset($singleKeyArray['label.']) ? $this->cObj->stdWrap($singleKeyArray['label'], $singleKeyArray['label.']) : $singleKeyArray['label'];
-                                               list($temp[0]) = explode('|', $label);
-                                               $type = isset($singleKeyArray['type.']) ? $this->cObj->stdWrap($singleKeyArray['type'], $singleKeyArray['type.']) : $singleKeyArray['type'];
-                                               list($temp[1]) = explode('|', $type);
-                                               $required = isset($singleKeyArray['required.']) ? $this->cObj->stdWrap($singleKeyArray['required'], $singleKeyArray['required.']) : $singleKeyArray['required'];
-                                               if ($required) {
-                                                       $temp[1] = '*' . $temp[1];
-                                               }
-                                               $singleValue = isset($singleKeyArray['value.']) ? $this->cObj->stdWrap($singleKeyArray['value'], $singleKeyArray['value.']) : $singleKeyArray['value'];
-                                               list($temp[2]) = explode('|', $singleValue);
-                                               // If value array is set, then implode those values.
-                                               if (is_array($singleKeyArray['valueArray.'])) {
-                                                       $temp_accumulated = array();
-                                                       foreach ($singleKeyArray['valueArray.'] as $singleKey => $singleKey_valueArray) {
-                                                               if (is_array($singleKey_valueArray) && (int)$singleKey . '.' === (string)$singleKey) {
-                                                                       $temp_valueArray = array();
-                                                                       $valueArrayLabel = isset($singleKey_valueArray['label.']) ? $this->cObj->stdWrap($singleKey_valueArray['label'], $singleKey_valueArray['label.']) : $singleKey_valueArray['label'];
-                                                                       list($temp_valueArray[0]) = explode('=', $valueArrayLabel);
-                                                                       $selected = isset($singleKey_valueArray['selected.']) ? $this->cObj->stdWrap($singleKey_valueArray['selected'], $singleKey_valueArray['selected.']) : $singleKey_valueArray['selected'];
-                                                                       if ($selected) {
-                                                                               $temp_valueArray[0] = '*' . $temp_valueArray[0];
-                                                                       }
-                                                                       $singleKeyValue = isset($singleKey_valueArray['value.']) ? $this->cObj->stdWrap($singleKey_valueArray['value'], $singleKey_valueArray['value.']) : $singleKey_valueArray['value'];
-                                                                       list($temp_valueArray[1]) = explode(',', $singleKeyValue);
-                                                               }
-                                                               $temp_accumulated[] = implode('=', $temp_valueArray);
-                                                       }
-                                                       $temp[2] = implode(',', $temp_accumulated);
-                                               }
-                                               $specialEval = isset($singleKeyArray['specialEval.']) ? $this->cObj->stdWrap($singleKeyArray['specialEval'], $singleKeyArray['specialEval.']) : $singleKeyArray['specialEval'];
-                                               list($temp[3]) = explode('|', $specialEval);
-                                               // Adding the form entry to the dataArray
-                                               $dataArray[] = implode('|', $temp);
-                                       }
-                               }
-                       }
-               }
-               $attachmentCounter = '';
-               $hiddenfields = '';
-               $fieldlist = array();
-               $propertyOverride = array();
-               $fieldname_hashArray = array();
-               $counter = 0;
-               $xhtmlStrict = GeneralUtility::inList('xhtml_strict,xhtml_11,xhtml_2', $GLOBALS['TSFE']->xhtmlDoctype);
-               // Formname
-               $formName = isset($conf['formName.']) ? $this->cObj->stdWrap($conf['formName'], $conf['formName.']) : $conf['formName'];
-               $formName = $this->cObj->cleanFormName($formName);
-               $formName = $GLOBALS['TSFE']->getUniqueId($formName);
-
-               $fieldPrefix = isset($conf['fieldPrefix.']) ? $this->cObj->stdWrap($conf['fieldPrefix'], $conf['fieldPrefix.']) : $conf['fieldPrefix'];
-               if (isset($conf['fieldPrefix']) || isset($conf['fieldPrefix.'])) {
-                       if ($fieldPrefix) {
-                               $prefix = $this->cObj->cleanFormName($fieldPrefix);
-                       } else {
-                               $prefix = '';
-                       }
-               } else {
-                       $prefix = $formName;
-               }
-               foreach ($dataArray as $dataValue) {
-                       $counter++;
-                       $confData = array();
-                       if (is_array($formData)) {
-                               $parts = $dataValue;
-                               // TRUE...
-                               $dataValue = 1;
-                       } else {
-                               $dataValue = trim($dataValue);
-                               $parts = explode('|', $dataValue);
-                       }
-                       if ($dataValue && strcspn($dataValue, '#/')) {
-                               // label:
-                               $confData['label'] = GeneralUtility::removeXSS(trim($parts[0]));
-                               // field:
-                               $fParts = explode(',', $parts[1]);
-                               $fParts[0] = trim($fParts[0]);
-                               if ($fParts[0][0] === '*') {
-                                       $confData['required'] = 1;
-                                       $fParts[0] = substr($fParts[0], 1);
-                               }
-                               $typeParts = explode('=', $fParts[0]);
-                               $confData['type'] = trim(strtolower(end($typeParts)));
-                               if (count($typeParts) == 1) {
-                                       $confData['fieldname'] = $this->cObj->cleanFormName($parts[0]);
-                                       if (strtolower(preg_replace('/[^[:alnum:]]/', '', $confData['fieldname'])) == 'email') {
-                                               $confData['fieldname'] = 'email';
-                                       }
-                                       // Duplicate fieldnames resolved
-                                       if (isset($fieldname_hashArray[md5($confData['fieldname'])])) {
-                                               $confData['fieldname'] .= '_' . $counter;
-                                       }
-                                       $fieldname_hashArray[md5($confData['fieldname'])] = $confData['fieldname'];
-                                       // Attachment names...
-                                       if ($confData['type'] == 'file') {
-                                               $confData['fieldname'] = 'attachment' . $attachmentCounter;
-                                               $attachmentCounter = (int)$attachmentCounter + 1;
-                                       }
-                               } else {
-                                       $confData['fieldname'] = str_replace(' ', '_', trim($typeParts[0]));
-                               }
-                               $confData['fieldname'] = htmlspecialchars($confData['fieldname']);
-                               $fieldCode = '';
-                               $wrapFieldName = isset($conf['wrapFieldName']) ? $this->cObj->stdWrap($conf['wrapFieldName'], $conf['wrapFieldName.']) : $conf['wrapFieldName'];
-                               if ($wrapFieldName) {
-                                       $confData['fieldname'] = $this->cObj->wrap($confData['fieldname'], $wrapFieldName);
-                               }
-                               // Set field name as current:
-                               $this->cObj->setCurrentVal($confData['fieldname']);
-                               // Additional parameters
-                               if (trim($confData['type'])) {
-                                       if (isset($conf['params.'][$confData['type']])) {
-                                               $addParams = isset($conf['params.'][$confData['type'] . '.']) ? trim($this->cObj->stdWrap($conf['params.'][$confData['type']], $conf['params.'][$confData['type'] . '.'])) : trim($conf['params.'][$confData['type']]);
-                                       } else {
-                                               $addParams = isset($conf['params.']) ? trim($this->cObj->stdWrap($conf['params'], $conf['params.'])) : trim($conf['params']);
-                                       }
-                                       if ((string)$addParams !== '') {
-                                               $addParams = ' ' . $addParams;
-                                       }
-                               } else {
-                                       $addParams = '';
-                               }
-                               $dontMd5FieldNames = isset($conf['dontMd5FieldNames.']) ? $this->cObj->stdWrap($conf['dontMd5FieldNames'], $conf['dontMd5FieldNames.']) : $conf['dontMd5FieldNames'];
-                               if ($dontMd5FieldNames) {
-                                       $fName = $confData['fieldname'];
-                               } else {
-                                       $fName = md5($confData['fieldname']);
-                               }
-                               // Accessibility: Set id = fieldname attribute:
-                               $accessibility = isset($conf['accessibility.']) ? $this->cObj->stdWrap($conf['accessibility'], $conf['accessibility.']) : $conf['accessibility'];
-                               if ($accessibility || $xhtmlStrict) {
-                                       $elementIdAttribute = ' id="' . $prefix . $fName . '"';
-                               } else {
-                                       $elementIdAttribute = '';
-                               }
-                               // Create form field based on configuration/type:
-                               switch ($confData['type']) {
-                                       case 'textarea':
-                                               $cols = trim($fParts[1]) ? (int)$fParts[1] : 20;
-                                               $compensateFieldWidth = isset($conf['compensateFieldWidth.']) ? $this->cObj->stdWrap($conf['compensateFieldWidth'], $conf['compensateFieldWidth.']) : $conf['compensateFieldWidth'];
-                                               $compWidth = doubleval($compensateFieldWidth ? $compensateFieldWidth : $GLOBALS['TSFE']->compensateFieldWidth);
-                                               $compWidth = $compWidth ? $compWidth : 1;
-                                               $cols = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($cols * $compWidth, 1, 120);
-                                               $rows = trim($fParts[2]) ? \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($fParts[2], 1, 30) : 5;
-                                               $wrap = trim($fParts[3]);
-                                               $noWrapAttr = isset($conf['noWrapAttr.']) ? $this->cObj->stdWrap($conf['noWrapAttr'], $conf['noWrapAttr.']) : $conf['noWrapAttr'];
-                                               if ($noWrapAttr || $wrap === 'disabled') {
-                                                       $wrap = '';
-                                               } else {
-                                                       $wrap = $wrap ? ' wrap="' . $wrap . '"' : ' wrap="virtual"';
-                                               }
-                                               $noValueInsert = isset($conf['noValueInsert.']) ? $this->cObj->stdWrap($conf['noValueInsert'], $conf['noValueInsert.']) : $conf['noValueInsert'];
-                                               $default = $this->getFieldDefaultValue($noValueInsert, $confData['fieldname'], str_replace('\\n', LF, trim($parts[2])));
-                                               $fieldCode = sprintf('<textarea name="%s"%s cols="%s" rows="%s"%s%s>%s</textarea>', $confData['fieldname'], $elementIdAttribute, $cols, $rows, $wrap, $addParams, GeneralUtility::formatForTextarea($default));
-                                               break;
-                                       case 'input':
-
-                                       case 'password':
-                                               $size = trim($fParts[1]) ? (int)$fParts[1] : 20;
-                                               $compensateFieldWidth = isset($conf['compensateFieldWidth.']) ? $this->cObj->stdWrap($conf['compensateFieldWidth'], $conf['compensateFieldWidth.']) : $conf['compensateFieldWidth'];
-                                               $compWidth = doubleval($compensateFieldWidth ? $compensateFieldWidth : $GLOBALS['TSFE']->compensateFieldWidth);
-                                               $compWidth = $compWidth ? $compWidth : 1;
-                                               $size = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($size * $compWidth, 1, 120);
-                                               $noValueInsert = isset($conf['noValueInsert.']) ? $this->cObj->stdWrap($conf['noValueInsert'], $conf['noValueInsert.']) : $conf['noValueInsert'];
-                                               $default = $this->getFieldDefaultValue($noValueInsert, $confData['fieldname'], trim($parts[2]));
-                                               if ($confData['type'] == 'password') {
-                                                       $default = '';
-                                               }
-                                               $max = trim($fParts[2]) ? ' maxlength="' . \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($fParts[2], 1, 1000) . '"' : '';
-                                               $theType = $confData['type'] == 'input' ? 'text' : 'password';
-                                               $fieldCode = sprintf('<input type="%s" name="%s"%s size="%s"%s value="%s"%s />', $theType, $confData['fieldname'], $elementIdAttribute, $size, $max, htmlspecialchars($default), $addParams);
-                                               break;
-                                       case 'file':
-                                               $size = trim($fParts[1]) ? \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($fParts[1], 1, 60) : 20;
-                                               $fieldCode = sprintf('<input type="file" name="%s"%s size="%s"%s />', $confData['fieldname'], $elementIdAttribute, $size, $addParams);
-                                               break;
-                                       case 'check':
-                                               // alternative default value:
-                                               $noValueInsert = isset($conf['noValueInsert.']) ? $this->cObj->stdWrap($conf['noValueInsert'], $conf['noValueInsert.']) : $conf['noValueInsert'];
-                                               $default = $this->getFieldDefaultValue($noValueInsert, $confData['fieldname'], trim($parts[2]));
-                                               $checked = $default ? ' checked="checked"' : '';
-                                               $fieldCode = sprintf('<input type="checkbox" value="%s" name="%s"%s%s%s />', 1, $confData['fieldname'], $elementIdAttribute, $checked, $addParams);
-                                               break;
-                                       case 'select':
-                                               $option = '';
-                                               $valueParts = explode(',', $parts[2]);
-                                               // size
-                                               if (strtolower(trim($fParts[1])) == 'auto') {
-                                                       $fParts[1] = count($valueParts);
-                                               }
-                                               // Auto size set here. Max 20
-                                               $size = trim($fParts[1]) ? \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($fParts[1], 1, 20) : 1;
-                                               // multiple
-                                               $multiple = strtolower(trim($fParts[2])) == 'm' ? ' multiple="multiple"' : '';
-                                               // Where the items will be
-                                               $items = array();
-                                               //RTF
-                                               $defaults = array();
-                                               $pCount = count($valueParts);
-                                               for ($a = 0; $a < $pCount; $a++) {
-                                                       $valueParts[$a] = trim($valueParts[$a]);
-                                                       // Finding default value
-                                                       if ($valueParts[$a][0] === '*') {
-                                                               $sel = 'selected';
-                                                               $valueParts[$a] = substr($valueParts[$a], 1);
-                                                       } else {
-                                                               $sel = '';
-                                                       }
-                                                       // Get value/label
-                                                       $subParts = explode('=', $valueParts[$a]);
-                                                       // Sets the value
-                                                       $subParts[1] = isset($subParts[1]) ? trim($subParts[1]) : trim($subParts[0]);
-                                                       // Adds the value/label pair to the items-array
-                                                       $items[] = $subParts;
-                                                       if ($sel) {
-                                                               $defaults[] = $subParts[1];
-                                                       }
-                                               }
-                                               // alternative default value:
-                                               $noValueInsert = isset($conf['noValueInsert.']) ? $this->cObj->stdWrap($conf['noValueInsert'], $conf['noValueInsert.']) : $conf['noValueInsert'];
-                                               $default = $this->getFieldDefaultValue($noValueInsert, $confData['fieldname'], $defaults);
-                                               if (!is_array($default)) {
-                                                       $defaults = array();
-                                                       $defaults[] = $default;
-                                               } else {
-                                                       $defaults = $default;
-                                               }
-                                               // Create the select-box:
-                                               $iCount = count($items);
-                                               for ($a = 0; $a < $iCount; $a++) {
-                                                       $option .= '<option value="' . $items[$a][1] . '"' . (in_array($items[$a][1], $defaults) ? ' selected="selected"' : '') . '>' . trim($items[$a][0]) . '</option>';
-                                               }
-                                               if ($multiple) {
-                                                       // The fieldname must be prepended '[]' if multiple select. And the reason why it's prepended is, because the required-field list later must also have [] prepended.
-                                                       $confData['fieldname'] .= '[]';
-                                               }
-                                               $fieldCode = sprintf('<select name="%s"%s size="%s"%s%s>%s</select>', $confData['fieldname'], $elementIdAttribute, $size, $multiple, $addParams, $option);
-                                               //RTF
-                                               break;
-                                       case 'radio':
-                                               $option = '';
-                                               $valueParts = explode(',', $parts[2]);
-                                               // Where the items will be
-                                               $items = array();
-                                               $default = '';
-                                               $pCount = count($valueParts);
-                                               for ($a = 0; $a < $pCount; $a++) {
-                                                       $valueParts[$a] = trim($valueParts[$a]);
-                                                       if ($valueParts[$a][0] === '*') {
-                                                               $sel = 'checked';
-                                                               $valueParts[$a] = substr($valueParts[$a], 1);
-                                                       } else {
-                                                               $sel = '';
-                                                       }
-                                                       // Get value/label
-                                                       $subParts = explode('=', $valueParts[$a]);
-                                                       // Sets the value
-                                                       $subParts[1] = isset($subParts[1]) ? trim($subParts[1]) : trim($subParts[0]);
-                                                       // Adds the value/label pair to the items-array
-                                                       $items[] = $subParts;
-                                                       if ($sel) {
-                                                               $default = $subParts[1];
-                                                       }
-                                               }
-                                               // alternative default value:
-                                               $noValueInsert = isset($conf['noValueInsert.']) ? $this->cObj->stdWrap($conf['noValueInsert'], $conf['noValueInsert.']) : $conf['noValueInsert'];
-                                               $default = $this->getFieldDefaultValue($noValueInsert, $confData['fieldname'], $default);
-                                               // Create the select-box:
-                                               $iCount = count($items);
-                                               for ($a = 0; $a < $iCount; $a++) {
-                                                       $optionParts = '';
-                                                       $radioId = $prefix . $fName . $this->cObj->cleanFormName($items[$a][0]);
-                                                       if ($accessibility) {
-                                                               $radioLabelIdAttribute = ' id="' . $radioId . '"';
-                                                       } else {
-                                                               $radioLabelIdAttribute = '';
-                                                       }
-                                                       $optionParts .= '<input type="radio" name="' . $confData['fieldname'] . '"' . $radioLabelIdAttribute . ' value="' . $items[$a][1] . '"' . ((string)$items[$a][1] === (string)$default ? ' checked="checked"' : '') . $addParams . ' />';
-                                                       if ($accessibility) {
-                                                               $label = isset($conf['radioWrap.']) ? $this->cObj->stdWrap(trim($items[$a][0]), $conf['radioWrap.']) : trim($items[$a][0]);
-                                                               $optionParts .= '<label for="' . $radioId . '">' . $label . '</label>';
-                                                       } else {
-                                                               $optionParts .= isset($conf['radioWrap.']) ? $this->cObj->stdWrap(trim($items[$a][0]), $conf['radioWrap.']) : trim($items[$a][0]);
-                                                       }
-                                                       $option .= isset($conf['radioInputWrap.']) ? $this->cObj->stdWrap($optionParts, $conf['radioInputWrap.']) : $optionParts;
-                                               }
-                                               if ($accessibility) {
-                                                       $accessibilityWrap = isset($conf['radioWrap.']['accessibilityWrap.']) ? $this->cObj->stdWrap($conf['radioWrap.']['accessibilityWrap'], $conf['radioWrap.']['accessibilityWrap.']) : $conf['radioWrap.']['accessibilityWrap'];
-                                                       if ($accessibilityWrap) {
-                                                               $search = array(
-                                                                       '###RADIO_FIELD_ID###',
-       &n