core-bundle/src/Resources/contao/library/Contao/Widget.php
public static function getAttributesFromDca($arrData, $strName, $varValue=null, $strField='', $strTable='', $objDca=null)
	{
		$arrAttributes = $arrData['eval'];

		$arrAttributes['id'] = $strName;
		$arrAttributes['name'] = $strName;
		$arrAttributes['strField'] = $strField;
		$arrAttributes['strTable'] = $strTable;
		$arrAttributes['label'] = (($label = \is_array($arrData['label']) ? $arrData['label'][0] : $arrData['label']) != false) ? $label : $strField;
		$arrAttributes['description'] = $arrData['label'][1];
		$arrAttributes['type'] = $arrData['inputType'];
		$arrAttributes['dataContainer'] = $objDca;

		// Internet Explorer does not support onchange for checkboxes and radio buttons
		if ($arrData['eval']['submitOnChange'])
		{
			if ($arrData['inputType'] == 'checkbox' || $arrData['inputType'] == 'checkboxWizard' || $arrData['inputType'] == 'radio' || $arrData['inputType'] == 'radioTable')
			{
				$arrAttributes['onclick'] = trim($arrAttributes['onclick'] . " Backend.autoSubmit('".$strTable."')");
			}
			else
			{
				$arrAttributes['onchange'] = trim($arrAttributes['onchange'] . " Backend.autoSubmit('".$strTable."')");
			}
		}

		$arrAttributes['allowHtml'] = ($arrData['eval']['allowHtml'] || \strlen($arrData['eval']['rte']) || $arrData['eval']['preserveTags']) ? true : false;

		// Decode entities if HTML is allowed
		if ($arrAttributes['allowHtml'] || $arrData['inputType'] == 'fileTree')
		{
			$arrAttributes['decodeEntities'] = true;
		}

		// Add Ajax event
		if ($arrData['inputType'] == 'checkbox' && \is_array($GLOBALS['TL_DCA'][$strTable]['subpalettes']) && \array_key_exists($strField, $GLOBALS['TL_DCA'][$strTable]['subpalettes']) && $arrData['eval']['submitOnChange'])
		{
			$arrAttributes['onclick'] = "AjaxRequest.toggleSubpalette(this, 'sub_".$strName."', '".$strField."')";
		}

		// Options callback
		if (\is_array($arrData['options_callback']))
		{
			$arrCallback = $arrData['options_callback'];
			$arrData['options'] = static::importStatic($arrCallback[0])->{$arrCallback[1]}($objDca);
		}
		elseif (\is_callable($arrData['options_callback']))
		{
			$arrData['options'] = $arrData['options_callback']($objDca);
		}

		// Foreign key
		elseif (isset($arrData['foreignKey']))
		{
			$arrKey = explode('.', $arrData['foreignKey'], 2);
			$objOptions = Database::getInstance()->query("SELECT id, " . $arrKey[1] . " AS value FROM " . $arrKey[0] . " WHERE tstamp>0 ORDER BY value");
			$arrData['options'] = array();

			while ($objOptions->next())
			{
				$arrData['options'][$objOptions->id] = $objOptions->value;
			}
		}

		// Add default option to single checkbox
		if ($arrData['inputType'] == 'checkbox' && !isset($arrData['options']) && !isset($arrData['options_callback']) && !isset($arrData['foreignKey']))
		{
			if (TL_MODE == 'FE' && isset($arrAttributes['description']))
			{
				$arrAttributes['options'][] = array('value'=>1, 'label'=>$arrAttributes['description']);
			}
			else
			{
				$arrAttributes['options'][] = array('value'=>1, 'label'=>$arrAttributes['label']);
			}
		}

		// Add options
		if (\is_array($arrData['options']))
		{
			$blnIsAssociative = ($arrData['eval']['isAssociative'] || array_is_assoc($arrData['options']));
			$blnUseReference = isset($arrData['reference']);

			if ($arrData['eval']['includeBlankOption'] && !$arrData['eval']['multiple'])
			{
				$strLabel = $arrData['eval']['blankOptionLabel'] ?? '-';
				$arrAttributes['options'][] = array('value'=>'', 'label'=>$strLabel);
			}

			foreach ($arrData['options'] as $k=>$v)
			{
				if (!\is_array($v))
				{
					$arrAttributes['options'][] = array('value'=>($blnIsAssociative ? $k : $v), 'label'=>($blnUseReference ? ((($ref = (\is_array($arrData['reference'][$v]) ? $arrData['reference'][$v][0] : $arrData['reference'][$v])) != false) ? $ref : $v) : $v));
					continue;
				}

				$key = $blnUseReference ? ((($ref = (\is_array($arrData['reference'][$k]) ? $arrData['reference'][$k][0] : $arrData['reference'][$k])) != false) ? $ref : $k) : $k;
				$blnIsAssoc = array_is_assoc($v);

				foreach ($v as $kk=>$vv)
				{
					$arrAttributes['options'][$key][] = array('value'=>($blnIsAssoc ? $kk : $vv), 'label'=>($blnUseReference ? ((($ref = (\is_array($arrData['reference'][$vv]) ? $arrData['reference'][$vv][0] : $arrData['reference'][$vv])) != false) ? $ref : $vv) : $vv));
				}
			}
		}

		if (\is_array($arrAttributes['sql']) && !isset($arrAttributes['sql']['columnDefinition']))
		{
			if (isset($arrAttributes['sql']['length']) && !isset($arrAttributes['maxlength']))
			{
				$arrAttributes['maxlength'] = $arrAttributes['sql']['length'];
			}

			if (isset($arrAttributes['sql']['customSchemaOptions']['unique']) && !isset($arrAttributes['unique']))
			{
				$arrAttributes['unique'] = $arrAttributes['sql']['customSchemaOptions']['unique'];
			}
		}

		$arrAttributes['value'] = StringUtil::deserialize($varValue);

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

		// Add the "rootNodes" array as attribute (see #3563)
		if (isset($arrData['rootNodes']) && !isset($arrData['eval']['rootNodes']))
		{
			$arrAttributes['rootNodes'] = $arrData['rootNodes'];
		}

		// HOOK: add custom logic
		if (isset($GLOBALS['TL_HOOKS']['getAttributesFromDca']) && \is_array($GLOBALS['TL_HOOKS']['getAttributesFromDca']))
		{
			foreach ($GLOBALS['TL_HOOKS']['getAttributesFromDca'] as $callback)
			{
				$arrAttributes = static::importStatic($callback[0])->{$callback[1]}($arrAttributes, $objDca);
			}
		}

		// Warn if someone uses the "encrypt" flag (see #8589)
		if (isset($arrAttributes['encrypt']))
		{
			@trigger_error('Using the "encrypt" flag' . (!empty($strTable) && !empty($strField) ? ' on ' . $strTable . '.' . $strField : '') . ' has been deprecated and will no longer work in Contao 5.0. Use the load and save callbacks with a third-party library such as OpenSSL or phpseclib instead.', E_USER_DEPRECATED);
		}

		return $arrAttributes;
	}
