Come passare variabili esterne a filtri / azioni


11

Mi trovo a dover passare i dati personalizzati a un filtro fornito da un plugin di terze parti. Tutti i modi in cui ho visto farlo sono davvero complicati e difficili da avvolgere la testa.

Prendi questo esempio:

$score = 42; //Some crazy calculation I don't want to repeat.

function add_score_to_title($title) {
    return 'Quiz Results (' . $score . '/') - ' . $title;
}

add_filter( 'aioseop_title_single', 'add_score_to_title');

Come posso passare la $scorevariabile a add_score_to_title()?

Quello che ho finito per fare è stato aggiungere la mia variabile $wpall'oggetto globale . Quindi finisci con questo:

global $wp;
$score = 42; //Some crazy calculation I don't want to repeat.
$wp->some_random_name_for_score = $score;

function add_score_to_title($title) {
    global $wp;
    $score = $wp->some_random_name_for_score;
    return 'Quiz Results (' . $score . '/') - ' . $title;
}

add_filter( 'aioseop_title_single', 'add_score_to_title');

Sporco? Può essere. Semplice? Sì! Qualche svantaggio di questa tecnica? Per favore discutete.

AGGIORNAMENTO Ecco il codice completo in questione -> http://pastebin.com/fkSXY04m


Fai semplicemente il tuo "folle calcolo" all'interno di quella funzione ...
onetrickpony,

Probabilmente è difficile da capire dal mio esempio semplificato. La variabile $ score viene utilizzata in tutto quel modello. Voglio calcolarlo una volta e passare quel valore alla funzione che è un callback per un filtro per cambiare il titolo della pagina. Questo filtro viene utilizzato nel pacchetto SEO All In One. L'esecuzione del calcolo più volte non è desiderata.
kingkool68,

Quindi dovresti pubblicare più codice se vuoi ottenere una soluzione che non implichi l'introduzione dello stato globale (che non dovrebbe mai essere necessario).
onetrickpony,

Ecco il codice completo in un file modello. $scoreviene calcolato eseguendo il ciclo su una matrice di cose e incrementando una variabile. pastebin.com/fkSXY04m
kingkool68

Risposte:


10

Hai almeno due opzioni:

  1. Globalizzare la variabile desiderata, quindi fare riferimento a essa all'interno del callback
  2. Avvolgere la logica di calcolo del punteggio con una funzione, quindi fare riferimento a essa all'interno del callback

Globalizza la variabile

<?php
global $score;
$score = 42; //Some crazy calculation I don't want to repeat.

function add_score_to_title($title) {
    global $score;
    return 'Quiz Results (' . $score . '/') - ' . $title;
}

add_filter( 'aioseop_title_single', 'add_score_to_title');
?>

Avvolgere il calcolo del punteggio

Se hai solo bisogno del calcolo del punteggio all'interno del filtro, trascina la logica nel callback stesso:

<?php
function add_score_to_title($title) {
    $score = 0;
    $questions = get_quiz_result_questions();
    $total_questions = 0;
    foreach( $questions as $question ) {
        $order = $question->order;

        if( $order >= 100 ) {
            break;
    }

    if( $question->correct == $_POST['Q'][$order] ) {
        $score++;
    }
    $total_questions++;

    return 'Quiz Results (' . $score . '/') - ' . $title;
}

add_filter( 'aioseop_title_single', 'add_score_to_title');
?>

Meglio ancora, potresti avvolgere il tuo calcolo del punteggio in una funzione a sé stante e quindi chiamare quella funzione all'interno del tuo callback:

<?php
function wpse48677_get_score() {
    $score = 0;
    $questions = get_quiz_result_questions();
    $total_questions = 0;
    foreach( $questions as $question ) {
    $order = $question->order;

    if( $order >= 100 ) {
        break;
    }

    if( $question->correct == $_POST['Q'][$order] ) {
        $score++;
    }
    $total_questions++;
    $output['score'] = $score;
    $output['total_questions'] = $total_questions;

    return $output;
}

function add_score_to_title($title) {

    $score_results = wpse48677_get_score();

    $score = $score_results['score'];

    return 'Quiz Results (' . $score . '/') - ' . $title;
}

