5

I have been using a plugin to help add extra parameters to modules, to do that I use JForm to load an xml file that is included with various plugins.

This is what I have been using and it works in 3.0 and up, it is taken form a fieldset loop and each "field" is an instance of JFormField.

$field->name = 'plg_form_settings['.$field->name.']';
$content .= '<div class="control-group">';
    $content .= '<div class="control-label">';
        $content .= $field->label;
    $content .= '</div>';
    $content .= '<div class="controls">';
        $content .= $field->input;
    $content .= '</div>';
$content .= '</div>';

As you can see it worked assuming that $field->name is public, however in 2.5 it is protected (it is in 3 as well which baffles me, its never not worked in any version of 3).

I have checked the differences between JFormField in 2.5 and 3 and there are massive differences, though one way or another I need to access the $field->name property (I do see I can do $field->__get('name') for read only access), I could ignore the functionality of JFormField but that seems a bit counter productive to add backwards compatibility.

In Joomla 3 there is a function called __set($name,$value) however it is not in Joomla 2.5

Is there any "simple" way to override a field name (or other property) in Joomla 2.5?

  • Are you getting a particular error when you do this in Joomla 2.5? It should still work in 2.5. – David Fritsch May 28 '14 at 16:07
  • It says it cannot access a protected property for all values other then $field->input or $field->label. – Jordan Ramstad May 28 '14 at 17:19
1

I have been working hard on this and come up with a solution, its the "proper" way to do it that other modules do but are hidden behind multiple layers of objects (so a bit hard to figure out).

First I thought that the problem was in JFormField but it really was not. It has no need to access those properties since they only "parse" the fields were not made to give any direct control.

So here is a bit of the other code I have.

if($form->loadFile($path.'/fields.xml')){
        $fieldset = $form->getFieldset();
        //SQL STUFF HERE TO GET $result
        $result = $db->loadObject();
        if(isset($result->params)){
            $moduleParams = json_decode($result->params);
        }else{
            $moduleParams = new stdClass;
        }
        foreach($fieldset as $index=>$field){
            $field->name = 'plg_form_settings['.$field->name.']';
            $content .= '<div class="control-group">';
                $content .= '<div class="control-label">';
                    $content .= $field->label;
                $content .= '</div>';
                $content .= '<div class="controls">';
                    $content .= $field->input;
                $content .= '</div>';
            $content .= '</div>';
        }
    }

This loops each field in the fieldset and returns an instance of JFormField a more or less read only class. What should be done is any edits you want to do is done via JForm itself.

if($form->loadFile($path.'/fields.xml')){
    $fieldset = $form->getFieldset();
    //SQL STUFF HERE TO GET $result
    $result = $db->loadObject();
    if(isset($result->params)){
        $moduleParams = json_decode($result->params);
    }else{
        $moduleParams = new stdClass;
    }
    $dataArray = array();
    //split the loop into 2, this way the data can be bound
    foreach($fieldset as $index=>$field){
        if($id!=0&&isset($moduleParams->{$index})){
            $dataArray[$index] = $moduleParams->{$index};
        }
    }
    //bind and reset to ensure it worked
    $form->bind($dataArray);
    $fieldset = $form->getFieldset();
    foreach($fieldset as $index=>$field){
        $output = '<div class="control-group">';
            $output .= '<div class="control-label">';
                $output .= $field->label;
            $output .= '</div>';
            $output .= '<div class="controls">';
                $output .= $field->input;
            $output .= '</div>';
        $output .= '</div>';
        $content .= $output;
    }
}

As you can see I use 2 loops, one is just to match a parameter to a field (I could probably improve it by looping the actual $moduleParams object). While the other is the same as the one I had before. In between I bind the data to form and "reset" the fieldset variable (not sure if its needed but it does not hurt in the debugging process. This however will only correctly change the $field->value as you are binding a forms value, so the other variables are still protected.

So I came up with a solution for name, which this question was mainly about. JForm is fairly strict on the name as it uses that as a basis for its interaction with other objects, so its best not to touch it while JForm is parsing the form, but after.

The function I have shown is part of a "helper" so I moved this outside of it and into the plugin itself. Since I am creating an html string I can use regex to find/replace.

$regex  = '/(?:name=")([^"]*)(?:")/';
//CALL HELPER TO GET $content
$content = '<input type="text" name="cc_field"/>'; //example of part of output from helper
$content = preg_replace($regex,"name=\"cc_settings[$1]\"",$content);

This should allow you to change the name as well, outside of issues that can be cause by editing it while the JForm object is parsing the fields.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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