Come rendere un plug-in necessario un altro plug-in?


30

Sto creando un plug-in che aggiunge funzionalità extra a un plug-in principale. Idealmente nella schermata di amministrazione dei plug-in, il link "attiva" dovrebbe essere disabilitato e dovrebbe essere aggiunta una nota in linea che dice all'utente di installare e attivare il plug-in principale prima di poter utilizzare il plug-in corrente.


1
Che ne dici di usare: is_plugin_active ()? ad esempio: if (is_plugin_active('path/to/plugin.php')) { // Do something }
TomC il

Risposte:


35

Grazie per la risposta ragazzi. Sebbene entrambe le risposte mi abbiano messo sulla strada giusta, nessuna ha funzionato immediatamente. Quindi sto condividendo le mie soluzioni di seguito.

Metodo 1 - Utilizzo di register_activation_hook:

Crea il plugin Parent in plugin / parent-plugin / parent-plugin.php:

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

Crea il plugin figlio in plugin / 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>');
    }
}

Si noti che non sto usando deactivate_plugins( $plugin );perché per qualche motivo non funziona. Quindi ho usato wp_die per annullare il reindirizzamento di attivazione e informare l'utente.

Vantaggio:

  • Soluzione semplice e non comporta ulteriori riscontri db rispetto al metodo 2

svantaggi:

  • Lo schermo di wp_die è brutto
  • La schermata di wp_die verrà ANCORA visualizzata se hai attivato il Plugin principale e il Plugin secondario contemporaneamente utilizzando le caselle di controllo nella schermata di amministrazione dei plug-in.

Metodo 2: utilizzo di admin_init e admin_notices

Crea il plugin Parent in plugin / parent-plugin / parent-plugin.php:

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

Crea il plugin figlio in plugin / 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
}

Vantaggio:

  • Funziona quando attivi il plug-in Parent e Child contemporaneamente usando le caselle di controllo

Svantaggio:

  • Incrementa ulteriori hit db poiché il plug-in viene inizialmente attivato e disattivato una volta eseguito admin_init.

Per quanto riguarda la mia domanda sulla disabilitazione del link di attivazione, potrei usare:

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;
}

Tuttavia, si è rivelato estremamente poco pratico in quanto NON esiste un posto dove inserire questo codice. Non sono riuscito a inserirlo nel plug-in parent poiché il plug-in parent dovrebbe essere attivo per l'esecuzione di questo codice. Certamente non appartiene a plugin figlio o funzioni.php. Quindi sto eliminando questa idea.


1
Il metodo 2 ha funzionato alla grande! L'ho usato per estendere il plugin di qualcun altro.
Collin Price,

2

Prova questo, è commentato, quindi dovrebbe aiutarti a capirlo.

<?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'
    }
}
?> 

Se questo genera un errore, puoi anche selezionare l '"opzione" di "myplugin" e impostarla su false o non attivata.


2

Entrambe le soluzioni suggerite presentano dei difetti.

Metodo 1: Come accennato, la schermata wp_die () verrà ANCORA visualizzata quando il Plugin principale e il Plugin secondario si attivano contemporaneamente usando le caselle di controllo nella schermata di amministrazione dei plugin.

Metodo 2: In alcuni casi d'uso non va bene poiché 'admin_init' viene eseguito dopo 'plugins_loaded' ( https://codex.wordpress.org/Plugin_API/Action_Reference ) e dopo il hook di disinstallazione ( https: // codex. wordpress.org/Function_Reference/register_uninstall_hook ). Quindi, ad esempio, se vogliamo che il componente aggiuntivo esegua del codice al momento della disinstallazione, indipendentemente dal fatto che il plugin padre sia attivo o meno, questo approccio NON funzionerà.

Soluzione:

Prima di tutto, dobbiamo aggiungere il seguente codice alla fine del file PHP principale del plugin genitore:

do_action( 'my_plugin_loaded' );

Questo invierà un evento / segnale a tutti gli abbonati, dicendo che il plugin principale è stato caricato.

Quindi, la classe del componente aggiuntivo dovrebbe essere simile alla seguente:

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();
}

Spero che sia d'aiuto :)


4
Anche questa risposta ha un difetto. :-) Presuppone che tu abbia il pieno controllo sul plugin principale dove puoi aggiungere do_action ('my_plugin_loaded'); nel suo codice. La risposta selezionata funzionerà con o senza controllo del plug-in parent (ad es. Il plug-in parent non è tuo)
kosinix

Grazie, questo è esattamente quello che stavo cercando. Nel mio caso, io fare avere il pieno controllo del plug-genitore, e aveva bisogno di creare questo tipo di dipendenza.
cr0ybot,

0

Penso che tu abbia bisogno dell'attivazione del plugin TGM .

TGM Plugin Activation è una libreria PHP che ti permette di richiedere o raccomandare facilmente plugin per i tuoi temi (e plugin) di WordPress. Consente agli utenti di installare, aggiornare e persino attivare automaticamente i plug-in singolarmente o in blocco utilizzando classi, funzioni e interfacce WordPress native. Puoi fare riferimento a plug-in in bundle, plug-in dal repository dei plug-in di WordPress o persino plug-in ospitati altrove su Internet.


Link errato. Link corretto qui
XedinSconosciuta il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.