Extrafields : ajouter dans l’init du descripteur de module

Quelques repères sur la création (ou la mise à jour) d’un extrafield (ef) dans le descripteur de module.

Création d’un nouvel ef

Dans l’init du descripteur, on va charger la class, puis générer un nouvel ef :

		include_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php';
		$extrafields = new ExtraFields($this->db);

		$res1 = $extrafields->addExtraField(
			'my_extrafield',  // attrname (nom de la colonne qui sera ajoutée dans la table llx_elementtype_extrafields, également répertorié dans la table llx_extrafields
			'MyExtrafieldName', // label (chaîne de traduction)
			'link', // type
			'123456', // pos (ordre d’emplacement sur la fiche et dans la liste, il est pertinent d’utiliser des numéros qui se suivent pour les champs d’un même module)
			'', // size''
			'product', // elementtype
			0, // unique
			0, // required
			'', // default_value''
			array('options' => array('Product:product/class/product.class.php::(e.another_extrafield:=:1)' => null)), // param
			1, // alwayeditable
			'$user->hasRight("product", "creer")', // perms
			-1, // list
			'', // help (chaîne de traduction s’affiche dans une infobulle si renseigné)''
			'', // computed (cf https://wiki.dolibarr.org/index.php/Extrafield_Champ_Calcul%C3%A9<nowiki/>)''
			$conf->entity, // entity
			'mymodule@mymodule, // langfile
			'isModEnabled("mymodule")', // enabled
            0, // $totalizable
            0, // $printable (sur PDF)
            array(), // $moreparams
            '', // $aiprompt''
            0, // $emptyonclone (ne pas reprendre la valeur pour un objet cloné)
		);

Point d’attention

Attribut attrname

La paire nom-type d’élément doit être unique dans la table llx_extrafields. Préfixer le nom avec celui du module est donc une bonne pratique.

Il est important que les paramètres jusqu’à enabled, soient définis, celui-ci permettant de ne pas afficher l’extrafield si le module qui l’utilise est désactivé, sans pour autant perdre les valeurs enregistrés en bdd, dans la table des ef de l’objet.

Attribut type

L’attribut stratégique.

ATTENTION : le type conditionne les valeurs attendues dans l’attribut param.

Le champ param sera stocké, dans la table llx_extrafields, sous la forme d’une chaîne sérialisée. On peut donc mettre cette chaîne directement en param, mais c’est beaucoup moins lisible/ facile à écrire.

L’array PHP array('options' => array('Product:product/class/product.class.php::(e.product_is_container:=:1)' => null)) deviendra par exemple a:1:{s:7:"options";a:1:{s:69:"Product:product/class/product.class.php::(e.product_is_container:=:1)";N;}}

Les valeurs reconnues pour le type sont :

separate

champ spécial qui ne créera pas de colonne dans la table des extrafields de l’objet mais seulement une entrée dans llx_extrafields. Affiche un texte de séparation qui peut masquer et démasquer les champs dont le l’attribut pos a une valeur supérieur au sien param nécessaire array('options' => array(1 => null)) ou array('options' => array(2 => null)) Une clé à 1 signifie que le champ sera replié par défaut (puis gardera les réglages utilisateur en mémoire). Une clé à 2, le contraire (déplié par défaut)

boolean

type int et taille fixées à 1 en bdd, pas de param

int

taille maxi 10 (dans la création d’ef via Dolibarr, en tout cas), pas de param

price

ne demande pas de valeur de taille (24,8 en bdd soit 24 chiffres dont 8 après la virgule), pas de param

pricecy

prix avec devise, champ texte (taille fixée à 64 char en bdd), pas de param

phone

chaîne de caractères, taille fixée à 20 en bdd, pas de param

email, mail, ip, icon

chaîne de caractère, taille fixée à 128 en bdd, pas de param

url

chaîne de caractère, taille fixée à 255 en bdd, pas de param

select, sellist, radio, checkbox, chkbxlst

