Comment rendre le plugin requis dans un thème wp sans utiliser les instructions conditionnelles php lors de l'appel d'une fonction individuelle à partir de ce plugin?

9

Un de mes thèmes Wordpress nécessite quelques plugins tiers pour fonctionner correctement.

La plupart du temps, j'appelais des fonctions à partir de plugins tiers à l'aide d'instructions conditionnelles comme

    if(function_exist('plugin_function')) {
             plugin_function() // do something
    }

supposons que j'ai besoin d'utiliser largement un plugin à travers de nombreux fichiers de mon thème ... Je voudrais éviter d'utiliser de nombreuses conditions IF ... existe-t-il un moyen approprié d'exiger l'installation de certains plugins spécifiques dans WP ou encore mieux de les installer s'ils manquent avant d'activer le thème?

Merci

unfulvio
la source

Réponses:

7

is_plugin_active()est plutôt fragile: il se cassera lorsque l'auteur du plugin renomme le fichier principal ou lorsque l'utilisateur renomme le répertoire ou le fichier principal du plugin. Il vaut mieux vérifier si une certaine fonction publique existe.

Pour éviter d'avoir à faire cette vérification chaque fois que vous avez besoin de certaines fonctionnalités du plugin, vous pouvez afficher un message dans la zone d'administration:

add_action( 'admin_notices', 'my_theme_dependencies' );

function my_theme_dependencies() {
  if( ! function_exists('plugin_function') )
    echo '<div class="error"><p>' . __( 'Warning: The theme needs Plugin X to function', 'my-theme' ) . '</p></div>';
}

Une autre alternative consiste à utiliser quelque chose comme http://tgmpluginactivation.com/

scribu
la source
Si l'auteur du plug-in modifie le nom d'une fonction avec laquelle vous vous interrogez function_exists, un utilisateur normal recevra simplement le message indiquant qu'il n'a pas installé le plug-in sur lequel un autre plug-in s'appuie. Le problème est que l'utilisateur aura réellement installé le plugin et se demandera alors pourquoi cela ne fonctionne pas . Oh, et je ne vais pas vous déprécier pour ça.
kaiser
Si vous vous souciez des votes, vous devriez voter pour le Q lui-même, car il est bon.
kaiser
Si l'auteur du plugin change le nom de la fonction, il recevra des plaintes de beaucoup plus d'utilisateurs que s'il changeait le nom du fichier.
scribu
Et j'ai rétrogradé votre réponse parce qu'elle ne répondait pas à la question, OMI. Ou préféreriez-vous que je vote en secret, sans aucune explication?
scribu
Je parlais juste du downvote, pas du commentaire. Le commentaire lui-même est correct, car ce sujet doit être discuté. J'ajouterai une autre réponse car mes pensées derrière cela dépasseront la longueur des commentaires. Veuillez simplement modifier la réponse, afin que nous puissions conserver les résultats de la discussion dans les révisions à suivre par tout le monde. Merci.
kaiser
1

Bien que cela n'empêche pas le thème de se casser lorsque le plug-in est désactivé, je consulterais cet article élégant sur le plug-in "Comment afficher une notification administrateur pour les thèmes requis" . Je n'ai jamais été à l'aise avec l'idée d'un thème forçant l'installation d'un plugin, et cela semble donc être la meilleure option suivante.

Une autre pensée rapide: je n'ai jamais essayé cela, mais je me demande si vous pourriez trouver un moyen intelligent de loger plusieurs crochets dans un seul conditionnel. Peut-être pourriez-vous séparer toutes les fonctions conditionnelles dans un fichier différent et ne l'exiger qu'en cas de if( function_exists( 'plugin_function' ) )retour true(étant entendu qu'il s'agit d'une vérification imparfaite.

mrwweb
la source
0

Si vous n'en avez besoin que d'une page de plugin, alors il y en a is_plugin_active(). Si vous en avez besoin à l'extérieur, vous feriez mieux de copier / coller la fonction principale dans votre thème, puis de la réutiliser:

