/**
* Generate the form
*
* @return string
*/
protected function compile()
{
$hasUpload = false;
$doNotSubmit = false;
$arrSubmitted = array();
$this->loadDataContainer('tl_form_field');
$formId = $this->formID != '' ? 'auto_' . $this->formID : 'auto_form_' . $this->id;
$this->Template->fields = '';
$this->Template->hidden = '';
$this->Template->formSubmit = $formId;
$this->Template->method = $this->method == 'GET' ? 'get' : 'post';
$this->initializeSession($formId);
$arrLabels = array();
// Get all form fields
$arrFields = array();
$objFields = \FormFieldModel::findPublishedByPid($this->id);
if ($objFields !== null) {
while ($objFields->next()) {
if ($objFields->name != '') {
$arrFields[$objFields->name] = $objFields->current();
} else {
$arrFields[] = $objFields->current();
}
}
}
// HOOK: compile form fields
if (isset($GLOBALS['TL_HOOKS']['compileFormFields']) && is_array($GLOBALS['TL_HOOKS']['compileFormFields'])) {
foreach ($GLOBALS['TL_HOOKS']['compileFormFields'] as $callback) {
$this->import($callback[0]);
$arrFields = $this->{$callback[0]}->{$callback[1]}($arrFields, $formId, $this);
}
}
// Process the fields
if (!empty($arrFields) && is_array($arrFields)) {
$row = 0;
$max_row = count($arrFields);
foreach ($arrFields as $objField) {
/** @var FormFieldModel $objField */
$strClass = $GLOBALS['TL_FFL'][$objField->type];
// Continue if the class is not defined
if (!class_exists($strClass)) {
continue;
}
$arrData = $objField->row();
$arrData['decodeEntities'] = true;
$arrData['allowHtml'] = $this->allowTags;
$arrData['rowClass'] = 'row_' . $row . ($row == 0 ? ' row_first' : ($row == $max_row - 1 ? ' row_last' : '')) . ($row % 2 == 0 ? ' even' : ' odd');
// Increase the row count if its a password field
if ($objField->type == 'password') {
++$row;
++$max_row;
$arrData['rowClassConfirm'] = 'row_' . $row . ($row == $max_row - 1 ? ' row_last' : '') . ($row % 2 == 0 ? ' even' : ' odd');
}
// Submit buttons do not use the name attribute
if ($objField->type == 'submit') {
$arrData['name'] = '';
}
// Unset the default value depending on the field type (see #4722)
if (!empty($arrData['value'])) {
if (!in_array('value', \StringUtil::trimsplit('[,;]', $GLOBALS['TL_DCA']['tl_form_field']['palettes'][$objField->type]))) {
$arrData['value'] = '';
}
}
/** @var Widget $objWidget */
$objWidget = new $strClass($arrData);
$objWidget->required = $objField->mandatory ? true : false;
// HOOK: load form field callback
if (isset($GLOBALS['TL_HOOKS']['loadFormField']) && is_array($GLOBALS['TL_HOOKS']['loadFormField'])) {
foreach ($GLOBALS['TL_HOOKS']['loadFormField'] as $callback) {
$this->import($callback[0]);
$objWidget = $this->{$callback[0]}->{$callback[1]}($objWidget, $formId, $this->arrData, $this);
}
}
// Validate the input
if (\Input::post('FORM_SUBMIT') == $formId) {
$objWidget->validate();
// HOOK: validate form field callback
if (isset($GLOBALS['TL_HOOKS']['validateFormField']) && is_array($GLOBALS['TL_HOOKS']['validateFormField'])) {
foreach ($GLOBALS['TL_HOOKS']['validateFormField'] as $callback) {
$this->import($callback[0]);
$objWidget = $this->{$callback[0]}->{$callback[1]}($objWidget, $formId, $this->arrData, $this);
}
}
if ($objWidget->hasErrors()) {
$doNotSubmit = true;
} elseif ($objWidget->submitInput()) {
$arrSubmitted[$objField->name] = $objWidget->value;
$_SESSION['FORM_DATA'][$objField->name] = $objWidget->value;
unset($_POST[$objField->name]);
// see #5474
}
}
if ($objWidget instanceof \uploadable) {
$hasUpload = true;
}
if ($objWidget instanceof FormHidden) {
$this->Template->hidden .= $objWidget->parse();
--$max_row;
continue;
}
if ($objWidget->name != '' && $objWidget->label != '') {
$arrLabels[$objWidget->name] = $this->replaceInsertTags($objWidget->label);
// see #4268
}
$this->Template->fields .= $objWidget->parse();
++$row;
}
}
// Process the form data
if (\Input::post('FORM_SUBMIT') == $formId && !$doNotSubmit) {
$this->processFormData($arrSubmitted, $arrLabels, $arrFields);
}
// Add a warning to the page title
if ($doNotSubmit && !\Environment::get('isAjaxRequest')) {
/** @var PageModel $objPage */
global $objPage;
$title = $objPage->pageTitle ?: $objPage->title;
$objPage->pageTitle = $GLOBALS['TL_LANG']['ERR']['form'] . ' - ' . $title;
$_SESSION['FILES'] = array();
// see #3007
}
$strAttributes = '';
$arrAttributes = \StringUtil::deserialize($this->attributes, true);
if ($arrAttributes[1] != '') {
$strAttributes .= ' class="' . $arrAttributes[1] . '"';
}
$formId = $arrAttributes[0] ?: 'f' . $this->id;
// Count up form usages
if (isset(static::$arrFormUsages[$formId])) {
static::$arrFormUsages[$formId]++;
} else {
static::$arrFormUsages[$formId] = 1;
}
// Adjust form id
if (static::$arrFormUsages[$formId] > 1) {
$formId .= '_' . static::$arrFormUsages[$formId];
}
$this->Template->hasError = $doNotSubmit;
$this->Template->attributes = $strAttributes;
$this->Template->enctype = $hasUpload ? 'multipart/form-data' : 'application/x-www-form-urlencoded';
$this->Template->formId = $formId;
$this->Template->action = \Environment::get('indexFreeRequest');
$this->Template->maxFileSize = $hasUpload ? $this->objModel->getMaxUploadFileSize() : false;
$this->Template->novalidate = $this->novalidate ? ' novalidate' : '';
// Get the target URL
if ($this->method == 'GET' && $this->jumpTo && ($objTarget = $this->objModel->getRelated('jumpTo')) instanceof PageModel) {
/** @var PageModel $objTarget */
$this->Template->action = $objTarget->getFrontendUrl();
}
return $this->Template->parse();
}