Sometimes you need to work with arrays of values or data which is stored as JSON but needs to be accessed as an object or array. Don't worry, this is possible with Joomla's Table class, albeit not immediately obvious.
Let's say you want to work with array data in a column called params, stored in the database as a JSON-encoded string. You will need to think about three things:
-
Resetting a table. By default, Joomla uses the default value you have for the same named column in your database table. You want to change that to an empty array.
-
Binding data. When Joomla loads a record and when we call the table object's
save()
method to create or modify a record, Joomla always calls thebind()
method to set up the object's properties in way which makes sense for use in the code. In there we will need to convert our encoded field into an array. -
Storing data. The store() method needs the data in the record to be in a format which can be stored in the database table as-is. The plan here is to convert the array data to JSON before this method executes and convert out data back to array data right before this method returns.
class ItemTable extends \Joomla\CMS\Table\Table { public function bind($src, $ignore = []) { $src = (array) $src; $src['params'] = @json_decode($src['params']); return parent::bind($src, $ignore); } public function store($updateNulls = false) { $this->params = @json_decode($this->params ?? '{}', true) ?? []; $result = parent::store($updateNulls); $this->params = @json_encode($this->params) ?? '{}'; return $result; } public function reset() { parent::reset(); $this->params = []; } }
Nothing stops you from using a
\Joomla\Registry\Registry
object instead of a plain array;
in fact, it may be easier to manage. You may also have multiple fields
in need of this kind of conversion.
Another practical example is multi-select form fields, e.g. selecting one or more usergroups. The resulting array of integers can be easily converted to a comma-separated string for saving in the database.