core-bundle/src/Resources/contao/forms/Form.php
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())
			{
				// Ignore the name of form fields which do not use a name (see #1268)
				if ($objFields->name != '' && isset($GLOBALS['TL_DCA']['tl_form_field']['palettes'][$objFields->type]) && preg_match('/[,;]name[,;]/', $GLOBALS['TL_DCA']['tl_form_field']['palettes'][$objFields->type]))
				{
					$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;
					}

					// Store current value in the session
					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[0] != '')
		{
			$strAttributes .= ' id="' . $arrAttributes[0] . '"';
		}

		if ($arrAttributes[1] != '')
		{
			$strAttributes .= ' class="' . $arrAttributes[1] . '"';
		}

		$this->Template->hasError = $doNotSubmit;
		$this->Template->attributes = $strAttributes;
		$this->Template->enctype = $hasUpload ? 'multipart/form-data' : 'application/x-www-form-urlencoded';
		$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' && ($objTarget = $this->objModel->getRelated('jumpTo')) instanceof PageModel)
		{
			/** @var PageModel $objTarget */
			$this->Template->action = $objTarget->getFrontendUrl();
		}
	}
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())
			{
				// Ignore the name of form fields which do not use a name (see #1268)
				if ($objFields->name != '' && isset($GLOBALS['TL_DCA']['tl_form_field']['palettes'][$objFields->type]) && preg_match('/[,;]name[,;]/', $GLOBALS['TL_DCA']['tl_form_field']['palettes'][$objFields->type]))
				{
					$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;
					}

					// Store current value in the session
					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[0] != '')
		{
			$strAttributes .= ' id="' . $arrAttributes[0] . '"';
		}

		if ($arrAttributes[1] != '')
		{
			$strAttributes .= ' class="' . $arrAttributes[1] . '"';
		}

		$this->Template->hasError = $doNotSubmit;
		$this->Template->attributes = $strAttributes;
		$this->Template->enctype = $hasUpload ? 'multipart/form-data' : 'application/x-www-form-urlencoded';
		$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' && ($objTarget = $this->objModel->getRelated('jumpTo')) instanceof PageModel)
		{
			/** @var PageModel $objTarget */
			$this->Template->action = $objTarget->getFrontendUrl();
		}
	}
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 ( ) ) { // Ignore the name of form fields which do not use a name (see #1268) if ( $ objFields -> name != '' && isset ( $ GLOBALS [ 'TL_DCA' ] [ 'tl_form_field' ] [ 'palettes' ] [ $ objFields -> type ] ) && preg_match ( '/[,;]name[,;]/' , $ GLOBALS [ 'TL_DCA' ] [ 'tl_form_field' ] [ 'palettes' ] [ $ objFields -> type ] ) ) { $ 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 ; } // Store current value in the session 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 [ 0 ] != '' ) { $ strAttributes .= ' id="' . $ arrAttributes [ 0 ] . '"' ; } if ( $ arrAttributes [ 1 ] != '' ) { $ strAttributes .= ' class="' . $ arrAttributes [ 1 ] . '"' ; } $ this -> Template -> hasError = $ doNotSubmit ; $ this -> Template -> attributes = $ strAttributes ; $ this -> Template -> enctype = $ hasUpload ? 'multipart/form-data' : 'application/x-www-form-urlencoded' ; $ 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' && ( $ objTarget = $ this -> objModel -> getRelated ( 'jumpTo' ) ) instanceof PageModel ) { /** @var PageModel $objTarget */ $ this -> Template -> action = $ objTarget -> getFrontendUrl ( ) ; } }
Generate the form
Generate the form