web-dev-qa-db-fra.com

Comment passer des variables externes aux filtres/actions

Je me trouve avoir besoin de transmettre des données personnalisées à un filtre fourni par un plugin tiers. Tous les moyens que j'ai vus pour faire cela sont vraiment compliqués et difficiles à comprendre.

Prenons cet exemple:

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

Comment puis-je passer la variable $score à add_score_to_title()?

Ce que j'ai fini par faire, c'est d'ajouter ma variable à l'objet global $wp. Alors vous vous retrouvez avec ceci:

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

Sale? Peut être. Simple? Ouaip! Des inconvénients à cette technique? Débattez s'il vous plaît.

UPDATEVoici le code complet en question -> http://Pastebin.com/fkSXY04m

11
kingkool68

Vous avez au moins deux options:

  1. Globaliser la variable souhaitée, puis la référencer dans le rappel
  2. Enveloppez la logique de calcul du score avec une fonction, puis référencez-la à l'intérieur du rappel

Globaliser la variable

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

Envelopper le calcul du score

Si vous avez uniquement besoin du calcul du score inside the filter, insérez la logique dans le rappel lui-même:

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

Mieux encore, vous pouvez envelopper votre calcul de score dans une fonction qui lui est propre, puis appeler cette fonction dans votre callback:

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

Si vous rencontrez des problèmes pour référencer l'objet $_POST, vous pouvez également enregistrer votre variable de requête, puis utiliser get_query_var() en interne pour obtenir des données:

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

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

Avec ceci en place, $_POST['Q'] peut être remplacé par get_query_var('Q').

10
Chip Bennett
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;
}

Appelez la fonction n'importe où dans votre script pour obtenir le score, celui-ci ne sera calculé qu'une fois.

Une autre façon, en utilisant fonctions anonymes :

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

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

L'exemple suivant voit la variable $my_calculation dans la portée globale. Cependant, depuis notre fonction locale, nous devons déclarer global $my_calculation afin d'accéder à la variable dans la portée globale.

<?php 

    $my_calculation = 'result!';

    function my_function() {

        global $my_calculation;
        return $my_calculation;

    }

    add_filter( 'function_something_here', 'my_function');   

?>

Ceci est juste une façon de s'y prendre et cela semble être chouette. Est-ce que cela fonctionnerait pour vous?

0
userabuser