Cara Melewati Variabel Eksternal ke Filter / Tindakan

11

Saya menemukan diri saya perlu meneruskan data khusus ke filter yang disediakan oleh plugin pihak ke-3. Semua cara yang kulihat untuk melakukan ini benar-benar rumit dan sulit untuk membungkus kepalaku.

Ambil contoh ini:

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

Bagaimana saya bisa meneruskan $scorevariabel ke add_score_to_title()?

Apa yang akhirnya saya lakukan adalah menambahkan variabel saya ke $wpobjek global . Jadi Anda berakhir dengan ini:

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

Kotor? Mungkin. Sederhana? Ya! Adakah kelemahan teknik ini? Tolong diskusikan.

PEMBARUAN Berikut adalah kode lengkap yang dimaksud -> http://pastebin.com/fkSXY04m

kingkool68
sumber
Cukup lakukan "perhitungan gila" Anda di dalam fungsi itu ...
onetrickpony
Mungkin sulit dimengerti dari contoh sederhana saya. Variabel $ skor digunakan di seluruh templat itu. Saya ingin menghitungnya sekali dan meneruskan nilai itu ke fungsi yang merupakan panggilan balik untuk filter untuk mengubah judul halaman. Filter ini digunakan dalam Paket SEO All In One. Menjalankan perhitungan berkali-kali tidak diinginkan.
kingkool68
Maka Anda harus memposting lebih banyak kode jika Anda ingin mendapatkan solusi yang tidak melibatkan memperkenalkan negara global (yang seharusnya tidak pernah diperlukan).
onetrickpony
Berikut adalah kode lengkap dalam file templat. $scoredihitung dengan mengulangi berbagai hal dan menambah variabel. pastebin.com/fkSXY04m
kingkool68

Jawaban:

10

Anda memiliki setidaknya dua opsi:

  1. Globalisasi variabel yang diinginkan, dan kemudian rujuk di dalam callback
  2. Bungkus logika perhitungan skor dengan fungsi, lalu rujuk di dalam panggilan balik

Globalisasi Variabelnya

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

Bungkus Perhitungan Skor

Jika Anda hanya membutuhkan perhitungan skor di dalam filter, tarik logika ke dalam callback itu sendiri:

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

Lebih baik lagi, Anda bisa membungkus perhitungan skor Anda dalam fungsi sendiri, dan kemudian memanggil fungsi itu di dalam panggilan balik Anda:

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

Jika Anda menemukan masalah dalam referensi $_POSTobjek, Anda juga dapat mendaftarkan variabel kueri Anda dan kemudian menggunakan secara get_query_var()internal untuk mendapatkan data:

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

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

Dengan ini di tempat, $_POST['Q']bisa diganti dengan get_query_var('Q').

Chip Bennett
sumber
Ini tidak ada hubungannya dengan jumlah argumen yang diteruskan ke fungsi oleh apply_filters ...
onetrickpony
Mencoba metode # 1 yang Anda sebutkan tentang mengglobalisasi variabel. Itu tidak bekerja. Parameter args yang diterima juga tidak membantu saya karena saya tidak memiliki kendali atas variabel apa yang dilewatkan ke fungsi callback.
kingkool68
Maaf kamu benar. Saya menghitung $scoredulu dan kemudian mengglobalkannya. Tidak heran itu tidak berhasil. Terima kasih!
kingkool68
-1. Opsi pertama memperlihatkan variabel dalam keadaan global, opsi 2 tidak berfungsi ...
onetrickpony
1
" Global itu jahat "? Benarkah ? Maka seluruh kode WordPress sebaiknya ditulis, karena bergantung pada beberapa variabel global .
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;
}

Panggil fungsi di mana saja dalam skrip Anda untuk mendapatkan skor, itu hanya akan dihitung sekali.

Cara lain, menggunakan fungsi anonim :

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

add_filter('aioseop_title_single', function($title) use($score){
  return 'Quiz Results (' . $score . ') - ' . $title;  
});
onetrickpony
sumber
3
Fungsi anonim tidak boleh digunakan add_filter()atau add_action()dipanggil. Mereka tidak dapat dihapus melalui remove_function().
Chip Bennett
Maksud Anda remove_filter, yang terutama digunakan untuk menghapus filter
bawaan
1
Iya; maaf: remove_filter()dan remove_action(). Dan tidak ada alasan filter Plugin / Tema tidak dapat dihilangkan secara wajar: timpa enqueues Plugin, Tema Anak, dll.
Chip Bennett
0

Contoh berikut melihat variabel $my_calculationdalam lingkup global, namun dari dalam fungsi lokal kami, kami perlu mendeklarasikan global $my_calculationuntuk mengakses variabel dalam lingkup global.

<?php 

    $my_calculation = 'result!';

    function my_function() {

        global $my_calculation;
        return $my_calculation;

    }

    add_filter( 'function_something_here', 'my_function');   

?>

Ini hanya salah satu cara untuk melakukannya dan tampaknya rapi. Apakah ini akan berhasil untuk Anda?

Adam
sumber
Bagaimana ini berbeda dari yang sudah dia miliki?
onetrickpony
Sekali lagi deklarasi "global". Lihatlah contoh keduanya, dia menyatakan $ $ dua kali gloabl!
Adam
Itu juga tidak bekerja. Ini adalah hal pertama yang saya coba.
kingkool68
Apakah Anda dapat printatau echohasil Anda untuk memastikan bahwa fungsi Anda memang berfungsi sebelum meneruskannya ke filter?
Adam
Ups! Globalisasi $scorememang berhasil. Saya melakukan kesalahan dan menetapkan $scorepertama kemudian mengglobal yang jelas tidak berhasil. Melakukannya dengan cara yang benar dengan mengglobalisasi $scoreterlebih dahulu kemudian memberikannya nilai berhasil seperti yang diharapkan. Terima kasih semuanya.
kingkool68