2

I'm writing to the db (I'm automatically creating a module):

$module = new stdClass();

$module->title = $moduleTitle;
$module->note = "";
$module->content = "";

$module->position = $modulePosition;
$module->checked_out = 0;

$module->publish_up = "";//current data and time in Y-M-day time e.g.2020-05-26 08:53:56
$module->publish_down = "0000-00-00 00:00:00";
$module->published = 1;
$module->module = $moduleModule;
$module->access = $moduleAccess;
$module->showtitle = 1;
$module->params = $moduleParams;
$module->client_id = 0; //front end module
$module->language = "*";


JFactory::getDbo()->insertObject('#__modules', $module, 'primary_key');

This all works great apart from the $module params. I create them by

$myParams->available_page_groups = '["'.$currentmenuid.'"]';
$myParams->show_page_title = 0;
$myParams->show_page_notes = 0;
$myParams->show_page_owner = 0;
etc.

$myJSON = json_encode($myParams);

Which produces correctly encoded JSON. However when I look in the database the params have been escaped:

{"available_page_groups":"[\"13\"]","show_page_title":0,"show_page_notes":0,...

they should read

{"available_page_groups":"["13"]","show_page_title":0,"show_page_notes":0,...

Can someone tell me how to stop the insertObject adding in the escape characters or is there another way I need to do this - i.e. some sort of raw filter to apply?

thanks

2 Answers 2

3

json_encode() is correctly doing its thing. Double quoting is used to isolated keys and values; any double quotes inside of these data points must be escaped to maintain the integrity of the data (otherwise the data structure will break/fail when json decoded).

If you tried to NOT json_encode() the iterable params data, then your code would fail because the params column (which is a VARCHAR(5120)) expects string-type data not an array/object.

The source of the issue comes from the fact that you are baking your own json string manually for available_page_groups. Please never do this. Always declare the complete data structure to be encoded then only json encode the structure one time when finished building it. Your code is effectly encoding a manually encoded string (IOW, double encoding).

If this was my project, here's how I would declare the object:

$module = (object)[
    'title' => $moduleTitle,
    'note' => '',
    'content' => '',
    'position' => $modulePosition,
    'checked_out' => 0,
    'publish_up' => '',
    'publish_down' => '0000-00-00 00:00:00',
    'published' => 1,
    'module' => $moduleModule,
    'access' => $moduleAccess,
    'showtitle' => 1,
    'params' => json_encode([
        'available_page_groups' => [
            $currentmenuid,
        ],
        'show_page_title' => 0,
        'show_page_notes' => 0,
        'show_page_owner' => 0,
        // ... more data
    ]),
    'client_id' => 0, //front end module
    'language' => '*',
];

Also, I think you went a little too literal on the primary_key parameter of your insertObject() call. I think the Joomla Docs tricked you: https://docs.joomla.org/Inserting,_Updating_and_Removing_data_using_JDatabase

  /**      * Inserts a row into a table based on an object's properties.  
    *      * @param   string  $table    The name of the database table to insert into.
    *      * @param   object  &$object  A reference to an object whose public properties match the table fields.
    *      * @param   string  $key      The name of the primary key. If provided the object property is updated.
    *      * @return  boolean    True on success.
    *      * @since   11.1
    *      * @throws  RuntimeException
    */
  public function insertObject($table, &$object, $key = null)

You probably want to go with:

JFactory::getDbo()->insertObject('#__modules', $module, 'id');

Since id is the name of the primary_key in the modules table. https://docs.joomla.org/Tables/modules

3
  • Hi this worked great thanks. On the second part about the module I used JFactory::getDbo()->insertObject('#__modules', $module, 'primary_key'); because I the go on to recover the created key with $moduleCreatedId = $module->primary_key; Is this wrong or perhaps there is a better (more standard) way of getting the id? Thanks again Jun 24, 2020 at 9:14
  • Should be $moduleCreatedId = $module->id;. I wouldn't declare a new variable; just access the updated property in the $module object when you need the value. The docs recommends that you declare 'id' => null, in your object before inserting. Jun 24, 2020 at 9:18
  • changed the code to match - thanks for the help saved me loads of time. Jun 24, 2020 at 12:25
-1

Save $myParams in array format, not json, i.e. do not json_encode($myParams);

1
  • The database will not properly receive iterable data in a VARCHAR column. Jun 23, 2020 at 23:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.