So übergeben Sie externe Variablen an Filter / Aktionen

11

Ich muss benutzerdefinierte Daten an einen Filter übergeben, der von einem Plugin eines Drittanbieters bereitgestellt wird. Alle Möglichkeiten, die ich gesehen habe, sind wirklich kompliziert und schwer, meinen Kopf herumzuwickeln.

Nehmen Sie dieses Beispiel:

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

Wie kann ich die $scoreVariable übergeben add_score_to_title()?

Am Ende habe ich meine Variable zum globalen $wpObjekt hinzugefügt . Am Ende haben Sie also Folgendes:

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

Schmutzig? Könnte sein. Einfach? Jep! Irgendwelche Nachteile dieser Technik? Bitte diskutiere.

UPDATE Hier ist der vollständige Code -> http://pastebin.com/fkSXY04m

kingkool68
quelle
Führen Sie
Aus meinem vereinfachten Beispiel ist es wahrscheinlich schwer zu verstehen. Die Variable $ score wird in dieser Vorlage verwendet. Ich möchte es einmal berechnen und diesen Wert an die Funktion übergeben, die ein Rückruf für einen Filter zum Ändern des Seitentitels ist. Dieser Filter wird im All In One SEO Pack verwendet. Das mehrmalige Ausführen der Berechnung ist nicht erwünscht.
Kingkool68
Dann sollten Sie mehr Code veröffentlichen, wenn Sie eine Lösung erhalten möchten, bei der kein globaler Status eingeführt wird (der niemals benötigt werden sollte).
Onetrickpony
Hier ist der vollständige Code in einer Vorlagendatei. $scorewird berechnet, indem ein Array von Dingen durchlaufen und eine Variable inkrementiert wird. pastebin.com/fkSXY04m
kingkool68
Mögliches Duplikat der
Übergabe

Antworten:

10

Sie haben mindestens zwei Möglichkeiten:

  1. Globalisieren Sie die gewünschte Variable und verweisen Sie sie dann im Rückruf
  2. Wickeln Sie die Score-Berechnungslogik mit einer Funktion ein und verweisen Sie darauf innerhalb des Rückrufs

Globalisieren Sie die Variable

<?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');
?>

Wickeln Sie die Score-Berechnung ein

Wenn Sie die Score-Berechnung nur innerhalb des Filters benötigen , ziehen Sie die Logik in den Rückruf selbst:

<?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');
?>

Besser noch, Sie könnten Ihre Punkteberechnung in eine eigene Funktion einschließen und diese Funktion dann in Ihrem Rückruf aufrufen:

<?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');
?>

Wenn Sie Probleme beim Verweisen auf das $_POSTObjekt haben, können Sie auch Ihre Abfragevariable registrieren und dann get_query_var()intern verwenden, um Daten abzurufen:

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

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

Wenn dies vorhanden ist, $_POST['Q']kann es durch ersetzt werden get_query_var('Q').

Chip Bennett
quelle
Dies hat nichts mit der Anzahl der Argumente zu tun, die von apply_filters an die Funktion übergeben wurden ...
onetrickpony
Die von Ihnen erwähnte Methode Nr. 1 zur Globalisierung der Variablen. Es funktioniert nicht. Der Parameter "Akzeptierte Argumente" hilft mir auch nicht, da ich keine Kontrolle darüber habe, welche Variablen an die Rückruffunktion übergeben werden.
Kingkool68
Entschuldigung, du hattest recht. Ich habe es $scorezuerst berechnet und dann globalisiert. Kein Wunder, dass es nicht funktionierte. Vielen Dank!
Kingkool68
-1. Die erste Option macht eine Variable im globalen Status
verfügbar
1
" Globals sind böse "? Wirklich ? Dann sollte der gesamte WordPress-Code besser geschrieben werden, da er auf einigen globalen Variablen beruht .
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;
}

Rufen Sie die Funktion an einer beliebigen Stelle in Ihrem Skript auf, um die Punktzahl zu erhalten. Sie wird nur einmal berechnet.

Eine andere Möglichkeit, anonyme Funktionen zu verwenden :

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

add_filter('aioseop_title_single', function($title) use($score){
  return 'Quiz Results (' . $score . ') - ' . $title;  
});
Onetrickpony
quelle
3
Anonyme Funktionen sollten nicht in add_filter()oder add_action()Aufrufen verwendet werden. Sie können nicht über entfernt werden remove_function().
Chip Bennett
Du meinst remove_filter, das hauptsächlich zum Entfernen von eingebauten Filtern verwendet wird, nicht von Filtern, die von Plugins / Themes hinzugefügt wurden ...
onetrickpony
1
Ja; Entschuldigung: remove_filter()und remove_action(). Und es gibt keinen Grund, warum Plugin / Theme-Filter nicht vernünftigerweise entfernt werden können: Überschreiben Sie Plugin-Stylesheet-Warteschlangen, untergeordnete Themes usw.
Chip Bennett
0

Im folgenden Beispiel wird die Variable $my_calculationim globalen Bereich angezeigt. Innerhalb unserer lokalen Funktion müssen wir jedoch deklarieren, global $my_calculationum auf die Variable im globalen Bereich zugreifen zu können.

<?php 

    $my_calculation = 'result!';

    function my_function() {

        global $my_calculation;
        return $my_calculation;

    }

    add_filter( 'function_something_here', 'my_function');   

?>

Dies ist nur ein Weg, und es scheint ordentlich zu sein. Würde das für dich funktionieren?

Adam
quelle
Wie unterscheidet sich das von dem, was er bereits hat?
Onetrickpony
Einmal weniger Deklaration von "global". Schauen Sie sich sein zweites Beispiel an, er erklärt zweimal gloabl $ wp!
Adam
Es funktioniert auch nicht. Dies ist das erste, was ich versucht habe.
Kingkool68
Können Sie printoder echoIhr Ergebnis sicherstellen, dass Ihre Funktion tatsächlich funktioniert, bevor Sie sie an den Filter übergeben?
Adam
Hoppla! Die Globalisierung $scorefunktioniert tatsächlich. Ich habe $scorezuerst gepatzt und gesetzt, dann globalisiert, was eindeutig nicht funktioniert. Wenn Sie es richtig machen, indem Sie $scorezuerst globalisieren und ihm dann einen Wert geben, funktioniert dies wie erwartet. Vielen Dank an alle.
Kingkool68