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.