web-dev-qa-db-fra.com

Comment WordPress s'assure-t-il que les plugins fonctionnent en même temps et comment résout-il la dépendance d'un plugin à un autre?

Disons que j'ai un plugin qui déclenche le plugin_1_action lors de son initialisation.

Maintenant, parce que je veux étendre ce plugin, je vais me connecter à plugin_1_action, mais que se passe-t-il si mon plugin a été installé après ce plugin? Ce plugin ne fonctionnera-t-il pas en premier et je ne perdrai donc plus la chance de rattraper le hook plugin_1_action?

C’est juste étrange et magique pour moi que je puisse, quoi qu’il en soit, accrocher, disons, les actions de Woo et que Woo puisse s’accrocher au mien, même si clairement mon plugin a été installé plus tard que prévu.

Même si la plupart des plugins fonctionnent sur le hook init (ils sont donc exécutés sur le même espace), leurs priorités sont toujours définies différemment. Cela signifie que le code de plugin1 sera exécuté avant celui de plugin2 et que si plugin2 a un crochet dans plugin1, eh bien, bonne chance ... ou pas, apparemment, WordPress n'a pas ce problème.

Comment ça marche?

2
coolpasta

Si le plugin exécute en effet plugin_1_action dès qu'il est chargé , ce qui signifie que l'appel do_action() est juste assis dans le fichier du plugin et non dans une fonction qui sera connectée plus tard, alors oui, vous avez raison: vous ne serez pas capable de s'y accrocher si votre plugin est chargé plus tard.

Ce n'est presque jamais comment les plugins fonctionnent. Presque tous les plugins n'exécutent aucun code dès qu'ils sont chargés. Les plugins relieront généralement toutes leurs fonctionnalités ultérieurement, généralement pas avant le hook init, qui est exécuté une fois que tous les plugins et thèmes ont été chargés.

Alors disons que le plugin original a ce code:

function og_plugin_initialize() {
    // Does stuff.

    do_action( 'og_plugin_initialized' );
}

Ce code sera probablement accroché pour s'exécuter sur le hook init:

add_action( 'init', 'og_plugin_initialize', 20 );

Ainsi, le hook og_plugin_initialized ne sera exécuté que jusqu'au hook init, de priorité 20.

Si vous aviez une fonction que vous souhaitiez intégrer au hook og_plugin_initialized, vous l'ajouteriez alors dans votre plugin:

function my_plugin_init() {
    // Do stuff.
}
add_action( 'og_plugin_initialized', 'my_plugin_init' );

Quand c'est fait comme ça, peu importe l'ordre dans lequel les plugins sont chargés, car les plugins et leurs files d'attente sont exécutés plus tard. Et puisque ces deux fonctions seront exécutées après le chargement de tous les plug-ins, vous pouvez utiliser les fonctions définies dans le plug-in d'origine sans problème.

3
Jacob Peattie

Important: Pensez aux actions et aux crochets plutôt qu'à des événements

Ce modèle mental vous servira beaucoup mieux.

Maintenant, parce que je veux étendre ce plugin, je vais me connecter à plugin_1_action, mais que se passe-t-il si mon plugin a été installé après ce plugin?

Vous pouvez installer vos plugins dans l'ordre que vous voulez, ils sont tous chargés dans le même ordre, peu importe. Installer le plugin C en premier ne signifie pas que son code est exécuté en premier.

Les plugins sont chargés par ordre alphabétique, donc le plugin a sera chargé avant le plugin b car A vient avant B, etc.

Ce plugin ne sera-t-il pas lancé en premier et je ne perdrai donc plus la chance de rattraper le hook plugin_1_action?

Correct, si l'action est déclenchée une fois et que cet événement a déjà eu lieu, il est trop tard. Vous pouvez toujours vous y accrocher, mais cet événement est déjà arrivé, il ne sera donc jamais exécuté.

Semblable à dire à quelqu'un d'acheter du lait après avoir été au magasin plutôt qu'avant. Vous pouvez le faire, mais vous ne recevrez pas de lait à moins qu'ils ne visitent le magasin une seconde fois.

Pour que cela fonctionne encore, il faudrait faire appel à une sorte de voyage dans le temps/à une mécanique temporelle. Le Dr Who pourrait peut-être le faire, mais nous aurons besoin d'un refactoring pour corriger le plugin d'origine.

C’est juste étrange et magique pour moi que je puisse, quoi qu’il en soit, accrocher, disons, les actions de Woo et que Woo puisse s’accrocher aux miens,

Les actions ne sont que des actions, elles n'appartiennent à personne. Il n'y a pas de sandboxing de code, et une fois chargé, il est chargé. Un code de plug-in partage tout le même espace que WP Core, et d'autres plug-ins.

même si clairement mon plugin a été installé plus tard.

L'ordre d'installation est sans importance. Comme nous l'avons appris précédemment, l'ordre d'exécution est important. Une fois que l'événement/l'action/le raccordement est déclenché, vous pouvez toujours vous y accrocher, mais vos fonctions ne s'exécutent pas tant qu'il n'est pas encore déclenché, ce qui pourrait ne jamais se produire. WP les crochets ne font pas le voyage dans le temps.

Même si la plupart des plugins fonctionnent sur le hook init (ils sont donc exécutés sur le même espace), leurs priorités sont toujours définies différemment.

En effet, si l'événement n'a pas encore eu lieu, vous pouvez indiquer une priorité pour influencer l'ordre dans lequel les fonctions sont appelées.

Cela signifie que le code de plugin1 sera exécuté avant celui de plugin2 et que si plugin2 a un crochet dans plugin1, eh bien, bonne chance ... ou pas, apparemment, WordPress n'a pas ce problème.

Oh mais c'est le cas! Comme je l’ai dit plus tôt, vous pouvez ajouter des fonctions à un crochet déjà déclenché, cela ne signifie pas qu’il l’appliquera rétroactivement aux moments précédents du coup. Comme je l'ai déjà mentionné, cela nécessiterait une technologie de voyage dans le temps.

Le problème fondamental ici est que le plug-in effectue le travail avant que les hooks init ou admin_init ne se produisent. Lorsque les plugins sont chargés, ils doivent configurer leurs objets, ajouter leurs crochets, etc., mais ils ne doivent pas fonctionner. C’est à cela que servent les événements de cycle de vie de init etc.

2
Tom J Nowell