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



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


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

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?


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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.