Quand on veut stocker des données dans un champ de la base de donnée en Json, Jtable peut faire le travail.

Pour cela il faut juste définir dans votre classe héritant de JTable :

class ContactTableContact extends JTable {
/**
* Ensure the params and metadata in json encoded in the bind method
*
* @var array
* @since 3.3
*/
protected $_jsonEncode = array('params', 'metadata');
....
}

Ceci signife que les rubriques params et metadata de votre table seront encodée Json.

Vous pouvez bien sûr en rajouter d'autres, ici je rajoute aussi inscriptions_params dans ma table, que je n'oublie pas de rajouter dans $_jsonEncode :

CREATE TABLE IF NOT EXISTS #__gski_users (
id int(11) unsigned NOT NULL AUTO_INCREMENT,
...,
inscriptions_params text NOT NULL,
params text NOT NULL,
created datetime NULL DEFAULT NULL,
created_by int(10) unsigned NOT NULL DEFAULT '0',
modified datetime NULL DEFAULT NULL,
modified_by int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (id), )
ENGINE=MyISAM /!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci/;

Du coup lors de l'enregistrement par la methode store, la methode bind, lancée au préalable fera un encodage Json de chaque champ défini dans $_jsonEncode.
Voir methode bin vers la ligne 595 de /librairies/src/Table/Table.php

$src[$field] = json_encode($src[$field]);

Par contre au niveau de la méthode load, il faudra penser ) faire la démarche inverse, je ne sais pas pourquoi cela n'a pas été prévu dans le framework dans la classe mère.

Du coup moi j'ai un classe Jtable intermédiaire où je fais d'office la démarche, toutes mes tables héritant alors de cette classe intermédiaire.

 

<?php
use Joomla\CMS\Table\Table;
class GskiTable extends Table
{
.... public function load($keys = null, $reset = true) { if (parent::load($keys, $reset)) { // Convert params field to registry. // convert any JSON encode fields in array if (!empty($this->_jsonEncode)) { foreach ($this->_jsonEncode as $field) { if (isset($this->$field) && !is_array($this->$field)) { GskiStringHelper::JsonToArray($this->$field); } } } return true; } else { return false; } }
....
}

Les différents éléments seront donc rendus dans un tableau du nom de la rubrique de la table.

Afin que le databinding fonctionne, dans le fichier xml de descriptions des champs, il faudra donc définir un groupe de champs avec le nom de la table, et chaque champ du groupe correspondant à un indice par exemple :

<form>
 <fieldset name="inscriptions" label="COM_GSKITITRES_CONFIG_GENERALE_LABEL" description="COM_GSKITITRES_CONFIG_GENERALE_DESC">
  <field name="info_onglet_inscriptions" ...  ... />
   <fields name="inscriptions_params">
    <field name="info_inscriptions_equipes" .... />
....
   </fields>
 </fieldset>
</form>

Ainsi la valeur contenue dans $inscriptions_params['info_inscriptions_equipes'] sera bien affectée au champ de nom info_inscriptions_equipes du groupe de champ de nom inscriptions_params.