1

I'm trying to write a plugin that needs to use the same subform twice, and I want to set different default values for these two subforms. The config part of my XML file looks like this:

<config>
    <fields name="params">
        <fieldset name="basic" addrulepath="/path/to/rules">
            <field name="first" type="subform"
                formsource="/path/to/subform.xml"
                label="First"
                default='{"length_max":"380", "width_max":"265", "height_max":"32", "weight_max":"2000", "rate":"4.85"}'
            />
            <field name="second" type="subform"
                formsource="/path/to/subform.xml"
                label="Second"
                default='{"length_max":"1000", "width_max":"500", "height_max":"500", "weight_max":"10000", "rate":"7.65"}'
            />
        </fieldset>
    </fields>
</config>

These fields are displaying properly on the plugin settings page and also showing the default values I specified.

However, if I check the database after installing the plugin, the params field in the *_extensions table looks like this (note the extra slashes):

{"first":"{\"length_max\":\"380\", \"width_max\":\"265\", \"height_max\":\"32\", \"weight_max\":\"2000\", \"rate\":\"4.85\"}","second":"{\"length_max\":\"1000\", \"width_max\":\"500\", \"height_max\":\"500\", \"weight_max\":\"10000\", \"rate\":\"7.65\"}"}

When I then try to access the "first" parameter from my plugin php file using $this->params->get('first') it returns a string:

string(94) "{"length_max":"380", "width_max":"265", "height_max":"32", "weight_max":"2000", "rate":"4.85"}"

If I now go to the plugin settings page and don't change anything but click Save, the database params value changes to the following (note the slashes are now gone):

{"first":{"length_max":"380","width_max":"265","height_max":"32","weight_max":"2000","rate":"4.85"},"second":{"length_max":"1000","width_max":"500","height_max":"500","weight_max":"10000","rate":"7.65"}}

And if I now get the "first" parameter (again using $this->params->get('first')), it returns an object:

object(stdClass)#1321 (5) { ["length_max"]=> string(3) "380" ["width_max"]=> string(3) "265" ["height_max"]=> string(2) "32" ["weight_max"]=> string(4) "2000" ["rate"]=> string(4) "4.85" }

Problem:

I want to be able to consistantly get either a string or an object for the parameter, not one or the other depending on whether the user has gone to the plugin settings page and clicked Save.

Am I doing something wrong in setting the default values for the fields, or in getting the parameter from the database? Is there another function I should be using to get the value from the database instead of $this->params->get(...)?

(Edit: using Joomla version 4.4.1 with php 7.4.28)

2 Answers 2

2

When your plugin is installed the manifest(.xml) file is parsed and a fairly basic process of saving your values into the #__extension table occurs. In the case of the params the default= is being saved as a simple string as your detailed post shows and this includes prefixing the '' slash to denote the following '"' is to be stored and is not the end of the value.

However when you view your Plugin settings the Form processing uses the get() method of ..\libraries\vendor\joomla\registry\src\Registry.php which parses the string and converts it into an Array or Object and thus displays correctly and then when it is saved it is stored as an object in this case.

The solution I can see for this issue involves using the post-install script processing the can be executed when your plugin is installed to update the string to replace it with the option.

The post-insatll script should retrieve the entire field of params from the #__extensions table using the Registry methods and then save all the values back again using the Registry methods and that should mean any subsequent calls to the plugin are not going to retrieve a string for your field(s).

I don't have any code to hand that I can think of to get you started but saving the Plugin settings after installation has been a fairly common requirement for all versions of Joomla so there are examples out there.

2
  • Thank you, good to hear that my default values and the use of $this->params->get(...) are correct. I've looked into using a script.php file with an ...InstallerScript class containing a postflight function, but I couldn't get that to work very quickly. And since I only need the parameter in one place in my php script anyway, I've resorted to using if (is_string($params)) { $params = json_decode($params); } in the plugin php file instead, which also works.
    – Marleen
    Dec 26, 2023 at 14:35
  • If you could post the solution you have decided to use as an Answer and Accept your Answer it would be appreciated.
    – Irata
    Dec 27, 2023 at 10:33
0

Thanks to Irata for confirming I've specified the default values correctly and that I should indeed be using $this->params->get(...).

Since I only need to access the parameter in one place, I've decided to simply use if (is_string($params)) { $params = json_decode($params); } in the plugin php file to convert the json string to an object in case the user hasn't clicked Save on the settings page yet.

$subforms = ['first', 'second'];

foreach ($subforms as $subform) {
    $params = $this->params->get($subform);

    if (is_string($params)) {
        $params = json_decode($params);
    }

    // do something with the $params object
}

Your Answer

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

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