Comment faire un plugin nécessite un autre plugin?

30

Je construis un plugin qui ajoute des fonctionnalités supplémentaires à un plugin principal. Idéalement, dans l'écran d'administration des plugins, le lien "activer" doit être désactivé et une note en ligne doit être ajoutée pour indiquer à l'utilisateur d'installer et d'activer le plugin principal avant de pouvoir utiliser le plugin actuel.

kosinix
la source
1
Qu'en est-il de l'utilisation: is_plugin_active ()? par exemple: if (is_plugin_active('path/to/plugin.php')) { // Do something }
TomC

Réponses:

35

Merci pour les réponses les gars. Bien que les deux réponses m'aient mis sur la bonne voie, aucune n'a fonctionné hors de la boîte. Je partage donc mes solutions ci-dessous.

Méthode 1 - Utilisation de register_activation_hook:

Créez le plugin parent dans plugins / parent-plugin / parent-plugin.php:

<?php
/*
Plugin Name: Parent Plugin
Description: Demo plugin with a dependent child plugin.
Version: 1.0.0
*/

Créez le plugin enfant dans plugins / child-plugin / child-plugin.php:

<?php
/*
Plugin Name: Child Plugin
Description: Parent Plugin should be installed and active to use this plugin.
Version: 1.0.0
*/
register_activation_hook( __FILE__, 'child_plugin_activate' );
function child_plugin_activate(){

    // Require parent plugin
    if ( ! is_plugin_active( 'parent-plugin/parent-plugin.php' ) and current_user_can( 'activate_plugins' ) ) {
        // Stop activation redirect and show error
        wp_die('Sorry, but this plugin requires the Parent Plugin to be installed and active. <br><a href="' . admin_url( 'plugins.php' ) . '">&laquo; Return to Plugins</a>');
    }
}

Notez que je n'utilise pas deactivate_plugins( $plugin );car pour une raison quelconque, cela ne fonctionne pas. J'ai donc utilisé wp_die pour annuler la redirection d'activation et informer l'utilisateur.

Avantage:

  • Solution simple et n'entraîne pas de hits db supplémentaires par rapport à la méthode 2

Désavantages:

  • L'écran wp_die est moche
  • L'écran wp_die apparaîtra TOUJOURS si vous avez activé le plug-in parent et le plug-in enfant en même temps en utilisant les cases à cocher dans l'écran d'administration des plug-ins.

Méthode 2 - Utilisation de admin_init et admin_notices

Créez le plugin parent dans plugins / parent-plugin / parent-plugin.php:

<?php
/*
Plugin Name: Parent Plugin
Description: Demo plugin with a dependent child plugin.
Version: 1.0.0
*/

Créez le plugin enfant dans plugins / child-plugin / child-plugin.php:

<?php
/*
Plugin Name: Child Plugin
Description: Parent Plugin should be installed and active to use this plugin.
Version: 1.0.0
*/
add_action( 'admin_init', 'child_plugin_has_parent_plugin' );
function child_plugin_has_parent_plugin() {
    if ( is_admin() && current_user_can( 'activate_plugins' ) &&  !is_plugin_active( 'parent-plugin/parent-plugin.php' ) ) {
        add_action( 'admin_notices', 'child_plugin_notice' );

        deactivate_plugins( plugin_basename( __FILE__ ) ); 

        if ( isset( $_GET['activate'] ) ) {
            unset( $_GET['activate'] );
        }
    }
}

function child_plugin_notice(){
    ?><div class="error"><p>Sorry, but Child Plugin requires the Parent plugin to be installed and active.</p></div><?php
}

Avantage:

  • Fonctionne lorsque vous activez le plug-in parent et enfant en même temps à l'aide de cases à cocher

Désavantage:

  • Générez des hits db supplémentaires car le plugin est en fait activé au début et désactivé une fois admin_init exécuté.

Quant à ma question concernant la désactivation du lien d'activation, je pourrais utiliser:

add_filter( 'plugin_action_links', 'disable_child_link', 10, 2 );
function disable_child_link( $links, $file ) {

    if ( 'child-plugin/child-plugin.php' == $file and isset($links['activate']) )
        $links['activate'] = '<span>Activate</span>';

    return $links;
}

Cependant, il s'est avéré très peu pratique car il n'y a PAS de place pour mettre ce code. Je ne pouvais pas le mettre sur le plugin parent car le plugin parent devrait être actif pour que ce code s'exécute. N'appartient certainement pas au plugin enfant ou à functions.php. Donc, je supprime cette idée.

kosinix
la source
1
La méthode 2 a très bien fonctionné! Je l'ai utilisé pour étendre le plugin de quelqu'un d'autre.
Collin Price
2

Essayez ceci, il est commenté, ce qui devrait vous aider à le comprendre.

<?php
register_activation_hook( __FILE__, 'myplugin_activate' ); // Register myplugin_activate on
function myplugin_activate() {
    $plugin = plugin_basename( __FILE__ ); // 'myplugin'
    if ( is_plugin_active( 'plugin-directory/first-plugin.php' ) ) {
        // Plugin was active, do hook for 'myplugin'
    } else {
        // Plugin was not-active, uh oh, do not allow this plugin to activate
        deactivate_plugins( $plugin ); // Deactivate 'myplugin'
    }
}
?> 

Si cela génère une erreur, vous pouvez également vérifier l '«option» de «myplugin» et la définir sur false ou non activée.

MrJustin
la source
2

Les deux solutions suggérées ont des défauts.

Méthode 1: Comme mentionné, l'écran wp_die () s'affiche TOUJOURS lorsque le plug-in parent et le plug-in enfant sont activés en même temps en utilisant les cases à cocher dans l'écran d'administration des plug-ins.

Méthode 2: dans certains cas d'utilisation, ce n'est pas bon car 'admin_init' est exécuté bien après 'plugins_loaded' ( https://codex.wordpress.org/Plugin_API/Action_Reference ), et après le crochet de désinstallation ( https: // codex. wordpress.org/Function_Reference/register_uninstall_hook ). Ainsi, par exemple, si nous voulons que le module complémentaire exécute du code lors de la désinstallation, que le plug-in parent soit actif ou non, cette approche ne fonctionnera PAS.

Solution:

Tout d'abord, nous devons ajouter le code suivant à la fin du fichier PHP principal du plugin parent:

do_action( 'my_plugin_loaded' );

Cela enverra un événement / signal à tous les abonnés, indiquant que le plugin principal a été chargé.

Ensuite, la classe du module complémentaire devrait ressembler à ceci:

class My_Addon
{
    static function init ()
    {
        register_activation_hook( __FILE__, array( __CLASS__, '_install' ) );

        if ( ! self::_is_parent_active_and_loaded() ) {
            return;
        }
    }

    #region Parent Plugin Check

    /**
     * Check if parent plugin is activated (not necessarly loaded).
     *
     * @author Vova Feldman (@svovaf)
     *
     * @return bool
     */
    static function _is_parent_activated()
    {
        $active_plugins_basenames = get_option( 'active_plugins' );
        foreach ( $active_plugins_basenames as $plugin_basename ) {
            if ( false !== strpos( $plugin_basename, '/my-plugin-main-file.php' ) ) {
                return true;
            }
        }

        return false;
    }

    /**
     * Check if parent plugin is active and loaded.
     *
     * @author Vova Feldman (@svovaf)
     *
     * @return bool
     */
    static function _is_parent_active_and_loaded()
    {
        return class_exists( 'My_Plugin' );
    }

    /**
     *
     * @author Vova Feldman (@svovaf)
     */
    static function _install()
    {
        if ( ! self::_is_parent_active_and_loaded() ) {
            deactivate_plugins( basename( __FILE__ ) );

            // Message error + allow back link.
            wp_die( __( 'My Add-on requires My Plugin to be installed and activated.' ), __( 'Error' ), array( 'back_link' => true ) );
        }
    }

    #endregion Parent Plugin Check
}

if (My_Addon::_is_parent_active_and_loaded())
{
    // If parent plugin already included, init add-on.
    My_Addon::init();
}
else if (My_Addon::_is_parent_activated())
{
    // Init add-on only after the parent plugins is loaded.
    add_action( 'my_plugin_loaded', array( __CLASS__, 'init' ) );
}
else
{
    // Even though the parent plugin is not activated, execute add-on for activation / uninstall hooks.
    My_Addon::init();
}

J'espère que ça aide :)

vovafeldman
la source
4
Cette réponse a aussi un défaut. :-) Il suppose que vous avez un contrôle total sur le plugin parent où vous pouvez ajouter do_action ('my_plugin_loaded'); dans son code. La réponse sélectionnée fonctionnera avec ou sans contrôle du plugin parent (par exemple, le plugin parent n'est pas le vôtre)
kosinix
Merci, c'est exactement ce que je cherchais. Dans mon cas, je ne le contrôle total sur le plugin parent et nécessaire pour créer ce genre de dépendance.
cr0ybot
0

Je pense que vous avez besoin de l' activation du plugin TGM .

TGM Plugin Activation est une bibliothèque PHP qui vous permet d'exiger ou de recommander facilement des plugins pour vos thèmes (et plugins) WordPress. Il permet à vos utilisateurs d'installer, de mettre à jour et même d'activer automatiquement des plugins de manière singulière ou en masse en utilisant des classes, des fonctions et des interfaces WordPress natives. Vous pouvez référencer des plugins groupés, des plugins du référentiel de plugins WordPress ou même des plugins hébergés ailleurs sur Internet.

Amir Hossein Hossein Zadeh
la source
Mauvais lien. Lien correct ici
XedinUnknown