Formulaires et enregistrements en base de données¶
Les enregistrements de base de données et la classe dbRecord¶
Que ce soit dans une application ou dans un site Internet, un développeur est très souvent appelé à extraire et écrire des données depuis une base de données. Néanmoins la syntaxe est complexe, et il est souvent fastidieux d’aller lire ou écrire ces données. Dans MindFlow il est possible (et recommandé) de créer un objet hérité de la classe dbRecord pour simplifier l’accès à la base de données.
Ainsi, si on veut lire l’email du membre ayant pour uid 113, plutôt que d’écrire :
$sql = "SELECT email FROM members WHERE uid = ".$pdo->quote(113);
$stmt = $pdo->query($sql);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
echo $row['email']
A partir du moment ou notre classe est définie, on peut écrire avec MindFlow:
$member = new member();
$member->load(113);
echo $member->data['email']['value'];
Et si on veut y modifier l’email d’un membre, plutôt que d’écrire :
$sql = "UPDATE members set email = ".$pdo->quote("john@doe.com")." WHERE uid = ".$pdo->quote(113);
$stmt = $pdo->query($sql);
On peut écrire :
$member->data['email']['value'] = "john@doe.com";
$member->store();
Dans les 2 cas, vous noterez que l’on lit ou qu’on écrit dans le tableau nommé ‘data’ contenu dans notre objet :
//lecture :
echo $member->data['email']['value'];
//écriture
$member->data['email']['value'] = "john@doe.com";
Le tableau ‘data’ contient donc toutes les données de notre objet. MindFlow se charge ensuite de lire ou d’écrire son contenu en base de données.
Ce service de lecture / écriture est fourni de base par la classe dbRecord, et vous n’avez pas à écrire de code SQL pour le faire fonctionner. Il vous faut simplement respecter le format du tableau data en respectant quelques règles élémentaires :
Un tableau data contient une clé pour chaque champ stocké en base de données. Chaque clé stocke un tableau contenant la définition du champ concerné. Si dans votre table vous avez une clé nommée ‘name’ alors vous la définirez comme suit :
$this->data['name'] = array(
'value' => '', //valeur du champ
'dataType' => 'input', //type de champ pour l'édition formulaire
'valueType' => 'text', //type de la valeur du champ
);
value
contient la valeur du champ, qui sera écrite ou lue dans la base de données.
dataType
indique le type de champ d’édition lorsqu’on affiche l’objet sous forme de formulaire (rappelez-vous, MindFlow génère les formulaires quasi automatiquement). Voir les valeurs possibles dans la section Les clés génériques du tableau ‘data’.
valueType :
pas vraiment obligatoire, mais permet de déterminer le type de valeur contenue dans le champ, indépendamment du type de champ d’édition. Voir les valeurs possibles dans la section Les clés génériques du tableau ‘data’. Cette information est utile pour traiter la valeur de manière appropriée lors d’un export au format Excel CSV par exemple. Il est conseillé de remplir ce champ lors de la définition.
Important
Lorsque vous accédez à la valeur d’un champ, attention à ne pas oublier de spécifier le sous-tableau ['value']
:
echo $member->data['email']['value'];
// BON : l'email est renvoyé
echo $member->data['email'];
// MAUVAIS : lève une erreur Notice: Array to string conversion
Pour pouvoir utiliser les services de dbRecord, il vous faut préalablement créer un objet hérité de cette classe. Cette définition inclus la spécification SQL des colonnes de la table associée à l’objet. Créons la classe member :
class member extends dbRecord { //on étend la classe dbRecord
// nom de la table dans la BDD sur laquelle va travailler cet objet
static $tableName = 'member';
// définition de la table dans la BDD.
// Celle-ci est utilisée pour pouvoir créer la table depuis l'installeur MindFlow
static $createTableSQL= "
`name` varchar(256) DEFAULT NULL,
`email` varchar(256) DEFAULT ''
";
// on peut spécifier des clés d'indexation pour augmenter les performances
// ou pour effectuer des recherches fulltext
static $createTableKeysSQL="
FULLTEXT KEY `member_search` (`name`,`email`)
";
// on initialise le tableau 'data' contenant les données de l'objet en précisant
// les valeurs par défaut dans les champ 'value' et le type de champ d'édition
// pour leur formulaire dans le champ 'dataType' :
function init(){
parent::init(); //Important ! Inclus les champs standard de la classe dbRecord (creation_date, hidden_deleted...) dans notre nouveau type d'enregistrement.
// on charge le fichier de localisation qui contient les noms d'affichage
// des champs suivants pour les être humains. Par exemple 'name' sera
// traduit en 'Votre nom'
$this->loadL10n('/mf/plugins/mf_users','objects');
$this->data['name'] = array(
'value' => '',
'dataType' => 'input',
'valueType' => 'text',
);
$this->data['email'] = array(
'value' => '@',
'dataType' => 'input',
'valueType' => 'text',
);
}
}
Après avoir défini ainsi votre objet, celui-ci devient utilisable.
Peut-être aurez-vous remarqué que le champ ‘uid’ qui apparaissait dans exemples précédent n’est pas cité dans la classe ? En fait, celui, ainsi qu’un certain nombre d’autres champs sont directement hérités de la classe dbRecord, qui fourni systématiquement les champs suivants :
`uid` int(11) NOT NULL AUTO_INCREMENT, # Identifiant unique de l'enregistrement
`parent_uid` int(11) unsigned NOT NULL DEFAULT '0', # si l'enregistrement a été créé par un autre enregistrement et est en lien avec celui-ci, on peut stocker ici l'uid de l'enregistrement parent
`parent_class` varchar(50) NOT NULL DEFAULT '', # si l'enregistrement a été créé par un autre enregistrement et est en lien avec celui-ci, on peut stocker ici la classe de l'enregistrement parent
`deleted` tinyint(4) NOT NULL DEFAULT '0', # valeur à 1 quand l'enregistrement est effacé
`hidden` tinyint(1) NOT NULL DEFAULT '0', # valeur à 1 quand l'enregistrement est masqué
`sorting` int(11) NOT NULL, # index de tri pour ordonner plusieurs enregistrements
`creation_date` datetime NOT NULL, # date de création de l'enregistrement
`modification_date` datetime NOT NULL, # date de dernière modification
`creator_uid` int(11) NOT NULL, # uid de l'utilisateur backend ou frontend à l'origine de la création de l'enregistrement
`parent_class` varchar(50) NOT NULL DEFAULT '', # classe de l'utilisateur backend ou frontend à l'origine de la création de l'enregistrement
`change_log` text NOT NULL, # log des modifications de l'enregistrement (encore inutilisé)
`edit_lock` int(11) NOT NULL, # pour verrouiller un enregistrement (encore inutilisé)
`start_time` datetime NOT NULL, # date d'activation d'un enregistrement (encore inutilisé)
`end_time` datetime NOT NULL, # date de désactivation d'un enregistrement (encore inutilisé)
`language` varchar(5) NOT NULL, # Code ISO langue de l'enregistrement
`alt_language` tinytext, # uid des enregistrements similaires dans des langues différentes
Tous ces champs sont créés et maintenus automatiquement par MindFlow. Vous n’avez rien à faire. Lors de la création de la table de votre objet, lors de son instanciation ou de son enregistrement, ceux-ci sont gérés par la classe dbRecord dont est hérité votre objet.
Vous avez néanmoins la possibilité de les lire ou de les modifier selon vos souhaits. Si par exemple vous souhaitez altérer la valeur du champ ‘creation_date’, il vous suffira d’y accéder via le tableau data :
$monObjet->data['creation_date']['value'] = '2016-03-02';
//notez au passage l'usage ici de l'argument optionel 'false' de la fonction store,
//qui permet ici de forcer la date de création (sinon elle serait gérée automatiquement par dbRecord).
$monObjet->store(false);
Note
Enregistrements et localisation
Par défaut, MindFlow va créer une table nommée selon la variable $tableName
que vous avez saisie dans la défintion de la classe.
Lorsque vous utilisez plusieurs langues dans votre site ou votre application, par défaut, chaque enregistrement verra sa colonne language
renseignée avec la locale courante lorsqu’il a été créé.
Ainsi cette colonne prendra par exemple pour valeur ‘fr’ lorsque vous aurez enregistré une demande de contact sur votre site en français et ‘en’ lorsque cette demande de contact aura été créée sur le site anglais.
Par defaut, la fonction showRecordEditTable() qui liste les enregistrements d’une table donnée n’affiche que les enregistrements dont la valeur du champ language
correspond à la locale courante du backend
(la locale du backend s’ajuste en sélectionnant la langue désirée dans la liste déroulante située en haut à droite du module d’administration).
Il existe néanmoins des cas de figure rares, mais réels, pour lesquels un développeur préfèrera avoir une table séparée par locale, plutôt que tous les enregistrements de toutes les langues dans une même table.
C’est le cas par exemple si vous aggrégez dans une même application Mindflow des données venues de plusieurs sites MindFlows indépendants et localisés chacun dans une langue différente, par exemple si vous centralisez dans un même outil d’administration les commandes venues de ces différents sites.
Dans ce cas de figure, les UIDs (identifiants uniques des enregistrements) des différentes tables vont rentrer en collision. Il vous faudra alors une table différente par locale. Ceci se fait en ajustant la variable $oneTablePerLocale
dans votre définition de classe :
// nom de la table dans la BDD sur laquelle va travailler cet objet
static $tableName = 'order';
//il est possible de créer une table d'enregistrement par locale
static $oneTablePerLocale = true;
Si la variable static::$oneTablePerLocale
est à true
, alors MindFlow va créer et gérer les tables order_fr
et order_en
dans cet exemple.
Format des données : Array vs stdClass¶
A ce stade, vous vous demandez peut-être pourquoi nous avons fait le choix d’utiliser un objet de type array pour stocker les données. En effet, la syntaxe serait un poil plus agréable si on écrivait :
$monObjet->creationDate->value = '2016-03-02';
Il y a une première raison à cela : la performance. En effet les tableaux sont des objets lourdement optimisés dans tous les langages de programmation, et il offrent des performances supérieures lorsqu’il s’agit de lire et écrire des données.
Voici le temps d’exécution d’un test de création de 1 million d’objets de type stdClass et d‘1 million d’objets de type Array :
stdClass=0.443578004837 sec
Array=0.210082054138 sec
Les objets Array sont 2 fois plus rapides à créer que les stdClass.
La seconde raison, et la plus importante, est que les Arrays peuvent être facilement multidimensionnels et surtout disposent de toute une foule de fonctions d’itération, de fusion, de scission, de tri, d’empilement etc qui en font la structure le plus approprié qui soit pour stocker des données et les manipuler.
Leur plus gros défaut, en définitive, c’est leur syntaxe puisqu’il faut taper des crochets et des guillemets, soit 2 caractères de plus à chaque accès ([‘’] vs ->). Espérons que les gains de performance et de possibilités obtenus vous motiveront à supporter cet affront !
Créer un formulaire ou un enregistrement¶
Spécification du formulaire¶
Avec MindFlow, il ne vous est plus nécessaire de rédiger le HTML pour créer un formulaire, ni d’écrire le code collectant les valeurs lors de sa soumission. Il vous faut juste spécifier les champs souhaités, avec la possibilité de personnaliser le formulaire dans une certaine mesure, qui tend à offrir de plus en plus de possibilités avec les nouvelles versions de MindFlow.
L’affichage des formulaires a recours à la bibliothèque Twitter Bootstrap qui permet de générer des formulaires responsive et mobile friendly.
Pour créer un formulaire, vous devez créer une classe héritant soit de la classe dbRecord
, soit de la classe dbForm
:
- dbRecord : crée un objet PHP qui pourra être affiché/édité sous forme de formulaire et qui pourra être sauvegardé en base de données. La création d’un objet dbRecord requiert qu’il existe dans la base de données une table comportant les champs listés dans le tableau ‘data’ de la classe définie.
- dbForm : crée un objet PHP qui pourra être affiché/édité sous forme de formulaire, mais qui n’a pas d’existence en base de données. Il vous appartient ensuite de traiter les valeurs obtenues selon vos besoins, en les glissant dans un mail par exemple.
Dans les 2 cas, la génération de formulaire repose sur la définition saisie dans le tableau ‘data’ contenu dans la classe, qui est 100% compatible entre les 2 classes. Ainsi il est possible de copier / coller la spécification du tableau data d’une classe héritée de dbRecord vers une classe héritée de dbForm, et vis-et-versa.
Le tableau ‘data’ doit toujours être initialisé dans la fonction init()
de l’objet dbRecord
ou dbForm
.
Voici un exemple de formulaire avec 1 seul champ de type ‘select’ (select box) :
class myContact extends dbRecord{
function init(){
//chargement du fichier de localisation situé
//dans le sous dossier 'objects' du plugin 'myContact'
$this->loadL10n('myContact','objects');
//creation d'un champ 'contact'
$this->data['contact'] = array(
'value' => '1', //
'dataType' => 'select',
'possibleValues' => array(
1 => 'Par téléphone et email',
2 => 'Par téléphone',
3 => 'Par email'
),
'valueType' => 'number',
'field_attributes' => array(
'class' => 'MyFieldClass MyOtherFieldClass', // Classe perso ou Bootstrap
//appel d'une fonction JS lors d'un changement sur le champ
'onChange' => 'updateOtherfield();'
),
'div_attributes' => array(
'class' => 'col-lg-3' // Classe Bootstrap grid
)
);
}
}
Dans l’exemple précédent, on notera les clés suivantes :
value :
la valeur par défaut du champ, tel qu’elle sera affichée si le formulaire est affiché vide. Cette valeur par défaut sera substituée par la valeur saisie par l’utilisateur une fois le formulaire rempli, ou par la valeur chargée depuis la base de données si l’objet y est lu.dataType :
le type de champ de formulaire qui sera affiché.valueType :
type de la valeur pour export CSVpossibleValues :
cette clé n’existe que pour les champs de type select. On y défini un tableau associatif ‘ valeur’ => ‘texte’ qui définira les champs <option> à afficher dans le input select.field_attributes :
liste des attributs à ajouter au champ input. Vous pouvez spécifier ici n’importe quel attribut conforme à la norme HTML dans un tableau associant ‘nomDelAttribut’ => ‘valeur’div_attributes :
liste des attributs à ajouter au container <div> qui entoure le champ input. Vous pouvez spécifier ici n’importe quel attribut conforme à la norme HTML dans un tableau associant ‘nomDelAttribut’ => ‘valeur’
Important
- Toutes ces clés sont sensibles à la casse. Si une clé saisie ne produit pas l’effet escompté, pensez à vérifier la casse et la syntaxe de la clé ajoutée.
- MindFlow va générer automatiquement pour chaque champ un ID de la forme
record|clé_du_champ
outemplate|clé_du_champ
si le champ est enregistré dans un template (plus rarement). - En javascript/jQuery, le caractère ‘|’ est un caractère spécial et il doit être préfixé des caractères ‘\’ pour être pris en compte. Par exemple :
alert($("#record\\|nom_client").val());
- Quand vous générez du javascript depuis PHP, il est EN PLUS nécessaire de doubler les caractères spéciaux quand vous voulez référencer votre champ :
$html = 'alert($("#record\\\\|nom_client").val());';
- Attention à ne pas utiliser les mêmes noms de clés dans 2 objets dbRecord ou dbForm différents si vous êtes susceptible de les afficher à l’écran en même temps ( par exemple sous forme de boites de dialogues superposées : vous ouvrez un fiche client à partir de l’enregistrement d’une commande qu’il a réalisé sur le site, et dans les 2 vous affichez un champ intitulé
nom_client
). Dans ce cas, vous auriez 2 champs avec le même ID dans le DOM. MindFlow saura s’en débrouiller, mais si vous référencez $(“#record\\|nom_client”) depuis une fonction javascript pour accéder à votre champ, vous aurez 2 résultats possibles et donc un résultat inprédictible.
Sur la base de cette spécification, MindFlow génère le code HTML suivant:
<div class="contact col-lg-3" >
<select name="record|contact" id="record|contact" class="form-control MyFieldClass MyOtherFieldClass" onChange="updateOtherfield();">
<option value='1'selected>Par téléphone et email</option>
<option value='2'>Par téléphone</option>
<option value='3'>Par email</option>
</select>
<span class="errorMsg"></span>
</div>
Ce qui produit cet affichage :

On voit que le champ field_attributes
appelle une fonction Javascript updateOtherfield()
. Comment ajouter cette fonction à notre formulaire ? Au moyen de la variable static::$postFormHTML
qui est en fait un tableau, auquel on peut ajouter des blocs de HTML qu’on voudrait voir affichés à la suite du formulaire. On ajoutera le code suivant, toujours au sein de la fonction init()
:
static::$postFormHTML[] = "
<script>
function updateOtherfield(){
var contact = $('#record\\\\|contact').val();
if(contact == 1 || contact == 3)
$('#div_email').hide('slow');
else $('#div_email').show('slow');
}
</script>";
On pourrait aussi bien lier un fichier JavaScript ou une feuille de style de la même manière :
static::$postFormHTML[] = "<link rel='stylesheet' href='".SUB_DIR."/mf/plugins/my_plugin/ressources/templates/my_plugin.css' type='text/css' media='screen'>";
Important
Par défaut, notre champ ne s’affiche pas dans le formulaire. Il faut explicitement spécifier qu’il s’affiche et sa position, via la variable
$this->showInEditForm
qui est encore une fois un Array :$this->showInEditForm = array( 'tab_main'=>array( 'creation_date', 'modification_date', 'contact'), 'tab_state'=>array( 'deleted','hidden') );La clé de la première dimension (‘tab_main’, ‘tab_state’) défini l’onglet du formulaire dans lequel seront affichés nos champs. Il y a une entrée par onglet :
'tab_main'
définit un onglet ettab_state
en définit un autre.
A chaque clé d’onglet correspond une valeur dans le fichier de localisation _l10n.php associé à la classe. Cette valeur définit le titre de notre onglet tel qu’il apparaitra dans l’interface utilisateur :
'fr' => array(
'tab_main' => 'Infos générales',
'tab_state' => 'Etat',
)
A noter :
- Si vous ne définissez qu’une seule clé pour la première dimension du tableau
$this->showInEditForm
, alors l’onglet n’apparaitra pas (mais son contenu oui), car celà n’a pas de sens d’afficher une seule languette d’onglet.
Si vous définissez plusieurs clés, mais que l’indice de la première clé est une chaine vide, alors les champs définis dans cette première clé seront affichés en amont de la liste des onglets. Par exemple, ci-dessous on voulait pouvoir afficher un tableau HTML récapitulatif en amont de notre formulaire d’édition. On a donc défini un champ de type “HTML” intitulé “summup” contenant notre tableau récapitulatif :
$this->showInEditForm = array( '' => array('summup'), 'tab_inscriptions'=> array('options','inscrits' ), 'tab_main'=> array('circuit','vendeur_depart'), //... autres onglets ... );
Ce qui donne :
La seconde dimension du tableau
$this->showInEditForm
définit les champs qui doivent être affichés et l’ordre dans lequel ils doivent être affichés. Dans l’exemple ci-dessus, si vous déplacez'contact'
entre'creation_date'
et'modification_date'
, le champ sera affiché entre les deux dans le formulaire HTML.En effet, on peut avoir des champs que l’on veut avoir présents dans la base de données, mais qu’on ne veut pas afficher dans notre formulaire. Ou alors on pourra avoir un champ qu’on voudra afficher en backend, mais pas en Frontend. Dans ce cas, il suffit de l’ommetre de la liste avant d’afficher le formulaire par exemple.
Si les affichages de formulaire en backend et en frontend sont trop différents pour être conciliables dans une même classe, on pourra envisager de créer 2 classes différentes interragissant avec une même table dans la base de données. Il est également possible de créer une classe héritée d’un enregistrement hérité de dbRecord, pour lui ajouter des champs supplémentaires par exemple.
Dans le code d’exemple ci-dessus, en plus du champ
'contact'
, on affiche aussi les champs'creation_date', 'modification_date','deleted','hidden'
qui ne sont pas spécifiés dans notre tableau data. C’est parce qu’ils sont hérités de la classe dbRecord et qu’ils sont déjà présents dans notre tableau ‘data’ que nous avons la possibilité de les reprendre et de les afficher
Localisation des champs¶
Vous avez peut-être noté que dans notre formulaire d’exemple, lors de l’affichage, le champ 'contact'
est précédé d’un label ‘comment vous contacter’ qui n’est pas mentionné dans la spécification du tableau ‘data’. De même les onglets ‘tab_main’ et ‘tab_state’ n’ont pas un nom très convivial et ne sont pas affiché en tant que tel en titre de nos onglets. Pourquoi ? C’est parce que leurs textes sont extraits depuis un fichier de localisation (en abrégé l10n), qui va rapatrier la valeur du label en fonction de la langue couramment affichée en Frontend ou en backend.
Un fichier de localisation est un fichier PHP nommé avec le nom de la classe à laquelle il correspond, et terminé par ``_l10n.php``. Pour la classe myContact
, on aura donc myContact_l10n.php
.
A l’intérieur, un fichier de localisation se présente comme suit :
<?php
$l10nText = array(
'fr' => array(
'contact' => 'Comment vous contacter',
'tab_main' => 'Infos générales',
'tab_state' => 'Etat',
),
'en' => array(
'contact' => 'How do we contact you',
'tab_main' => 'Global info',
'tab_state' => 'Status',
),
);
?>
La variable $l10nText
se voit affectée un tableau à 2 dimensions. La clé de la première dimension est le code ISO2 de la langue traduite (‘fr’, ‘en’, ‘de’...), spécifiée en base de casse (‘fr’ et pas ‘FR’). La seconde dimension est un tableau associant à la clé de localisation la traduction correspondante. Il faut évidement spécifier les mêmes clés dans chaque langue. Si une clé n’est pas trouvée, MindFlow retournera une chaîne vide.
Dans les objets hérités de la classe dbForm, le fichier de localisation est chargé en tête de notre fonction init() via la commande :
$this->loadL10n('myContact','objects');
Dans les objets hérités de dbRecord, le fichier de localisation est recherché automatiquement par le pluginManager et il n’est pas nécessaire de saisir cette commande dans votre fonction init(). Dans les objets dbForm, l’opération reste manuelle pour le moment. Si elle n’est pas réalisée, les textes localisés n’apparaîtront pas.
La commande $this->loadL10n('myContact','objects');
charge dans le domaine de localisation ‘myContact’ le fichier de localisation nommé myContact_l10n.php
présent dans le sous-dossier objects
du dossier /monPlugin/languages/
Le domaine de localisation est une clé qui permet d’identifier un jeu de traductions. Quand on veut afficher une traduction dans MindFlow, on appelle la fonction :
$mf->l10n->getLabel('nom_du_domaine','clé_de_localisation');
MindFlow se charge de rapatrier la clé traduite dans la langue d’affichage courante, sans qu’il soit nécessaire de préciser cette dernière. Dans le cadre de notre formulaire d’exemple, si on veut rapatrier la valeur de la clé ‘contact’, on écrira donc :
echo $mf->l10n->getLabel('myContact','contact');
//affiche : "Comment vous contacter"
Si pour une raison inconnue votre fichier de localisation ne semble pas être chargé, ou que vous souhaitez l’exploiter en dehors d’une classe héritée de dbRecord ou dbForm, ou que vous voulez placer votre fichier de localisation à un emplacement arbitraire, vous pouvez forcer son chargement à l’aide de la fonction :
l10nManager::loadL10nFile('nom_du_domaine','chemin_relatif_a_la_racine_du_site');
Afficher l’objet sous forme de formulaire¶
Pour afficher notre objet, on appelle l’une des fonctions suivantes à partir de l’instance $mf->formsManager
:
editForm() :
affiche un formulaire hérité de la classe dbFormeditRecord() :
affiche un formulaire hérité de la classe dbRecord
Exemple d’utilisation :
$objetContact = new myContact();
$html = $mf->formsManager->editRecord($objetContact, $this->pluginName);
echo $html;
Ces fonctions proposent des paramètres assez nombreux. Nous vous invitons à consulter la classe formsManager dans la documentation phpDoc ou son code source. Ces paramètres y sont documentés.
Récupérer les valeurs du formulaire¶
Pour récupérer un objet contenant les valeurs d’un formulaire, on emploiera la fonction processForm()
de la classe formsManager. Qu’il s’agisse d’un formulaire hérité de dbForm, ou d’un objet hérité de dbRecord, la methode renverra directement une instance de l’objet concerné :
global $formsManager;
$myObject = $formsManager->processForm();
//ou
$myObject = $formsManager->processForm($record = $myObject);
Important
La fonction processForm()
ne sauve pas l’objet renvoyé, d’une part parce que l’enregistrement dans la base de données ne s’applique pas aux objets hérités de dbForm, d’autre part parce que vous ne souhaitez pas nécessairemnt le faire pour un objet hérité de dbRecord.
Il vous incombe donc d’executer un store()
sur l’objet renvoyé si nécessaire.
Note
L’argument optionnel $record
de la fonction processForm() permet une optimisation de performance, notamment lorsque l’objet a déjà été créé et passé à travers la fonction checkAndProcessForm(), ce qui permet de le réutiliser au lieu de le recréer. Vous ne l’utiliserez pas dans la plupart des cas.
- Si l’argument storeRecord est à false, alors la fonction retourne l’instance de l’objet récupéré, avec toutes les valeurs du formulaire intégrées dans les champs ‘value’ du tableau ‘data’. Cette instance n’est alors pas sauvée dans la base de données, et il vous incombera de lui appliquer un
->store()
pour ce faire.
Création d’objet vs enregistrement en base de données¶
Poursuivons avec notre exemple de classe myContact héritée de dbRecord. Pour créer une instance de myContact, comme on l’a déjà vu, on écrit :
$contact = new myContact();
A partir de ce moment là, notre objet existe en mémoire avec son tableau data initialisé par la fonction init()
(celle-ci est appelée automatiquement lors de la création de l’objet), mais les données de notre objet n’existent pas encore en base de données. Ce n’est que lorsqu’on aura appelé la fonction $contact->store()
que les données seront écrites dans la base :
$contactUid = $contact->store();
Important
Que l’on réalise une création d’objet (CREATE
en SQL) ou une mise à jour (UPDATE
), on appelle toujours la fonction store()
. C’est MindFlow qui se préoccupe de savoir s’il doit exécuter un CREATE
ou un UPDATE
.
La règle étant que si le champ $contact->data['uid']['value']
correspondant à la clé primaire de l’enregistrement est vide (valeur = ‘’ ou valeur = ‘0’) ou contient une valeur uid qui n’existe pas dans la table, alors MindFlow exécute un CREATE
. Sinon il met à jour l’enregistrement avec l’uid correspondant au moyen d’un UPDATE
.
La fonction $contact->store()
retourne l’uid de l’objet en cas de succès, ou la valeur 0 en cas d’échec. Ainsi il est possible de réaliser facilement une action conditionnelle en cas de succès ou d’échec :
if($contactUid = $contact->store()){
echo "le contact ayant pour uid ".$contactUid." a été créé avec succès";
}
else{
echo "La création du contact a échoué";
}
Triggers¶
Il est pratique de spécifier dans un objet dbRecord des actions qui accompagnent les enregistrements en base de données. Par exemple, on pourrait vouloir envoyer un mail automatiquement avec le login et le mot de passe à un utilisateur chaque fois qu’un profil myContact est créé. Dans ce cas, on pourra surcharger le code de la fonction postCreate()
de dbRecord et rédiger le code d’envoi d’email. Voici les différents triggers de la même trempe.
function postLoad()
La fonction postLoad()
est exécutée après qu’un enregistrement a été chargé depuis MySQL, via la fonction load()
.
function preCreate()
La fonction preCreate()
est exécutée avant qu’un enregistrement soit créé dans MySQL, via la fonction store()
.
function postCreate()
La fonction postCreate()
est exécutée après qu’un enregistrement soit créé dans MySQL, via la fonction store()
.
function preStore()
La fonction preStore()
est exécutée avant qu’un enregistrement soit modifié dans MySQL, via la fonction store()
.
function postStore()
La fonction postStore()
est exécutée après qu’un enregistrement soit modifié dans MySQL, via la fonction store()
.
function onSubmit()
La fonction onSubmit()
est exécutée durant le traitement d’un formulaire par la fonction formsManager::processForm()
(MindFlow > 1.4) ou formsManager::processSubmition()
(MindFlow < 1.4).
Cette fonction est destinée à être employée avec les objets hérités de dbForm, qui n’ont pas d’existence en base de données et pour lesquels les triggers de type postCreate() etc... ne s’appliquent pas.
function preDelete()
La fonction preDelete()
est exécutée juste avant l’effacement d’un enregistrement, via la fonction delete()
. On pourra l’utiliser pour effacer un enregistrement associé dans une autre table par exemple. Cette fonction est destinée à être employée avec les objets hérités de dbRecord uniquement.
function postDelete()
La fonction postDelete()
est exécutée juste après l’effacement d’un enregistrement, via la fonction delete()
.
function preRestore()
La fonction preRestore()
est exécutée juste avant l’effacement d’un enregistrement, via la fonction delete()
. On pourra l’utiliser pour restaurer un enregistrement associé dans une autre table par exemple. Cette fonction est destinée à être employée avec les objets hérités de dbRecord uniquement.
function postRestore()
La fonction postRestore()
est exécutée juste après l’effacement d’un enregistrement, via la fonction delete()
.
Note
Il est possible de désactiver temporairement les triggers. Par exemple, si vous importez un fichier CSV de 1000 contacts via un script, et que vous créez en boucle des objets myContact
, vous ne voudrez sans doute pas qu’a chaque création de contact, l’utilisateur reçoive un mail avec son login et son mot de passe comme défini dans le trigger postCreate()
de notre classe myContact.
Pour ce faire, avant de sauver notre contact, on écrira :
$contact->enablePostCreate = false;
$contact->store();
La valeur du flag $enablePostCreate
n’est valable que durant la durée de vie de l’objet PHP courant. Elle n’est pas enregistrée en base de données.
Voici la liste des variables disponibles dans la classe dbRecord pour neutraliser les triggers :
var $enablePreCreate=true;
var $enablePostCreate=true;
var $enablePreStore=true;
var $enablePostStore=true;
var $enablePreLoad=true;
var $enablePostLoad=true;
var $enablePreDelete=true;
var $enablePostDelete=true;
var $enablePreRestore=true;
var $enablePostRestore=true;
Flags¶
Il existe différentes variables drapeaux (flags) qui peuvent être ajustés dans la classe dbRecord, et par conséquent pour tous les enregistrements hérités de celle-ci :
$enableHistory
lorsque ce drapeau est positionné à true, il active le stockage de l’historique de l’enregistrement de 2 manières. D’une part le champhistory_last
stocke la dernière copie enregistrée du tableau data de l’objet, ce qui servira a établir une comparaison avec la nouvelle version à chaque appel de store(). D’autre part le champhistory_past
stocke les différences entre la version actuelle et les versions précédentes de l’enregistrement (le fait de ne stocker que les différences permet de réduire l’espace occupé dans la base de données et d’impacter le moins possible les performances en lecture/écriture). La sauvegarde de l’historique d’un enregistrement diminue les performances, aussi ce drapeau est-il positionné à false par défaut.
$reloadFormOnSave
lorsque ce drapeau est positionné à true, il force le re-téléchargement en AJAX et le ré-affichage du formulaire d’édition de l’enregistrement après sa sauvegarde. C’est utile si certaines modifications ou calculs sont effectués au niveau serveur dans la procédure onStore() et qu’on veut les refléter immédiatement dans l’affichage du navigateur. Ce drapeau est positionné à false par défaut de manière à minimiser le trafic de données entre le serveur et le navigateur, la régénération du formulaire n’étant pas nécessaire dans la plupart des cas.
Les clés du tableau ‘data’¶
Clés génériques¶
Selon les types de champs (définis et différenciés par la valeur du champ 'datatype'
), certaines clés supplémentaires peuvent être spécifiées. D’autres en revanche sont communes à tous types les champs. Voici leur documentation complète :
value | valeur par défaut lorsque l'enregistrement est créé, ou valeur courante de l'enregistrement
lorsque celui-ci a été extrait de la base
de données via la fonction load() ou lorsque la valeur a été modifiée par l'utilisateur. Tous les types de champ ont un attribut 'value', à l'exception notable du champ recordEditTable qui ne stocke par d'information dans la table associée à la classe, mais qui donne une vue spécifiée par une requête SQL sur une table tierce. |
dataType |
définit le type de champ de formulaire qui devra être affiché, parmi les valeurs suivantes :
Exemple d'usage : 'dataType' => 'hidden'
Les rôles et les clés spécifiques de ces types de champs sont détaillés dans la section suivante. Additionnellement, il est possible de préfixer le datatype de la plupart des champs avec la valeur 'dummy-'. Ainsi 'input' devient 'dummy-input'. En anglais, un dummy est une maquette. On pourrait parler aussi ici de pseudo-champ : il s'agit de champs qui apparaissent dans le formulaire, mais qui ne seront pas traités pour l'enregistrement en base de données. Par exemple si on enregistre en base de données un champ 'password' de type 'input', on pourra créer a coté un champ 'password-confirmation' de type 'dummy-input' qui ne sera pas enregistrée en base de données, mais traité dans la fonction trigger preCreate() pour contrôler que les champs 'password' et 'password-confirmation' correspondent bien. |
valueType |
définit le type de valeurs pour l'export CSV ou le réutilisation des données, parmi les types suivants :
Exemple d'usage : 'valueType' => 'time'
|
editable |
Valeur par défaut à 1. Passer la valeur à 0 pour rendre le champ non éditable dans le formulaire. Exemple d'usage : 'editable' => '0'
|
label_attributes |
liste des attributs à ajouter au tag Exemple d'usage : 'label_attributes' => array(
'class' => 'myClass',
)
|
field_attributes |
liste des attributs à ajouter au container <div> qui entoure le champ input. Vous pouvez spécifier ici n'importe quel attribut conforme à la norme HTML dans un tableau associant 'nomDelAttribut' => 'valeur'. Exemple d'usage : 'div_attributes' => array(
'class' => 'myClass',
'width'=>'256'
)
|
div_attributes |
liste des attributs à ajouter au container qui entoure le champ input. Vous pouvez spécifier ici n'importe quel attribut conforme à la norme HTML dans un tableau associant 'nomDelAttribut' => 'valeur'.
Exemple d'usage : 'div_attributes' => array(
'class' => 'myClass',
'width'=>'256'
)
|
validation |
Spécifie si un champ est obligatoire ou pas, ce qui provoquera l'affichage d'un message d'erreur dans le cas ou :
Exemple d'usage : 'validation' => array(
'mandatory' => '1',
'fail_values' => array('','0'),
// OU si besoin de validation plus élaborée
'filterFunc' => 'myContact::validateMember',
//affiche des infos durant le test de validation
'debug' => false,
//nombre d'entrées minimum requis
//(champs à sélection multiples uniquement :
//select, recordSelect, files, checkbox)
'min_entries' => 1,
//nombre d'entrées maximum requis
//(champs à sélection multiples uniquement :
//select, recordSelect, files, checkbox)
'max_entries' => 3,
),
En cas d'échec, le message d'erreur renvoyé sera lu dans le fichier de localisation _l10n.php associé à l'objet PHP et sera celui défini dans la clé de localisation du champ suffixée de la valeur '_fail'. Par exemple :
'password' => 'Mot de passe',
'password_fail' => 'Le mot de passe spécifié est vide',
Exemple de fonction de validation employée en conjonction avec filterfunc. On vérifie ici si le username existe déjà dans la BDD : Exemple de fonction : static function validateMember($fieldValue, $fullSubmitedRecord){
//vérification de la valeur du champ courant
if($fieldValue != '' && $fieldValue > 0) return true;
else {
//vérification d'un autre champ de l'enregistrement
//et décision
if ($fieldValue == 0 && $fullSubmitedRecord->data['otherfield']['value'] == 1)
return true;
else return false;
}
}
|
preRecord |
Appelle une fonction pour traiter le champ concerné avant de l'enregistrer dans la base de données : Exemple d'usage : 'preRecord' => '$this->cryptPassword',
Note : la clé 'preRecord' est exécutée après la clé 'validation'. Voici le profil de la fonction cryptPassword. Notez les 2 paramètres : $newValue est la valeur tapée par l'utilisateur dans le formulaire, tandis que $previousValue est la valeur qui était présente avant la saisie de l'utilisateur. Exemple de fonction :
function cryptPassword($newValue, $previousValue){
if($newValue != $previousValue)
return crypt($newValue, $config['salt']);
else return $newValue;
}
|
preDisplay |
Traite la valeur avant son affichage dans le formulaire. Ceci n'altère pas la valeur contenue dans le champ, uniquement la valeur affichée. Exemple d'usage : 'preDisplay' => 'formFormatDate',
Exemple de fonction :
function formatDate($key,$value,$locale,$additionalValue=''){
$dateFormated=parent::formatDate($key, $value, $locale);
if($dateFormated=='30/11/-0001')return '00/00/0000';
else return $dateFormated;
}
|
noClearFix |
Quand on indique la valeur '1', prévient l'affichage du code <div class="clearfix"></div> après le champ. La classe 'clearfix' à pour effet d'annuler les float avec l'instruction CSS 'clear:both;'. En effet, vous voudrez parfois désactivez cette instruction pour un meilleur contrôle sur l'affichage du formulaire, quand par exemple vous voudrez afficher plusieurs champs en inline. Exemple d'usage : 'noClearfix' => '1'
|
preLabelHTML |
Spécifie du code HTML à placer immédiatement avant le tag <label> du champ. C'est utile pour ajouter du code personnalisé à l'intérieur du conteneur <div> qui entoure le champ. Exemple d'usage : 'preLabelHTML' => '<span class="blue">',
|
postLabelHTML |
Spécifie du code HTML à placer immédiatement après le tag <label> du champ. C'est utile pour ajouter du code personnalisé à l'intérieur du conteneur <div> qui entoure le champ. Exemple d'usage : 'postLabelHTML' => '</span>',
|
innerPreLabelHTML |
Spécifie du code HTML à placer avant le texte, à l'intérieur du tag <label> du champ. C'est utile pour ajouter du code personnalisé à l'intérieur du conteneur <label>. Exemple d'usage : 'innerPreLabelHTML' => '<span class="blue">',
|
innerPostLabelHTML |
Spécifie du code HTML à placer immédiatement après le texte, à l'intérieur du tag <label> du champ. C'est utile pour ajouter du code personnalisé à l'intérieur du conteneur <label>. Exemple d'usage : 'innerPostLabelHTML' => '</span>',
|
preFieldHTML |
Spécifie du code HTML à placer immédiatement avant le tag <input> du champ. C'est utile pour ajouter du code personnalisé à l'intérieur du conteneur <div> qui entoure le champ. Exemple d'usage : 'preFieldHTML' => ' |
postFieldHTML |
Spécifie du code HTML à placer immédiatement après le tag <input> du champ. C'est utile pour ajouter du code personnalisé à l'intérieur du conteneur <div> qui entoure le champ. Exemple d'usage : 'postFieldHTML' => '</div><button>Valider</button>',
|
preDivHTML |
Spécifie du code HTML à placer immédiatement avant le tag <div> du champ. C'est utile pour ajouter du code personnalisé à l'extérieur du conteneur <div> qui entoure le champ. Exemple d'usage : 'preDivHTML' => '<div style="display:inline;">',
|
postDivHTML |
Spécifie du code HTML a placer immédiatement après le tag <div> du champ. C'est utile pour ajouter du code personnalisé à l'extérieur du conteneur <div> qui entoure le champ. Exemple d'usage : 'postDivHTML' => '</div><button>Valider</button>',
|
showLabel |
Permet de désactiver l'ajout du tag <label> devant le champ si spécifié à false. La valeur par défaut est fixée à true. Exemple d'usage : 'showLabel' => false,
|
showFieldDiv |
Permet de désactiver l'ajout du tag <div> autour du champ si spécifié à false. La valeur par défaut est fixée à true. Exemple d'usage : 'showFieldDiv' => false,
|
showWrapDiv |
Permet de désactiver l'ajout du tag <div> englobant le bloc label + champ si spécifié à false. La valeur par défaut est fixée à true. Exemple d'usage : 'showWrapDiv' => false,
|
Clés spécifiques¶
Champ “input”¶
Ajoute un champ input.
dataType | Vous pouvez spécifier en second argument du champ dataType une variante du champ texte. Par défaut, le datatype 'input' équivaut à 'input text'. Mais vous pouvez aussi spécifier d'autres variantes prévues par la norme HTML pour l'attribut 'type' du tag 'input', par exemple :
Exemple d'usage : 'dataType' => 'input password',
L'affichage de ces types de champs dépend du niveau de support du navigateur de l'utilisateur. En effet certains types de champs HTML5 ne sont pas correctement supportés, par exemple les types 'date' ou 'color' qui nous ont amené à mettre en place une implémentation spécifique à base de plugins pour Bootstrap. Pour les types 'checkbox' ou 'radio' également, voir notre implémentation spécifique car ceux-ci requièrent un traitement particulier de l'attribut checked. Note : le type 'radio' n'est disponible qu'à partir de MindFlow 1.6. On pourra en attendant contourner le problème par l'emploi d'un champ de type 'select' qui fournit la même fonctionnalité, avec néanmoins une ergonomie différente. |
Champ “date”¶
Ajoute un champ date.
Settings | Permet de customiser le champ Bootstrap datetimepicker selon les options dans la doc http://eonasdan.github.io/bootstrap-datetimepicker/ Exemple d'usage :
'settings'=> array(
'minDate' => '"01/01/1900"',
'showToday' => 'true',
'defaultDate' => '"01/01/1950"',
)
|
Settings | Permet d'ajouter des appels chainés à la commande de création du dateTimePicker. Exemple d'usage :
'jQueryChainedCalls' => 'on("dp.change",function(e){console.log(datetimepickers["au"]);})'
|
Champ “datetime”¶
Permet d’insérer un champ date et heure / minutes / secondes.
Settings | Permet de customiser le champ Bootstrap datetimepicker selon les options dans la doc http://eonasdan.github.io/bootstrap-datetimepicker/ Exemple d'usage :
'settings'=> array(
'useCurrent' => 'true',
'sideBySide' => 'true',
'showClose' => 'true',
)
|
Settings | Permet d'ajouter des appels chainés à la commande de création du dateTimePicker. Exemple d'usage :
'jQueryChainedCalls' => 'on("dp.change",function(e){console.log(datetimepickers["au"]);})'
|
Champ “time”¶
Permet d’insérer un champ date et heure / minutes / secondes.
Settings | Permet de customiser le champ Bootstrap datetimepicker selon les options dans la doc http://eonasdan.github.io/bootstrap-datetimepicker/ Exemple d'usage :
'settings'=> array(
'minDate' => '"01/01/1900"',
'showToday' => 'true',
'defaultDate' => '"01/01/1950"',
)
|
Settings | Permet d'ajouter des appels chainés à la commande de création du dateTimePicker. Exemple d'usage :
'jQueryChainedCalls' => 'on("dp.change",function(e){console.log(datetimepickers["au"]);})'
|
Champ “color”¶
Permet d’insérer un champ de type color picker. On pourra personnaliser le champ Bootstrap colorpicker selon les options dans la doc http://www.eyecon.ro/bootstrap-colorpicker/
dataType | On doit ajouter en second argument le format de couleur parmi l'une des valeurs suivantes : Exemple d'usage :
'dataType'=> 'color rgb'
|
Champ “urlinput”¶
Champ initialement prévu pour le Plugin pages uniquement. Permet de saisir un segment d’URL tout en affichant l’URL complète + le segment en dessous du champ.
Aucun champ spécifique |
Champ “checkbox”¶
Affiche une case à cocher.
value | 1 pour cocher la case, sinon 0 Exemple d'usage :
'value'=> '1'
|
swap | Permet de permuter l'ordre du label et de la case à cocher. 1 pour afficher le label après la case, sinon 0 Exemple d'usage :
'swap'=> '1'
|
Champ “radio”¶
Affiche un ou plusieurs boutons radio.
possibleValues | tableau associatif 'clé' => Array qui définira les différents input radio à afficher |
editable |
Valeur par défaut à 1. Passer la valeur à 0 pour rendre le bouton radio non éditable dans le formulaire. Il est aussi possible de placer une valeur 'editable' dans la définition de chaque option de manière à en activer certaines et d'autres pas. Si le champ 'editable' est défini au niveau du champ ET au niveau des options, c'est la valeur au niveau du champ qui prend le pas sur tous les 'editable' définis en option. Aussi il est recommandé de définir 'editable' soit au niveau du champ, soit au niveau des options, mais pas les 2 simultanément. Exemple d'usage : 'editable' => '0'
|
preFieldHTML |
Spécifie du code HTML a placer immédiatement avant le tag <input> du champ. C'est utile pour ajouter du code personnalisé à l'intérieur du conteneur <div> qui entoure le champ. Exemple d'usage : 'preFieldHTML' => ' |
postFieldHTML |
Spécifie du code HTML a placer immédiatement après le tag <input> du champ. C'est utile pour ajouter du code personnalisé à l'intérieur du conteneur <div> qui entoure le champ. Exemple d'usage : 'postFieldHTML' => '</div><button>Valider</button>',
|
Exemple de définition d’un champ radio :
'accueil' => array(
'value' => '',
'dataType' => 'radio',
'valueType' => 'text',
'possibleValues' => array(
'TS' => array(
'value' => 5,
'field_attributes' => array(
'class' => 'test',
'onChange' => 'doSomething();',
),
'div_attributes' => array(
'class' => 'col-lg-2'
),
//'preFieldHTML' => 'this is ',
//'postFieldHTML' => ' a test',
'editable'=> 0,
),
'S' => array(
'value' => 4,
'div_attributes' => array(
'class' => 'col-lg-2'
),
),
'MS' => array(
'value' => 3,
'div_attributes' => array(
'class' => 'col-lg-2'
),
),
'PS' => array(
'value' => 2,
'div_attributes' => array(
'class' => 'col-lg-2'
),
),
'PSD' => array(
'value' => 1,
'div_attributes' => array(
'class' => 'col-lg-2'
),
),
'SA' => array(
'value' => 0,
'div_attributes' => array(
'class' => 'col-lg-2'
),
),
),
//pas de field_attributes !
'div_attributes' => array(
'class' => 'row'
),
),
Dans le fichier de localisation associé à ce formulaire, on aura les entrées suivantes:
'accueil' => 'Accueil général (téléphone et/ou mail)',
'accueil_fail' => 'Ce champ n\'à pas été rempli',
'accueil_TS' => 'Très satisfait',
'accueil_S' => 'satisfait',
'accueil_MS' => 'moyennement satisfait',
'accueil_PS' => 'pas satisfait',
'accueil_PSD' => 'pas satisfait du tout',
'accueil_SA' => 'sans avis',
Cette définition, couplée avec les données du fichier de localisation, nous affiche :

