it-swarm.it

Differenze di Joomla 2.5 in JFormField da 3.x

Ho usato un plugin per aiutare ad aggiungere parametri extra ai moduli, per fare ciò uso JForm per caricare un file xml che è incluso con vari plugin.

Questo è quello che ho usato e funziona in 3.0 e versioni successive, è preso da un ciclo fieldset e ogni "campo" è un'istanza di 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>';

Come puoi vedere ha funzionato supponendo che $field->name Sia pubblico, tuttavia in 2.5 è protetto (è anche in 3 che mi sconcerta, non è mai funzionato in nessuna versione di 3).

Ho verificato le differenze tra JFormField in 2.5 e 3 e ci sono enormi differenze, anche se in un modo o nell'altro devo accedere alla proprietà $field->name (Vedo che posso fare $field->__get('name') per l'accesso in sola lettura), potrei ignorare la funzionalità di JFormField ma sembra un po 'controproducente per aggiungere la retrocompatibilità.

In Joomla 3 c'è una funzione chiamata __set($name,$value) ma non è in Joomla 2.5

Esiste un modo "semplice" per sovrascrivere un nome di campo (o altra proprietà) in Joomla 2.5?

5
Jordan Ramstad

Ho lavorato duramente su questo e ho trovato una soluzione, è il modo "corretto" di farlo che altri moduli fanno ma sono nascosti dietro più strati di oggetti (quindi un po 'difficile da capire).

Innanzitutto ho pensato che il problema fosse in JFormField ma in realtà non lo era. Non è necessario accedere a tali proprietà poiché "analizzano" solo i campi non sono stati creati per fornire alcun controllo diretto.

Quindi ecco un po 'dell'altro codice che ho.

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

Ciò esegue il loop di ogni campo nel set di campi e restituisce un'istanza di JFormField una classe di sola lettura più o meno. Quello che dovrebbe essere fatto è qualsiasi modifica che vuoi fare è fatta tramite JForm stesso.

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

Come puoi vedere, utilizzo 2 loop, uno è solo quello di abbinare un parametro a un campo (probabilmente potrei migliorarlo eseguendo il loop dell'oggetto $ moduleParams effettivo). Mentre l'altro è uguale a quello che avevo prima. Tra unendo i dati per formare e "resettando" la variabile fieldset (non sono sicuro che sia necessario, ma non danneggia il processo di debug. Questo tuttavia modificherà correttamente solo il $field->value poiché stai vincolando un valore di moduli, quindi le altre variabili sono ancora protette.

Quindi mi è venuta in mente una soluzione per nome, di cui questa domanda riguardava principalmente. JForm è abbastanza rigoroso sul nome in quanto lo utilizza come base per la sua interazione con altri oggetti, quindi è meglio non toccarlo mentre JForm sta analizzando il modulo, ma dopo.

La funzione che ho mostrato fa parte di un "aiutante", quindi l'ho spostato al di fuori di esso e nel plugin stesso. Dal momento che sto creando una stringa HTML, posso usare regex per trovare/sostituire.

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

Ciò dovrebbe consentire anche di modificare il nome, al di fuori dei problemi che possono essere causati modificandolo mentre l'oggetto JForm sta analizzando i campi.

1
Jordan Ramstad