Как передать внешние переменные в фильтры / действия


11

Мне нужно передать пользовательские данные в фильтр, предоставленный сторонним плагином. Все способы, которые я видел, чтобы сделать это, действительно сложны и трудно обернуть мою голову вокруг.

Возьмите этот пример:

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

Как я могу передать $scoreпеременную add_score_to_title()?

В итоге я добавил свою переменную в глобальный $wpобъект. Итак, вы в конечном итоге с этим:

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

Грязные? Может быть. Просто? Ага! Есть ли недостатки этой техники? Пожалуйста, обсудите.

ОБНОВЛЕНИЕ Вот полный рассматриваемый код -> http://pastebin.com/fkSXY04m


Просто сделайте свой "сумасшедший расчет" внутри этой функции ...
— onetrickpony

Это, вероятно, трудно понять из моего упрощенного примера. Переменная $ score используется во всем этом шаблоне. Я хочу вычислить его один раз и передать это значение функции, которая является обратным вызовом для фильтра для изменения заголовка страницы. Этот фильтр используется в пакете SEO «все в одном». Запускать вычисления несколько раз нежелательно.
— kingkool68

Затем вы должны опубликовать больше кода, если вы хотите получить решение, которое не предполагает введения глобального состояния (которое никогда не требуется).
— onetrickpony

Вот полный код в файле шаблона. $scoreрассчитывается путем зацикливания на массиве вещей и увеличения переменной. pastebin.com/fkSXY04m
— kingkool68

Ответы:


10

У вас есть как минимум два варианта:

  1. Глобализировать желаемую переменную, а затем ссылаться на нее внутри обратного вызова
  2. Оберните логику вычисления оценки функцией, а затем сделайте ссылку на нее внутри обратного вызова

Глобализировать переменную

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

Оберните расчет баллов

Если вам когда-либо понадобится вычисление оценки внутри фильтра, включите логику в сам обратный вызов:

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

А еще лучше, вы можете обернуть вычисление баллов в собственную функцию, а затем вызвать эту функцию внутри вашего обратного вызова:

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

Если вы обнаружите, что у вас есть проблемы со ссылкой на $_POSTобъект, вы можете также зарегистрировать переменную запроса и затем использовать ее get_query_var()для получения данных:

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

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

С этим на месте, $_POST['Q']можно заменить на get_query_var('Q').


Это не имеет никакого отношения к числу аргументов, передаваемых функции apply_filters ...
— onetrickpony

Попробованный метод № 1 вы упомянули о глобализации переменной. Не работает Принятый параметр args мне тоже не помогает, так как я не контролирую, какие переменные передаются в функцию обратного вызова.
— kingkool68

Извините, вы были правы. $scoreСначала я вычислил, а затем глобализировал его. Не удивительно, что это не сработало. Спасибо!
— kingkool68

-1. Первый вариант выставляет переменную в глобальном состоянии, второй вариант не работает ...
— onetrickpony

1
" Глобалы злые "? Действительно ? Тогда лучше написать весь код WordPress, так как он использует довольно много глобальных переменных .
— Чип Беннетт

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

Вызовите функцию в любом месте вашего скрипта, чтобы получить оценку, она будет рассчитана только один раз.

Другой способ, используя анонимные функции :

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

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

3
Не следует использовать анонимные функции add_filter()или add_action()вызовы. Они не могут быть удалены через remove_function().
— Чип Беннетт

Вы имеете в виду remove_filter, который в основном используется для удаления встроенных фильтров, а не фильтров, добавляемых плагинами / темами ...
— onetrickpony

1
Да; извините: remove_filter()и remove_action(). И нет никаких причин, по которым фильтры плагинов / тем не могут быть разумно удалены: переопределить очереди таблиц стилей плагинов, дочерние темы и т. Д.
— Chip Bennett

0

В следующем примере переменная видится $my_calculationв глобальной области видимости, однако внутри нашей локальной функции мы должны объявить ее global $my_calculation, чтобы получить доступ к переменной в глобальной области видимости.

<?php 

    $my_calculation = 'result!';

    function my_function() {

        global $my_calculation;
        return $my_calculation;

    }

    add_filter( 'function_something_here', 'my_function');   

?>

Это всего лишь один из способов сделать это, и он кажется аккуратным. Будет ли это работать для вас?


Чем это отличается от того, что он уже имеет?
— onetrickpony

Еще раз декларация "глобальная". Посмотрите на его второй пример, он объявляет gloabl $ wp дважды!
— Адам

Это также не работает. Это первое, что я попробовал.
— kingkool68

Можете ли вы printили echoваш результат убедиться, что ваша функция действительно работает до ее передачи в фильтр?
— Адам

К сожалению! Глобализация $scoreдействительно работает. Я обманываю и устанавливаю $scoreсначала глобализированный, который явно не работает. Правильное выполнение, $scoreсначала глобализация, а затем присвоение значения, работает, как и ожидалось. Спасибо всем.
— kingkool68
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.