Як передавати зовнішні змінні у фільтри / дії


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

Напевно, важко зрозуміти з мого спрощеного прикладу. Змінна $ оцінка використовується в усьому шаблоні. Я хочу обчислити його один раз і передати це значення функції, яка є зворотним викликом для фільтра для зміни заголовка сторінки. Цей фільтр використовується в 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 ви згадуєте про глобалізацію змінної. Це не працює. Параметр прийнятих аргументів мені також не допомагає, оскільки я не маю контролю над тим, які змінні передаються функції зворотного виклику.
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.