core-bundle/src/Resources/contao/drivers/DC_Table.php
protected function save($varValue)
	{
		if (Input::post('FORM_SUBMIT') != $this->strTable)
		{
			return;
		}

		$arrData = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField];

		// Convert date formats into timestamps
		if ($varValue !== null && $varValue !== '' && \in_array($arrData['eval']['rgxp'], array('date', 'time', 'datim')))
		{
			$objDate = new Date($varValue, Date::getFormatFromRgxp($arrData['eval']['rgxp']));
			$varValue = $objDate->tstamp;
		}

		// Make sure unique fields are unique
		if ($arrData['eval']['unique'] && $varValue != '' && !$this->Database->isUniqueValue($this->strTable, $this->strField, $varValue, $this->objActiveRecord->id))
		{
			throw new \Exception(sprintf($GLOBALS['TL_LANG']['ERR']['unique'], $arrData['label'][0] ?: $this->strField));
		}

		// Handle multi-select fields in "override all" mode
		if (Input::get('act') == 'overrideAll' && ($arrData['inputType'] == 'checkbox' || $arrData['inputType'] == 'checkboxWizard') && $arrData['eval']['multiple'])
		{
			if ($this->objActiveRecord !== null)
			{
				$new = StringUtil::deserialize($varValue, true);
				$old = StringUtil::deserialize($this->objActiveRecord->{$this->strField}, true);

				// Call load_callback
				if (\is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['load_callback']))
				{
					foreach ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['load_callback'] as $callback)
					{
						if (\is_array($callback))
						{
							$this->import($callback[0]);
							$old = $this->{$callback[0]}->{$callback[1]}($old, $this);
						}
						elseif (\is_callable($callback))
						{
							$old = $callback($old, $this);
						}
					}
				}

				switch (Input::post($this->strInputName . '_update'))
				{
					case 'add':
						$varValue = array_values(array_unique(array_merge($old, $new)));
						break;

					case 'remove':
						$varValue = array_values(array_diff($old, $new));
						break;

					case 'replace':
						$varValue = $new;
						break;
				}

				if (empty($varValue) || !\is_array($varValue))
				{
					$varValue = Widget::getEmptyStringOrNullByFieldType($arrData['sql']);
				}
				elseif (isset($arrData['eval']['csv']))
				{
					$varValue = implode($arrData['eval']['csv'], $varValue); // see #2890
				}
				else
				{
					$varValue = serialize($varValue);
				}
			}
		}

		// Convert arrays (see #2890)
		if ($arrData['eval']['multiple'] && isset($arrData['eval']['csv']))
		{
			$varValue = implode($arrData['eval']['csv'], StringUtil::deserialize($varValue, true));
		}

		// Trigger the save_callback
		if (\is_array($arrData['save_callback']))
		{
			foreach ($arrData['save_callback'] as $callback)
			{
				if (\is_array($callback))
				{
					$this->import($callback[0]);
					$varValue = $this->{$callback[0]}->{$callback[1]}($varValue, $this);
				}
				elseif (\is_callable($callback))
				{
					$varValue = $callback($varValue, $this);
				}
			}
		}

		// Save the value if there was no error
		if (($varValue != '' || !$arrData['eval']['doNotSaveEmpty']) && ($this->varValue !== $varValue || $arrData['eval']['alwaysSave']))
		{
			// If the field is a fallback field, empty all other columns (see #6498)
			if ($arrData['eval']['fallback'] && $varValue != '')
			{
				if ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 4)
				{
					$this->Database->prepare("UPDATE " . $this->strTable . " SET " . Database::quoteIdentifier($this->strField) . "='' WHERE pid=?")
								   ->execute($this->activeRecord->pid);
				}
				else
				{
					$this->Database->execute("UPDATE " . $this->strTable . " SET " . Database::quoteIdentifier($this->strField) . "=''");
				}
			}

			// Set the correct empty value (see #6284, #6373)
			if ($varValue === '')
			{
				$varValue = Widget::getEmptyValueByFieldType($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['sql']);
			}

			$arrValues = $this->values;
			array_unshift($arrValues, $varValue);

			$objUpdateStmt = $this->Database->prepare("UPDATE " . $this->strTable . " SET " . Database::quoteIdentifier($this->strField) . "=? WHERE " . implode(' AND ', $this->procedure))
											->execute($arrValues);

			if ($objUpdateStmt->affectedRows)
			{
				$this->blnCreateNewVersion = true;
				$this->varValue = StringUtil::deserialize($varValue);

				if (\is_object($this->objActiveRecord))
				{
					$this->objActiveRecord->{$this->strField} = $this->varValue;
				}
			}
		}
	}
