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.

플러그 할 수있는 함수에서만 실행되는 기회가 없기 때문에 하나는 "깨지기 쉬운"훅이라고 말할 가치가 있습니다.

그러나 초기화 때까지 기다릴 수없는 경우 ( @toscho 와 같은 )가 있습니다 .이 경우 선택의 여지가 없습니다.

비 호환성을 해결하는 유일한 방법은 경우에 따라 다릅니다.

대부분의 경우 작동 할 있는 솔루션 (bbPress / BuddyPress 포함)은 다음 대신 다음 기능을 사용하는 것입니다 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

_doing_it_wrong메시지 를 발행하기 전에 BuddyPress와 bbPress가 다른 것을 확인해야한다고 생각 합니다.

$ 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.