/** * 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(); }