ti-enxame.com

Joomla 2.5 diferenças no JFormField de 3.x

Eu tenho usado um plug-in para ajudar a adicionar parâmetros extras aos módulos. Para isso, uso o JForm para carregar um arquivo xml incluído em vários plug-ins.

É isso que eu tenho usado e funciona na versão 3.0 ou superior, é feita a partir de um loop fieldset e cada "campo" é uma instância de 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>';

Como você pode ver, funcionou assumindo que $field->name É público, no entanto, na versão 2.5, ele está protegido (também é em 3, o que me deixa perplexo, nunca funcionou em nenhuma versão do 3).

Eu verifiquei as diferenças entre JFormField em 2.5 e 3 e existem diferenças enormes, embora de uma forma ou de outra eu precise acessar a propriedade $field->name (Vejo que posso executar a função $field->__get('name') para acesso somente leitura), eu poderia ignorar a funcionalidade de JFormField, mas isso parece um pouco contraproducente para adicionar compatibilidade com versões anteriores.

No Joomla 3, existe uma função chamada __set($name,$value) no entanto, não está no Joomla 2.5

Existe alguma maneira "simples" de substituir um nome de campo (ou outra propriedade) no Joomla 2.5?

5
Jordan Ramstad

Eu tenho trabalhado duro nisso e encontrei uma solução, é a maneira "correta" de fazer isso que outros módulos fazem, mas estão escondidos atrás de várias camadas de objetos (é um pouco difícil de descobrir).

Primeiro, pensei que o problema estava em JFormField, mas realmente não estava. Não é necessário acessar essas propriedades, pois elas apenas "analisam" os campos não foram criados para fornecer controle direto.

Então, aqui está um pouco do outro código que tenho.

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>';
        }
    }

Isso faz um loop em cada campo no conjunto de campos e retorna uma instância de JFormField uma classe mais ou menos somente leitura. O que deve ser feito é que todas as edições que você deseja fazer são feitas através do próprio JForm.

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;
    }
}

Como você pode ver, eu uso 2 loops, um é apenas para combinar um parâmetro com um campo (eu provavelmente poderia melhorá-lo fazendo um loop no objeto $ moduleParams real). Enquanto o outro é o mesmo que eu tinha antes. No meio, vinculo os dados ao formulário e "redefino" a variável fieldset (não tenho certeza se é necessário, mas não prejudica o processo de depuração. Isso, no entanto, alterará corretamente apenas o $field->value ao vincular um valor de formulário, as outras variáveis ​​ainda estão protegidas.

Então, eu vim com uma solução para o nome, sobre a qual essa pergunta era principalmente. O JForm é bastante rígido quanto ao nome, pois ele é usado como base para sua interação com outros objetos; portanto, é melhor não tocá-lo enquanto o JForm estiver analisando o formulário, mas depois.

A função que mostrei faz parte de um "auxiliar", então mudei isso para fora dele e para o próprio plugin. Como eu estou criando uma string html, posso usar o regex para encontrar/substituir.

$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);

Isso também permitirá que você altere o nome, fora dos problemas que podem ser causados ​​editando-o enquanto o objeto JForm está analisando os campos.

1
Jordan Ramstad