protected function save($varValue)
	{
		if (Input::post('FORM_SUBMIT') != $this->strTable)
		{
			return;
		}

		$arrData = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField];

		// Convert date formats into timestamps
		if ($varValue !== null && $varValue !== '' && \in_array($arrData['eval']['rgxp'], array('date', 'time', 'datim')))
		{
			$objDate = new Date($varValue, Date::getFormatFromRgxp($arrData['eval']['rgxp']));
			$varValue = $objDate->tstamp;
		}

		// Make sure unique fields are unique
		if ($arrData['eval']['unique'] && $varValue != '' && !$this->Database->isUniqueValue($this->strTable, $this->strField, $varValue, $this->objActiveRecord->id))
		{
			throw new \Exception(sprintf($GLOBALS['TL_LANG']['ERR']['unique'], $arrData['label'][0] ?: $this->strField));
		}

		// Handle multi-select fields in "override all" mode
		if (Input::get('act') == 'overrideAll' && ($arrData['inputType'] == 'checkbox' || $arrData['inputType'] == 'checkboxWizard') && $arrData['eval']['multiple'])
		{
			if ($this->objActiveRecord !== null)
			{
				$new = StringUtil::deserialize($varValue, true);
				$old = StringUtil::deserialize($this->objActiveRecord->{$this->strField}, true);

				// Call load_callback
				if (\is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['load_callback']))
				{
					foreach ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['load_callback'] as $callback)
					{
						if (\is_array($callback))
						{
							$this->import($callback[0]);
							$old = $this->{$callback[0]}->{$callback[1]}($old, $this);
						}
						elseif (\is_callable($callback))
						{
							$old = $callback($old, $this);
						}
					}
				}

				switch (Input::post($this->strInputName . '_update'))
				{
					case 'add':
						$varValue = array_values(array_unique(array_merge($old, $new)));
						break;

					case 'remove':
						$varValue = array_values(array_diff($old, $new));
						break;

					case 'replace':
						$varValue = $new;
						break;
				}

				if (empty($varValue) || !\is_array($varValue))
				{
					$varValue = Widget::getEmptyStringOrNullByFieldType($arrData['sql']);
				}
				elseif (isset($arrData['eval']['csv']))
				{
					$varValue = implode($arrData['eval']['csv'], $varValue); // see #2890
				}
				else
				{
					$varValue = serialize($varValue);
				}
			}
		}

		// Convert arrays (see #2890)
		if ($arrData['eval']['multiple'] && isset($arrData['eval']['csv']))
		{
			$varValue = implode($arrData['eval']['csv'], StringUtil::deserialize($varValue, true));
		}

		// Trigger the save_callback
		if (\is_array($arrData['save_callback']))
		{
			foreach ($arrData['save_callback'] as $callback)
			{
				if (\is_array($callback))
				{
					$this->import($callback[0]);
					$varValue = $this->{$callback[0]}->{$callback[1]}($varValue, $this);
				}
				elseif (\is_callable($callback))
				{
					$varValue = $callback($varValue, $this);
				}
			}
		}

		// Save the value if there was no error
		if (($varValue != '' || !$arrData['eval']['doNotSaveEmpty']) && ($this->varValue !== $varValue || $arrData['eval']['alwaysSave']))
		{
			// If the field is a fallback field, empty all other columns (see #6498)
			if ($arrData['eval']['fallback'] && $varValue != '')
			{
				if ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 4)
				{
					$this->Database->prepare("UPDATE " . $this->strTable . " SET " . Database::quoteIdentifier($this->strField) . "='' WHERE pid=?")
								   ->execute($this->activeRecord->pid);
				}
				else
				{
					$this->Database->execute("UPDATE " . $this->strTable . " SET " . Database::quoteIdentifier($this->strField) . "=''");
				}
			}

			// Set the correct empty value (see #6284, #6373)
			if ($varValue === '')
			{
				$varValue = Widget::getEmptyValueByFieldType($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['sql']);
			}

			$arrValues = $this->values;
			array_unshift($arrValues, $varValue);

			$objUpdateStmt = $this->Database->prepare("UPDATE " . $this->strTable . " SET " . Database::quoteIdentifier($this->strField) . "=? WHERE " . implode(' AND ', $this->procedure))
											->execute($arrValues);

			if ($objUpdateStmt->affectedRows)
			{
				$this->blnCreateNewVersion = true;
				$this->varValue = StringUtil::deserialize($varValue);

				if (\is_object($this->objActiveRecord))
				{
					$this->objActiveRecord->{$this->strField} = $this->varValue;
				}
			}
		}
	}
Save the current value

@param mixed $varValue

@throws \Exception