วิธีทำปลั๊กอินต้องใช้ปลั๊กอินอื่น?


30

ฉันกำลังสร้างปลั๊กอินที่เพิ่มฟังก์ชันการทำงานพิเศษให้กับปลั๊กอินหลัก ในหน้าจอการจัดการปลั๊กอินควรเปิดใช้งานลิงก์ "เปิดใช้งาน" และควรเพิ่มข้อความแบบอินไลน์ที่บอกให้ผู้ใช้ติดตั้งและเปิดใช้งานปลั๊กอินหลักก่อนที่เขา / เธอจะสามารถใช้ปลั๊กอินปัจจุบันได้


1
สิ่งที่เกี่ยวกับการใช้: is_plugin_active ()? เช่น: if (is_plugin_active('path/to/plugin.php')) { // Do something }
TomC

คำตอบ:


35

ขอบคุณสำหรับคำตอบพวก แม้ว่าคำตอบทั้งสองจะกำหนดให้ฉันบนเส้นทางที่ถูกต้อง แต่ก็ไม่มีใครทำงานนอกกรอบได้ ดังนั้นฉันจึงแบ่งปันวิธีแก้ปัญหาด้านล่าง

วิธีที่ 1 - การใช้ register_activation_hook:

สร้างปลั๊กอินหลักในปลั๊กอิน / parent-plugin / parent-plugin.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

สร้างปลั๊กอินหลักในปลั๊กอิน / parent-plugin / parent-plugin.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
}

ความได้เปรียบ:

  • ทำงานเมื่อคุณเปิดใช้งานปลั๊กอินผู้ปกครองและเด็กพร้อมกันโดยใช้ช่องทำเครื่องหมาย

ข้อด้อย:

  • รับ db hits เพิ่มเติมเนื่องจากปลั๊กอินถูกเปิดใช้งานจริงในตอนแรกและปิดใช้งานเมื่อ 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;
}

อย่างไรก็ตามมันกลับกลายเป็นว่าทำไม่ได้อย่างมากเนื่องจากไม่มีที่สำหรับใส่รหัสนี้ ฉันไม่สามารถวางลงในปลั๊กอินผู้ปกครองได้เนื่องจากปลั๊กอินหลักควรใช้งานได้เพื่อให้โค้ดนี้ทำงาน ไม่ได้เป็นของปลั๊กอินลูกหรือฟังก์ชั่น. php แน่นอน ดังนั้นฉันจึงทิ้งความคิดนี้


1
วิธีที่ 2 ทำงานได้ดีมาก! ฉันใช้มันเพื่อขยายปลั๊กอินของคนอื่น
Collin ราคา

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 หลักของ parent parent:

do_action( 'my_plugin_loaded' );

สิ่งนี้จะส่งเหตุการณ์ / สัญญาณไปยังสมาชิกทั้งหมดโดยบอกว่ามีการโหลดปลั๊กอินหลัก

จากนั้นคลาสของ Add-on ควรมีลักษณะดังต่อไปนี้:

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
คำตอบนี้มีข้อบกพร่องเช่นกัน :-) สมมติว่าคุณมีการควบคุมปลั๊กอินหลักซึ่งคุณสามารถเพิ่ม do_action ('my_plugin_loaded'); ในรหัส คำตอบที่เลือกจะทำงานโดยมีหรือไม่มีการควบคุมของผู้ปกครองปลั๊กอิน (เช่นปลั๊กอินผู้ปกครองที่ไม่ได้เป็นของคุณ)
kosinix

ขอบคุณนี่คือสิ่งที่ฉันกำลังมองหา ในกรณีที่ผมทำมีการควบคุมเต็มรูปแบบผ่านปลั๊กอินแม่และจำเป็นในการสร้างชนิดของการพึ่งพานี้
cr0ybot

0

ผมคิดว่าคุณต้องTGM ปลั๊กอินการเปิดใช้งาน

การเปิดใช้งานปลั๊กอิน TGMเป็นไลบรารี PHP ที่ช่วยให้คุณต้องการหรือแนะนำปลั๊กอินสำหรับธีม WordPress ของคุณ (และปลั๊กอิน) ได้อย่างง่ายดาย อนุญาตให้ผู้ใช้ของคุณติดตั้งอัปเดตและเปิดใช้งานปลั๊กอินโดยอัตโนมัติในแบบเอกพจน์หรือเป็นกลุ่มโดยใช้คลาส WordPress ฟังก์ชันและอินเทอร์เฟซ คุณสามารถอ้างอิงปลั๊กอินที่รวมมาจากปลั๊กอินจากที่เก็บปลั๊กอิน WordPress หรือแม้กระทั่งปลั๊กอินที่โฮสต์ไว้ที่อื่นบนอินเทอร์เน็ต


ลิงค์ผิด ลิงก์ที่ถูกต้องที่นี่
XedinUnknown
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.