web-dev-qa-db-fra.com

Comment faire en sorte qu'un plugin soit requis dans un thème wp sans utiliser d'instructions conditionnelles php lors de l'appel d'une fonction individuelle à partir de ce plugin?

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

La plupart du temps, j’appelais des fonctions de plugins tiers en utilisant des instructions conditionnelles telles que

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

supposons que j’ai besoin d’utiliser beaucoup un plugin dans plusieurs fichiers de mon thème ... Je voudrais éviter d’utiliser beaucoup de conditions IF ... existe-t-il un moyen approprié de demander l’installation de certains plugins spécifiques dans WP ou même mieux les installer s'ils manquent avant d'activer le thème?

merci

8
unfulvio

is_plugin_active() est plutôt fragile: il se brisera lorsque l'auteur du plug-in renomme le fichier principal ou lorsque l'utilisateur renomme le répertoire ou le fichier principal du plug-in. Il est préférable de vérifier si une fonction publique existe.

Pour éviter de devoir effectuer 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/

6
scribu

Bien que cela n’empêche pas le thème de s’écrouler lorsque le plug-in est désactivé, j’examinerais cet article épineux sur "Comment afficher une notification de l’administrateur pour les thèmes obligatoires" plugin. Je n'ai jamais été à l'aise avec l'idée d'un thème forçant un plugin à installer, ce qui semble être la prochaine meilleure option.

Une autre pensée rapide: je n’ai jamais essayé cela, mais je me demande si vous pourriez trouver un moyen astucieux de loger plusieurs crochets dans une seule condition. Vous pourriez peut-être séparer toutes les fonctions conditionnelles dans un fichier différent et ne l'exiger que si if( function_exists( 'plugin_function' ) ) renvoie true (en sachant qu'il s'agit d'une vérification imparfaite.

1
mrwweb

Note: _ Cette réponse est là pour faciliter la discussion entre @scribu et @kaiser. Mods: Merci de ne pas supprimer. Utilisateurs/Lecteurs: Merci de 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, elle sera marquée comme telle. Merci.


Scénarios

Il existe également différents scénarios de poids différents, dans lesquels vous pouvez avoir une dépendance de plug-in. (Les exemples ne sont que fictifs). Le mot "plugin (parent)" peut être échangé avec "Thème" du point de vue parent.

  1. (difficile) Un plugin enfant qui étend seulement la fonctionnalité 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 une fonctionnalité étendue lorsqu'un plugin enfant est activé. Exemple: jQueryAttachmentCarousel "jQuerySlideDeck
  3. (soft) Un plugin qui ajoute une fonctionnalité. Exemple: DisneyWonderlandTheme "MickeysSocialLinks

Dans ce qui suit, je tente d’esquisser ce qui se passe lorsque vous mettez à jour le "autre" plug-in et que la vérification ne fonctionne plus.

  • Ad 1) Le plugin ne pourrait pas exister sans BuddyPress activé "La substance est complètement cassée.
  • Ad 2) Le plug-in ne pouvait pas offrir l'option de basculer de Carousel à SlideDeck "Affiche câblé (je suppose que les styles sont modifiés en SlideDeck).
  • Ad 3) MickeysSocialLinks disparaissent.

Vérifier

Il existe trois options à vérifier, si vous voulez savoir si un plugin est actif:

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

Si je prends maintenant mon plugin Internal Link Checker comme exemple, qui ne propose aucune API publique et n'est pas destiné à être étendu, je ne vois aucune raison (en tant qu'auteur) de ne pas modifier le nom des fonctions internes à la demande. ou juste sur volonté. Donc, si quelqu'un essayait de se greffer sur ce plugin, alors les choses se briseraient simplement (en fonction de la fonctionnalité et de l'étroitesse du bundling) lors de 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) pour 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 sont exécutées en fonction du nom du fichier, s'il est hébergé dans le référentiel officiel.

Donc, je dirais de la partie la plus faible (facile à changer) au plus difficile (beaucoup parlent contre le changement) d'un plugin (parent) serait:

fonction "nom de fichier principal" dossier


Lorsque j'ai dit qu'une vérification de fonction est moins fragile que d'utiliser is_plugin_active(), j'ai supposé que la fonction en question était une fonction explicitement encouragée par l'auteur du plug-in. L'exemple ultime de ceci serait la balise de modèle wp_pagenavi() proposée par le plugin WP-PageNavi.

La difficulté à définir les dépendances réside dans le fait qu’il n’existe pas de moyen standard d’identifier de manière unique les plug-ins n’impliquant 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 pense que nous pouvons jusqu’à présent résumer la situation en trois points:

  • Nous avons parlé de sujets légèrement différents
  • Nous convenons qu'il n'y a pas de moyen infaillible de contourner ce que je pensais être le sujet.
  • De votre compréhension de la question, vous avez proposé une solution valable

Le moyen le plus intelligent (jusqu'à présent) auquel je puisse penser, que j'ai déjà vu dans certains plugins (beaucoup trop):

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

Sans trop y penser, mais je suppose que vous pouvez insérer votre avis dans un filtre de vérification de tous les filtres et vérifier à l'intérieur du filtre actuel s'il a été déclenché lorsque vous êtes sur le crochet shutdown ...?


L'utilisation de hooks fonctionne 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 "tous" pour cela serait trop coûteux, OMI.

@scibu Cela visait "votre" sujet. (J'ai déjà abandonné parler de la mienne). :)

Donc, fondamentalement, si vous avez besoin d’une dépendance - et que vous avez un auteur gentil - alors il pourrait offrir un crochet à la place/en remplacement d’une balise 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 écrire une notification de l'administrateur pour informer l'utilisateur de la dépendance "Vous devez installer" DisneyWonderLinks ", vous pouvez vérifier la fonction array_keys( $GLOBALS['wp_filter']['template_tag_like_hook'] ). Je ne sais pas si cela fonctionnerait, mais autant que je sache, le tableau devrait être accessible des deux côtés (public/admin).


Cela ne marcherait pas. Ce n’est pas parce qu’un rappel est enregistré sur un hook que celui-ci sera déclenché comme prévu. La seule chose qui ferait un genre de travail serait d'utiliser le crochet '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 balise </html>, sur le front-end (puisque c’est là que les balises de gabarit sont normalement utilisées), ce qui n’est pas très utile.

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

0
kaiser

Si vous n'en avez besoin que d'une page de plug-in, alors il y a is_plugin_active() . Si vous en avez besoin à l'extérieur, il est préférable de copier/coller la fonction principale dans votre thème, puis de le 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 les erreurs avec une double définition de la fonction.

0
kaiser