Champ “select”¶
Affiche une liste déroulante.
possibleValues | Liste des valeurs affichées dans la liste de sélection. On y défini un tableau associatif ' valeur' => 'texte' qui définira les champs |
option_attributes | Permet de spécifier des attributs à ajouter aux options sous forme de tableau associatif Exemple d'usage:
'option_attributes' => array(
'class' => 'myOption',
),
|
Astuce : pour créer un champ select a sélection multiple, spécifiez le tableau field_attributes comme suit :
'field_attributes' => array(
'multiple' => 'multiple',
),
Champ “recordSelect”¶
Affiche un champ de type select simple rempli avec une liste d’objets PHP dont l’un d’entre eux pourra être sélectionné, édité (via une fenêtre popup), supprimé. Il sera également possible de créer un enregistrement et de l’ajouter à la liste, de modifier l’ordre des enregistrements, et de copier / coller des entrées vers un autre champ affichant la même classe d’enregistrements.

Avertissement
Important : Le type de colonne pour ce champ en base de données recommandé est ‘TEXT’ (recommandé) ou l’une de ses variantes (‘LONGTEXT’, ‘BLOB’ etc.). Le champ peut être défini comme INT uniquement dans le cas d’un champ de type simple, car le type INT ne permet pas de stocker plusieurs valeurs uid dans le cas d’un champ select multiple. Attention dans ce cas si vous basculez le champ en multiple ultérieurement et que vous ne penser pas à changer la définition de la colonne SQL en TEXT, vous rencontrerez des dysfonctionnements.
Avertissement
Pour des raisons techniques, les champs recordSelect ne sont pas compatibles avec les objets dbForm. Dans ce cas de figure, il faudra utiliser un champ select simple et le gérer vous même.
La liste des enregistrements pourra être établie au moyen d’une requête SQL spécifiée directement dans la configuration du champ selon 2 modes : addItemsSQL
ou initItemsSQL
value | Liste des uids sélectionnés dans la select box, séparés par des virgules |
editType | Type de select box : 'single' ou 'multiple' Exemple d'usage:
'editType' => 'multiple'
|
editClass | Nom de la classe PHP a éditer. Celle-ci devra être hérité de dbRecord
'editClass' => 'myContact'
|
addItemsSQL | On spécifiera soit addItemsSQL, soit initItemsSQL, mais pas les deux. En mode addItemsSQL, la liste est vide par défaut et on y ajoute des éléments au fur et à mesure. Les champs listés en tant que titre de chaque option dans la select box sont ceux listés dans la clé SELECT. Le champ ORDER_BY défini par ailleurs l'ordre dans lequel ces éléments sont affichés. Exemple d'usage:
'addItemsSQL' => array(
'SELECT' => 'date, i_prix',
'FROM' => 'vz_departs',
'WHERE' => '',
'ORDER BY' => 'date',
'ORDER DIRECTION' => 'ASC',
),
|
addItemsSQL | On spécifiera soit initItemsSQL, soit initItemsSQL, mais pas les deux. En mode initItemsSQL, la liste est remplie par défaut avec les éléments spécifiés dans la requête. On y sélectionne les éléments que l'on souhaite retenir. Les champs listés en tant que titre de chaque option dans la select box sont ceux listés dans la clé SELECT. Le champ ORDER_BY défini par ailleurs l'ordre dans lequel ces éléments sont affichés. Exemple d'usage:
'initItemsSQL' => array(
'SELECT' => 'date, i_prix',
'FROM' => 'vz_departs',
'WHERE' => '',
'ORDER BY' => 'date',
'ORDER DIRECTION' => 'ASC',
),
|
prependEmptyEntry | Ajoute une entrée vide dans le select en tête des options. Utile pour forcer l'utilisateur a sélectionner une valeur sans présélectionner une valeur par défaut. S'utilise en conjonction avec initItemsSQL en affichant le recordSelect en mode Single Exemple d'usage:
'prependEmptyEntry' => true,
|
columnSeparator | Par défaut les valeurs des colonnes de votre SELECT sont présentées entre elles séparées par de simples espaces. Vous pouvez spécifier une chaine de caractère à insérer entre chaque valeur de colonne présentée dans l'option, faisant ainsi office de séparateur. Pour un tritement plus élaboré, par exemple si vous souhaitez entourer votre valeur de parenthèses, il vous faudra plutôt utiliser un keyProcessor. Exemple d'usage:
'columnSeparator' => ' -> ',
|
selectActions | Tableau associatif définissant les icônes d'action qui seront affichées, ou pas. La valeur '1' active l'icône, la valeur '0' la désactive. Par défaut, toutes les icônes sont actives, sauf la recherche (search). Attention, quand le champ search est à 1, il est impératif de définir searchTitleFields, et au moins l'un des champs suivants : searchFulltextFields, searchVarcharFields, searchEqualFields. Exemple d'usage:
'selectActions' => array(
'create' => 1,
'view' => 0,
'edit' => 1,
'delete' => 1,
'sort' => 1,
'clipboard' => 1,
'search' => 0,
),
Il est également possible de remplacer la valeur 1 par un lien personnalisé. Dans ce cas, c'est ce lien qui sera appellé pour ouvrir la fenêtre popup. Par exemple qui permet d'appeler un popup fait maison plutôt que le popup standard de MindFlow :
'selectActions' => array(
'create' => demandUtils::createDemand({record_uid}),
'view' => 0,
'edit' => 1,
'delete' => 1,
'sort' => 0,
),
Avec notre fonction qui crée le lien définie ainsi :
static function createDemand($recordUid){
//On crée les variables de sécurité pour prévenir les formulaires forgés
$sec = getSec(array(
'action' => 'createDemand',
'record_class' => 'demand',
'parent_uid' => $recordUid
));
// on retourne le lien en y injectant les paramètres de sécurité
// l'usage de $sec->parameters retourne les paramètres dans l'URL et évite de les saisir une seconde fois
// avec la source d'erreur que cela représente
// car si les paramètres dans l'URL et le Hash ne correspondent pas, la requête sera rejetée !
return $config['website_pluginsdir'].'/plugin_demands/
ajax-demand-json.php?'.$sec->parameters.'&sec='.$sec->hash.'&fields='.$sec->fields;
}
Et dans notre fichier ajax-demand-json.php, on traitera la requête de la manière suivante :
//vérification que les champs sécurisés n'ont pas été altérés
if(checkSec()){
if($_REQUEST['action'] == 'createDemand'){
$myDemand = new demand();
$myDemand->data['parent_uid']['value'] = intval($_REQUEST['parent_uid']);
$form = $mf->formsManager;
$htmlBody = '
|
icon | Permet de personnaliser l'icône affichée en haut à gauche de la select box avec le code HTML souhaité. Exemple d'usage:
'icon' => '',
|
debugSQL | Passer à true pour voir la requête SQL générée pour la sélection du contenu du champ et ainsi voir ce qui cloche en cas de problème. Exemple d'usage:
'debugSQL' => true,
|
keyProcessors | Permet de personnaliser l'affichage d'une valeur remontée de la base de données à la volée, au moyen d'une fonction. Par exemple si i_prix==1, afficher 'A'. Exemple d'usage:
'keyProcessors' => array(
'date'=>'depart::formatDateDepart',
'i_prix'=>'depart::formatIPrix'
),
|
onRefresh | Spécifie une fonction retour (callback) Javascript qui sera notifiée des modifications apportées par l'utilisateur à la liste des options du recordSelect Exemple d'usage:
'onRefresh' => 'participantChange',
La fonction participantChange est définie comme suit :
function participantChange(optionIndex,optionClass,actionName,
listOptionsFuncArguments){
console.log("participantChange("+optionIndex+","+optionClass+",
"+actionName+")");
var jqxhr = $.post("/mf/core/ajax-core-json.php",
listOptionsFuncArguments)
.success(function(jsonData) {
if(jsonData.result=="success"){
console.log("listOptionsFuncArguments success");
for(optionItem in jsonData.optionsList){
first_name = jsonData.optionsList[optionItem]
['first_name']['value'];
last_name = jsonData.optionsList[optionItem]
['last_name']['value'];
console.log("user names="+first_name+" "
+last_name);
}
}
else{
console.log("listOptionsFuncArguments error");
alert(jsonData.message);
}
})
}
Notez les arguments de rappel de notre fonction de callback / onRefresh : optionIndex : indice de l'option qui a été modifiée par l'utilisateur. Il s'agit également de l'uid de l'enregistrement affecté. optionClass : classe de l'enregistrement modifié par l'utilisateur. actionName : action réalisée par l'utilisateur. Peut être l'une des valeurs suivantes : view, create, edit, delete, sortUp, sortDown, paste listOptionsFuncArguments : retourne une série d'arguments sécurisée (inaltérable) qui peut être utilisée pour obtenir les données détaillées des enregistrements contenus dans la liste des options. Pour les obtenir, il suffit d'appeler ajax-core-json.php en lui passant ces arguments, comme suit : var jqxhr = $.post("/mf/core/ajax-core-json.php", listOptionsFuncArguments);
Voyez l'exemple ci-dessus pour un usage plus détaillé des valeurs de retour de la fonction. |
icons-wrap | Si à false, désactive le code qui génère un cadre gris autour des icônes d'action. Exemple d'usage:
'icons-wrap' => false,
|
icon-view | Permet de personnaliser l'icône de l'action 'voir' Exemple d'usage:
'icon-view' => '<b class="glyphicon glyphicon-eye-open"></b>',
|
icon-edit | Permet de personnaliser l'icône de l'action 'éditer' Exemple d'usage:
'icon-edit' => '<span class="btnMultiSelect"><b class="glyphicon
glyphicon-pencil"></b> Éditer la formation sélectionnée</span>',
|
icon-create | Permet de personnaliser l'icône de l'action 'créer' Exemple d'usage:
'icon-create' => '<span class="btnMultiSelect"><b class="glyphicon
glyphicon-plus"></b> Ajouter une formation</span>',
|
icon-delete | Permet de personnaliser l'icône de l'action 'effacer' Exemple d'usage:
'icon-delete' => '<span class="btnMultiSelect"><b class="glyphicon
glyphicon-trash"></b> Supprimer la formation sélectionnée</span>',
|
icon-add | Permet de personnaliser l'icône de l'action 'ajouter' Exemple d'usage:
'icon-add' => '<b class="glyphicon glyphicon-plus-sign"></b>',
|
icon-remove | Permet de personnaliser l'icône de l'action 'ôter' Exemple d'usage:
'icon-remove' => '<b class="glyphicon glyphicon-minus-sign"></b>',
|
icon-up | Permet de personnaliser l'icône de l'action 'déplacer vers le haut' Exemple d'usage:
'icon-up' => '<b class="glyphicon glyphicon-circle-arrow-up"></b>',
|
icon-down | Permet de personnaliser l'icône de l'action 'déplacer vers le bas' Exemple d'usage:
'icon-down' => '<b class="glyphicon glyphicon-circle-arrow-down"></b>',
|
allow_cross_editing | Par défaut ce champ est fixé à true. Si spécifié à false, ce champ permet de désactiver l'édition des entrées du recordSelect par des utilisateurs autres que le créateur de l'enregistrement. Les autres utilisateurs peuvent encore visualiser ou copier/coller l'enregistrement, mais ne peuvent pas l'éditer ou le supprimer. Exemple d'usage:
'allow_cross_editing' => false,
|
Options associées à la recherche :
Ces options ne sont effectives que lorsque le champ selectActions['search'] est fixé à 1 pour que la recherche soit activée.
Vous devez impérativement spécifier le champ 'searchTitleFields' ainsi que l'un des 3 champs suivants pour que la recherche fonctionne : 'searchFulltextFields', 'searchVarcharFields' ou 'searchEqualFields'
searchTitleFields | Liste séparée par des virgules de nom de champs / colonnes qui seront affichés en tant que résultat de recherche. Ceci influence le segment SELECT de la requête de recherche : Exemple d'usage:'searchTitleFields' => 'ref,titre',
SELECT uid,ref,titre FROM vz_circuits WHERE MATCH(ref,titre)
AGAINST('Timbr*' IN BOOLEAN MODE) AND deleted=0
|
searchFulltextFields | Liste séparée par des virgules de nom de champs / colonnes présentes dans l'index fulltext de la table et pouvant être recherchées. Exemple d'usage:
'searchFulltextFields' => '`ref`,`titre`',
Ceci produit une recherche du type :
SELECT uid,ref,titre FROM vz_circuits WHERE MATCH(`ref`,`titre`)
AGAINST('Timbr*' IN BOOLEAN MODE) AND deleted=0
Note : le champ selectActions['search'] doit être fixé à 1 pour que la recherche soit activée. |
searchVarcharFields | Liste séparée par des virgules de nom de champs / colonnes de type varchar et pouvant être recherchés. Exemple d'usage:
'searchVarcharFields' => 'ref,titre',
Ceci produit une recherche du type :
SELECT uid,ref,titre FROM vz_circuits
WHERE ( ref LIKE '%Timbr%' OR titre LIKE '%Timbr%')
AND deleted=0
Note : le champ selectActions['search'] doit être fixé à 1 pour que la recherche soit activée. |
searchEqualFields | Liste séparée par des virgules de nom de champs / colonnes de seront recherchés avec un critère d’égalité stricte. Exemple d'usage:
'searchEqualFields' => 'ref,titre',
Ceci produit une recherche du type :
SELECT uid,ref,titre FROM vz_circuits
WHERE (ref = 'Timbre' OR titre = 'Timbre') AND deleted=0
Note : le champ selectActions['search'] doit être fixé à 1 pour que la recherche soit activée. |
searchOrderByFields | Rajoute une clause ORDER BY à la requête de recherche. Exemple d'usage:
'searchOrderByFields' => 'titre',
Ceci produit une recherche du type :
SELECT uid,ref,titre FROM vz_circuits WHERE (ref = 'Timbre')
AND deleted=0 ORDER BY titre
Note : le champ selectActions['search'] doit être fixé à 1 pour que la recherche soit activée. |
searchDebug | Permet de visualiser la requête SQL générée pour la recherche dans la réponse AJAX, et d'analyser ainsi d'éventuels problèmes.
Exemple d'usage:
'searchDebug' => true,
|
Champ “recordEditTable”¶
Affiche un recordEditTable au sein d’un enregistrement dbRecord. L’objet est simplement de permettre d’offrir une “vue” vers d’autres enregistrements : le contenu du recordEditTable n’est pas sauvé dans l’enregistrement courant car il est est juste défini par une requête SQL vers d’autres tables. Les éléments affichés sont ceux qui satisfont les critères de cette requête. Pour l’essentiel, le champ recordEditTable reprend les arguments de la fonction showRecordEditTable de la classe dbRecord

//Voici un exemple de définition de champ recordEditTable
'options' => array(
'dataType' => 'recordEditTable',
'editClass' => 'vzDossier',
'selectItemsSQL' => array(
'SELECT' => 'vzUser.first_name,vzUser.last_name,statut_vente,interet,titre',
'FROM' => '',
'JOIN' => 'JOIN vz_users vzUser on vzUser.uid=client',
'WHERE' => '0', // la condition est ajustée dans les fonctions postCreate() et postLoad()
'ORDER BY' => 'titre',
'ORDER DIRECTION' => 'ASC',
),
'moduleName' => 'gestionDeparts',
'subModuleName' => '',
'mainKey' => 'titre',
'keyProcessors' => array(),
'page' => null,
'selectActions' => array(
'view' => 1,
'edit' => 1,
'delete' => 1,
),
'advancedOptions'=> array(
'ajaxActions' => true,
'buttons' => $buttonCreateDossier,
'debugSQL' => 1,
'editRecordButtons' => array(
'showSaveButton' => true,
'showSaveCloseButton' => true,
'showPreviewButton' => false,
'showCloseButton' => true
),
'showPrint' => false,
'actionOnTitleClick' => 'edit',
'forceNumRowsPerPage' => '6',
),
'recordEditTableID' => 'depart_options',
'innerPreLabelHTML' => '<b class="glyphicon glyphicon-folder-open"></b>',
'div_attributes' => array('class' => 'col-lg-12','style' => 'padding-right:20px;'),
'label_attributes' => array('class' => 'col-lg-12'),
'fullWidth' => true,
),
dataTypeType | recordEditTable |
editClass | Nom de la classe PHP a éditer. Celle-ci devra être hérité de dbRecord
'editClass' => 'myContact'
|
selectItemsSQL | On spécifiera ici la requête spécifiant les éléments à afficher Exemple d'usage:
'selectItemsSQL' => array(
'SELECT' => 'first_name,last_name,statut_vente,interet',
'FROM' => '',
'WHERE' => "statut_vente='option'",
'ORDER BY' => 'last_name',
'ORDER DIRECTION' => 'ASC',
),
Notez que si vous devez faire référence à l'uid de l'enregistrement courant dans votre clause WHERE, il vous faudra ajuster le WHERE dans les fonctions postCreate() et postLoad(). En effet, au moment de l'exécution de la fonction init(), il n'y a qu'une simple déclaration de la structure du tableau data et tous les champs value() sont vides : vous ne pouvez donc pas vous y référer à ce stade pour récupérer l'uid de l'enregistrement courant. En revanche, une fois l'enregistrement créé ou chargé depuis la base de données, son uid devient disponible.
function postCreate(){
$this->data['options']['selectItemsSQL']['WHERE'] =
"depart=".$this->data['uid']['value']." AND statut_vente='option'";
}
|
moduleName | Clé du module courant. Peut être laissée vide. |
subModuleName | Clé du sous-module courant. Peut être laissée vide. |
mainKey | Champ/colonne du tableau dont le titre sera clicable Exemple d'usage:
'mainKey' => 'last_name',
|
keyProcessors | Permet de personnaliser l'affichage d'une valeur remontée de la base de données à la volée, au moyen d'une fonction. Par exemple si i_prix==1, afficher 'A'. Exemple d'usage:
'keyProcessors' => array(
'date'=>'depart::formatDateDepart',
'i_prix'=>'depart::formatIPrix'
),
|
page | Permet de forcer un numéro de pagination pour l'affichage des résultats. On laissera généralement la valeur à null. Exemple d'usage:
'page' => '2',
|
selectActions | Liste des actions disponibles dans la colonne "actions" sur la droite du tableau. Référez-vous à la documentation de la fonction showRecordEditTable() pour plus de détails. Exemple d'usage:
'mainKey' => array(
'create' => 1,
'view' => 1,
'edit' => 1,
'delete' => 1,
),
|
advancedOptions | Liste des options avancées en appel de showRecordEditTable(). Référez-vous à la documentation de la fonction showRecordEditTable() pour plus de détails. Exemple d'usage:
'advancedOptions'=> array(
'ajaxActions' => true,
'buttons' => null, //assigné dans postCreate + postLoad
'columnClasses' => array(
'creation_date' => 'hidden-xs',
'email' => 'hidden-xs hidden-sm',
'deleted' => 'hidden-xs hidden-sm',
),
'debugSQL' => 0,
'editRecordButtons' => array(
'showSaveButton' => true,
'showSaveCloseButton' => true,
'showPreviewButton' => false,
'showCloseButton' => true
),
'showPrint' => false,
'actionOnTitleClick' => 'edit',
'forceNumRowsPerPage' => '6',
),
|
recordEditTableID | Spécifie un string qui servira d'ID unique pour ce recordEditTable. Si aucun recordEditTableID n'est fourni, une valeur numérique aléatoire sera générée. Si vous avez besoin d'accéder au recordEditTable via javascript, vous aurez besoin d'un ID prédictible et vous voudrez donc spécifier ici une valeur personnalisée. Exemple d'usage:
'recordEditTableID' => 'depart_options',
|
fullWidth | Permet d'étendre le recordEditTable à toute la largeur du formulaire, si positionné à true. Exemple d'usage:
'fullWidth' => 'true',
|
Champ “textarea”¶
Affiche un champ textarea.
dataType | On spécifiera en second argument le nombre de colonnes et en troisième argument le nombre de lignes. Exemple d'usage:
'dataType' => 'textarea 50 8'
|
Champ “files”¶
Affiche un champ d’upload de fichiers. Ces fichiers seront placés dans le sous-dossier ‘uploads/’ du dossier défini pour le site courant dans mf_websites/
AllowedExtensions | Liste séparée par des virgules des extensions de fichiers autorisées en upload. Si la clé n'est pas définie, la valeur par défaut suivante s'applique : gif, jpg, jpeg, png, xls, xlsx, doc, docx, ppt, pptx, pdf, odb, odc, odf, odg, odp, ods, odt, oxt
'allowedExtensions' => 'jpg,jpeg,gif,png',
|
jsCallbackFunc | Spécifier une fonction javascript qui sera appelée une fois l'upload terminé
'jsCallbackFunc' => 'statAdhesion'
La fonction sera alors définie comme suit dans votre code :
<script>
function statAdhesion(){
alert('statAdhesion appellée !');
}
</script>
|
maxItems | Indique le nombre maximum de fichiers autorisés en upload dans ce champ.
'maxItems' => 6,
|
Important
L’attribut ‘value’ du champ files est sauvegardée par MindFlow sous la forme d’une donnée structurée au format suivant :
array (
0 =>
array (
'timestamp' => 1452700155,
'filename' => 'velo-birmanie-2_1452700155.jpg',
'filepath' => 'circuit/circuit_726/',
'width' => 1920,
'height' => 1080,
),
1 =>
array (
'timestamp' => 1452700185,
'filename' => 'velo-birmanie-4_1452700185.jpg',
'filepath' => 'circuit/circuit_726/',
'width' => 1920,
'height' => 1080,
),
)
L’ordre des entrées dans le tableau reflète le classement des fichiers, initialement selon leur ordre d’upload, ou selon le tri manuel effectué en drag & drop dans le backend.
timestamp
: moment ou le fichier a été uploadé, au format timestamp unixfilename
: nom du fichier sur le disquefilepath
: chemin relatif par rapport au dossier d’upload défini dans la variable $config[‘uploads_directory’]. Pour retrouver le chemin relatif à la racine de l’hébergement, concaténez la valeur avec$mf->getUploadsDir().DIRECTORY_SEPARATOR
. Pour retrouver le chemin absolu sur le disque, préfixez avec la constanteDOC_ROOT
.width
,height
: Ces champs mettent en cache après l’upload, pour les fichiers images uniquement, la largeur et la hauteur, de manière à ne pas avoir a les extraire de l’image à chaque accès et affichage de celle-ci, ce qui est extrêmement préjudiciable au niveau des performances.
D’autres meta-informations sont susceptibles d’être ajoutées dans le futur, par exemple un attribut ‘alt’ serait bienvenu. Vous devriez également être en mesure d’ajouter vos meta-informations personnalisées au tableau, mais cet aspect n’a pas encore été testé et validé.
Pour afficher une image, vous pouvez procéder comme suit :
$photo = $record->data['mon_champ_files']['value'];
$imageSrc = $mf->getUploadsDir().$photo['filepath'].$photo['filename'];
$html = '<img src="'.$imageSrc.'" width="'.$photo['width'].'" height="'.$photo['height'].'" />';
Note
Le champ files fonctionne en conjonction avec la fonction mfResizeImage()
du fichier utils.php qui optimise la génération de vignettes en les gardant en cache sur le système de fichiers du serveur, pour éviter d’avoir à les ré-génerer à chaque consultation, ce qui soulage le CPU du serveur. La fonction préserve aussi le ratio et la qualité de l’image lors du re-dimensionnement, en se basant notamment sur les meta-données width et height enregistrées avec l’image dans le tableau serialisé.
Voici un exemple d’usage, qui extrait une série d’images d’une fiche circuit et les travaille en plusieurs résolution avant leur affichage. Comme vous pourrez le constater, avec ce système, les images sont facilement et rapidement exploitables :
$imagesFiche = $circuit->data['imgs']['value']; // le tableau est déjà déserialisé automatiquement
// quand l’enregistrement est chargé via sa fonction load()
if(is_array($imagesFiche) and sizeof($imagesFiche) > 0){
foreach($imagesFiche as $bigImage){
$smallImage = mfResizeImage($bigImage, 302, 200, false); //on spécifie les nouvelles largeur / hauteur pour le redimensionnement
$mediumImage = mfResizeImage($bigImage, 592, 592); //les images redimensionnées sont écrites dans le même dossier que $bigImage ['filepath']
// et spécifiées dans l’array() retourné par la fonction mfResizeImage()
if(isset($smallImage['filepath'])){
$smallImageSrc = $mf->getUploadsDir().$smallImage['filepath'].$smallImage['resizedFilename'] ;
}
if(isset($mediumImage['filepath'])){
$mediumImageSrc = $mf->getUploadsDir().$mediumImage['filepath'].$mediumImage['resizedFilename'] ;
}
if(isset($bigImage['filepath'])){
$bigImageSrc = $mf->getUploadsDir().$bigImage['filepath'].$bigImage['filename'] ;
}
//ici on peut exploiter facilement les metadonnées
$carousel .= "<a class='CarImgLink' style=’margin: 30px;width:".$smallImage['width']."px; height: ".$smallImage['height']."px; background-repeat:no-repeat; background-image: url('$smallImageSrc')’ href=’".$bigImageSrc."’ data-size=’".$bigImage['width']."x".$bigImage['height']."’ data-med=’".$mediumImageSrc."’ data-med-size=’".$mediumImage['width']."x".$mediumImage['height']."’ ><img src=’".$smallImageSrc."’ alt=’’ /></a>";
}
}
Champ “fieldset”¶
Ajoute un cadre fieldset autour de certains champs du formulaire, qui démarre à l’emplacement ou est inséré le champ et qui se termine après le champ spécifié dans la clé ‘closeAfterKey’
closeAfterKey | Spécifier la clé champ après lequel fermer ce fieldset Exemple d'usage:
'closeAfterKey' => 'email',
|
Champ “html”¶
Ajoute un code HTML personnalisé dans le formulaire à l’emplacement ou est inséré le champ.
value | Le code HTML qui doit être inséré Exemple d'usage:
'value' => '<hr />',
|
Champ “template_name”¶
Ce champ est toujours associé à un champ template_data.
value | Indique la clé du template qui défini la structure de données stockée dans le champ template_data généralement associé à ce champ. Cette clé correspond à une entrée existante dans le tableau $mf->templates. Exemple d'usage:
'value' => '404-page',
|
Champ “template_data”¶
Ce champ est toujours associé à un champ template_name.
Champ permettant de stocker une structure de données de type template. Il n’est pas destiné à être affiché en tant que champ de formulaire.
Un objet template est une structure de données de spécification similaire à ce qu’on peut trouver pour le tableau ‘data’. Néanmoins celle-ci est sérialisée, puis stockée en base de données dans un seul champ de type longblob, au lieu d’avoir une colonne dans la table par clé/champ. Ceci permet d’avoir une structure de données souple, modifiable dynamiquement et enregistrable en base de données sans avoir à modifier la structure de la table MySQL.
La structure template_data est utilisée par la classe ‘page’ du Plugin ‘pages’ et par la classe ‘mfUserGroup’ du plugin ‘mf_users’ si vous voulez voir des exemples d’utilisation.
Dans la majorité des cas, vous n’en aurez pas besoin, sauf si vous voulez générer des formulaires dynamiques dont vous ne pouvez prévoir la structure à l’avance.
Aucun champ spécifique |
Champ “microtemplate”¶
Permet d’insérer des microtemplates HTML dans la page.
AllowedMicrotemplateTypes | Liste de clés de microtemplates séparées par des virgules pour indiquer quels types de microtemplates sont autorisés en insertion de ce champ. Un microtemplate ou micro-gabarit est une portion de code HTML, qui n'inclus pas une page entière, mais seulement une fraction de cette page, par exemple le microtemplate permettant l'affichage d'une actualité, que l'on pourra répéter et afficher autant de fois qu'il y aura d'actualités à montrer au sein d'une même page. Exemple d'usage:
'allowedMicrotemplateTypes' => 'infoBlock, purchaseBlock',
|
Types SQL selon les types de champs¶
Vous créez donc un champ dans un enregistrement de base de données. Mais quel type SQL lui donner ?
Alors que vous êtes libre d’adopter le type qui vous convient, voici des types éprouvés par l’expérience qui fonctionneront dans la plupart des cas :
input | VARCHAR(256) |
date | DATE |
datetime | DATETIME |
time | TIME |
color | VARCHAR(10) |
hidden | Dépend de la nature de la valeur portée par le champ. VARCHAR(256) devrait convenir dans la plupart des cas. |
urlinput | VARCHAR(256) |
checkbox | TINYINT(1) NOT NULL DEFAULT '0' |
select | VARCHAR(256) ou ENUM('valeur1','valeur2',etc..) si on veut contraindre les valeurs dès le niveau SQL |
record | VARCHAR(256) ou TEXT si le nombre d'enregistrement susceptibles d'être ajoutés est important |
recordEditTable | Les champs recordEditTable fournissent une vue sur une autre table en fonction des critères indiqués dans la requête SQL associée. A ce titre, il n'y a aucune donnée stockée dans la table de l'objet local. Il ne faut donc pas définir de colonne associée à un champ recordEditTable |
rich_text | TEXT |
textarea | TEXT |
files | TEXT |
template_name | VARCHAR(256) |
microtemplate | Sans objet : un microtemplate est un sous ensemble d'un champ template. C'est le champ template qui est stocké en base de données. |
template_data | LONGBLOB |
fieldset | Sans objet (non stocké en BDD) |
html | Sans objet (non stocké en BDD) |