Index de l'article

Calcul, récupération, manipulation de champs

Exemple simple (un devis)

Fabrik 4.1 (GitDate: 2024-05-22)  

Dans un élément calc nommé prix, dans une liste devis, et à partir d'un champ nombre_heures (qui sera ici multiplié par 55 pour donner le prix final): 

$nombreHeure = (int)'{devis___nombre_heures_raw}' ;
 
$prixFinal = $nombreHeure * 55 ;
 
return number_format($prixFinal, 0, ',', ' ') ;

Récupérer le nom et le prénom à partir du nom d'utilisateur Joomla

Bien souvent on souhaite récupérer l'identité complète d'un utilisateur (dans un formulaire de profil, de commande...).

Mais Joomla ne prend qu'un seul vrai nom d'utilisateur (name). Il s'agit donc de découper ce champ en 2 nouveaux champs pour le prénom et le nom (ce qui nous permettra de ne pas toucher à l'utilisateur système, l'utilisateur Joomla).

Dans un champ firstname, dans la valeur par défaut de l'élément, nous pouvons récupérer le 1er mot saisi dans le champ utilisateur name de l'utilisateur connecté, avant un espace. Ne retournera rien s'il n'y a pas d'espace (nous préférons ici conserver la valeur pour le lastname, sans faire doublon) :

$MonName = '{$my->name}' ;
 
$Espace = ' ' ;
$CherchePosEspace = strpos($MonName, $Espace) ;
$MonName2 = substr($MonName,0,$CherchePosEspace) ;
 
return $MonName2 ;

Pour le lastname (la chaîne suivante supposée du moins), il faudra prévoir l'existence ou non d'un espace dans le name, avec une condition if, afin de le conserver tel quel si le nom de l'utilisateur ne contient qu'un seul mot :

$MonName = '{$my->name}' ;
 
// Il y a au moins un espace
if(strpos($MonName, ' ') !== false){
 
$Espace = ' ' ;
$CherchePosEspace = strpos($MonName, $Espace) + 1 ;
$MonName2 = substr($MonName,$CherchePosEspace,strlen($MonName)) ;
}
 
// Il n'y a aucun espace
else{
$MonName2 = $MonName;
}
 
return $MonName2 ;

Allié ensuite à des jointures ou d'autres règles de validation PHP ou notempty, vous pourrez contraindre la saisie de l'identité complète dans les profils, la correspondance entre les champs... ou au contraire autoriser les saisies d'objets à d'autres noms mais liés au même utilisateur.

Récupérer des données JSON

Certains champs Joomla (ou d'extensions, ou autres...) stockent des données en JSON. Pour customiser certains affichages avec Fabrik, il est intéressant de savoir récupérer les données souhaitées.

Ici par exemple, nous récupérons le code vidéo YouTube d'une URL stockée dans le champ attribs de la table #_content, juste avant de l'afficher dans un iframe.

Dans un champ calc :

$My_Json_String = '{#_content___attribs}' ;
 
// Fix quotes
$json = str_replace('"', '"', $My_Json_String);
$object = json_decode($json);
$videoUrl = $object->video;
 
// Recover only the Youtube Video Code (deleting the beginning of the url - to do an iframe after)
$videoCode = str_replace('https://youtu.be/', '', $videoUrl);
 
// Tests:
// var_dump($videoUrl); exit;
// echo '<pre>'. $videoCode . '</pre>';
 
// Iframe
return '<iframe width="100%" height="250px" src="https://www.youtube.com/embed/'.$videoCode.'" frameborder="0" allow="encrypted-media" allowfullscreen></iframe>' ;

Nous commençons par récupérer le champ JSON voulu dans une variable ($My_Json_String). Par commodité nous plaçons de vrais guillemets dans le JSON (str_replace), peut renvoyer NULL sans cela).

Ensuite nous décodons le JSON (json_decode) afin d'extraire la chaîne voulue (utilisez l'echo pour vérifier sa forme, ici l'URL de la vidéo).

Dans notre cas nous souhaitons intégrer la vidéo dans un iframe, nous supprimons donc le début de l'URL afin de ne conserver que le code YouTube d'intégration (str_replace).

Le return construit ensuite l'iframe dynamiquement.

Attention : Parfois, si vous n'êtes pas déjà en UTF-8, vous devrez ré-encoder votre variable avant de décoder le JSON (utf8_encode).

