web-dev-qa-db-ja.com

どのようにそのプラグインから個々の関数を呼び出すときにPHPの条件文を使用せずにプラグインをwpテーマで必須にするか?

私のWordpressテーマの1つは、正しく動作するためにいくつかのサードパーティ製プラグインを必要とします。

ほとんどの場合、私はサードパーティ製のプラグインから次のような条件文を使って関数を呼び出していました。

    if(function_exist('plugin_function')) {
             plugin_function() // do something
    }

テーマの多くのファイルで1つのプラグインを広く使用する必要があるとします。多くのIF条件を使用しないようにしたいのですが…特定のプラグインをWPにインストールする必要があります。 _またはテーマをアクティブにする前にそれらが見つからない場合はさらにそれらをインストールしますか?

ありがとう

8
unfulvio

is_plugin_active()はやや壊れやすいです:プラグインの作者がメインファイルの名前を変更したり、ユーザーがプラグインのディレクトリやメインファイルの名前を変更したりすると壊れます。特定の公共機能が存在するかどうかを確認することをお勧めします。

プラグインの機能の一部が必要になるたびにこのチェックを行わなくても済むようにするには、管理領域にメッセージを表示します。

add_action( 'admin_notices', 'my_theme_dependencies' );

function my_theme_dependencies() {
  if( ! function_exists('plugin_function') )
    echo '<div class="error"><p>' . __( 'Warning: The theme needs Plugin X to function', 'my-theme' ) . '</p></div>';
}

もう一つの選択肢は http://tgmpluginactivation.com/ /のようなものを使うことです。

6
scribu

これは、プラグインが無効になっているときにテーマが壊れるのを防ぐことはできませんが、 "必須テーマの管理者向け通知を表示する方法" pluginについてのこの素朴な記事を見てください。 を強制する プラグインをインストールするという考え方に慣れたことは一度もないので、これが次善の策のようです。

もう一つの簡単な考え:私はこれを試したことがありませんが、単一の条件式で複数のフックを収容するための賢い方法を考え出すことができるかどうか疑問に思います。おそらく、if( function_exists( 'plugin_function' ) )trueを返す場合に限り、すべての条件付き関数を別のファイルに分割して必要とする可能性があります(これは不完全なチェックであることを理解した上で)。

1
mrwweb

注:この回答は@scribuと@kaiserの間の議論を容易にするためのものです。改造:削除しないでください。ユーザー/読者:投票しないでください。あなたが議論に従うことを望むなら、改訂/編集ログを見てください。あなたが議論に加わりたいなら、答えを編集してください。議論が結果を持っているなら、それはそのようにマークされるでしょう。ありがとうございます。


シナリオ

あなたがプラグインの依存関係を持っている可能性がある場合は、重みが異なるさまざまなシナリオもあります。 (例は架空のものです)。 「(parent)Plugin」という単語は、親の観点からは「Theme」と交換できます。

  1. (hard)機能を拡張するか、既存のプラグインの表示(および同様のもの)を変更するだけなので、親なしでは存在できない子プラグイン。 例: BuddyPress"BuddyPress-FunkyCommentDisplay
  2. (通常)子プラグインがアクティブになったときに機能が拡張されたプラグイン。 例: jQueryAttachmentCarousel"jQuerySlideDeck
  3. (ソフト)機能を追加するだけのプラグイン。 例: DisneyWonderlandTheme"ミッキーソーシャルリンク

以下では、 "other"プラグインを更新したときに何が起きるのかをスケッチしてみましたが、チェックはもううまくいきません。

  • 広告1)BuddyPressが有効になっていないとプラグインは存在できません"スタッフは完全に壊れています。
  • 広告2)プラグインは、カルーセルからSlideDeckへの切り替えオプションを提供できませんでした"有線ディスプレイ(私はスタイルがSlideDeckに変更されると仮定します)。
  • 広告3)MickeysSocialLinksは消えます。

チェック

プラグインがアクティブかどうかを知りたい場合は、次の3つの方法で確認してください。

  • A.フォルダは存在しますか?
  • B.メインファイル - オプション'active_plugins' - は存在しますか?
  • C.特定の機能はありますか?