if ( ! is_admin() )
{
/**
 * Check whether the plugin is active by checking the active_plugins list.
 *
 * @since 2.5.0
 *
 * @param string $plugin Base plugin path from plugins directory.
 * @return bool True, if in the active plugins list. False, not in the list.
 */
function is_plugin_active( $plugin ) {
    return in_array( $plugin, (array) get_option( 'active_plugins', array() ) ) || is_plugin_active_for_network( $plugin );
}
}

Le conditionnel évite toute erreur de double définition de la fonction.

kaiser
la source
Cela ne répond pas vraiment à la question. Il remplace simplement if(function_exist('plugin_function'))parif(is_plugin_active('plugin-file.php'))
scribu
0

Remarque: Cette réponse est juste là pour faciliter la discussion entre @scribu et @kaiser. Mods: veuillez ne pas supprimer. Utilisateurs / lecteurs: veuillez ne pas voter. Si vous souhaitez suivre la discussion, consultez le journal de révision / édition. Si vous souhaitez participer à la discussion, modifiez la réponse. Si la discussion a un résultat, il sera marqué comme tel. Je vous remercie.


Scénarios

Il existe également différents scénarios qui pèsent différemment, où vous pourriez avoir une dépendance de plugin. (Les exemples ne sont que fictifs). Le mot "(parent) Plugin" peut être échangé avec "Theme" du point de vue parent.

  1. (difficile) Un plugin enfant qui étend uniquement les fonctionnalités ou modifie l'affichage (et similaire) d'un plugin existant et ne peut donc pas exister sans le parent. Exemple: BuddyPress »BuddyPress-FunkyCommentDisplay
  2. (normal) Un plugin qui a des fonctionnalités étendues lorsqu'un plugin enfant est activé. Exemple: jQueryAttachmentCarousel »jQuerySlideDeck
  3. (soft) Un plugin qui ajoute juste une fonctionnalité. Exemple: DisneyWonderlandTheme »MickeysSocialLinks

Dans ce qui suit, j'essaie d'esquisser ce qui se passe lorsque vous mettez à jour le "autre" plugin et que la vérification ne fonctionne plus.

  • Annonce 1) Le plugin ne pourrait pas exister sans BuddyPress activé »Les choses sont complètement cassées.
  • Annonce 2) Le plugin ne pouvait pas offrir la possibilité de passer du carrousel à SlideDeck »Affiche câblé (je suppose que les styles sont modifiés en SlideDeck).
  • Annonce 3) Les liens sociaux Mickeys disparaissent.

Vérifier

Il existe trois possibilités de vérification, si vous souhaitez savoir si un plugin est actif:

  • A. Le dossier existe-t-il?
  • B. Le fichier principal - option 'active_plugins'- existe-t-il?
  • C. Existe-t-il une fonction particulière?

