Jak przekazać zmienne zewnętrzne do filtrów / akcji


11

Uważam, że muszę przekazać niestandardowe dane do filtra udostępnianego przez wtyczkę innej firmy. Wszystkie sposoby, które widziałem, aby to zrobić, są naprawdę skomplikowane i trudne do obejrzenia.

Weź ten przykład:

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

Jak mogę przekazać $scorezmienną add_score_to_title()?

Skończyło się na dodaniu mojej zmiennej do $wpobiektu globalnego . Tak więc kończy się to:

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

Brudny? Może. Prosty? Tak! Jakieś wady tej techniki? Proszę omówić

AKTUALIZACJA Oto pełny kod, o którym mowa -> http://pastebin.com/fkSXY04m


Po prostu wykonaj „szalone obliczenia” wewnątrz tej funkcji ...
onetrickpony

Prawdopodobnie trudno to zrozumieć na podstawie mojego uproszczonego przykładu. Zmienna $ score jest używana w całym tym szablonie. Chcę to obliczyć raz i przekazać tę wartość do funkcji, która jest wywołaniem zwrotnym dla filtra do zmiany tytułu strony. Ten filtr jest używany w pakiecie SEO All In One. Wielokrotne wykonywanie obliczeń nie jest pożądane.
kingkool68

Następnie powinieneś opublikować więcej kodu, jeśli chcesz uzyskać rozwiązanie, które nie wymaga wprowadzenia stanu globalnego (które nigdy nie powinno być potrzebne).
onetrickpony

Oto pełny kod w pliku szablonu. $scorejest obliczany przez zapętlanie tablicy rzeczy i zwiększanie zmiennej. pastebin.com/fkSXY04m
kingkool68

Odpowiedzi:


10

Masz co najmniej dwie opcje:

  1. Globalizuj żądaną zmienną, a następnie odwołaj się do niej w wywołaniu zwrotnym
  2. Zawiń logikę obliczania wyniku funkcją, a następnie odwołaj się do niej w wywołaniu zwrotnym

Globalizuj zmienną

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

Zwiń obliczenia wyniku

Jeśli tylko kiedykolwiek potrzeba obliczania punktacji wewnątrz filtra, wyciągnij logikę do samego zwrotnego:

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

Co więcej, możesz zawrzeć swoje obliczenia wyniku we własnej funkcji, a następnie wywołać tę funkcję w swoim wywołaniu zwrotnym:

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

Jeśli okaże się, że masz problemy z odniesieniem do $_POSTobiektu, możesz również zarejestrować zmienną zapytania, a następnie użyć jej get_query_var()wewnętrznie, aby uzyskać dane:

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

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

Dzięki temu $_POST['Q']można go zastąpić get_query_var('Q').


Nie ma to nic wspólnego z liczbą argumentów przekazanych do funkcji przez Apply_filters ...
onetrickpony

Wypróbowana metoda nr 1, o której wspomniałeś o globalizacji zmiennej. To nie działa Zaakceptowany parametr args też mi nie pomaga, ponieważ nie mam kontroli nad tym, jakie zmienne są przekazywane do funkcji zwrotnej.
kingkool68

Przepraszam, masz rację. $scoreNajpierw obliczyłem, a potem zglobalizowałem. Nic dziwnego, że to nie działało. Dziękuję Ci!
kingkool68

-1. Pierwsza opcja wyświetla zmienną w stanie globalnym, druga opcja nie działa ...
onetrickpony

1
Globale są złe ”? Naprawdę ? Następnie lepiej napisać cały kod WordPress, ponieważ opiera się on na kilku zmiennych globalnych .
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;
}

Wywołaj funkcję w dowolnym miejscu skryptu, aby uzyskać wynik, zostanie on obliczony tylko raz.

Innym sposobem jest użycie anonimowych funkcji :

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

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

3
Anonimowych funkcji nie należy używać add_filter()ani add_action()wywoływać. Nie można ich usunąć za pośrednictwem remove_function().
Chip Bennett

Masz na myśli remove_filter, który jest stosowany głównie w celu usunięcia wbudowane filtry, filtry nie dodał plugins / tematów ...
onetrickpony

1
Tak; przepraszam: remove_filter()i remove_action(). I nie ma powodu, dla którego filtry wtyczek / motywów nie powinny być w sposób rozsądny możliwe do usunięcia: przesłonić kolejkowanie arkuszy stylów wtyczek, motywy podrzędne itp.
Chip Bennett

0

Poniższy przykład pokazuje zmienną $my_calculationw zakresie globalnym, jednak z naszej funkcji lokalnej musimy zadeklarować global $my_calculation, aby uzyskać dostęp do zmiennej w zakresie globalnym.

<?php 

    $my_calculation = 'result!';

    function my_function() {

        global $my_calculation;
        return $my_calculation;

    }

    add_filter( 'function_something_here', 'my_function');   

?>

To tylko jeden ze sposobów, aby się tym zająć i wydaje się być fajny. Czy to by Ci pasowało?


Czym to się różni od tego, co już ma?
onetrickpony

Niegdyś deklaracja „globalna”. Spójrz na swój drugi przykład, deklaruje gloabl $ wp dwa razy!
Adam

To też nie działa. To jest pierwsza rzecz, której spróbowałem.
kingkool68

Czy jesteś w stanie printlub echoTwój wynik, aby upewnić się, że twoja funkcja rzeczywiście działa przed przekazaniem jej do filtra?
Adam

Ups! Globalizacja $scorerzeczywiście działa. Wygłupiłem się i ustawiłem $scorenajpierw, a potem zglobalizowałem, co najwyraźniej nie działa. Zrób to we właściwy sposób, $scorenajpierw globalizując, a następnie nadając mu wartość, zgodnie z oczekiwaniami. Dziękuje wszystkim.
kingkool68
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.