私が今、 Internal Link Checker Plugin を例にとると、それはパブリックAPIを提供せず、拡張することを意図していないのであれば、内部関数の命名をオンデマンドで変更しない理由はありません。またはただ意志で。そのため、誰かがこのプラグインに便乗しようとすると、アップデート時に(機能とバンドルの厳しさに応じて)機能が壊れてしまいます。ファイル名についても同様です。ファイル名を変更しないという本当の理由はありません(更新時にプラグインが無効になることを除けば)。フォルダ名を変更できないのは、更新チェックと通知がファイル名に対して実行されることだけです。公式リポジトリでホストされている場合はそれだけです。

だから私は(親)プラグインの最も弱い(変更するのが簡単な)部分から最も難しい(変更に対して反対の話をする)部分になるだろうと言うでしょう:

機能"メインファイル名"フォルダ


関数チェックはis_plugin_active()を使うよりも壊れにくいと言ったとき、問題の関数はプラグインの作者が明示的に推奨しているものだと思いました。この最終的な例は、WP-PageNaviプラグインによって提供されるwp_pagenavi()テンプレートタグです。

依存関係を定義するのが難しいのは、ファイル名を含まないプラグインを一意に識別する標準的な方法がないということです。

主題についてのさらなる考え:

http://wordpress.org/support/topic/plugin-plugin-dependencies-unreliable-plugin-namingidentifying-scheme


これまでのところ、3つの点にまとめることができると思います。

  • 少し異なる話題について話しました
  • 私たちは、私がそのトピックがあると思ったことを回避するための完璧な方法がないことに同意します
  • 質問に対するあなたの理解から、あなたは行くための有効な方法を提供しました

私が考えることができる(今のところ)最も賢い方法、私はすでにいくつかの(はるかに少ない)プラグインで見たことがある:

// inside the plugin file:
add_action( 'plugin_custom_hook', 'plugin_trigger' );
// inside some template:
do_action( 'plugin_custom_hook' );

あまり詳細に考えなくても、 'all'フィルタのチェックに注意を喚起し、 current filter の内側にチェックを入れてshutdownフックをオンにしたときにトリガされるのであればよいのでしょうか。


フックを使用すると、「通常」と「弱い」依存関係に適しています。唯一の欠点は、依存関係が満たされていない場合に停止したい場合は、function_exists()またはis_plugin_active()を使用する必要があることです。そのために 'all'フィルタを使用すると、IMOが高すぎます。

@scibuこれは「あなたの」トピックを対象としていました。 (私はすでに私のことについて話すのをやめました)。 :)

つまり基本的に、もしあなたが依存関係を必要としていて - そしてあなたがNice作者を持っているなら - そして彼は代わりに/テンプレートタグの代わりとしてフックを提供することができます。フックが存在する場合にのみプラグインがそれにフックするか、または単に何もしないためです。そして反対に、プラグインが存在しなくてもエラーにはなりません。

これは難しい部分です(またはQの詳細):依存関係についてユーザーに通知するための管理者通知を作成するには、「"DisneyWonderLinks"をインストールする必要があります」とarray_keys( $GLOBALS['wp_filter']['template_tag_like_hook'] )を確認できます。これでうまくいくかどうかはわかりませんが、配列が(public/admin)両側からアクセスできるようにする必要があります。


それはうまくいかないでしょう。コールバックがフックに登録されているからといって、そのフックが予期されたときにトリガーされるという意味ではありません。ある種の仕事になるだろう唯一のことはあなたが以前に述べた 'shutdown'フックを使うことです:

add_action( 'shutdown', function() {
  if ( !did_action( 'template_tag_like_hook' ) )
    echo 'Problem.';
} );

もちろん、これは一番下のフロントエンドの</html>タグの後ろに印刷されます(テンプレートタグが通常使用される場所です)ので、あまり役に立ちません。

メッセージをwp_optionsに保存してから管理領域に表示しようとすることもできますが、無効化、キャッシュプラグインなど、まったく新しいワームの可能性が開かれます。

0
kaiser

プラグインページだけが必要な場合は、 is_plugin_active() があります。あなたがそれを外で必要とするならば、あなたはあなたの主題に中心的な機能をコピーして貼り付けて、それからそれを再利用するべきです:

if ( ! is_admin() )
{
/**
 * Check whether the plugin is active by checking the active_plugins list.
 *
 * @since 2.5.0
 *
 * @param string $plugin Base plugin path from plugins directory.
 * @return bool True, if in the active plugins list. False, not in the list.
 */
function is_plugin_active( $plugin ) {
    return in_array( $plugin, (array) get_option( 'active_plugins', array() ) ) || is_plugin_active_for_network( $plugin );
}
}

条件付きは、関数を二重に定義することでエラーを回避します。

0
kaiser