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)
$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’attributposa une valeur supérieur au sien param nécessairearray('options' => array(1 => null))ouarray('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ùtableest une table de Dolibarr,refle ou les champs uniques qu’on va afficher,rowidla 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 etarray('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
- pour select, ce doit être de la forme
- ===== 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 commee, alors que pour sellist/chkbxlst, ce seraextra! - ===== 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 !