add_filter( 'aioseop_title_single', 'add_score_to_title');
?>

Se riscontri problemi con riferimento $_POSTall'oggetto, puoi anche registrare la tua variabile di query e quindi utilizzare get_query_var()internamente per ottenere i dati:

function add_score_query_vars( $query_vars ) {
    $query_vars[] = 'Q';

    return $query_vars;
}
add_filter( 'query_vars', 'add_score_query_vars' );

Con questo in atto, $_POST['Q']può essere sostituito con get_query_var('Q').


Questo non ha nulla a che fare con il numero di argomenti passati alla funzione da apply_filters ...
onetrickpony

Ho provato il metodo n. 1 che hai citato di globalizzare la variabile. Non funziona Il parametro args accettato non mi aiuta neanche perché non ho alcun controllo su quali variabili vengono passate alla funzione di callback.
kingkool68,

Scusa, avevi ragione. Ho calcolato $scoreprima e poi globalizzato. Non c'è da stupirsi che non funzionasse. Grazie!
kingkool68,

-1. La prima opzione espone una variabile nello stato globale, la seconda opzione non funziona ...
onetrickpony

1
"I globuli sono cattivi "? Davvero ? Quindi è meglio scrivere l'intero codice WordPress, poiché si basa su alcune variabili globali .
Chip Bennett,

3
function add_score_to_title($title = false) {
  static $score = false;

  if($score === false){
    // do calc
  }

  // plugin call (filter)   
  if($title !== false)
    return 'Quiz Results (' . $score . ') - ' . $title;

  // your call
  return $score;
}

Chiama la funzione in qualsiasi punto dello script per ottenere il punteggio, verrà calcolato solo una volta.

Un altro modo, usando funzioni anonime :

// do the calc
$score = 'xxx';

add_filter('aioseop_title_single', function($title) use($score){
  return 'Quiz Results (' . $score . ') - ' . $title;  
});

3
Le funzioni anonime non devono essere utilizzate add_filter()o add_action()chiamate. Non possono essere rimossi tramite remove_function().
Chip Bennett,

Vuoi dire remove_filter, che viene utilizzato principalmente per rimuovere i filtri integrati, non i filtri aggiunti da plugin / temi ...
onetrickpony

1
Sì; scusa: remove_filter()e remove_action(). E non c'è motivo per cui i filtri Plugin / Temi non debbano essere ragionevolmente rimossi: sovrascrivi gli stili dei fogli di stile del Plugin, i Temi per bambini, ecc.
Chip Bennett,

0

L'esempio seguente vede la variabile $my_calculationnell'ambito globale, tuttavia all'interno della nostra funzione locale dobbiamo dichiarare global $my_calculationper accedere alla variabile nell'ambito globale.

<?php 

    $my_calculation = 'result!';

    function my_function() {

        global $my_calculation;
        return $my_calculation;

    }

    add_filter( 'function_something_here', 'my_function');   

?>

Questo è solo un modo per farlo e sembra essere pulito. Funzionerebbe per te?


In che modo è diverso da quello che ha già?
onetrickpony,

Una volta meno dichiarazione di "globale". Guarda il suo secondo esempio, dichiara gloabl $ wp due volte!
Adam,

Inoltre non funziona. Questa è la prima cosa che ho provato.
kingkool68,

Sei in grado printo il echotuo risultato di garantire che la tua funzione funzioni davvero prima di passarla al filtro?
Adam,

Oops! La globalizzazione $scorefunziona davvero. Ho preso in giro e impostato $scoreprima poi globalizzato che chiaramente non funziona. Farlo nel modo giusto globalizzando $scoreprima quindi dandogli un valore funziona come previsto. Ringrazia tutti.
kingkool68,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.