สร้าง Search ของตัวเองด้วยฟิลเตอร์ posts_results

ได้โจทย์มาว่าเราจะต้องหาทางทำให้เราสามารถสร้าง Search ของเราเองได้ใน WordPress ความยากจะอยู่ที่ว่าทำอย่างไรเราถึงจะเอาผลลัพธ์ที่เราได้จากการ Search ไปแทรกก่อนที่ WordPress จะเอาผลลัพธ์นั้นไปแสดงผล

ตอนแรกนึกถึงฟิลเตอร์ pre_get_posts แต่มันไม่ได้ตอบโจทย์ที่เราตั้งไว้ เพราะว่า ฟิลเตอร์นี้เอาไว้ใช้ปรับแก้ตัว Query ของเรา ก่อนที่ WordPress จะเอา Query ไปประมวลผลจริงๆ ซึ่งผลลัพธ์จากการ Search สุดท้ายที่เราได้ มันก็จะมาจาก WordPress อยู่ดี

ได้คุยกับ Alex คนให้โจทย์นี้ เค้าได้ไปเจอปลั๊กอินตัวหนึ่งชื่อ Lift: Search for WordPress เป็นปลั๊กอินที่เอา Amazon CloudSearch มาใช้ใน WordPress ซึ่งดูๆ แล้วก็น่าจะพอเป็นแนวทางให้เราได้ หลังจากได้ไปลองดูโค้ดมาคร่าวๆ ก็ได้เห็นว่าเค้าใช้ฟิลเตอร์ posts_results ปัญหาต่อมาคือ.. ฟิลเตอร์นี้ไม่มีคนเขียนไว้ใน Codex โอ้ เย..

ฟิลเตอร์ posts_results อยู่ที่ไฟล์ /wp-includes/query.php ที่บรรทัด 3273--3281 ตามนี้

/**
 * Filter the raw post results array, prior to status checks.
 *
 * @since 2.3.0
 *
 * @param array $posts The post results array.
 * @param WP_Query &$this The WP_Query instance (passed by reference).
 */
$this->posts = apply_filters_ref_array( 'posts_results', array( $this->posts, &$this ) );

เค้าบอกว่าฟิลเตอร์นี้จะทำก่อนที่จะเช็คสถานะของโพสต์ ตรงตามที่เราต้องการเลย เพราะว่าการเช็คสถานะของโพสต์จะเป็นขั้นตอนท้ายๆ ก่อนที่ WordPress จะแสดงผลออกมาทางหน้าเว็บ 😀

ฟิลเตอร์นี้จะรับ 2 อาร์กิวเมนต์คือ โพสต์ และ $wp_query (เป็น WP_Query object) ดังนั้นวิธีสร้าง Search ของตัวเอง (จริงๆ ก็เอาไปทำอย่างอื่นได้นอกเหนือจาก Search นะ) ทำได้ดังนี้

add_filter( 'posts_results', 'override_search_results', 10, 2 );
function override_search_results( $posts, $wp_query ) {
    if ( $wp_query->is_search ) {
        // ทำอะไรก็ได้ แล้วเซตค่าผลลัพธ์ของ Search ของเรากลับเข้าไปที่ $posts
    }
    return $posts;
}

พอเราทำแบบนี้แล้ว $posts ที่ส่งกลับออกมาจากฟังก์ชั่นนี้จะเป็นผลลัพธ์ที่ได้จาก Search ของเราเอง แล้วหน้าอื่นที่ไม่เกี่ยวกับ Search ก็จะทำงานปกติ เพราะเราเขียนฟังก์ชั่นเพื่อให้ทำงานเฉพาะเวลาที่เรา Search เท่านั้น

หวังว่าจะเป็นประโยชน์ต่อคนที่อยากเขียนปลั๊กอิน Search มาแทนของ WordPress นะครับ 😀 แต่อย่างไรก็ดี สำหรับคนที่ไม่ได้อยากจะเขียนปลั๊กอินมาแทน ผมอยากแนะนำว่าให้ลองฟิลเตอร์อื่นก่อน ไม่งั้นถ้าเราอยากได้ผลลัพธ์อะไรเราก็ใช้ฟิลเตอร์นี้ แล้วมันอาจจะทำให้เรามักง่ายโดยไม่รู้ตัว >_<

หมายเหตุ โค้ดข้างต้นผ่านการทดสอบกับแค่ WordPress เวอร์ชั่น 3.9.2 เท่านั้น แต่ก็คิดว่าสามารถนำไปใช้กับเวอร์ชั่นใหม่ๆ ในอนาคตได้เช่นกัน


Kan Ouivirach

Kan Ouivirach

Lead Software Architect

Being interested in Agile software development, I joined an Agile team at Pronto Tools as a Research & Development Architect (as Lead Software Architect now). I am an enthusiastic architect who not only has a scientific mindset, but also a practical approach to software solutions.