Wie erstelle ich ein Plugin, das ein anderes Plugin benötigt?

30

Ich erstelle ein Plugin, das einem Haupt-Plugin zusätzliche Funktionen hinzufügt. Idealerweise sollte im Verwaltungsbildschirm der Plugins der Link "Aktivieren" deaktiviert und ein Inline-Hinweis hinzugefügt werden, der den Benutzer auffordert, das Haupt-Plugin zuerst zu installieren und zu aktivieren, bevor er das aktuelle Plugin verwenden kann.

kosinix
quelle
1
Was ist mit: is_plugin_active ()? zB: if (is_plugin_active('path/to/plugin.php')) { // Do something }
TomC

Antworten:

35

Danke für die Antworten Jungs. Obwohl beide Antworten mich auf den richtigen Weg brachten, funktionierte keiner sofort. Also teile ich meine Lösungen unten.

Methode 1 - register_activation_hook verwenden:

Erstelle das Parent Plugin in der Datei plugins / parent-plugin / parent-plugin.php:

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

Erstellen Sie das Child Plugin in der Datei 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>');
    }
}

Beachten Sie, dass ich deactivate_plugins( $plugin );aus irgendeinem Grund nicht benutze, es funktioniert nicht. Deshalb habe ich wp_die verwendet, um die Aktivierungsumleitung abzubrechen und den Benutzer zu informieren.

Vorteil:

  • Einfache Lösung und keine zusätzlichen Datenbank-Treffer im Vergleich zu Methode 2

Nachteile:

  • wp_die bildschirm ist hässlich
  • Der wp_die-Bildschirm wird NOCH angezeigt, wenn Sie das übergeordnete Plugin und das untergeordnete Plugin gleichzeitig über die Kontrollkästchen im Verwaltungsbildschirm des Plugins aktiviert haben.

Methode 2 - Verwenden von admin_init und admin_notices

Erstelle das Parent Plugin in der Datei plugins / parent-plugin / parent-plugin.php:

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

Erstellen Sie das Child Plugin in der Datei 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
}

Vorteil:

  • Funktioniert, wenn Sie das übergeordnete und das untergeordnete Plugin gleichzeitig mithilfe von Kontrollkästchen aktivieren

Nachteil:

  • Es kommt zu zusätzlichen Datenbank-Treffern, da das Plugin zuerst aktiviert und nach Ausführung von admin_init deaktiviert wird.

Bei meiner Frage zum Deaktivieren des Aktivierungslinks könnte ich Folgendes verwenden:

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

Es stellte sich jedoch als äußerst unpraktisch heraus, da es KEINEN Platz gibt, um diesen Code zu platzieren. Ich konnte es nicht auf das übergeordnete Plugin setzen, da das übergeordnete Plugin aktiv sein sollte, damit dieser Code ausgeführt wird. Gehört mit Sicherheit nicht zu child plugin oder functions.php. Also verschrotte ich diese Idee.

kosinix
quelle
1
Methode 2 hat super funktioniert! Ich habe es benutzt, um das Plugin eines anderen zu erweitern.
Collin Price
2

Probieren Sie es aus, es ist kommentiert, damit Sie es besser verstehen.

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

Wenn dies einen Fehler auslöst, können Sie auch die 'Option' von 'myplugin' markieren und auf false oder nicht aktiviert setzen.

MrJustin
quelle
2

Beide Lösungsvorschläge weisen Mängel auf.

Methode 1: Wie bereits erwähnt, wird der Bildschirm wp_die () STILL angezeigt, wenn das übergeordnete Plugin und das untergeordnete Plugin gleichzeitig mithilfe der Kontrollkästchen im Verwaltungsbildschirm des Plugins aktiviert werden.

Methode 2: In einigen Anwendungsfällen ist es nicht gut, da 'admin_init' nach 'plugins_loaded' ( https://codex.wordpress.org/Plugin_API/Action_Reference ) und nach dem Deinstallations-Hook ( https: // codex) ausgeführt wird. wordpress.org/Function_Reference/register_uninstall_hook ). Wenn das Add-On beispielsweise bei der Deinstallation Code ausführen soll, unabhängig davon, ob das übergeordnete Plug-In aktiv ist oder nicht, funktioniert dieser Ansatz NICHT.

Lösung:

Zunächst müssen wir den folgenden Code an das Ende der Haupt-PHP-Datei des übergeordneten Plugins anhängen:

do_action( 'my_plugin_loaded' );

Dadurch wird ein Ereignis / Signal an alle Abonnenten gesendet, das besagt, dass das Core-Plugin geladen wurde.

Die Klasse des Add-Ons sollte dann folgendermaßen aussehen:

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

Ich hoffe es hilft :)

Vovafeldman
quelle
4
Diese Antwort hat auch einen Fehler. :-) Es wird vorausgesetzt, dass Sie die volle Kontrolle über das übergeordnete Plugin haben, in dem Sie do_action ('my_plugin_loaded') hinzufügen können. in seinem Code. Die ausgewählte Antwort funktioniert mit oder ohne Kontrolle über das übergeordnete Plugin (z. B. das übergeordnete Plugin gehört nicht Ihnen)
Kosinix
Danke, genau das habe ich gesucht. In meinem Fall habe ich die volle Kontrolle über das übergeordnete Plugin und musste diese Art von Abhängigkeit erstellen.
cr0ybot
0

Ich denke, Sie brauchen die TGM-Plugin-Aktivierung .

TGM Plugin Activation ist eine PHP-Bibliothek, mit der Sie Plugins für Ihre WordPress-Themes (und Plugins) einfach anfordern oder empfehlen können. Es ermöglicht Ihren Benutzern, Plugins in Singular- oder Bulk-Form unter Verwendung nativer WordPress-Klassen, -Funktionen und -Schnittstellen zu installieren, zu aktualisieren und sogar automatisch zu aktivieren. Sie können auf gebündelte Plugins, Plugins aus dem WordPress-Plugin-Repository oder sogar auf Plugins verweisen, die an anderer Stelle im Internet gehostet werden.

Amir Hossein Hossein Zadeh
quelle
Falscher Link. Richtiger Link hier
XedinUnknown