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


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.