current_user_can()および関連する関数を使用する有効なタイミングは何ですか?


10

通常のWPコアのロード中に、現在のユーザーがセットアップされて$wp-init()initます。テーマのロード後、フック前です。これは、機能に慣れる、initまたは後で慣れるのと同じです。

ただし、それcurrent_user_can() より前など、関連する関数を呼び出すことも一般的です。これは、ロードプロセスの初期段階で動作するプラグインに必要な定義です(私のツールバーテーマスイッチャープラグインがその例です)。

ドキュメンテーションは、(私が見つけることができた)この慣行に対する賛成も反対もしません。

ただし、一部のプラグインはユーザー関連の機能にフックしinit、常にポスト状態を期待するようです。

たとえば、bbPressは次の通知をスローします。

// If the current user is being setup before the "init" action has fired,
// strange (and difficult to debug) role/capability issues will occur.
if ( ! did_action( 'after_setup_theme' ) ) {
    _doing_it_wrong( __FUNCTION__, __( 'The current user is being initialized without using $wp->init().', 'bbpress' ), '2.3' );
}

簡単なデモンストレーションのために、これをコアの定義に入れcurrent_user_can()ます:

function current_user_can( $capability ) {

    if ( ! did_action('after_setup_theme') ) {
        echo wp_debug_backtrace_summary();
    }

この状況で誰が「正しい」のでしょうか。以前にユーザー関連機能の許可/禁止の使用についての正式な決定はありinitますか?


回答:


7

の唯一の前提条件current_user_can()は、既存のwp_get_current_user()です。後者はで定義されているpluggable.phpため、後で使用できますplugins_loaded

_doing_it_wrong()あなたは、あなたの質問に引用されているコールは、自分自身のために間違っています。私の推測では、BuddyPressまたはbbPressからそれを取得したと思います。どちらもそれほど長く待たなければ、再帰に直面しています。再帰を防ぐ他のより良い方法があります。

場合によっては、ロケールの変更などのように、現在のユーザーオブジェクトに早くアクセスする必要があるため、待機するafter_setup_themeこともできません。



2

以前にユーザー機能を確認した場合、現在のユーザーオブジェクトの設定に責任があるinit可能性があることを意味します。

initにユーザーアクセスする場合、他の何かがすでにユーザーを設定していることが確実です。ほとんどの場合、それ自体がコアです。

これが、後でユーザーにアクセスすることinit安全と見なされる理由です。

実際、早期アクセスは、で実行されているフィルタを壊す可能性がありますdetermine_current_user

プラグイン可能な関数でのみ実行され、実行されない可能性があるため、1つは「壊れやすい」フックであると言う価値があります。

ただし、(@ toschoが言ったように)初期化するまで待てない場合があり、そのような場合には選択の余地がありません。

非互換性を解決する唯一の方法は、状況に応じてケースバイケースです。

溶液できる(bbPress /バディを含む)ほとんどの場合、動作は、関数を次の代わりに使用することですcurrent_user_can

function compat_current_user_can( $capability )
{
  if ( did_action( 'init' ) ) {
     return current_user_can( $capability );
  }

  $user_id = apply_filters( 'determine_current_user', false );

  return user_can( $user_id, $capability );
}

これにより、グローバルユーザーを設定せずに現在のユーザー機能を早期に確認できるため、理論上は前に実行しても安全initです。

問題は、前述のように、プラグ可能な関数をオーバーライドし、起動しないコードは、determine_current_userそれを壊すことです。


あなたの関数には、めちゃくちゃになってしまった変数があると思います。:)
Rarst

はい...夕食前に入力が速すぎました:P修正のために@ialocinに感謝します。
gmazzap

それについては触れないでください。何が問題なのかを単に言うのではなく、@ Rarstを修正してください:)
Nicolai

1

BuddyPressとbbPressは_doing_it_wrongメッセージを発行する前に他のものをチェックするべきだと思う傾向があります

$ current_userの実際の設定もチェックするように、両方のルーチンを変更しました。

global $current_user; 
if ( is_null( $current_user ) ) {
    _doing_it_wrong( ... );
}

通知は表示されなくなりました。

のテストはdid_action( "after_setup_theme" )、ベルトと一緒に使用するブレースになります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.