2025-11-19 14:14:53 +00:00
< ? php
/* Copyright ( C ) 2002 - 2003 Rodolphe Quiedeville < rodolphe @ quiedeville . org >
* Copyright ( C ) 2002 - 2003 Jean - Louis Bergamo < jlb @ j1b . org >
* Copyright ( C ) 2004 Sebastien Di Cintio < sdicintio @ ressource - toi . org >
* Copyright ( C ) 2004 Benoit Mortier < benoit . mortier @ opensides . be >
* Copyright ( C ) 2009 - 2012 Laurent Destailleur < eldy @ users . sourceforge . net >
* Copyright ( C ) 2009 - 2012 Regis Houssin < regis . houssin @ inodbox . com >
* Copyright ( C ) 2013 Florian Henry < forian . henry @ open - concept . pro >
* Copyright ( C ) 2015 Charles - Fr BENKE < charles . fr @ benke . fr >
* Copyright ( C ) 2016 Raphaël Doursenaud < rdoursenaud @ gpcsolutions . fr >
* Copyright ( C ) 2017 Nicolas ZABOURI < info @ inovea - conseil . com >
* Copyright ( C ) 2018 - 2022 Frédéric France < frederic . france @ netlogic . fr >
* Copyright ( C ) 2022 Antonin MARCHAL < antonin @ letempledujeu . fr >
2026-07-20 13:26:30 +00:00
* Copyright ( C ) 2026 MDW < mdeweerd @ users . noreply . github . com >
2025-11-19 14:14:53 +00:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < https :// www . gnu . org / licenses />.
*/
/**
* \file htdocs / core / class / fieldsmanager . class . php
* \ingroup core
* \brief File of class to manage fields
*/
require_once DOL_DOCUMENT_ROOT . '/core/class/fieldinfos.class.php' ;
require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php' ;
/**
* Class to manage fields
*/
class FieldsManager
{
/**
* @ var DoliDB Database handler .
*/
public $db ;
/**
* @ var string Error code ( or message )
*/
public $error = '' ;
/**
* @ var string [] Array of Error code ( or message )
*/
public $errors = array ();
/**
* @ var array < string , string > To store error results of -> validateField ()
*/
public $validateFieldsErrors = array ();
/**
* @ var string Path to fields classes
*/
public $fieldsPath = '/core/class/fields/' ;
/**
* @ var array < string , CommonField > Field classes cached
*/
public static $fieldClasses = array ();
/**
* @ var array < string , array < string , array { object : array < string , FieldInfos > , extraField : array < string , FieldInfos > } >> Field infos cached ( array < element , array < mode ,{ object : array < fieldKey , fieldInfos > , extraField : array < fieldKey , fieldInfos > } >> )
*/
public static $fieldInfos = array ();
/**
* @ var array < string , bool | int < 0 , 1 >>| null Array with boolean of status of groups
*/
public $expand_display = array ();
///**
// * @var array<string,string> Array of type to label
// */
//public static $type2label = array(
// 'varchar' => 'String1Line',
// 'text' => 'TextLongNLines',
// 'html' => 'HtmlText',
// 'int' => 'Int',
// 'double' => 'Float',
// 'date' => 'Date',
// 'datetime' => 'DateAndTime',
// 'duration' => 'Duration',
// //'datetimegmt'=>'DateAndTimeUTC',
// 'boolean' => 'Boolean',
// 'price' => 'ExtrafieldPrice',
// 'pricecy' => 'ExtrafieldPriceWithCurrency',
// 'phone' => 'ExtrafieldPhone',
// 'email' => 'ExtrafieldMail',
// 'url' => 'ExtrafieldUrl',
// 'ip' => 'ExtrafieldIP',
// 'icon' => 'Icon',
// 'password' => 'ExtrafieldPassword',
// 'radio' => 'ExtrafieldRadio',
// 'select' => 'ExtrafieldSelect',
// 'sellist' => 'ExtrafieldSelectList',
// 'checkbox' => 'ExtrafieldCheckBox',
// 'chkbxlst' => 'ExtrafieldCheckBoxFromList',
// 'link' => 'ExtrafieldLink',
// 'point' => 'ExtrafieldPointGeo',
// 'multipts' => 'ExtrafieldMultiPointGeo',
// 'linestrg' => 'ExtrafieldLinestringGeo',
// 'polygon' => 'ExtrafieldPolygonGeo',
// 'separate' => 'ExtrafieldSeparator',
// 'stars' => 'ExtrafieldStars',
// //'real' => 'ExtrafieldReal',
//);
/**
* Constructor
*
* @ param DoliDB $db Database handler
* @ param Form | null $form Specific form handler
*/
public function __construct ( $db , $form = null )
{
$this -> db = $db ;
$this -> error = '' ;
$this -> errors = array ();
if ( isset ( $form )) {
CommonField :: setForm ( $form );
}
}
/**
* Get field handler for the provided type
*
* @ param string $type Field type
* @ return CommonField | null
*/
public function getFieldClass ( $type )
{
global $hookmanager , $langs ;
$type = trim ( $type );
if ( ! isset ( self :: $fieldClasses [ $type ])) {
$field = null ;
$parameters = array (
'type' => $type ,
// @phan-suppress-next-line PhanPluginConstantVariableNull
'field' => & $field ,
);
$hookmanager -> executeHooks ( 'getFieldClass' , $parameters , $this ); // Note that $object may have been modified by hook
// @phpstan-ignore-next-line @phan-suppress-next-line PhanPluginConstantVariableNull
if ( isset ( $field ) && is_object ( $field )) {
self :: $fieldClasses [ $type ] = $field ;
} else {
$filename = strtolower ( $type ) . 'field.class.php' ;
$classname = ucfirst ( $type ) . 'Field' ;
// Load class file
dol_include_once ( rtrim ( $this -> fieldsPath , '/' ) . '/' . $filename );
if ( ! class_exists ( $classname )) {
@ include_once DOL_DOCUMENT_ROOT . '/core/class/fields/' . $filename ;
}
if ( class_exists ( $classname )) {
self :: $fieldClasses [ $type ] = new $classname ( $this -> db );
} else {
$langs -> load ( " errors " );
$this -> errors [] = $langs -> trans ( 'ErrorFieldClassNotFoundForClassName' , $classname , $type );
return null ;
}
}
}
$field = self :: $fieldClasses [ $type ];
$field -> clearErrors ();
return $field ;
}
/**
* Get all fields handler available
*
* @ return array < string , CommonField >
*/
public function getAllFields ()
{
// Todo to make
return self :: $fieldClasses ;
}
/**
* clear errors
*
* @ return void
*/
public function clearErrors ()
{
$this -> error = '' ;
$this -> errors = array ();
}
/**
* Method to output saved errors
*
* @ param string $separator Separator between each error
* @ return string String with errors
*/
public function errorsToString ( $separator = ', ' )
{
return $this -> error . ( is_array ( $this -> errors ) ? ( ! empty ( $this -> error ) ? $separator : '' ) . implode ( $separator , $this -> errors ) : '' );
}
/**
* clear validation message result for a field
*
* @ param string $fieldKey Key of attribute to clear
* @ return void
*/
public function clearFieldError ( $fieldKey )
{
$this -> error = '' ;
unset ( $this -> validateFieldsErrors [ $fieldKey ]);
}
/**
* set validation error message a field
*
* @ param string $fieldKey Key of attribute
* @ param string $msg the field error message
* @ return void
*/
public function setFieldError ( $fieldKey , $msg = '' )
{
global $langs ;
if ( empty ( $msg )) {
$msg = $langs -> trans ( " UnknownError " );
}
$this -> error = $this -> validateFieldsErrors [ $fieldKey ] = $msg ;
}
/**
* get field error message
*
* @ param string $fieldKey Key of attribute
* @ return string Error message of validation ( '' if no error )
*/
public function getFieldError ( $fieldKey )
{
if ( ! empty ( $this -> validateFieldsErrors [ $fieldKey ])) {
return $this -> validateFieldsErrors [ $fieldKey ];
}
return '' ;
}
/**
* get field error icon
*
* @ param string $fieldValidationErrorMsg message to add in tooltip
* @ return string html output
*/
public function getFieldErrorIcon ( $fieldValidationErrorMsg )
{
$out = '' ;
if ( ! empty ( $fieldValidationErrorMsg ) && function_exists ( 'getFieldErrorIcon' )) {
$out .= ' ' . getFieldErrorIcon ( $fieldValidationErrorMsg );
}
return $out ;
}
/**
* Get list of fields infos for the provided mode into X columns
*
* @ param CommonObject $object Object handler
* @ param ExtraFields $extrafields ExtraFields handler
* @ param string $mode Get the fields infos for the provided mode ( 'create' , 'edit' , 'view' , 'list' )
* @ param int $nbColumn Split fields infos into X columns
* @ param array < int , string > $breakKeys Key used for break on each column ( ex : array ( 1 => 'total_ht' , ... ))
* @ param array < string , mixed > $params Other params
* @ return array { columns : array < int , array < string , FieldInfos >> , hiddenFields : array < string , FieldInfos > } List of fields info by column and hidden
*/
public function getAllFieldsInfos ( & $object , & $extrafields = null , $mode = 'view' , $nbColumn = 2 , $breakKeys = array (), $params = array ())
{
global $hookmanager , $langs ;
// Get object fields
$fields = $this -> getAllObjectFieldsInfos ( $object , $mode , $params );
// Old sort
if ( ! getDolGlobalInt ( 'MAIN_FIELDS_SORT_WITH_EXTRA_FIELDS' )) {
$fields = dol_sort_array ( $fields , 'position' );
}
// Get extra fields
$fields2 = $this -> getAllExtraFieldsInfos ( $object , $extrafields , $mode , $params );
$fields = array_merge ( $fields , $fields2 );
// New sort
if ( getDolGlobalInt ( 'MAIN_FIELDS_SORT_WITH_EXTRA_FIELDS' )) {
$fields = dol_sort_array ( $fields , 'position' );
}
// Split in columns
$idxColumn = 1 ;
$columns = array ();
$hiddenFields = array ();
$columns [ $idxColumn ] = array ();
$nbVisibleFields = 0 ;
foreach ( $fields as $field ) {
if ( $field -> visible ) {
$nbVisibleFields ++ ;
}
}
$nbFieldsByColumn = ceil ( $nbVisibleFields / $nbColumn );
$breakKey = $breakKeys [ $idxColumn ] ? ? '' ;
$idxField = 0 ;
foreach ( $fields as $key => $field ) {
if ( $idxColumn < $nbColumn && (( ! empty ( $breakKey ) && $key == $breakKey ) || ( empty ( $breakKey ) && $idxField == $nbFieldsByColumn ))) {
$idxColumn ++ ;
$idxField = 0 ;
$columns [ $idxColumn ] = array ();
}
if ( $field -> visible ) {
if ( $field -> type != 'separate' ) {
$idxField ++ ;
}
// Add field into column
$columns [ $idxColumn ][ $key ] = $field ;
} else {
$hiddenFields [ $key ] = $field ;
}
}
// Add column not created
for ( $idxColumn = 1 ; $idxColumn <= $nbColumn ; $idxColumn ++ ) {
if ( ! isset ( $columns [ $idxColumn ])) {
$columns [ $idxColumn ] = array ();
}
}
$parameters = array (
'object' => & $object ,
'extrafields' => & $extrafields ,
'mode' => $mode ,
'nbColumn' => $nbColumn ,
'breakKeys' => $breakKeys ,
'params' => $params ,
'columns' => & $columns ,
'hiddenFields' => & $hiddenFields ,
);
$hookmanager -> executeHooks ( 'getFieldInfosFromObjectField' , $parameters , $this ); // Note that $object may have been modified by hook
return array (
'columns' => $columns ,
'hiddenFields' => $hiddenFields ,
);
}
/**
* Get list of object fields infos
*
* @ param CommonObject $object Object handler
* @ param string $mode Get the fields infos for the provided mode ( 'create' , 'edit' , 'view' , 'list' )
* @ param array < string , mixed > $params Other params
* @ return array < string , FieldInfos > List of fields infos
*/
public function getAllObjectFieldsInfos ( & $object , $mode = 'view' , $params = array ())
{
global $hookmanager ;
// Get object fields
$fields = array ();
// @phpstan-ignore-next-line
if ( isset ( $object -> fields ) && is_array ( $object -> fields )) {
$keyPrefix = getDolGlobalInt ( 'MAIN_FIELDS_NEW_OBJECT_KEY_PREFIX' ) ? 'object_' : '' ;
foreach ( $object -> fields as $key => $field ) {
$fieldInfos = $this -> getFieldInfosFromObjectField ( $object , $key , $mode , $params );
$fields [ $keyPrefix . $key ] = $fieldInfos ;
}
}
$parameters = array (
'object' => & $object ,
'mode' => $mode ,
'params' => $params ,
'fields' => & $fields ,
);
$hookmanager -> executeHooks ( 'getAllObjectFieldsInfos' , $parameters , $this ); // Note that $object may have been modified by hook
return $fields ;
}
/**
* Get list of extra fields infos
*
* @ param CommonObject $object Object handler
* @ param ExtraFields $extrafields ExtraFields handler
* @ param string $mode Get the fields infos for the provided mode ( 'create' , 'edit' , 'view' , 'list' )
* @ param array < string , mixed > $params Other params
* @ return array < string , FieldInfos > List of fields infos
*/
public function getAllExtraFieldsInfos ( & $object , & $extrafields = null , $mode = 'view' , $params = array ())
{
global $hookmanager ;
// Get extra fields
$fields = array ();
if ( isset ( $extrafields -> attributes [ $object -> table_element ]) && is_array ( $extrafields -> attributes [ $object -> table_element ])) {
2025-11-25 13:39:30 +00:00
if ( isset ( $extrafields -> attributes [ $object -> table_element ][ 'label' ]) && is_array ( $extrafields -> attributes [ $object -> table_element ][ 'label' ])) {
$keyPrefix = 'options_' ;
foreach ( $extrafields -> attributes [ $object -> table_element ][ 'label' ] as $key => $label ) {
$fieldInfos = $this -> getFieldInfosFromExtraField ( $object , $extrafields , $key , $mode , $params );
$fields [ $keyPrefix . $key ] = $fieldInfos ;
}
2025-11-19 14:14:53 +00:00
}
}
$parameters = array (
'object' => & $object ,
'extrafields' => & $extrafields ,
'mode' => $mode ,
'params' => $params ,
'fields' => & $fields ,
);
$hookmanager -> executeHooks ( 'getAllExtraFieldsInfos' , $parameters , $this ); // Note that $object may have been modified by hook
return $fields ;
}
/**
* Get list of fields infos for the provided mode into X columns
*
* @ param string $key Field key ( begin by object_ for object or options_ for extrafields )
* @ param CommonObject $object Object handler
* @ param ExtraFields $extrafields ExtraFields handler
* @ param string $mode Get the fields infos for the provided mode ( 'create' , 'edit' , 'view' , 'list' )
* @ param array < string , mixed > $params Other params
* @ return FieldInfos | null Get field info or null if not found
*/
public function getFieldsInfos ( $key , & $object , & $extrafields = null , $mode = 'view' , $params = array ())
{
$fieldInfos = null ;
$patternObjectPrefix = getDolGlobalInt ( 'MAIN_FIELDS_NEW_OBJECT_KEY_PREFIX' ) ? 'object_' : '' ;
2026-03-26 20:16:46 +00:00
$matches = array ();
2025-11-19 14:14:53 +00:00
if ( preg_match ( '/^options_(.*)/i' , $key , $matches )) {
$fieldKey = $matches [ 1 ];
$fieldInfos = $this -> getFieldInfosFromExtraField ( $object , $extrafields , $fieldKey , $mode , $params );
} elseif ( preg_match ( '/^' . $patternObjectPrefix . '(.*)/i' , $key , $matches )) {
$fieldKey = $matches [ 2 ];
$fieldInfos = $this -> getFieldInfosFromObjectField ( $object , $fieldKey , $mode , $params );
}
return $fieldInfos ;
}
/**
* Get field infos from object field infos
*
* @ param CommonObject $object Object handler
* @ param string $key Field key
* @ param string $mode Get the fields infos for the provided mode ( 'create' , 'edit' , 'view' , 'list' )
* @ param array < string , mixed > $params Other params
* @ return FieldInfos | null Properties of the field or null if field not found
*/
public function getFieldInfosFromObjectField ( & $object , $key , $mode = 'view' , $params = array ())
{
global $hookmanager ;
if ( ! isset ( $object -> fields [ $key ])) {
return null ;
}
if ( isset ( self :: $fieldInfos [ $object -> element ][ $mode ][ 'object' ][ $key ])) {
return self :: $fieldInfos [ $object -> element ][ $mode ][ 'object' ][ $key ];
}
$attributes = $object -> fields [ $key ];
$fieldInfos = new FieldInfos ();
$fieldInfos -> fieldType = FieldInfos :: FIELD_TYPE_OBJECT ;
$fieldInfos -> originType = $attributes [ 'type' ] ? ? '' ;
$fieldInfos -> size = $attributes [ 'length' ] ? ? '' ;
$fieldInfos -> label = $attributes [ 'label' ] ? ? '' ;
$fieldInfos -> langFile = $attributes [ 'langfile' ] ? ? '' ;
2026-07-20 13:26:30 +00:00
$fieldInfos -> sqlAlias = $attributes [ 'alias' ] ? ? null ; // @phan-suppress-current-line SqlInjection
2025-11-19 14:14:53 +00:00
$fieldInfos -> picto = $attributes [ 'picto' ] ? ? '' ;
$fieldInfos -> position = $attributes [ 'position' ] ? ? 0 ;
$fieldInfos -> required = ( $attributes [ 'notnull' ] ? ? 0 ) > 0 ;
$fieldInfos -> alwaysEditable = ! empty ( $attributes [ 'alwayseditable' ]);
$fieldInfos -> defaultValue = $attributes [ 'default' ] ? ? '' ;
$fieldInfos -> css = $attributes [ 'css' ] ? ? '' ;
$fieldInfos -> viewCss = $attributes [ 'cssview' ] ? ? '' ;
$fieldInfos -> listCss = $attributes [ 'csslist' ] ? ? '' ;
$fieldInfos -> inputPlaceholder = $attributes [ 'placeholder' ] ? ? '' ;
$fieldInfos -> help = $attributes [ 'help' ] ? ? '' ;
$fieldInfos -> listHelp = $attributes [ 'helplist' ] ? ? '' ;
$fieldInfos -> showOnComboBox = ! empty ( $attributes [ 'showoncombobox' ]);
$fieldInfos -> inputDisabled = ! empty ( $attributes [ 'disabled' ]);
$fieldInfos -> inputAutofocus = ! empty ( $attributes [ 'autofocusoncreate' ]) && $mode == 'create' ;
$fieldInfos -> comment = $attributes [ 'comment' ] ? ? '' ;
$fieldInfos -> listTotalizable = ! empty ( $attributes [ 'isameasure' ]) && $attributes [ 'isameasure' ] == 1 ;
$fieldInfos -> validateField = ! empty ( $attributes [ 'validate' ]);
$fieldInfos -> copyToClipboard = $attributes [ 'copytoclipboard' ] ? ? 0 ;
$fieldInfos -> tdCss = $attributes [ 'tdcss' ] ? ? '' ;
$fieldInfos -> multiInput = ! empty ( $attributes [ 'multiinput' ]);
$fieldInfos -> nameInClass = $attributes [ 'nameinclass' ] ? ? $key ;
$fieldInfos -> nameInTable = $attributes [ 'nameintable' ] ? ? $key ;
$fieldInfos -> getNameUrlParams = $attributes [ 'get_name_url_params' ] ? ? null ;
$fieldInfos -> showOnHeader = ! empty ( $attributes [ 'showonheader' ]);
// TODO set nameinclass = "id" in fields "rowid"
if ( $fieldInfos -> nameInClass == 'rowid' ) {
$fieldInfos -> nameInClass = 'id' ;
}
$enabled = $attributes [ 'enabled' ] ? ? '1' ;
$visibility = $attributes [ 'visible' ] ? ? '1' ;
$perms = empty ( $attributes [ 'noteditable' ]) ? '1' : '0' ;
$this -> setCommonFieldInfos ( $fieldInfos , $object , $extrafields , $key , $mode , $enabled , $visibility , $perms , $params );
// Special case that force options and type ($type can be integer, varchar, ...)
if ( ! empty ( $attributes [ 'arrayofkeyval' ]) && is_array ( $attributes [ 'arrayofkeyval' ])) {
$fieldInfos -> options = $attributes [ 'arrayofkeyval' ];
// Special case that prevent to force $type to have multiple input @phan-suppress-next-line PhanTypeMismatchProperty
if ( ! $fieldInfos -> multiInput ) {
$fieldInfos -> type = (( $fieldInfos -> type == 'checkbox' ) ? $fieldInfos -> type : 'select' );
}
}
$parameters = array (
'object' => & $object ,
'key' => $key ,
'mode' => $mode ,
'fieldInfos' => & $fieldInfos ,
);
$hookmanager -> executeHooks ( 'getFieldInfosFromObjectField' , $parameters , $this ); // Note that $object may have been modified by hook
self :: $fieldInfos [ $object -> element ][ $mode ][ 'object' ][ $key ] = $fieldInfos ;
return $fieldInfos ;
}
/**
* Get field infos from extra field infos
*
* @ param CommonObject $object Object handler
* @ param ExtraFields $extrafields Extrafields handler
* @ param string $key Field key
* @ param string $mode Get the fields infos for the provided mode ( 'create' , 'edit' , 'view' , 'list' )
* @ param array < string , mixed > $params Other params
* @ return FieldInfos | null Properties of the field or null if not found
*/
public function getFieldInfosFromExtraField ( & $object , & $extrafields , $key , $mode = 'view' , $params = array ())
{
global $hookmanager ;
if ( ! isset ( $extrafields -> attributes [ $object -> table_element ][ 'label' ][ $key ])) {
return null ;
}
if ( isset ( self :: $fieldInfos [ $object -> element ][ $mode ][ 'extraField' ][ $key ])) {
return self :: $fieldInfos [ $object -> element ][ $mode ][ 'extraField' ][ $key ];
}
$attributes = $extrafields -> attributes [ $object -> table_element ];
$fieldInfos = new FieldInfos ();
$fieldInfos -> fieldType = FieldInfos :: FIELD_TYPE_EXTRA_FIELD ;
$fieldInfos -> originType = $attributes [ 'type' ][ $key ] ? ? '' ;
$fieldInfos -> label = $attributes [ 'label' ][ $key ] ? ? '' ;
$fieldInfos -> position = $attributes [ 'pos' ][ $key ] ? ? 0 ;
$fieldInfos -> required = ! empty ( $attributes [ 'required' ][ $key ]);
$fieldInfos -> defaultValue = $attributes [ 'default' ][ $key ] ? ? '' ;
$fieldInfos -> css = $attributes [ 'css' ][ $key ] ? ? '' ;
$fieldInfos -> help = $attributes [ 'help' ][ $key ] ? ? '' ;
$fieldInfos -> size = $attributes [ 'size' ][ $key ] ? ? '' ;
$fieldInfos -> computed = $attributes [ 'computed' ][ $key ] ? ? '' ;
$fieldInfos -> unique = ! empty ( $attributes [ 'unique' ][ $key ]);
$fieldInfos -> alwaysEditable = ! empty ( $attributes [ 'alwayseditable' ][ $key ]);
$fieldInfos -> emptyOnClone = ! empty ( $attributes [ 'emptyonclone' ][ $key ]);
$fieldInfos -> langFile = $attributes [ 'langfile' ][ $key ] ? ? '' ;
$fieldInfos -> printable = ! empty ( $attributes [ 'printable' ][ $key ]);
2026-03-13 07:25:40 +00:00
$fieldInfos -> showintooltip = ! empty ( $attributes [ 'showintooltip' ][ $key ]);
2025-11-19 14:14:53 +00:00
$fieldInfos -> aiPrompt = $attributes [ 'aiprompt' ][ $key ] ? ? '' ;
$fieldInfos -> viewCss = $attributes [ 'cssview' ][ $key ] ? ? '' ;
$fieldInfos -> listCss = $attributes [ 'csslist' ][ $key ] ? ? '' ;
$fieldInfos -> listTotalizable = ! empty ( $attributes [ 'totalizable' ][ $key ]);
$fieldInfos -> options = array_diff_assoc ( $attributes [ 'param' ][ $key ][ 'options' ] ? ? array (), array ( '' => null )); // For remove case when not defined
$fieldInfos -> nameInClass = $key ;
$fieldInfos -> nameInTable = $key ;
$enabled = $attributes [ 'enabled' ][ $key ] ? ? '1' ;
$visibility = $attributes [ 'list' ][ $key ] ? ? '1' ;
$perms = $attributes [ 'perms' ][ $key ] ? ? null ;
$this -> setCommonFieldInfos ( $fieldInfos , $object , $extrafields , $key , $mode , $enabled , $visibility , $perms , $params );
$parameters = array (
'object' => & $object ,
'extraFields' => & $extrafields ,
'key' => $key ,
'mode' => $mode ,
'fieldInfos' => & $fieldInfos ,
);
$hookmanager -> executeHooks ( 'getFieldInfosFromExtraField' , $parameters , $this ); // Note that $object may have been modified by hook
self :: $fieldInfos [ $object -> element ][ $mode ][ 'extraField' ][ $key ] = $fieldInfos ;
return $fieldInfos ;
}
/**
* Set common field infos
*
* @ param FieldInfos $fieldInfos Field infos to set with common infos
* @ param CommonObject $object Object handler
* @ param ExtraFields $extrafields Extrafields handler
* @ param string $key Field key
* @ param string $mode Get the fields infos for the provided mode ( 'create' , 'edit' , 'view' , 'list' )
* @ param string $enabled Condition when the field must be managed ( Example : 1 or 'getDolGlobalInt("MY_SETUP_PARAM")' or 'isModEnabled("multicurrency")' ... )
* @ param string $visibility Condition when the field must be visible ( Examples : 0 = Not visible , 1 = Visible on list and create / update / view forms , 2 = Visible on list only , 3 = Visible on create / update / view form only ( not list ), 4 = Visible on list and update / view form ( not create ) . 5 = Visible on list and view form ( not create / not update ) . 6 = visible on list and update / view form ( not create ) . Using a negative value means field is not shown by default on list but can be selected for viewing )
* @ param string $perms Condition when the field must be editable
* @ param array < string , mixed > $params Other params
* @ return void
*/
public function setCommonFieldInfos ( & $fieldInfos , & $object , & $extrafields , $key , $mode = 'view' , $enabled = '1' , $visibility = '' , $perms = null , $params = array ())
{
global $user ;
$fieldInfos -> object = & $object ;
$fieldInfos -> mode = preg_replace ( '/[^a-z0-9_]/i' , '' , $mode );
$fieldInfos -> type = $fieldInfos -> originType ;
$fieldInfos -> key = $key ;
$fieldInfos -> otherParams = $params ;
if ( preg_match ( '/^(integer|link):(.*):(.*):(.*):(.*)/i' , $fieldInfos -> originType , $reg )) {
$fieldInfos -> options = array ( $reg [ 2 ] . ':' . $reg [ 3 ] . ':' . $reg [ 4 ] . ':' . $reg [ 5 ] => 'N' );
$fieldInfos -> type = 'link' ;
} elseif ( preg_match ( '/^(integer|link):(.*):(.*):(.*)/i' , $fieldInfos -> originType , $reg )) {
$fieldInfos -> options = array ( $reg [ 2 ] . ':' . $reg [ 3 ] . ':' . $reg [ 4 ] => 'N' );
$fieldInfos -> type = 'link' ;
} elseif ( preg_match ( '/^(integer|link):(.*):(.*)/i' , $fieldInfos -> originType , $reg )) {
$fieldInfos -> options = array ( $reg [ 2 ] . ':' . $reg [ 3 ] . ( $reg [ 1 ] == 'User' ? ':#getnomurlparam1=-1' : '' ) => 'N' );
$fieldInfos -> type = 'link' ;
} elseif ( preg_match ( '/^(sellist):(.*):(.*):(.*):(.*)/i' , $fieldInfos -> originType , $reg )) {
$fieldInfos -> options = array ( $reg [ 2 ] . ':' . $reg [ 3 ] . ':' . $reg [ 4 ] . ':' . $reg [ 5 ] => 'N' );
$fieldInfos -> type = 'sellist' ;
} elseif ( preg_match ( '/^(sellist):(.*):(.*):(.*)/i' , $fieldInfos -> originType , $reg )) {
$fieldInfos -> options = array ( $reg [ 2 ] . ':' . $reg [ 3 ] . ':' . $reg [ 4 ] => 'N' );
$fieldInfos -> type = 'sellist' ;
} elseif ( preg_match ( '/^(sellist):(.*):(.*)/i' , $fieldInfos -> originType , $reg )) {
$fieldInfos -> options = array ( $reg [ 2 ] . ':' . $reg [ 3 ] => 'N' );
$fieldInfos -> type = 'sellist' ;
} elseif ( preg_match ( '/^chkbxlst:(.*)/i' , $fieldInfos -> originType , $reg )) {
$fieldInfos -> options = array ( $reg [ 1 ] => 'N' );
$fieldInfos -> type = 'chkbxlst' ;
} elseif ( preg_match ( '/varchar\((\d+)\)/' , $fieldInfos -> originType , $reg )) {
$fieldInfos -> options = array ();
$fieldInfos -> type = 'varchar' ;
$fieldInfos -> size = $reg [ 1 ];
$fieldInfos -> maxLength = ( int ) $reg [ 1 ];
} elseif ( preg_match ( '/varchar/' , $fieldInfos -> originType )) {
$fieldInfos -> options = array ();
$fieldInfos -> type = 'varchar' ;
} elseif ( preg_match ( '/stars\((\d+)\)/' , $fieldInfos -> originType , $reg )) {
$fieldInfos -> options = array ();
$fieldInfos -> type = 'stars' ;
$fieldInfos -> size = $reg [ 1 ];
} elseif ( preg_match ( '/integer/' , $fieldInfos -> originType )) {
$fieldInfos -> type = 'int' ;
} elseif ( $fieldInfos -> originType == 'mail' ) {
$fieldInfos -> type = 'email' ;
} elseif ( preg_match ( '/^(text):(.*)/i' , $fieldInfos -> originType , $reg )) {
$fieldInfos -> type = 'text' ;
$fieldInfos -> getPostCheck = $reg [ 2 ];
} elseif ( preg_match ( '/^(html):(.*)/i' , $fieldInfos -> originType , $reg )) {
$fieldInfos -> type = 'html' ;
$fieldInfos -> getPostCheck = $reg [ 2 ];
} elseif ( preg_match ( '/^double\(([0-9]+,[0-9]+)\)/' , $fieldInfos -> originType , $reg )) {
$fieldInfos -> type = 'double' ;
$fieldInfos -> size = $reg [ 1 ];
}
// Set visibility
$visibility = ( int ) dol_eval (( string ) $visibility , 1 , 1 , '2' );
$absVisibility = abs ( $visibility );
$enabled = ( int ) dol_eval (( string ) $enabled , 1 , 1 , '2' );
$fieldInfos -> visible = true ;
if ( empty ( $visibility ) ||
empty ( $enabled ) ||
( $mode == 'create' && ! in_array ( $absVisibility , array ( 1 , 3 , 6 ))) ||
( $mode == 'edit' && ! in_array ( $absVisibility , array ( 1 , 3 , 4 ))) ||
( $mode == 'view' && ( ! in_array ( $absVisibility , array ( 1 , 3 , 4 , 5 )) || $fieldInfos -> showOnHeader )) ||
( $mode == 'list' && $absVisibility == 3 )
) {
$fieldInfos -> visible = false ;
}
// Set edit perms
if ( isset ( $perms )) {
$perms = ( int ) dol_eval (( string ) $perms , 1 , 1 , '2' );
} else {
//TODO Improve element and rights detection
$mappingKeyForPerm = array (
'fichinter' => 'ficheinter' ,
'product' => 'produit' ,
'project' => 'projet' ,
'order_supplier' => 'supplier_order' ,
'invoice_supplier' => 'supplier_invoice' ,
'shipping' => 'expedition' ,
'productlot' => 'stock' ,
'facturerec' => 'facture' ,
'mo' => 'mrp' ,
'salary' => 'salaries' ,
'member' => 'adherent' ,
);
$keyForPerm = $mappingKeyForPerm [ $object -> element ] ? ? $object -> element ;
$perms = false ;
if ( isset ( $user -> rights -> $keyForPerm )) {
$perms = $user -> hasRight ( $keyForPerm , 'creer' ) || $user -> hasRight ( $keyForPerm , 'create' ) || $user -> hasRight ( $keyForPerm , 'write' );
}
if ( $object -> element == 'order_supplier' && ! getDolGlobalString ( 'MAIN_USE_NEW_SUPPLIERMOD' )) {
$perms = $user -> hasRight ( 'fournisseur' , 'commande' , 'creer' );
} elseif ( $object -> element == 'invoice_supplier' && ! getDolGlobalString ( 'MAIN_USE_NEW_SUPPLIERMOD' )) {
$perms = $user -> hasRight ( 'fournisseur' , 'facture' , 'creer' );
} elseif ( $object -> element == 'delivery' ) {
$perms = $user -> hasRight ( 'expedition' , 'delivery' , 'creer' );
} elseif ( $object -> element == 'contact' ) {
$perms = $user -> hasRight ( 'societe' , 'contact' , 'creer' );
}
}
// Manage always editable of extra field
$isDraft = (( isset ( $object -> statut ) && $object -> statut == 0 ) || ( isset ( $object -> status ) && $object -> status == 0 ));
if ( $mode == 'view' && ! $isDraft && ! $fieldInfos -> alwaysEditable ) {
$perms = false ;
}
// Case visible only in view so not editable
if ( $mode == 'view' && $absVisibility == 5 ) {
$perms = false ;
}
// Case field computed
if ( ! empty ( $fieldInfos -> computed )) {
$perms = false ;
}
$fieldInfos -> editable = ! empty ( $perms );
// Set list info 'checked'
$fieldInfos -> listChecked = $mode == 'list' && $visibility > 0 ;
}
/**
* Set all values of the object ( with extra field ) from POST
*
* @ param CommonObject $object Object handler
* @ param ExtraFields $extrafields Extrafields handler
* @ param string $keyPrefix Prefix string to add into name and id of field ( can be used to avoid duplicate names )
* @ param string $keySuffix Suffix string to add into name and id of field ( can be used to avoid duplicate names )
* @ param string $mode Get the fields infos for the provided mode ( 'create' , 'edit' , 'view' , 'list' )
* @ param array < string , mixed > $params Other params
* @ return int Result < 0 if KO , > 0 if OK
*/
public function setFieldValuesFromPost ( & $object , & $extrafields , $keyPrefix = '' , $keySuffix = '' , $mode = 'view' , $params = array ())
{
$result = $this -> setObjectFieldValuesFromPost ( $object , $keyPrefix , $keySuffix , $mode , $params );
$result2 = $this -> setExtraFieldValuesFromPost ( $object , $extrafields , $keyPrefix , $keySuffix , $mode , $params );
return $result > 0 && $result2 > 0 ? 1 : - 1 ;
}
/**
* Set all object values of the object from POST
*
* @ param CommonObject $object Object handler
* @ param string $keyPrefix Prefix string to add into name and id of field ( can be used to avoid duplicate names )
* @ param string $keySuffix Suffix string to add into name and id of field ( can be used to avoid duplicate names )
* @ param string $mode Get the fields infos for the provided mode ( 'create' , 'edit' , 'view' , 'list' )
* @ param array < string , mixed > $params Other params
* @ return int Result < 0 if KO , > 0 if OK
*/
public function setObjectFieldValuesFromPost ( & $object , $keyPrefix = '' , $keySuffix = '' , $mode = 'view' , $params = array ())
{
$fields = $this -> getAllObjectFieldsInfos ( $object , $mode , $params );
$error = 0 ;
foreach ( $fields as $fieldKey => $fieldInfos ) {
$check = true ;
$key = $fieldInfos -> nameInClass ? ? $fieldInfos -> key ;
if ( $fieldInfos -> visible ) {
$check = $this -> verifyPostFieldValue ( $fieldInfos , $fieldKey , $keyPrefix , $keySuffix );
}
if ( $check ) {
$object -> $key = $this -> getPostFieldValue ( $fieldInfos , $fieldKey , $object -> $key , $keyPrefix , $keySuffix );
}
if ( ! $fieldInfos -> visible ) {
$check = $this -> verifyFieldValue ( $fieldInfos , $fieldKey , $object -> $key );
}
if ( ! $check ) {
$error ++ ;
}
}
return $error ? - 1 : 1 ;
}
/**
* Set all extra field values of the object from POST
*
* @ param CommonObject $object Object handler
* @ param ExtraFields $extrafields Extrafields handler
* @ param string $keyPrefix Prefix string to add into name and id of field ( can be used to avoid duplicate names )
* @ param string $keySuffix Suffix string to add into name and id of field ( can be used to avoid duplicate names )
* @ param string $mode Get the fields infos for the provided mode ( 'create' , 'edit' , 'view' , 'list' )
* @ param array < string , mixed > $params Other params
* @ return int Result < 0 if KO , > 0 if OK
*/
public function setExtraFieldValuesFromPost ( & $object , & $extrafields , $keyPrefix = '' , $keySuffix = '' , $mode = 'view' , $params = array ())
{
$fields = $this -> getAllExtraFieldsInfos ( $object , $extrafields , $mode , $params );
$error = 0 ;
foreach ( $fields as $fieldKey => $fieldInfos ) {
$check = true ;
$key = 'options_' . ( $fieldInfos -> nameInClass ? ? $fieldInfos -> key );
if ( $fieldInfos -> visible ) {
$check = $this -> verifyPostFieldValue ( $fieldInfos , $fieldKey , $keyPrefix , $keySuffix );
}
if ( $check ) {
$object -> array_options [ $key ] = $this -> getPostFieldValue ( $fieldInfos , $fieldKey , $object -> array_options [ $key ], $keyPrefix , $keySuffix );
}
if ( ! $fieldInfos -> visible ) {
$check = $this -> verifyFieldValue ( $fieldInfos , $fieldKey , $object -> array_options [ $key ]);
}
if ( ! $check ) {
$error ++ ;
}
}
return $error ? - 1 : 1 ;
}
/**
* Verify if the field value is valid
*
* @ param FieldInfos $fieldInfos Properties of the field
* @ param string $key Key of attribute
* @ param string $keyPrefix Prefix string to add into name and id of field ( can be used to avoid duplicate names )
* @ param string $keySuffix Suffix string to add into name and id of field ( can be used to avoid duplicate names )
* @ return bool
*/
public function verifyPostFieldValue ( $fieldInfos , $key , $keyPrefix = '' , $keySuffix = '' )
{
global $hookmanager ;
$result = true ;
if ( getDolGlobalInt ( 'MAIN_FEATURES_LEVEL' ) >= 1 || getDolGlobalString ( 'MAIN_ACTIVATE_VALIDATION_RESULT' )) {
$parameters = array (
'fieldInfos' => & $fieldInfos ,
'key' => $key ,
'keyPrefix' => $keyPrefix ,
'keySuffix' => $keySuffix ,
);
$reshook = $hookmanager -> executeHooks ( 'verifyPostFieldValue' , $parameters , $this ); // Note that $object may have been modified by hook
if ( $reshook > 0 ) {
return ( bool ) $hookmanager -> resPrint ;
}
$this -> clearErrors ();
$field = $this -> getFieldClass ( $fieldInfos -> type );
if ( isset ( $field )) {
$this -> clearFieldError ( $key );
$result = $field -> verifyPostFieldValue ( $fieldInfos , $key , $keyPrefix , $keySuffix );
if ( ! $result ) {
$this -> setFieldError ( $key , CommonField :: $validator -> error );
}
}
}
return $result ;
}
/**
* Verify if the field value is valid
*
* @ param FieldInfos $fieldInfos Properties of the field
* @ param string $key Key of field
* @ param mixed $value Value to check ( for date type it must be in timestamp format , for amount or price it must be a php numeric value , for array type must be array )
* @ return bool
*/
public function verifyFieldValue ( $fieldInfos , $key , $value )
{
global $hookmanager ;
$result = true ;
if ( getDolGlobalInt ( 'MAIN_FEATURES_LEVEL' ) >= 1 || getDolGlobalString ( 'MAIN_ACTIVATE_VALIDATION_RESULT' )) {
$parameters = array (
'fieldInfos' => & $fieldInfos ,
'key' => $key ,
'value' => $value ,
);
$reshook = $hookmanager -> executeHooks ( 'verifyFieldValue' , $parameters , $this ); // Note that $object may have been modified by hook
if ( $reshook > 0 ) {
return ( bool ) $hookmanager -> resPrint ;
}
$this -> clearErrors ();
$field = $this -> getFieldClass ( $fieldInfos -> type );
if ( isset ( $field )) {
$this -> clearFieldError ( $key );
$result = $field -> verifyFieldValue ( $fieldInfos , $key , $value );
if ( ! $result ) {
$this -> setFieldError ( $key , CommonField :: $validator -> error );
}
}
}
return $result ;
}
/**
* Get field value from GET / POST
*
* @ param FieldInfos $fieldInfos Properties of the field
* @ param string $key Key of field
* @ param mixed $defaultValue Preselected value to show ( for date type it must be in timestamp format , for amount or price it must be a php numeric value , for array type must be array )
* @ param string $keyPrefix Prefix string to add into name and id of field ( can be used to avoid duplicate names )
* @ param string $keySuffix Suffix string to add into name and id of field ( can be used to avoid duplicate names )
* @ return mixed
*/
public function getPostFieldValue ( $fieldInfos , $key , $defaultValue = null , $keyPrefix = '' , $keySuffix = '' )
{
global $hookmanager ;
$value = '' ;
$parameters = array (
'fieldInfos' => & $fieldInfos ,
'key' => $key ,
'value' => & $value ,
'keyPrefix' => $keyPrefix ,
'keySuffix' => $keySuffix ,
);
$reshook = $hookmanager -> executeHooks ( 'getPostFieldValue' , $parameters , $this ); // Note that $object may have been modified by hook
if ( $reshook > 0 ) {
return $value ;
}
$this -> clearErrors ();
$field = $this -> getFieldClass ( $fieldInfos -> type );
if ( isset ( $field )) {
$value = $field -> getPostFieldValue ( $fieldInfos , $key , $defaultValue , $keyPrefix , $keySuffix );
} else {
$value = $defaultValue ;
}
return $value ;
}
/**
* Get search field value from GET / POST
*
* @ param FieldInfos $fieldInfos Properties of the field
* @ param string $key Key of field
* @ param mixed $defaultValue Preselected value to show ( for date type it must be in timestamp format , for amount or price it must be a php numeric value , for array type must be array )
* @ param string $keyPrefix Prefix string to add into name and id of field ( can be used to avoid duplicate names )
* @ param string $keySuffix Suffix string to add into name and id of field ( can be used to avoid duplicate names )
* @ return mixed
*/
public function getPostSearchFieldValue ( $fieldInfos , $key , $defaultValue = null , $keyPrefix = '' , $keySuffix = '' )
{
global $hookmanager ;
$value = '' ;
$parameters = array (
'fieldInfos' => & $fieldInfos ,
'key' => $key ,
'value' => & $value ,
'keyPrefix' => $keyPrefix ,
'keySuffix' => $keySuffix ,
);
$reshook = $hookmanager -> executeHooks ( 'getPostSearchFieldValue' , $parameters , $this ); // Note that $object may have been modified by hook
if ( $reshook > 0 ) {
return $value ;
}
$this -> clearErrors ();
$field = $this -> getFieldClass ( $fieldInfos -> type );
if ( isset ( $field )) {
$value = $field -> getPostSearchFieldValue ( $fieldInfos , $key , $defaultValue , $keyPrefix , $keySuffix );
} else {
$value = $defaultValue ;
}
return $value ;
}
/**
* Return HTML string to put an input search field into a page
*
* @ param FieldInfos $fieldInfos Properties of the field
* @ param string $key Key of attribute
* @ param mixed $value Preselected value to show ( for date type it must be in timestamp format , for amount or price it must be a php numeric value , for array type must be array )
* @ param string $keyPrefix Prefix string to add into name and id of field ( can be used to avoid duplicate names )
* @ param string $keySuffix Suffix string to add into name and id of field ( can be used to avoid duplicate names )
* @ param string $moreCss Value for css to define style / length of field .
* @ param string $moreAttrib To add more attributes on html input tag
* @ param int < 0 , 1 > $noNewButton Force to not show the new button on field that are links to object
* @ return string
*/
public function printInputSearchField ( $fieldInfos , $key , $value , $keyPrefix = '' , $keySuffix = '' , $moreCss = '' , $moreAttrib = '' , $noNewButton = 0 )
{
global $hookmanager ;
$overwrite_before = '' ;
$overwrite_content = '' ;
$overwrite_after = '' ;
$parameters = array (
'fieldInfos' => & $fieldInfos ,
'key' => $key ,
'value' => & $value ,
'keyPrefix' => $keyPrefix ,
'keySuffix' => $keySuffix ,
'moreCss' => $moreCss ,
'moreAttrib' => $moreAttrib ,
'noNewButton' => $noNewButton ,
'overwrite_before' => & $overwrite_before ,
'overwrite_content' => & $overwrite_content ,
'overwrite_after' => & $overwrite_after ,
);
$hookmanager -> executeHooks ( 'printInputSearchField' , $parameters , $this ); // Note that $this may have been modified by hook
if ( ! empty ( $fieldInfos -> computed )) {
return '' ;
}
$out = $overwrite_before ;
if ( empty ( $overwrite_content )) {
$this -> clearErrors ();
$field = $this -> getFieldClass ( $fieldInfos -> type );
if ( isset ( $field )) {
$moreCss = $field -> getInputCss ( $fieldInfos , $moreCss );
$out .= $field -> printInputSearchField ( $fieldInfos , $key , $value , $keyPrefix , $keySuffix , $moreCss , $moreAttrib );
} else {
$out .= $this -> errorsToString ();
}
} else {
$out .= $overwrite_content ;
}
$out .= $overwrite_after ;
return $out ;
}
/**
* Return HTML string to put an input field into a page
*
* @ param FieldInfos $fieldInfos Properties of the field
* @ param string $key Key of attribute
* @ param mixed $value Preselected value to show ( for date type it must be in timestamp format , for amount or price it must be a php numeric value , for array type must be array )
* @ param string $keyPrefix Prefix string to add into name and id of field ( can be used to avoid duplicate names )
* @ param string $keySuffix Suffix string to add into name and id of field ( can be used to avoid duplicate names )
* @ param string $moreCss Value for css to define style / length of field .
* @ param string $moreAttrib To add more attributes on html input tag
* @ param int < 0 , 1 > $noNewButton Force to not show the new button on field that are links to object
* @ return string
*/
public function printInputField ( $fieldInfos , $key , $value , $keyPrefix = '' , $keySuffix = '' , $moreCss = '' , $moreAttrib = '' , $noNewButton = 0 )
{
global $hookmanager , $langs ;
$overwrite_before = '' ;
$overwrite_content = '' ;
$overwrite_after = '' ;
$parameters = array (
'fieldInfos' => & $fieldInfos ,
'key' => $key ,
'value' => & $value ,
'keyPrefix' => $keyPrefix ,
'keySuffix' => $keySuffix ,
'moreCss' => $moreCss ,
'moreAttrib' => $moreAttrib ,
'noNewButton' => $noNewButton ,
'overwrite_before' => & $overwrite_before ,
'overwrite_content' => & $overwrite_content ,
'overwrite_after' => & $overwrite_after ,
);
$hookmanager -> executeHooks ( 'printInputField' , $parameters , $this ); // Note that $this may have been modified by hook
if ( ! empty ( $fieldInfos -> computed )) {
return '<span class="opacitymedium">' . $langs -> trans ( " AutomaticallyCalculated " ) . '</span>' ;
}
if ( ! $fieldInfos -> editable ) {
return $this -> printOutputField ( $fieldInfos , $key , $value , $keyPrefix , $keySuffix , $moreCss , $moreAttrib );
}
// Get validation error
$fieldValidationErrorMsg = $this -> getFieldError ( $key );
$out = $overwrite_before ;
if ( empty ( $overwrite_content )) {
$this -> clearErrors ();
$field = $this -> getFieldClass ( $fieldInfos -> type );
if ( isset ( $field )) {
$moreCss = $field -> getInputCss ( $fieldInfos , $moreCss );
// Add validation state class
if ( ! empty ( $fieldValidationErrorMsg )) {
$moreCss .= ' --error' ; // the -- is use as class state in css : .--error can't be be defined alone it must be define with another class like .my-class.--error or input.--error
} else {
$moreCss .= ' --success' ; // the -- is use as class state in css : .--success can't be be defined alone it must be define with another class like .my-class.--success or input.--success
}
$out .= $field -> printInputField ( $fieldInfos , $key , $value , $keyPrefix , $keySuffix , $moreCss , $moreAttrib );
} else {
$out .= $this -> errorsToString ();
}
} else {
$out .= $overwrite_content ;
}
if ( empty ( $overwrite_after )) {
// Display error message for field
$out .= $this -> getFieldErrorIcon ( $fieldValidationErrorMsg );
} else {
$out .= $overwrite_after ;
}
return $out ;
}
/**
* Return HTML string to show a field into a page
*
* @ param FieldInfos $fieldInfos Properties of the field
* @ param string $key Key of attribute
* @ param mixed $value Preselected value to show ( for date type it must be in timestamp format , for amount or price it must be a php numeric value , for array type must be array )
* @ param string $keyPrefix Prefix string to add into name and id of field ( can be used to avoid duplicate names )
* @ param string $keySuffix Suffix string to add into name and id of field ( can be used to avoid duplicate names )
* @ param string $moreCss Value for css to define style / length of field .
* @ param string $moreAttrib To add more attributes on html input tag
* @ return string
*/
public function printOutputField ( $fieldInfos , $key , $value , $keyPrefix = '' , $keySuffix = '' , $moreCss = '' , $moreAttrib = '' )
{
global $hookmanager ;
$overwrite_before = '' ;
$overwrite_content = '' ;
$overwrite_after = '' ;
$parameters = array (
'fieldInfos' => & $fieldInfos ,
'key' => $key ,
'value' => & $value ,
'keyPrefix' => $keyPrefix ,
'keySuffix' => $keySuffix ,
'moreCss' => $moreCss ,
'moreAttrib' => $moreAttrib ,
'overwrite_before' => & $overwrite_before ,
'overwrite_content' => & $overwrite_content ,
'overwrite_after' => & $overwrite_after ,
);
$hookmanager -> executeHooks ( 'printOutputField' , $parameters , $this ); // Note that $object may have been modified by hook
$out = $overwrite_before ;
if ( empty ( $overwrite_content )) {
$this -> clearErrors ();
$field = $this -> getFieldClass ( $fieldInfos -> type );
if ( isset ( $field )) {
$moreCss = $field -> getInputCss ( $fieldInfos , $moreCss );
$out .= $field -> printOutputField ( $fieldInfos , $key , $value , $keyPrefix , $keySuffix , $moreCss , $moreAttrib );
} else {
$out .= $this -> errorsToString ();
}
} else {
$out .= $overwrite_content ;
}
$out .= $overwrite_after ;
return $out ;
}
/**
* Return HTML string to print separator field
*
* @ param string $key Key of attribute
* @ param object $object Object
* @ param int $colspan Value of colspan to use ( it must include the first column with title )
* @ param string $display_type " card " for form display , " line " for document line display
* @ param string $mode Show output ( 'view' ) or input ( 'create' or 'edit' ) for field
* @ return string HTML code with line for separator
*/
public function printSeparator ( $key , & $object , $colspan = 2 , $display_type = 'card' , $mode = 'view' )
{
global $conf , $langs ;
// TODO to adapt for field and not extra fields only
$out = '' ;
/* $tagtype = 'tr' ;
$tagtype_dyn = 'td' ;
if ( $display_type == 'line' ) {
$tagtype = 'div' ;
$tagtype_dyn = 'span' ;
$colspan = 0 ;
}
$extrafield_param = $this -> attributes [ $object -> table_element ][ 'param' ][ $key ];
$extrafield_param_list = array ();
if ( ! empty ( $extrafield_param ) && is_array ( $extrafield_param )) {
$extrafield_param_list = array_keys ( $extrafield_param [ 'options' ]);
}
// Set $extrafield_collapse_display_value (do we have to collapse/expand the group after the separator)
$extrafield_collapse_display_value = - 1 ;
$expand_display = false ;
if ( is_array ( $extrafield_param_list ) && count ( $extrafield_param_list ) > 0 ) {
$extrafield_collapse_display_value = intval ( $extrafield_param_list [ 0 ]);
$expand_display = (( isset ( $_COOKIE [ 'DOLUSER_COLLAPSE_' . $object -> table_element . '_extrafields_' . $key ]) || GETPOSTINT ( 'ignorecollapsesetup' )) ? ( ! empty ( $_COOKIE [ 'DOLUSER_COLLAPSE_' . $object -> table_element . '_extrafields_' . $key ])) : ! ( $extrafield_collapse_display_value == 2 ));
}
$disabledcookiewrite = 0 ;
if ( $mode == 'create' ) {
// On create mode, force separator group to not be collapsible
$extrafield_collapse_display_value = 1 ;
$expand_display = true ; // We force group to be shown expanded
$disabledcookiewrite = 1 ; // We keep status of group unchanged into the cookie
}
$out = '<' . $tagtype . ' id="trextrafieldseparator' . $key . ( ! empty ( $object -> id ) ? '_' . $object -> id : '' ) . '" class="trextrafieldseparator trextrafieldseparator' . $key . ( ! empty ( $object -> id ) ? '_' . $object -> id : '' ) . '">' ;
$out .= '<' . $tagtype_dyn . ' ' . ( ! empty ( $colspan ) ? 'colspan="' . $colspan . '"' : '' ) . '>' ;
// Some js code will be injected here to manage the collapsing of fields
// Output the picto
$out .= '<span class="' . ( $extrafield_collapse_display_value ? 'cursorpointer ' : '' ) . ( $extrafield_collapse_display_value == 0 ? 'fas fa-square opacitymedium' : 'far fa-' . (( $expand_display ? 'minus' : 'plus' ) . '-square' )) . '"></span>' ;
$out .= ' ' ;
$out .= '<strong>' ;
$out .= $langs -> trans ( $this -> attributes [ $object -> table_element ][ 'label' ][ $key ]);
$out .= '</strong>' ;
$out .= '</' . $tagtype_dyn . '>' ;
$out .= '</' . $tagtype . '>' ;
$collapse_group = $key . ( ! empty ( $object -> id ) ? '_' . $object -> id : '' );
//$extrafields_collapse_num = $this->attributes[$object->table_element]['pos'][$key].(!empty($object->id)?'_'.$object->id:'');
if ( $extrafield_collapse_display_value == 1 || $extrafield_collapse_display_value == 2 ) {
// Set the collapse_display status to cookie in priority or if ignorecollapsesetup is 1, if cookie and ignorecollapsesetup not defined, use the setup.
$this -> expand_display [ $collapse_group ] = $expand_display ;
if ( ! empty ( $conf -> use_javascript_ajax )) {
$out .= '<!-- Add js script to manage the collapse/uncollapse of extrafields separators ' . $key . ' -->' . " \n " ;
$out .= '<script nonce="' . getNonce () . '" type="text/javascript">' . " \n " ;
$out .= 'jQuery(document).ready(function(){' . " \n " ;
if ( empty ( $disabledcookiewrite )) {
if ( ! $expand_display ) {
$out .= ' console.log("Inject js for the collapsing of extrafield ' . $key . ' - hide");' . " \n " ;
$out .= ' jQuery(".trextrafields_collapse' . $collapse_group . '").hide();' . " \n " ;
} else {
$out .= ' console.log("Inject js for collapsing of extrafield ' . $key . ' - keep visible and set cookie");' . " \n " ;
$out .= ' document.cookie = "DOLUSER_COLLAPSE_' . $object -> table_element . '_extrafields_' . $key . '=1; path=' . $_SERVER [ " PHP_SELF " ] . '"' . " \n " ;
}
}
$out .= ' jQuery("#trextrafieldseparator' . $key . ( ! empty ( $object -> id ) ? '_' . $object -> id : '' ) . '").click(function(){' . " \n " ;
$out .= ' console.log("We click on collapse/uncollapse to hide/show .trextrafields_collapse' . $collapse_group . '");' . " \n " ;
$out .= ' jQuery(".trextrafields_collapse' . $collapse_group . '").toggle(100, function(){' . " \n " ;
$out .= ' if (jQuery(".trextrafields_collapse' . $collapse_group . '").is(":hidden")) {' . " \n " ;
$out .= ' jQuery("#trextrafieldseparator' . $key . ( ! empty ( $object -> id ) ? '_' . $object -> id : '' ) . ' ' . $tagtype_dyn . ' span").addClass("fa-plus-square").removeClass("fa-minus-square");' . " \n " ;
$out .= ' document.cookie = "DOLUSER_COLLAPSE_' . $object -> table_element . '_extrafields_' . $key . '=0; path=' . $_SERVER [ " PHP_SELF " ] . '"' . " \n " ;
$out .= ' } else {' . " \n " ;
$out .= ' jQuery("#trextrafieldseparator' . $key . ( ! empty ( $object -> id ) ? '_' . $object -> id : '' ) . ' ' . $tagtype_dyn . ' span").addClass("fa-minus-square").removeClass("fa-plus-square");' . " \n " ;
$out .= ' document.cookie = "DOLUSER_COLLAPSE_' . $object -> table_element . '_extrafields_' . $key . '=1; path=' . $_SERVER [ " PHP_SELF " ] . '"' . " \n " ;
$out .= ' }' . " \n " ;
$out .= ' });' . " \n " ;
$out .= ' });' . " \n " ;
$out .= '});' . " \n " ;
$out .= '</script>' . " \n " ;
}
} else {
$this -> expand_display [ $collapse_group ] = 1 ;
} */
return $out ;
}
}