chaîne de caractère, taille fixée à 255 en bdd, demandent que param soit renseigné

  • pour select, ce doit être de la forme array('options' => array('1' =>' tructruc', '2' => 'machinmachin'))
  • pour sellist et chkbxlst, on attend array('options' => array('table:ref|label:rowid::filtre sql' => null)) où table est une table de Dolibarr, ref le ou les champs uniques qu’on va afficher, rowid la clé primaire. Le filtre sql doit être au format Univeral Search Filter de Dolibarr la différence entre les deux étant que chkbxlst permet une sélection multiple
  • pour radio ou checkbox array('options' => array('1' =>' tructruc', '2' => 'machinmachin')) la valeur 0 n’est pas autorisée ! checkbox permet une sélection multiple. Le choix proposé peut reprendre des clés-valeurs issues de champs ou ef de l’objet, suivant la syntaxe : array('options' => array('1' =>' tructruc|options_nom_du_champ:valeur_du_champ', '2' => 'machinmachin|options_nom_du_champ:autre_valeur_du_champ'))pour les ef et array('options' => array('1' =>' tructruc|nom_du_champ:valeur_du_champ', '2' => 'machinmachin|nom_du_champ:autre_valeur_du_champ')) pour les champs de l’objet
link

lien vers un objet de Dolibarr, chaîne de caractère, type int et taille 11 en bdd, param doit être renseigne sous la forme array('options' => array('Objet:objet/class/objet.class.php::filtre sql' => null)) exemple pour un lien vers les produits avec filtre sur un ef : array('options' => array('Product:product/class/product.class.php::(e.another_extrafield:=:1)' => null)) Comme on le voit dans l’exemple ci-dessus, la table des ef de l’objet est identifiée comme e, alors que pour sellist/chkbxlst, ce sera extra !

duration

type int en bdd, longueur 11. Durée en seconde ?

point, multipts, linestrg, polygon

données géométriques dont j’ignore l’usage dans Dolibarr, respectivement typées point, multipoint, linstring, polygon, pas de taille. Aucune idée de paramètres qui seraient pertinents (je soupçonne pas de paramètres du tout)

html

type text en bdd, pas de param

password

type varchar et taille 128 en bdd, pas de param

stars

pour attribuer des notes. Type varchar et taille 128 en bdd, pas de param, mais nécessite en taille le nombre d’étoiles !

autre valeur

doit correspondre à un type de champ reconnu par la base de données. Si on met varchar, la taille sera de 255 si non précisée par ailleurs

Attribut alwayeditable

Si positionné à 1, rend les champs non modifiables sur un objet validé. NE PAS METTRE 1 SUR UN PRODUIT, le champ devient non modifiable, puisque le produit n’a pas de statut brouillon.

Attributs perms et enabled

Les permissions utilisateurs  pour voir et modifier l’ef (perms) et l’activation ou non de l’ef (enabled). La condition doit être une chaîne de caractère qui sera interprétée lors de l’affichage. Attention à l’imbrication des quotes : '$user->hasRight("product", "creer")' ou '$user->hasRight(\'product\', \'creer\')', mais pas '$user->hasRight('product', 'creer')'

Si la valeur perms n’est pas précisée, ce sont les droits sur l’objet qui s’appliquent.

Attribut entity

Contrairement aux précédents, ce n’est pas la chaîne mais bien la variable $conf->entity qui doit être appelée, permettant à l’ef d’être créé pour chaque entité dans la table des extrafields

Attribut list

Détermine la visibilité :

0 => Jamais visible

1 => Visible sur les listes et les formulaires créer/mettre à jour/afficher

2 => Visible sur les listes uniquement

3 => Visible sur les formulaires créer/mettre à jour/afficher uniquement (pas les listes)

4 => Visible sur les listes et formulaires de

mise à jour/affichage uniquement (pas en création)

5 => Visible sur la liste et le formulaire de consultation uniquement (pas en création, pas en mise à jour).

L'utilisation d'une valeur négative signifie que le champ n'est pas affiché par défaut sur la liste mais peut être sélectionné pour la visualisation).

On peut utiliser des conditions pour la valeur :

'preg_match("/public/", $_SERVER["PHP_SELF"]) ? 0 : 1' (si l’url de la page contient /public, on n’affiche jamais le champ, sinon on l’affiche toujours. Utile pour des tickets, par exemple)

'$user->hasRight("holiday", "define_holiday") ? 1 : 5' (si l’utilisateur a les droits sur la création de jours fériés, on l’affiche en tout contexte, sinon uniquement en lecture)

Là encore, attention aux imbrications de quotes.

Mise à jour

Depuis Dolibarr 20, on dispose dans la class Extrafields d’une méthode updateExtrafield() qui permet de mettre à jour la définition d’un extrafield avec les mêmes paramètres dans le même ordre que la méthode createExtrafields() ci-dessus. Les méthodes historiques update() (pour la table des extrafields) et update_label() (pour la table des ef de l’objet) existent toujours (et sont appelées par createExtrafields()) mais les paramètres ne sont pas dans le même ordre, ce qui n’est pas follement pratique !