เวลาที่ถูกต้องในการใช้ current_user_can () และฟังก์ชั่นที่เกี่ยวข้องคืออะไร?


10

ในระหว่างการโหลดแกน vanilla WP ผู้ใช้ปัจจุบันจะถูกตั้งค่า$wp-init()ซึ่งอยู่หลังโหลดธีมและก่อนinitฮุก สิ่งนี้สอดคล้องกับแนวปฏิบัติที่ดีในการใช้งานฟังก์ชั่นที่จะเชื่อมinitต่อหรือใหม่กว่า

อย่างไรก็ตามมันก็เป็นเรื่องธรรมดาที่จะเรียกฟังก์ชั่นที่เกี่ยวข้องเช่นcurrent_user_can() ก่อนหน้านั้น มันเป็นข้อกำหนดที่จำเป็นสำหรับปลั๊กอินที่ทำงานกับขั้นตอนการโหลดก่อนหน้านี้ (ปลั๊กอิน Toolbar Theme Switcher ของฉันจะเป็นตัวอย่าง)

เอกสารทำให้ไม่มีการเรียกร้องหรือต่อต้านการปฏิบัตินี้ (ที่ฉันสามารถหาได้)

อย่างไรก็ตามปลั๊กอินบางตัวดูเหมือนจะเชื่อมโยงเข้ากับฟังก์ชั่นที่เกี่ยวข้องกับผู้ใช้และคาดว่าจะมีการโพสต์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' );
}

สำหรับการสาธิตอย่างรวดเร็วให้คำจำกัดความของ core 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.phpplugins_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ความปลอดภัยที่จะทำงานก่อน

ปัญหาคือว่าในขณะที่กล่าวข้างต้นรหัสใด ๆ ที่ฟังก์ชั่นการแทนที่ pluggable และไม่ได้ยิงdetermine_current_userแบ่งมัน


ฉันคิดว่าฟังก์ชั่นของคุณมีตัวแปรที่ทำให้เกิดความสับสน :)
Rarst

ใช่ ... พิมพ์เร็วเกินไปก่อนอาหารเย็น: P ขอบคุณ @ialocin สำหรับการแก้ไข
gmazzap

อย่าพูดถึงมัน นอกจากอย่าเพิ่งบอกว่ามีอะไรผิดพลาดให้แก้ไข @Rarst :)
นิโคไล

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.