Jak sprawić, by wtyczka wymagała innej wtyczki?

30

Buduję wtyczkę, która dodaje dodatkową funkcjonalność do głównej wtyczki. Idealnie na ekranie administrowania wtyczkami link „aktywuj” powinien być wyłączony i należy dodać notatkę, która mówi użytkownikowi, aby najpierw zainstalował i aktywował główną wtyczkę, zanim będzie mógł korzystać z bieżącej wtyczki.

Kosinix
źródło
1
Co z użyciem: is_plugin_active ()? np .: if (is_plugin_active('path/to/plugin.php')) { // Do something }
TomC

Odpowiedzi:

35

Dzięki za odpowiedzi chłopaki. Chociaż obie odpowiedzi postawiły mnie na właściwej ścieżce, żadna nie wyszła z pudełka. Dlatego dzielę się moimi rozwiązaniami poniżej.

Metoda 1 - Użycie register_activation_hook:

Utwórz wtyczkę nadrzędną we wtyczkach / parent-plugin / parent-plugin.php:

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

Utwórz wtyczkę podrzędną we wtyczkach / wtyczce podrzędnej / wtyczce podrzędnej.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>');
    }
}

Zauważ, że nie używam, deactivate_plugins( $plugin );ponieważ z jakiegoś powodu to nie działa. Użyłem wp_die, aby anulować przekierowanie aktywacyjne i poinformować użytkownika.

Korzyść:

  • Proste rozwiązanie i nie powoduje dodatkowych trafień db w porównaniu z metodą 2

Niedogodności:

  • ekran wp_die jest brzydki
  • Ekran wp_die nadal będzie wyświetlany, jeśli aktywowałeś wtyczkę nadrzędną i wtyczkę podrzędną w tym samym czasie, korzystając z pól wyboru na ekranie administratora wtyczek.

Metoda 2 - Korzystanie z admin_init i admin_notices

Utwórz wtyczkę nadrzędną we wtyczkach / parent-plugin / parent-plugin.php:

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

Utwórz wtyczkę podrzędną we wtyczkach / wtyczce podrzędnej / wtyczce podrzędnej.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
}

Korzyść:

  • Działa, gdy aktywujesz wtyczkę Parent i Child w tym samym czasie za pomocą pól wyboru

Niekorzyść:

  • Podaj dodatkowe trafienia db, ponieważ wtyczka jest faktycznie aktywowana na początku i dezaktywowana po uruchomieniu admin_init.

Jeśli chodzi o moje pytanie dotyczące wyłączenia linku aktywacyjnego, mogę użyć:

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

Okazało się to jednak bardzo niepraktyczne, ponieważ nie ma miejsca na umieszczenie tego kodu. Nie mogłem umieścić go we wtyczce nadrzędnej, ponieważ wtyczka nadrzędna powinna być aktywna, aby ten kod działał. Z pewnością nie należy do wtyczki potomnej ani funkcji. Php. Więc złomuję ten pomysł.

Kosinix
źródło
1
Metoda 2 działała świetnie! Użyłem go do rozszerzenia wtyczki innej osoby.
Collin Price
2

Wypróbuj to, jest to skomentowane, aby pomóc Ci to zrozumieć.

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

Jeśli spowoduje to błąd, możesz również zaznaczyć opcję „myplugin” i ustawić ją na false lub nie aktywować.

MrJustin
źródło
2

Oba sugerowane rozwiązania mają wady.

Metoda 1: Jak wspomniano, ekran wp_die () nadal będzie wyświetlany, gdy wtyczka nadrzędna i wtyczka podrzędna zostaną aktywowane w tym samym czasie przy użyciu pól wyboru na ekranie administratora wtyczek.

Metoda 2: W niektórych przypadkach użycia nie jest to dobre, ponieważ „admin_init” jest wykonywany po „plugins_loaded” ( https://codex.wordpress.org/Plugin_API/Action_Reference ) i po haku deinstalacyjnym ( https: // codex. wordpress.org/Function_Reference/register_uninstall_hook ). Na przykład, jeśli chcemy, aby dodatek uruchamiał jakiś kod podczas dezinstalacji, niezależnie od tego, czy wtyczka nadrzędna jest aktywna, czy nie, to podejście NIE zadziała.

Rozwiązanie:

Przede wszystkim musimy dołączyć następujący kod na końcu głównego pliku PHP wtyczki nadrzędnej:

do_action( 'my_plugin_loaded' );

Spowoduje to wysłanie zdarzenia / sygnału do wszystkich subskrybentów, informując, że wtyczka została załadowana.

Następnie klasa dodatku powinna wyglądać następująco:

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

Mam nadzieję, że to pomoże :)

vovafeldman
źródło
4
Ta odpowiedź ma również wadę. :-) Zakłada się, że masz pełną kontrolę nad wtyczką nadrzędną, do której możesz dodać do działań ('my_plugin_loaded'); w swoim kodzie. Wybrana odpowiedź będzie działać z kontrolą nad wtyczką nadrzędną lub bez niej (np. Wtyczka nadrzędna nie jest twoja)
kosinix
Dziękuję, właśnie tego szukałem. W moim przypadku, zrobić mieć pełną kontrolę nad pluginem macierzystej, a potrzebne do stworzenia tego rodzaju uzależnienia.
cr0ybot,
0

Myślę, że potrzebujesz aktywacji wtyczki TGM .

Aktywacja wtyczek TGM to biblioteka PHP, która pozwala łatwo wymagać lub polecać wtyczki do motywów WordPress (i wtyczek). Pozwala użytkownikom instalować, aktualizować, a nawet automatycznie aktywować wtyczki pojedynczo lub zbiorczo, używając rodzimych klas, funkcji i interfejsów WordPress. Możesz odwoływać się do dołączonych wtyczek, wtyczek z repozytorium wtyczek WordPress, a nawet wtyczek hostowanych gdzie indziej w Internecie.

Amir Hossein Hossein Zadeh
źródło
Zły link. Prawidłowy link tutaj
XedinUnknown