یکی از مشکلات یا محدودیتهای کلاس WP_Query این هست که امکان جستجوی فصلی غیروابسته (منفصل یا disjunctional) بین عنوان (متن، ...) و یک متا دلخواه وجود نداره.
با یک مثال توضیح میدم.
فرض کنید قصد داریم روی محصولاتی که عنوانشون یا متافیلد brand شامل کلمه «سامسونگ» هست کوئری کنیم. به طور طبیعی احتمالا این قطعه کد رو مینویسیم:
$args = array( 'post_type' => 'product', 'post_status' => 'publish', 's' => 'سامسونگ', 'meta_query' => array( array( 'key' => 'brand', 'value' => 'سامسونگ', 'compare' => 'LIKE', ), ), ); $query = new WP_Query($args);
مشکل قطعه کد بالا اینه که وقتی پارامتر s و یک meta_query رو به عنوان ورودیهای WP_Query در نظر بگیریم، وردپرس به طور پیشفرض عملگر AND رو برای کوئری در نظر میگیره و عملاً فقط محصولاتی که هم عنوانشون و هم مِتاشون شامل «سامسونگ» هست جستجو میشه.
برای رفع این مشکل راهکار جالبی وجود داره. در این روش به جای پارامتر s، از پارامتر meta_or_title_ استفاده میکنیم و با استفاده از هوک pre_get_posts در قسمت WHERE گزاره sql یه تغییر کوچک به شکل زیر ایجاد میکنیم:
/// page.php $args = array( 'post_type' => 'product', 'post_status' => 'publish', '_meta_or_title' => 'سامسونگ', 'meta_query' => array( array( 'key' => 'brand', 'value' => 'سامسونگ', 'compare' => 'LIKE', ), ), ); $query = new WP_Query($args); /// /// functions.php /// add_action( 'pre_get_posts', function( $q ) { if ( $title = $q->get( '_meta_or_title' ) ) { add_filter( 'get_meta_sql', function( $sql ) use ( $title ) { global $wpdb; // Only run once: static $nr = 0; if( 0 != $nr++ ) return $sql; // Modified WHERE $sql['where'] = sprintf( " AND ( %s OR %s ) ", $wpdb->prepare( "{$wpdb->posts}.post_title like '%%%s%%'", $title), mb_substr( $sql['where'], 5, mb_strlen( $sql['where'] ) ) ); return $sql; }); } });
با این تغییر، عملگر OR بین دو شرط عنوان و متاکوئری قرار گرفته و نتیجه جستجو به شکل مطلوب خواهد بود.
شاد باشید :)