Bagaimana cara membuat plugin membutuhkan plugin lain?

30

Saya sedang membangun sebuah plugin yang menambahkan fungsionalitas tambahan ke sebuah plugin utama. Idealnya di layar administrasi plugin, tautan "aktifkan" harus dinonaktifkan dan catatan sebaris harus ditambahkan yang memberi tahu pengguna untuk menginstal dan mengaktifkan plugin utama terlebih dahulu sebelum ia dapat menggunakan plugin saat ini.

kosinix
sumber
1
Bagaimana dengan menggunakan: is_plugin_active ()? misal: if (is_plugin_active('path/to/plugin.php')) { // Do something }
TomC

Jawaban:

35

Terima kasih atas jawabannya kawan. Meskipun kedua jawaban itu menempatkan saya di jalan yang benar, tidak ada yang berhasil. Jadi saya membagikan solusi saya di bawah ini.

Metode 1 - Menggunakan register_activation_hook:

Buat Plugin Induk di plugins / parent-plugin / parent-plugin.php:

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

Buat Child Plugin di 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>');
    }
}

Perhatikan bahwa saya tidak menggunakan deactivate_plugins( $plugin );karena beberapa alasan tidak berfungsi. Jadi saya menggunakan wp_die untuk membatalkan pengalihan aktivasi dan memberi tahu pengguna.

Keuntungan:

  • Solusi sederhana dan tidak menimbulkan hit db tambahan dibandingkan dengan metode 2

Kekurangan:

  • Layar wp_die jelek
  • Layar wp_die akan MASIH muncul jika Anda mengaktifkan Plugin Induk dan Plugin Anak secara bersamaan menggunakan kotak centang di layar admin plugin.

Metode 2 - Menggunakan admin_init dan admin_notices

Buat Plugin Induk di plugins / parent-plugin / parent-plugin.php:

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

Buat Child Plugin di 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
}

Keuntungan:

  • Bekerja ketika Anda mengaktifkan plugin Parent and Child secara bersamaan menggunakan kotak centang

Kerugian:

  • Hasilkan tambahan db karena plugin sebenarnya diaktifkan pada awalnya dan dinonaktifkan setelah admin_init berjalan.

Adapun pertanyaan saya tentang menonaktifkan tautan aktif, saya dapat menggunakan:

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

Namun, ternyata sangat tidak praktis karena TIDAK ada tempat untuk meletakkan kode ini. Saya tidak bisa meletakkannya di plugin induk karena plugin induk harus aktif untuk menjalankan kode ini. Tentu saja bukan milik plugin anak atau functions.php. Jadi saya membatalkan ide ini.

kosinix
sumber
1
Metode 2 bekerja dengan sangat baik! Saya menggunakannya untuk memperluas plugin orang lain.
Harga Collin
2

Coba ini, ini dikomentari, sehingga akan membantu Anda memahaminya.

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

Jika ini menghasilkan kesalahan, Anda juga dapat memeriksa 'opsi' dari 'myplugin' dan mengaturnya ke false atau tidak diaktifkan.

TuanJustin
sumber
2

Kedua solusi yang disarankan memiliki kekurangan.

Metode 1: Seperti yang disebutkan, layar wp_die () akan MASIH muncul ketika Plugin Induk dan Plugin Anak diaktifkan secara bersamaan menggunakan kotak centang di layar admin plugins.

Metode 2: Dalam beberapa kasus penggunaan, ini tidak baik karena 'admin_init' dieksekusi dengan cara setelah 'plugins_loaded' ( https://codex.wordpress.org/Plugin_API/Action_Reference ), dan setelah kait penghapusan instalasi ( https: // codex. wordpress.org/Function_Reference/register_uninstall_hook ). Jadi misalnya, jika kita ingin add-on untuk menjalankan beberapa kode pada penghapusan instalasi apakah plugin induk aktif atau tidak, pendekatan ini TIDAK akan berfungsi.

Larutan:

Pertama-tama, kita perlu menambahkan kode berikut ke akhir file PHP utama induk plugin:

do_action( 'my_plugin_loaded' );

Ini akan mengirimkan acara / sinyal ke semua pelanggan, dengan mengatakan bahwa plugin inti telah dimuat.

Maka, kelas add-on akan terlihat seperti berikut:

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

Semoga bisa membantu :)

vovafeldman
sumber
4
Jawaban ini juga memiliki kekurangan. :-) Diasumsikan bahwa Anda memiliki kendali penuh atas plugin induk tempat Anda dapat menambahkan do_action ('my_plugin_loaded'); dalam kodenya. Jawaban yang dipilih akan bekerja dengan atau tanpa kendali dari plugin induk (mis. Plugin induk bukan milik Anda)
kosinix
Terima kasih, inilah tepatnya yang saya cari. Dalam kasus saya, saya lakukan memiliki kontrol penuh atas plugin orang tua, dan dibutuhkan untuk menghasilkan ini ketergantungan.
cr0ybot
0

Saya pikir Anda perlu Aktivasi Plugin TGM .

Aktivasi Plugin TGM adalah perpustakaan PHP yang memungkinkan Anda untuk dengan mudah memerlukan atau merekomendasikan plugin untuk tema WordPress Anda (dan plugin). Ini memungkinkan pengguna Anda untuk menginstal, memperbarui, dan bahkan secara otomatis mengaktifkan plugin dalam mode tunggal atau massal menggunakan kelas, fungsi, dan antarmuka WordPress asli. Anda dapat merujuk plugin yang dibundel, plugin dari Repositori Plugin WordPress atau bahkan plugin yang diinangi di tempat lain di internet.

Amir Hossein Hossein Zadeh
sumber
Tautan salah. Tautan yang benar di sini
Xedin Tidak diketahui