Si je prends maintenant mon plugin Internal Link Checker comme exemple, qui n'offre aucune API publique et n'est pas destiné à être étendu, je ne verrais aucune raison (en tant qu'auteur) de ne pas changer le nom des fonctions internes à la demande ou simplement à volonté. . Donc, si quelqu'un essayait de se greffer sur ce plugin, alors les choses se briseraient simplement (selon la fonctionnalité et l'étroitesse du regroupement) à la mise à jour. Il en va de même pour les noms de fichiers. Je n'aurais aucune raison réelle (à part que le plugin serait désactivé lors de la mise à jour) de ne pas changer le nom du fichier. La seule chose qui m'empêcherait de changer le nom du dossier est que la vérification et la notification de la mise à jour s'exécutent par rapport au nom du fichier - s'il est hébergé dans le référentiel officiel.

Je dirais donc que la partie la plus faible (facile à changer) à la plus difficile (beaucoup parlent contre le changement) d'un plugin (parent) serait:

fonction »nom du fichier principal» dossier


Quand j'ai dit qu'une vérification de fonction est moins fragile que l'utilisation, is_plugin_active()j'ai supposé que la fonction en question est celle que l'auteur du plugin encourage explicitement. L'exemple ultime de ceci serait la wp_pagenavi()balise de modèle offerte par le plugin WP-PageNavi.

La difficulté de définir des dépendances est qu'il n'existe aucun moyen standard d'identifier de manière unique les plugins qui n'impliquent pas de noms de fichiers.

Plus de réflexions sur le sujet:

http://wordpress.org/support/topic/plugin-plugin-dependencies-unreliable-plugin-namingidentifying-scheme


Je suppose que nous pouvons jusqu'à présent le résumer en trois points:

  • Nous avons parlé de sujets légèrement différents
  • Nous convenons qu'il n'y a pas de moyen à toute épreuve de contourner ce que je pensais que le sujet serait
  • D'après votre compréhension de la question, vous avez proposé un chemin valide

La manière la plus intelligente (jusqu'à présent) à laquelle je peux penser, que j'ai déjà vue dans certains plugins (beaucoup moins):

// inside the plugin file:
add_action( 'plugin_custom_hook', 'plugin_trigger' );
// inside some template:
do_action( 'plugin_custom_hook' );

Sans trop y penser en détail, mais je suppose que vous pouvez accrocher votre avis dans un filtre sur 'tous' et vérifier à l' intérieur du filtre actuel s'il a été déclenché lorsque vous êtes shutdownaccroché ...?


L'utilisation de hooks fonctionnerait bien pour les dépendances «normales» et «faibles». Le seul inconvénient est que vous devrez toujours utiliser function_exists()ou is_plugin_active()si vous souhaitez arrêter si la dépendance n'est pas remplie. Utiliser le filtre «tout» pour cela serait trop cher à l'OMI.

@scibu Cela visait "votre" sujet. (J'ai déjà arrêté de parler du mien). :)

Donc, fondamentalement, si vous avez besoin d'une dépendance - et que vous avez un bon auteur - alors il pourrait offrir un crochet à la place / en remplacement d'une balise de modèle. Parce que le plugin ne s'y accrocherait que si le crochet était présent, ou ne faisait simplement rien. Et de l'autre côté, vous n'auriez pas d'erreur, lorsque les plugins ne sont pas présents.

Voici la partie difficile (ou plus d'un Q): Pour rédiger un avis administrateur pour informer l'utilisateur de la dépendance "Vous devez installer» DisneyWonderLinks «", vous pouvez vérifier le array_keys( $GLOBALS['wp_filter']['template_tag_like_hook'] ). Je ne sais pas si cela fonctionnerait, mais afaik le tableau devrait être accessible des deux côtés (public / admin).


Ça ne marcherait pas. Le fait qu'un rappel soit enregistré sur un hook ne signifie pas que le hook sera déclenché lorsque prévu. La seule chose qui ferait une sorte de travail est d'utiliser le hook 'shutdown', que vous avez mentionné précédemment:

add_action( 'shutdown', function() {
  if ( !did_action( 'template_tag_like_hook' ) )
    echo 'Problem.';
} );

Bien sûr, cela serait imprimé tout en bas, après la </html>balise, sur le front-end (car c'est là que les balises de modèle sont normalement utilisées), ce qui n'est pas très utile.

Vous pouvez essayer de stocker le message dans wp_options puis l'afficher dans la zone d'administration, mais cela ouvrirait une toute nouvelle boîte de vers: invalidation, mise en cache des plugins, etc.

kaiser
la source
Pour mémoire, il s'agit d'une façon plutôt peu orthodoxe d'utiliser les fonctionnalités du site. Cela me rappelle c2.com/cgi/wiki
scribu
Oui, ça l'est. Mais je ne savais pas comment nous pourrions poursuivre la discussion sans la cacher aux lecteurs ultérieurs.
kaiser
Je ne me rendrais pas compte que la publication de la question aurait généré toute une discussion :) Mais c'est effectivement intéressant et je vous remercie à la fois pour vos efforts et votre temps à donner des conseils et à fournir un débat réfléchi. Je pense que les conseils de scribu (l'un des nombreux) pour utiliser la classe d'activation TGM pourraient offrir une solution à ma réponse au moins d'un point de vue simplement pratique, je vais y réfléchir. Cependant, je garde toujours un œil sur toute la discussion, car d'autres méthodes proposées ont du sens dans certains scénarios et sont très intéressantes pour moi à lire, merci!
unfulvio