Un autre exemple de génération puis récupération de données JSON externes (à partir de l'API Google Maps) se trouve ici !

Calcul ou récupération de champs de tables externes

Parfois vous souhaitez utiliser des valeurs de tables jointes via un champ de type databasejoin. Prendre le prix unitaire d'un produit pour calculer le prix total d'une commande par exemple.

Votre champ databasejoin stocke typiquement l'id de l'enregistrement distant, l'utiliser dans un champ calc vous permettra de récupérer d'autres valeurs de cet enregistrement distant.

Ici nous allons récupérer un entier dans une variable nommée $MaValeurRecupere, avant de le multiplier par une donnée saisie.

// Declaration de la variable stockant l id d'origine
$MonIdDistant = '{Ma_Table___Id_Distant_raw}';
 
// if-else de gestion des cas vides - pour eviter de declencer une requete WHERE vide
if (!empty($MonIdDistant)) {
 
// Acces a la base de donnees
$myDb = JFactory::getDbo();
 
// Creation requete - argument true pour nettoyer une eventuelle ancienne requete
$myQuery = $myDb->getQuery(true);
 
// Requete de recuperation de la valeur concernee en fonction de l id d'origine
$myQuery->select('Champ_A_Recuperer')->from('Table_Distante')->where('Champ_Id = ' . $myDb->quote($MonIdDistant));
$myDb->setQuery($myQuery);
$MaValeurRecupere = $myDb->loadResult();
 
// Calcul
return $MaValeurRecupere * '{Ma_Table___Champ_Nombre}' ;
}
 
// Si vide
else {
return '';
}

Ce type de code peut tout-à-fait être utilisé dans les pré-filtres d'une liste (choisir Eval dans le champ Type d'un pré-filtre, pour interprêter du code PHP). Autrement dit, on peut lier des données provenant de bases distantes pour faire un peu plus que du simple affichage !

Sommer les valeurs d'un sous-formulaire

À partir de l'exemple précédent des commandes clients, on souhaite parfois regrouper des commandes de produits différents dans une seule commande, afin d'additionner les totaux et de produire une somme finale. On a donc un formulaire principal de commande, et ses sous-formulaires des quantités par produits.

En reprenant le code de l'exemple précédent, dans un champ calc, ou encore dans le plugin de formulaire pour Paypal, ajouter un sum dans votre requête $myQuery fera l'affaire :

$myQuery->select('sum(Champ_A_Sommer)')->from('Ma_Table')->where('Champ_Id = ' . $myDb->quote($tableId));

Utiliser des données tiers comme des variables de session

Parfois vous avez besoin de récupérer des données, internes ou externes (la BDD d'origine ou une autre) en tant que variable de session. Exemple : des données de profil utilisateur (détails, adresses, téléphones...) séparées de la table #_users. Bien sûr vous n'y avez pas accès via les variables de sessions classiques.

Si ces données sont correctement liées aux utilisateurs (un champ user_id faisant le lien avec la table #_users), vous pouvez alors les appeler une par une dans des champs calc, en utilisant {$my->id} :

// DB access, with Fabrik connection ID
$myDb = FabrikWorker::getDbo(false, 1) ;
 
// Recover query
$myQuery = $myDb->getQuery(true) ;
$myQuery->select('lastname')
->from('profiles')
->where('user_id = {$my->id}') ;
 
$myDb->setQuery($myQuery) ;
$MyData = $myDb->loadResult() ;
 
return $MyData ;

Afficher des données d'un tableau

Si vos données proviennent d'une requête SQL avec des résultats multiples par exemple :

$VideoId = '{videos___id}' ;
$Title = '{videos___title}' ;
$Speaker = '{videos___speaker_name}' ;
$Tags = '{videos___video_tags}' ;
 
// Acces a la base de donnees
$myDb = FabrikWorker::getDbo(false, 1);
 
// Creation requete - argument true pour nettoyer une eventuelle ancienne requete
$myQuery = $myDb->getQuery(true);
 
$myQuery = "
SELECT id, title, category,
CONCAT('published on ', DATE_FORMAT(date_publish, '%d/%m/%Y')) as my_date_publish,
speaker_name,
tag_unique
FROM videos_tags_uniques
WHERE tag_unique IN ('Periorbital')
AND id <> $VideoId
ORDER BY date_publish DESC
LIMIT 0,10
" ;
 
$myDb->setQuery($myQuery);
$MyResults = $myDb->loadObjectList();
 
$list = array();
foreach ($MyResults as $row)
{
$list[] = "<div><a href='/video-v3/details/42/". $row->id ."' style='font-size: 18px; font-weight: bold'>" . $row->title . "</a><font style='font-size: 14px; font-style: italic;'> - ". $row->speaker_name ." " . $row->category . ", " . $row->my_date_publish . "</font></div>";
}
 
if (!empty($MyResults)) {
return "<div style='font-size: 17px;margin-bottom: 5px;'>Others videos related</div>
<div>" . implode($list) . "</div>";
}else {
return '';
}
;
Liens ou pièces jointes
Accéder à cette adresse URL (http://fabrikar.com/forums/index.php?wiki/troubleshooting-tools/)Wiki Fabrik sur les troubleshooting tools[Article]0 Ko
Accéder à cette adresse URL (http://fabrikar.com/forums/index.php?wiki/calculation-element/)Wiki Fabrik sur les champs calc pour débogage[Article]0 Ko
Accéder à cette adresse URL (http://fabrikar.com/forums/index.php?wiki/php-form-plugin/)Wiki Fabrik sur le plugin PHP pour les formulaires[Article]0 Ko
Accéder à cette adresse URL (http://fabrikar.com/forums/index.php?wiki/filtering-lists-tables/)Filtres de listes[Article officiel Fabrik sur les pré-filtres de listes]0 Ko
Accéder à cette adresse URL (https://api.joomla.org/cms-3/classes/JDatabaseDriver.html)Joomla! API[Documentation Joomla]0 Ko
Accéder à cette adresse URL (https://docs.joomla.org/Selecting_data_using_JDatabase)Selecting data using JDatabase[Documentation Joomla]0 Ko