web-dev-qa-db-fra.com

Ajout d'une action dans une fonction appelée par add_filter

J'essaie d'appeler la fonction woocommerce_custom_surcharge . Je dois l'appeler dans le filtre pour woocommerce_checkout_fields , car j'ai besoin de $ fields ['billing'] ['forhandler_kode'] dans ma déclaration IF, et je ne sais pas comment l'utiliser à l'extérieur le filtre. De plus, j'ai essayé add_action en dehors de la fonction, et ça fonctionne très bien là-bas.

Mon écho est appelé, c'est-à-dire que l'instruction if renvoie true, ce n'est donc pas le problème. Pour une raison quelconque, add_action ne fonctionne pas dans ma fonction

add_filter( 'woocommerce_checkout_fields' , 'call_my_add_action' );
function call_my_add_action($fields) {


    if ($fields['billing']['forhandler_kode']) {
         add_action( 'woocommerce_cart_calculate_fees','woocommerce_custom_surcharge' );
         echo "I am being called";
     }



     return $fields;
}

function woocommerce_custom_surcharge() {
        global $woocommerce;

        if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
            return;
        }

        $percentage = -0.1;
        $surcharge = ( $woocommerce->cart->cart_contents_total + $woocommerce->cart->shipping_total ) * $percentage;    
        $woocommerce->cart->add_fee( 'Forhandlerkode Rabat', $surcharge, true, '' );
}

Ma question n'est PAS spécifique au commerce, car sa solution peut aider à une compréhension plus générale des actions et des filtres. Merci d'avance pour toute aide que vous pouvez fournir!

MODIFIER:

Peut-être une solution quelque peu délirante à ce problème (j'ai fini par faire quelque chose de complètement différent, donc je n'ai plus le problème, mais quelqu'un pourrait trouver cela alors:)

Si vous DEVEZ réactiver un hook sans changer son nom ni utiliser jQuery, vous pouvez simplement utiliser do_action

Avec mon code ci-dessus, j'ai le crochet pour tirer à nouveau comme ceci:

if ($fields['billing']['forhandler_kode']) {
     add_action( 'woocommerce_cart_calculate_fees','woocommerce_custom_surcharge' );
     do_action('woocommerce_cart_calculate_fees');
     echo "I am being called";
 }

TOUTEFOIS, VEUILLEZ NOTER

Cela fonctionne, mais comme l’a souligné Otto, c’est une façon idiote de le faire. Une meilleure solution consiste simplement à appeler la fonction de la manière suivante:

if ($fields['billing']['forhandler_kode']) {
         woocommerce_custom_surcharge();
         echo "I am being called";
     }
3
Kristoffer M

La réponse lorsque la question concerne les points d'ancrage est toujours soit: le moment choisi, la priorité ou les deux.

Considérons le code suivant:

add_action( 'shutdown', 'wpse_258451_shutdown' );
function wpse_258451_shutdown() {
  add_action( 'init', 'wpse_258451_init' );
}
function wpse_258451_init() {
  wp_die( 'I will never be called.' );
}

Il devrait être évident que la fonction wpse_258451_init() ne sera jamais appelée. En effet, init n'est déclenché qu'une seule fois par demande de page, ce qui est très proche du début de la demande. De plus, shutdown est déclenché une seule fois par demande de page, ce qui est très proche de la fin de la demande.

Qu'est-ce qui se passe exactement dans notre code? WordPress arrive à la première add_action() et ajoute un rappel à la balise de crochet d'arrêt. WordPress déclenche toutes sortes de crochets avant d'arriver enfin à la fin de la requête et de déclencher shutdown. À la priorité 10, par défaut, WordPress tentera d’appeler le rappel, qui est la fonction wpse_258451_shutdown().

Dans la fonction wpse_258451_shutdown(), nous ajoutons une autre action. Cette fois à init avec le rappel de wpse_258451_init(). Ceci est bien ajouté au $wp_filter global. Cependant, étant donné que nous avons déjà passé init et que nous arrêtons la demande, ce rappel ne se déclenche jamais.

Comment cela se rapporte-t-il à votre question?

Si "je suis appelé" est en écho mais que votre action ne semble pas déclencher, il n'y a que deux raisons possibles.

  1. Le crochet a déjà tiré et ne tire pas à nouveau sur cette demande
  2. Le crochet n'est pas tiré du tout sur cette demande

Comment puis-je déterminer le timing des crochets

Ce qui suit fera écho à chaque hook (action et filtre) qui est déclenché pendant une requête.

add_filter( 'all', function( $a ) { 
  echo $a . "\\n";
  return $a; 
}, 10, 1 );

Une autre option serait d’utiliser Query Monitor de John Blackbourn.

3
Nathan Johnson