web-dev-qa-db-ja.com

プラグインに別のプラグインを要求させる方法は?

メインプラグインに機能を追加するプラグインを作成しています。理想的には、プラグイン管理画面で、「アクティブ化」リンクを無効にし、現在のプラグインを使用する前にメインプラグインを最初にインストールしてアクティブ化するようにユーザーに指示するインラインメモを追加する必要があります。

26
kosinix

答えてくれてありがとう。両方の答えが私を正しい道に導いたけれども、誰も箱から出してうまくいかなかった。だから私は私の解決策を以下で共有しています。

方法1 - register_activation_hookを使用する

Plugins/parent-plugin/parent-plugin.phpに親プラグインを作成します。

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

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

私はdeactivate_plugins( $plugin );を使用していないことに注目してください。そのため、wp_dieを使用してアクティブ化のリダイレクトをキャンセルし、ユーザーに通知しました。

利点:

  • 簡単な解決方法で、方法2と比較して追加のdbヒットは発生しません。

デメリット:

  • wp_die画面が見苦しい
  • プラグイン管理画面のチェックボックスを使用して、親プラグインと子プラグインを同時に有効にした場合は、wp_die画面が表示されたままになります。

方法2 - admin_initとadmin_noticesを使用する

Plugins/parent-plugin/parent-plugin.phpに親プラグインを作成します。

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

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
}

利点:

  • チェックボックスを使用して、親と子のプラグインを同時にアクティブ化したときに機能します。

不利益:

  • プラグインは実際には最初にアクティブ化され、admin_initが実行されると非アクティブ化されるため、追加のdbヒットが発生します。

アクティブリンクを無効にすることに関する私の質問に関しては、私は使用することができます:

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

しかし、このコードを置く場所がないため、非常に実用的ではないことがわかりました。このコードを実行するには、親プラグインがアクティブになっている必要があるため、親プラグインには配置できませんでした。確かに子プラグインやfunctions.phpに属していません。だから私はこのアイデアを廃止しました。

33
kosinix

これを試してください、それはコメントされています、それであなたはそれを理解するのを助けるべきです。

<?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'の 'option'をチェックしてfalseに設定するか、またはアクティブにしないでください。

2
MrJustin

両方の提案された解決策には欠陥があります。

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

それが役に立てば幸い :)

2
vovafeldman

あなたはTGM Plugin Activationが必要だと思います。

TGMプラグインのアクティブ化 は、WordPressテーマ用のプラグイン(およびプラグイン)を簡単に要求または推奨することを可能にするPHPライブラリです。それはあなたのユーザーがネイティブのWordPressクラス、機能およびインターフェースを使用して単数または一括方式でプラグインをインストール、更新そしてさらには自動的にアクティブにすることさえ可能にします。バンドルされているプラ​​グイン、WordPressプラグインリポジトリからのプラグイン、あるいはインターネット上の他の場所でホストされているプラ​​グインさえも参照できます。