Як зробити плагін вимагає іншого плагіна?


30

Я будую плагін, який додає додаткового функціоналу до основного плагіна. В ідеалі на екрані адміністрування плагінів посилання "активувати" повинно бути відключене і слід додати вбудовану примітку, яка сповіщає користувача спочатку встановити та активувати головний плагін, перш ніж він зможе використовувати поточний плагін.


1
Що з використанням: is_plugin_active ()? наприклад: if (is_plugin_active('path/to/plugin.php')) { // Do something }
TomC

Відповіді:


35

Дякую за відповіді, хлопці. Хоча обидві відповіді ставили мене на правильний шлях, жодна з них не вийшла. Тому я ділюсь своїми рішеннями нижче.

Спосіб 1 - Використання register_activation_hook:

Створіть батьківський плагін у плагінах / батьківських плагінах / батьківських плагінах.php:

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

Створіть дитячий плагін у плагінах / 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>');
    }
}

Зауважте, що я не використовую, deactivate_plugins( $plugin );оскільки чомусь це не працює. Тому я використав wp_die, щоб скасувати переадресацію активації та повідомити користувача.

Перевага:

  • Просте рішення і не спричиняє додаткових звернень на db порівняно з методом 2

Недоліки:

  • Екран wp_die некрасивий
  • Екран wp_die ВИНАГИ з’явиться, якщо ви одночасно активували батьківський плагін та дочірній плагін за допомогою прапорців на екрані адміністратора плагінів.

Спосіб 2 - Використання admin_init та admin_notices

Створіть батьківський плагін у плагінах / батьківських плагінах / батьківських плагінах.php:

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

Створіть дитячий плагін у плагінах / 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
}

Перевага:

  • Працює, коли ви одночасно активуєте плагін Parent and Child, використовуючи прапорці

Недолік:

  • Введіть додаткові хіти db, оскільки плагін насправді активується спочатку та деактивується, як тільки admin_init запускається.

Що стосується мого питання щодо відключення активаційного посилання, я можу використати:

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

Однак це виявилося вкрай непрактично, оскільки немає місця для цього коду. Я не зміг поставити його на батьківський плагін, оскільки батьківський плагін повинен бути активним для запуску цього коду. Безумовно, не належить до дочірніх плагінів або function.php. Тож я беру цю ідею.


1
Метод 2 чудово працював! Я використовував його для розширення чужого плагіна.
Ціна Колліна

2

Спробуйте це, це коментується, щоб це допомогло вам зрозуміти це.

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

Якщо це видаляє помилку, ви також можете перевірити "параметр" "myplugin" і встановити його на помилкове або не активоване.


2

Обидва запропоновані рішення мають вади.

Спосіб 1: Як згадувалося, екран wp_die () ВИНАГИ з’явиться, коли батьківський плагін та дочірній плагін активуються одночасно за допомогою прапорців на екрані адміністратора плагінів.

Спосіб 2. У деяких випадках використання це не добре, оскільки "admin_init" виконується після "plugins_loaded" ( https://codex.wordpress.org/Plugin_API/Action_Reference ) та після гачка для видалення ( https: // codex). wordpress.org/Function_Reference/register_uninstall_hook ). Наприклад, якщо ми хочемо, щоб надбудова запустила якийсь код при видаленні, чи активний батьківський плагін чи ні, такий підхід НЕ працює.

Рішення:

Перш за все, нам потрібно додати наступний код до кінця головного PHP-файлу батьківського плагіна:

do_action( 'my_plugin_loaded' );

Це відправить подію / сигнал усім підписникам, повідомляючи, що основний плагін завантажений.

Тоді клас надбудови повинен виглядати наступним чином:

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

Сподіваюся, це допомагає :)


4
У цій відповіді є і вада. :-) Передбачається, що ви маєте повний контроль над батьківським плагіном, куди ви можете додати dogery ('my_plugin_loaded'); у своєму коді. Вибрана відповідь буде працювати з батьківським плагіном або без нього (наприклад, батьківський плагін не ваш)
kosinix

Дякую, саме це я шукав. У моєму випадку, я робити повний контроль над батьківським плагін, і необхідний для створення такого роду залежності.
cr0ybot

0

Я думаю, вам потрібна активація плагінів TGM .

Активація плагінів TGM - це бібліотека PHP, яка дозволяє легко вимагати або рекомендувати плагіни для ваших тем WordPress (та плагінів). Це дозволяє вашим користувачам встановлювати, оновлювати та навіть автоматично активувати плагіни в єдиному або масовому вигляді за допомогою рідних класів, функцій та інтерфейсів WordPress. Ви можете посилатися на комплектувані плагіни, плагіни з репозиторію плагінів WordPress або навіть плагіни, розміщені в інших місцях Інтернету.


Неправильне посилання. Правильне посилання тут
XedinUnknown
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.