public static function getAttributesFromDca($arrData, $strName, $varValue=null, $strField='', $strTable='', $objDca=null)
	{
		$arrAttributes = $arrData['eval'];

		$arrAttributes['id'] = $strName;
		$arrAttributes['name'] = $strName;
		$arrAttributes['strField'] = $strField;
		$arrAttributes['strTable'] = $strTable;
		$arrAttributes['label'] = (($label = \is_array($arrData['label']) ? $arrData['label'][0] : $arrData['label']) != false) ? $label : $strField;
		$arrAttributes['description'] = $arrData['label'][1];
		$arrAttributes['type'] = $arrData['inputType'];
		$arrAttributes['dataContainer'] = $objDca;

		// Internet Explorer does not support onchange for checkboxes and radio buttons
		if ($arrData['eval']['submitOnChange'])
		{
			if ($arrData['inputType'] == 'checkbox' || $arrData['inputType'] == 'checkboxWizard' || $arrData['inputType'] == 'radio' || $arrData['inputType'] == 'radioTable')
			{
				$arrAttributes['onclick'] = trim($arrAttributes['onclick'] . " Backend.autoSubmit('".$strTable."')");
			}
			else
			{
				$arrAttributes['onchange'] = trim($arrAttributes['onchange'] . " Backend.autoSubmit('".$strTable."')");
			}
		}

		$arrAttributes['allowHtml'] = ($arrData['eval']['allowHtml'] || \strlen($arrData['eval']['rte']) || $arrData['eval']['preserveTags']) ? true : false;

		// Decode entities if HTML is allowed
		if ($arrAttributes['allowHtml'] || $arrData['inputType'] == 'fileTree')
		{
			$arrAttributes['decodeEntities'] = true;
		}

		// Add Ajax event
		if ($arrData['inputType'] == 'checkbox' && \is_array($GLOBALS['TL_DCA'][$strTable]['subpalettes']) && \array_key_exists($strField, $GLOBALS['TL_DCA'][$strTable]['subpalettes']) && $arrData['eval']['submitOnChange'])
		{
			$arrAttributes['onclick'] = "AjaxRequest.toggleSubpalette(this, 'sub_".$strName."', '".$strField."')";
		}

		// Options callback
		if (\is_array($arrData['options_callback']))
		{
			$arrCallback = $arrData['options_callback'];
			$arrData['options'] = static::importStatic($arrCallback[0])->{$arrCallback[1]}($objDca);
		}
		elseif (\is_callable($arrData['options_callback']))
		{
			$arrData['options'] = $arrData['options_callback']($objDca);
		}

		// Foreign key
		elseif (isset($arrData['foreignKey']))
		{
			$arrKey = explode('.', $arrData['foreignKey'], 2);
			$objOptions = Database::getInstance()->query("SELECT id, " . $arrKey[1] . " AS value FROM " . $arrKey[0] . " WHERE tstamp>0 ORDER BY value");
			$arrData['options'] = array();

			while ($objOptions->next())
			{
				$arrData['options'][$objOptions->id] = $objOptions->value;
			}
		}

		// Add default option to single checkbox
		if ($arrData['inputType'] == 'checkbox' && !isset($arrData['options']) && !isset($arrData['options_callback']) && !isset($arrData['foreignKey']))
		{
			if (TL_MODE == 'FE' && isset($arrAttributes['description']))
			{
				$arrAttributes['options'][] = array('value'=>1, 'label'=>$arrAttributes['description']);
			}
			else
			{
				$arrAttributes['options'][] = array('value'=>1, 'label'=>$arrAttributes['label']);
			}
		}

		// Add options
		if (\is_array($arrData['options']))
		{
			$blnIsAssociative = ($arrData['eval']['isAssociative'] || array_is_assoc($arrData['options']));
			$blnUseReference = isset($arrData['reference']);

			if ($arrData['eval']['includeBlankOption'] && !$arrData['eval']['multiple'])
			{
				$strLabel = $arrData['eval']['blankOptionLabel'] ?? '-';
				$arrAttributes['options'][] = array('value'=>'', 'label'=>$strLabel);
			}

			foreach ($arrData['options'] as $k=>$v)
			{
				if (!\is_array($v))
				{
					$arrAttributes['options'][] = array('value'=>($blnIsAssociative ? $k : $v), 'label'=>($blnUseReference ? ((($ref = (\is_array($arrData['reference'][$v]) ? $arrData['reference'][$v][0] : $arrData['reference'][$v])) != false) ? $ref : $v) : $v));
					continue;
				}

				$key = $blnUseReference ? ((($ref = (\is_array($arrData['reference'][$k]) ? $arrData['reference'][$k][0] : $arrData['reference'][$k])) != false) ? $ref : $k) : $k;
				$blnIsAssoc = array_is_assoc($v);

				foreach ($v as $kk=>$vv)
				{
					$arrAttributes['options'][$key][] = array('value'=>($blnIsAssoc ? $kk : $vv), 'label'=>($blnUseReference ? ((($ref = (\is_array($arrData['reference'][$vv]) ? $arrData['reference'][$vv][0] : $arrData['reference'][$vv])) != false) ? $ref : $vv) : $vv));
				}
			}
		}

		if (\is_array($arrAttributes['sql']) && !isset($arrAttributes['sql']['columnDefinition']))
		{
			if (isset($arrAttributes['sql']['length']) && !isset($arrAttributes['maxlength']))
			{
				$arrAttributes['maxlength'] = $arrAttributes['sql']['length'];
			}

			if (isset($arrAttributes['sql']['customSchemaOptions']['unique']) && !isset($arrAttributes['unique']))
			{
				$arrAttributes['unique'] = $arrAttributes['sql']['customSchemaOptions']['unique'];
			}
		}

		$arrAttributes['value'] = StringUtil::deserialize($varValue);

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

		// Add the "rootNodes" array as attribute (see #3563)
		if (isset($arrData['rootNodes']) && !isset($arrData['eval']['rootNodes']))
		{
			$arrAttributes['rootNodes'] = $arrData['rootNodes'];
		}

		// HOOK: add custom logic
		if (isset($GLOBALS['TL_HOOKS']['getAttributesFromDca']) && \is_array($GLOBALS['TL_HOOKS']['getAttributesFromDca']))
		{
			foreach ($GLOBALS['TL_HOOKS']['getAttributesFromDca'] as $callback)
			{
				$arrAttributes = static::importStatic($callback[0])->{$callback[1]}($arrAttributes, $objDca);
			}
		}

		// Warn if someone uses the "encrypt" flag (see #8589)
		if (isset($arrAttributes['encrypt']))
		{
			@trigger_error('Using the "encrypt" flag' . (!empty($strTable) && !empty($strField) ? ' on ' . $strTable . '.' . $strField : '') . ' has been deprecated and will no longer work in Contao 5.0. Use the load and save callbacks with a third-party library such as OpenSSL or phpseclib instead.', E_USER_DEPRECATED);
		}

		return $arrAttributes;
	}
