按标题或Meta以及Tax_Query参数进行查询以获得结果

时间:2022-02-23 作者:Subhojit Mukherjee

如果我使用以下代码,它将正常工作:

new WP_Query([
            \'post_status\'    => \'publish\',
            \'post_type\'      => "some_custom_post_type",
            \'orderby\'        => \'DATE\',
            \'order\'          => \'DESC\',
            \'facetwp\'        => true,
            \'posts_per_page\' => 15,
            \'paged\'          => $paged,
            \'_meta_or_title\'=> $_POST[\'query\'],
            \'meta_query\'    => array(
                \'relation\'      => \'OR\',
                array(
                    \'key\'       => \'some_meta_value1\',
                    \'value\'     => $_POST[\'query\'],
                    \'compare\'   => \'LIKE\',
                ),
                array(
                    \'key\'       => \'some_meta_value2\',
                    \'value\'     => $_POST[\'query\'],
                    \'compare\'   => \'LIKE\',
                ),
            )
        ])
但每当我使用tax_quey, 它不工作,例如:

new WP_Query([
                \'post_status\'    => \'publish\',
                \'post_type\'      => "some_custom_post_type",
                \'orderby\'        => \'DATE\',
                \'order\'          => \'DESC\',
                \'facetwp\'        => true,
                \'posts_per_page\' => 15,
                \'paged\'          => $paged,
                \'tax_query\'      => [[
                   \'taxonomy\' => \'some_taxonomy\',
                   \'terms\'    => [\'some_terms_slug\'],
                   \'field\'    => \'slug\',
                   \'operator\' => \'IN\',
                ]],
                \'_meta_or_title\'=> $_POST[\'query\'],
                \'meta_query\'    => array(
                    \'relation\'      => \'OR\',
                    array(
                        \'key\'       => \'some_meta_value1\',
                        \'value\'     => $_POST[\'query\'],
                        \'compare\'   => \'LIKE\',
                    ),
                    array(
                        \'key\'       => \'some_meta_value2\',
                        \'value\'     => $_POST[\'query\'],
                        \'compare\'   => \'LIKE\',
                    ),
                )
            ])
元查询修改器代码

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;
        });
    }
});
我需要过滤掉数据的元数据或标题,有什么建议吗?提前感谢

1 个回复
SO网友:Sally CJ

documentation:

apply_filters_ref_array( \'get_meta_sql\', string[] $sql, array $queries, string $type, string $primary_table, string $primary_id_column, object $context )

过滤元查询生成的SQL。

$type

(字符串)元的类型。可能的值包括但不限于“post”、“comment”、“blog”、“term”和“user”。

因此,因为像上面这样的钩子可以在一个页面上多次运行,这意味着可以为同一个post查询多次调用您的过滤器/闭包(即。WP_Query 打电话),然后你应该这样做if ( \'post\' === $type ) { modify the $sql[\'where\'] } 要修改WHERE 仅当元类型为post.

基本上在我测试了你的代码之后,我注意到if( 0 != $nr++ ) return $sql; 跳过了修改post元查询,而是修改了一个术语元查询,这意味着当钩子第一次调用闭包时,它是针对术语元查询的。

因此,这就解释了为什么每当我使用tax_query, 它不工作;。

How can you fix the issue

<更改add_filter( \'get_meta_sql\', function( $sql ) use ( $title )add_filter( \'get_meta_sql\', function( $sql, $queries, $type ) use ( $title ).

更改return $sql; });return $sql; }, 10, 3); (即,让上述闭包接受3个参数)。

然后更改if( 0 != $nr++ ) return $sql;if( \'post\' !== $type || 0 != $nr++ ) return $sql;

Additional Code

你可以使用get_meta_sql 单独使用,无需使用pre_get_posts 为添加筛选器get_meta_sql, 像这样:

add_filter( \'get_meta_sql\', \'my_get_meta_sql\', 10, 6 );
function my_get_meta_sql( $sql, $queries, $type, $primary_table, $primary_id_column, $context ) {
    // Check that it\'s a post meta type and that the main query object is an instance of WP_Query.
    if ( \'post\' === $type && $context instanceof WP_Query &&
        // And check that the _meta_or_title arg is set.
        ( $title = $context->get( \'_meta_or_title\' ) )
    ) {
        global $wpdb;

        $sql[\'where\'] = \'YOUR CODE..\';
    }

    return $sql;
}