public static function getAttributesFromDca ( $ arrData , $ strName , $ varValue = null , $ strField = '' , $ strTable = '' , $ objDca = null ) { $ arrAttributes = $ arrData [ 'eval' ] ; $ arrAttributes [ 'id' ] = $ strName ; $ arrAttributes [ 'name' ] = $ strName ; $ arrAttributes [ 'strField' ] = $ strField ; $ arrAttributes [ 'strTable' ] = $ strTable ; $ arrAttributes [ 'label' ] = ( ( $ label = \ is_array ( $ arrData [ 'label' ] ) ? $ arrData [ 'label' ] [ 0 ] : $ arrData [ 'label' ] ) != false ) ? $ label : $ strField ; $ arrAttributes [ 'description' ] = $ arrData [ 'label' ] [ 1 ] ; $ arrAttributes [ 'type' ] = $ arrData [ 'inputType' ] ; $ arrAttributes [ 'dataContainer' ] = $ objDca ; // Internet Explorer does not support onchange for checkboxes and radio buttons if ( $ arrData [ 'eval' ] [ 'submitOnChange' ] ) { if ( $ arrData [ 'inputType' ] == 'checkbox' || $ arrData [ 'inputType' ] == 'checkboxWizard' || $ arrData [ 'inputType' ] == 'radio' || $ arrData [ 'inputType' ] == 'radioTable' ) { $ arrAttributes [ 'onclick' ] = trim ( $ arrAttributes [ 'onclick' ] . " Backend.autoSubmit('" . $ strTable . "')" ) ; } else { $ arrAttributes [ 'onchange' ] = trim ( $ arrAttributes [ 'onchange' ] . " Backend.autoSubmit('" . $ strTable . "')" ) ; } } $ arrAttributes [ 'allowHtml' ] = ( $ arrData [ 'eval' ] [ 'allowHtml' ] || \ strlen ( $ arrData [ 'eval' ] [ 'rte' ] ) || $ arrData [ 'eval' ] [ 'preserveTags' ] ) ? true : false ; // Decode entities if HTML is allowed if ( $ arrAttributes [ 'allowHtml' ] || $ arrData [ 'inputType' ] == 'fileTree' ) { $ arrAttributes [ 'decodeEntities' ] = true ; } // Add Ajax event if ( $ arrData [ 'inputType' ] == 'checkbox' && \ is_array ( $ GLOBALS [ 'TL_DCA' ] [ $ strTable ] [ 'subpalettes' ] ) && \ array_key_exists ( $ strField , $ GLOBALS [ 'TL_DCA' ] [ $ strTable ] [ 'subpalettes' ] ) && $ arrData [ 'eval' ] [ 'submitOnChange' ] ) { $ arrAttributes [ 'onclick' ] = "AjaxRequest.toggleSubpalette(this, 'sub_" . $ strName . "', '" . $ strField . "')" ; } // Options callback if ( \ is_array ( $ arrData [ 'options_callback' ] ) ) { $ arrCallback = $ arrData [ 'options_callback' ] ; $ arrData [ 'options' ] = static :: importStatic ( $ arrCallback [ 0 ] ) -> { $ arrCallback [ 1 ] } ( $ objDca ) ; } elseif ( \ is_callable ( $ arrData [ 'options_callback' ] ) ) { $ arrData [ 'options' ] = $ arrData [ 'options_callback' ] ( $ objDca ) ; } // Foreign key elseif ( isset ( $ arrData [ 'foreignKey' ] ) ) { $ arrKey = explode ( '.' , $ arrData [ 'foreignKey' ] , 2 ) ; $ objOptions = Database :: getInstance ( ) -> query ( "SELECT id, " . $ arrKey [ 1 ] . " AS value FROM " . $ arrKey [ 0 ] . " WHERE tstamp>0 ORDER BY value" ) ; $ arrData [ 'options' ] = array ( ) ; while ( $ objOptions -> next ( ) ) { $ arrData [ 'options' ] [ $ objOptions -> id ] = $ objOptions -> value ; } } // Add default option to single checkbox if ( $ arrData [ 'inputType' ] == 'checkbox' && ! isset ( $ arrData [ 'options' ] ) && ! isset ( $ arrData [ 'options_callback' ] ) && ! isset ( $ arrData [ 'foreignKey' ] ) ) { if ( TL_MODE == 'FE' && isset ( $ arrAttributes [ 'description' ] ) ) { $ arrAttributes [ 'options' ] [ ] = array ( 'value' => 1 , 'label' => $ arrAttributes [ 'description' ] ) ; } else { $ arrAttributes [ 'options' ] [ ] = array ( 'value' => 1 , 'label' => $ arrAttributes [ 'label' ] ) ; } } // Add options if ( \ is_array ( $ arrData [ 'options' ] ) ) { $ blnIsAssociative = ( $ arrData [ 'eval' ] [ 'isAssociative' ] || array_is_assoc ( $ arrData [ 'options' ] ) ) ; $ blnUseReference = isset ( $ arrData [ 'reference' ] ) ; if ( $ arrData [ 'eval' ] [ 'includeBlankOption' ] && ! $ arrData [ 'eval' ] [ 'multiple' ] ) { $ strLabel = $ arrData [ 'eval' ] [ 'blankOptionLabel' ] ?? '-' ; $ arrAttributes [ 'options' ] [ ] = array ( 'value' => '' , 'label' => $ strLabel ) ; } foreach ( $ arrData [ 'options' ] as $ k => $ v ) { if ( ! \ is_array ( $ v ) ) { $ arrAttributes [ 'options' ] [ ] = array ( 'value' => ( $ blnIsAssociative ? $ k : $ v ) , 'label' => ( $ blnUseReference ? ( ( ( $ ref = ( \ is_array ( $ arrData [ 'reference' ] [ $ v ] ) ? $ arrData [ 'reference' ] [ $ v ] [ 0 ] : $ arrData [ 'reference' ] [ $ v ] ) ) != false ) ? $ ref : $ v ) : $ v ) ) ; continue ; } $ key = $ blnUseReference ? ( ( ( $ ref = ( \ is_array ( $ arrData [ 'reference' ] [ $ k ] ) ? $ arrData [ 'reference' ] [ $ k ] [ 0 ] : $ arrData [ 'reference' ] [ $ k ] ) ) != false ) ? $ ref : $ k ) : $ k ; $ blnIsAssoc = array_is_assoc ( $ v ) ; foreach ( $ v as $ kk => $ vv ) { $ arrAttributes [ 'options' ] [ $ key ] [ ] = array ( 'value' => ( $ blnIsAssoc ? $ kk : $ vv ) , 'label' => ( $ blnUseReference ? ( ( ( $ ref = ( \ is_array ( $ arrData [ 'reference' ] [ $ vv ] ) ? $ arrData [ 'reference' ] [ $ vv ] [ 0 ] : $ arrData [ 'reference' ] [ $ vv ] ) ) != false ) ? $ ref : $ vv ) : $ vv ) ) ; } } } if ( \ is_array ( $ arrAttributes [ 'sql' ] ) && ! isset ( $ arrAttributes [ 'sql' ] [ 'columnDefinition' ] ) ) { if ( isset ( $ arrAttributes [ 'sql' ] [ 'length' ] ) && ! isset ( $ arrAttributes [ 'maxlength' ] ) ) { $ arrAttributes [ 'maxlength' ] = $ arrAttributes [ 'sql' ] [ 'length' ] ; } if ( isset ( $ arrAttributes [ 'sql' ] [ 'customSchemaOptions' ] [ 'unique' ] ) && ! isset ( $ arrAttributes [ 'unique' ] ) ) { $ arrAttributes [ 'unique' ] = $ arrAttributes [ 'sql' ] [ 'customSchemaOptions' ] [ 'unique' ] ; } } $ arrAttributes [ 'value' ] = StringUtil :: deserialize ( $ varValue ) ; // Convert timestamps if ( $ varValue !== null && $ varValue !== '' && \ in_array ( $ arrData [ 'eval' ] [ 'rgxp' ] , array ( 'date' , 'time' , 'datim' ) ) ) { $ objDate = new Date ( $ varValue , Date :: getFormatFromRgxp ( $ arrData [ 'eval' ] [ 'rgxp' ] ) ) ; $ arrAttributes [ 'value' ] = $ objDate -> { $ arrData [ 'eval' ] [ 'rgxp' ] } ; } // Add the "rootNodes" array as attribute (see #3563) if ( isset ( $ arrData [ 'rootNodes' ] ) && ! isset ( $ arrData [ 'eval' ] [ 'rootNodes' ] ) ) { $ arrAttributes [ 'rootNodes' ] = $ arrData [ 'rootNodes' ] ; } // HOOK: add custom logic if ( isset ( $ GLOBALS [ 'TL_HOOKS' ] [ 'getAttributesFromDca' ] ) && \ is_array ( $ GLOBALS [ 'TL_HOOKS' ] [ 'getAttributesFromDca' ] ) ) { foreach ( $ GLOBALS [ 'TL_HOOKS' ] [ 'getAttributesFromDca' ] as $ callback ) { $ arrAttributes = static :: importStatic ( $ callback [ 0 ] ) -> { $ callback [ 1 ] } ( $ arrAttributes , $ objDca ) ; } } // Warn if someone uses the "encrypt" flag (see #8589) if ( isset ( $ arrAttributes [ 'encrypt' ] ) ) { @ trigger_error ( 'Using the "encrypt" flag' . ( ! empty ( $ strTable ) && ! empty ( $ strField ) ? ' on ' . $ strTable . '.' . $ strField : '' ) . ' has been deprecated and will no longer work in Contao 5.0. Use the load and save callbacks with a third-party library such as OpenSSL or phpseclib instead.' , E_USER_DEPRECATED ) ; } return $ arrAttributes ; }
Extract the Widget attributes from a Data Container array

@param array              $arrData  The field configuration array
@param string             $strName  The field name in the form
@param mixed              $varValue The field value
@param string             $strField The field name in the database
@param string             $strTable The table name in the database
@param DataContainer|null $objDca   An optional DataContainer object

@return array An attributes array that can be passed to a widget
Extract the Widget attributes from a Data Container array