来自自定义字段的查询字符串参数,结果不一致

时间:2015-11-11 作者:lotech

我有一个自定义的帖子类型叫做course. 在课程帖子中,我有许多自定义字段,特别是(所有AFC select下拉列表):course_or_project, time_to_complete_project, time_to_complete_coursedifficulty. 我还有一个分类法叫做course_project_category.

我的目标是能够创建许多下拉列表/滑块,通过读取所述下拉列表/滑块的值并单击搜索按钮来构建URL,使用我组合的查询字符串(jQuery)来筛选正确的帖子。此功能完全正常。好有时结果有点混乱,即仅通过一些参数进行过滤。

转到代码。

我在中添加了一个函数以公开自定义字段:

function my_pre_get_posts( $query ) {

// do not modify queries in the admin
if( is_admin() ) {
    return $query;
}

// only modify queries for \'course\' post type
if( isset($query->query_vars[\'post_type\']) && $query->query_vars[\'post_type\'] == \'course\' ) {

    // allow the url to alter the query
    if( isset($_GET[\'course_or_project\']) ) {
        $query->set(\'meta_key\', \'course_or_project\');
        $query->set(\'meta_value\', $_GET[\'course_or_project\']);
    } 

    if( isset($_GET[\'time_to_complete_project\']) ) {
        $query->set(\'meta_key\', \'time_to_complete_project\');
        $query->set(\'meta_value\', $_GET[\'time_to_complete_project\']);
    } 

    if( isset($_GET[\'time_to_complete_course\']) ) {
        $query->set(\'meta_key\', \'time_to_complete_course\');
        $query->set(\'meta_value\', $_GET[\'time_to_complete_course\']);    
    } 

    if( isset($_GET[\'difficulty\']) ) {    
        $query->set(\'meta_key\', \'difficulty\');
        $query->set(\'meta_value\', $_GET[\'difficulty\']);
    } 

}

// return
return $query;

}

add_action(\'pre_get_posts\', \'my_pre_get_posts\');
查询分类法似乎是现成的。

因此,我完成的URL的一个示例可能是:

http://localhost:3000/courses/?course_project_category=jokes&course_or_project=project&difficulty=easy&time_to_complete_project=15
目前我的结果好坏参半。

从上面的查询中,我返回了2篇文章,它们大部分符合我的条件,但作为一个具体的例子,一篇文章有time_to_complete_project 值为30 即使指定了查询15.

我想不出来。通过Chrome开发工具,我可以看到所有参数都如预期的那样:

enter image description here

有什么想法吗?!

Update

我有一种新的方法正在发挥作用(但缺乏验证和卫生):

// array of filters (field key => field name)
    $GLOBALS[\'my_query_filters\'] = array( 
        \'field_1\'   => \'course_or_project\', 
        \'field_2\'   => \'difficulty\',
        \'field_3\'   => \'time_to_complete_project\',
        \'field_4\'   => \'time_to_complete_course\'
    );
// action

add_action(\'pre_get_posts\', \'my_pre_get_posts\', 10, 1);

function my_pre_get_posts( $query ) {

    // bail early if is in admin
    if( is_admin() ) {

        return;

    }

    if( isset($query->query_vars[\'post_type\']) && $query->query_vars[\'post_type\'] == \'course\' ) {

        // get meta query
        $meta_query = $query->get(\'meta_query\');


        // loop over filters
        foreach( $GLOBALS[\'my_query_filters\'] as $key => $name ) {

            // continue if not found in url
            if( empty($_GET[ $name ]) ) {

                continue;

            }


            // get the value for this filter
            // eg: http://www.website.com/events?city=melbourne,sydney
            $value = explode(\',\', $_GET[ $name ]);


            // append meta query
            $meta_query[] = array(
                \'key\'       => $name,
                \'value\'     => $value,
                \'compare\'   => \'IN\',
            );

        } 


        // update meta query
        $query->set(\'meta_query\', $meta_query);

    }

}

2 个回复
最合适的回答,由SO网友:lotech 整理而成

好的,这是我最后的工作。老实说,我不确定我是否正确地清理了参数,所以请输入欢迎!除此之外,一切正常。非常感谢彼得·古森!

// action
add_action(\'pre_get_posts\', \'my_pre_get_posts\', 10, 1);

function my_pre_get_posts( $query ) {

    // bail early if is in admin
    if( is_admin() ) {
        return;
    }

    if( isset($query->query_vars[\'post_type\']) && $query->query_vars[\'post_type\'] == \'course\' ) {

        // array of filters (field key => field name)
        $GLOBALS[\'my_query_filters\'] = array( 
            \'field_1\'   => \'course_or_project\', 
            \'field_2\'   => \'difficulty\',
            \'field_3\'   => \'time_to_complete_project\',
            \'field_4\'   => \'time_to_complete_course\'
        );

        // get meta query
        $meta_query = $query->get(\'meta_query\');

        // loop over filters
        foreach( $GLOBALS[\'my_query_filters\'] as $key => $name ) {

            // sanitize parameter
            $name = filter_input( INPUT_GET, $name, FILTER_SANITIZE_STRING );

            // continue if not found in url
            if( empty($_GET[ $name ]) ) {
                continue;
            }

            // get the value for this filter
            // eg: http://www.website.com/events?city=melbourne,sydney
            $value = explode(\',\', $_GET[ $name ]);

            // append meta query
            $meta_query[] = array(
                \'key\'       => $name,
                \'value\'     => $value,
            );

        } 

        // update meta query
        $query->set(\'meta_query\', $meta_query);

    }

}

SO网友:Pieter Goosen

你需要建立一个适当的meta_query. 只有当您有一个代码时,您的代码才能工作meta_key 设置,如果你有超过1个,一切都将混乱。

另外请注意,您应该never ever 使用来自$_GET 变量(以及来自任何地方的任何值)。通过在URL中添加一些脚本,很容易将恶意代码注入站点。验证和卫生对性能的影响非常小,但绝对值得一试。

为了解决您的问题,让我们尝试重新编码您的操作。我已经在需要的地方发表了评论。

add_action( \'pre_get_posts\', function ( $q )
{
    if (    !is_admin() // Do this only on the front end
         && $q->is_main_query() // Targets the main query only
    ) {

        if( isset($query->query_vars[\'post_type\']) && $query->query_vars[\'post_type\'] == \'course\' ) { // Not sure about this, can be $q->is_post_type_archive( \'course\' )
            // Get all our $_GET variables and sanitize and validate them
            $course_or_project        = filter_input( INPUT_GET, \'course_or_project\',        FILTER_SANITIZE_STRING );
            $time_to_complete_project = filter_input( INPUT_GET, \'time_to_complete_project\', FILTER_SANITIZE_STRING ); 
            $time_to_complete_course  = filter_input( INPUT_GET, \'time_to_complete_course\',  FILTER_SANITIZE_STRING );
            $difficulty               = filter_input( INPUT_GET, \'difficulty\',               FILTER_VALIDATE_INT    ); 

            // Set our variable to hold the meta_query
            $meta_query = [];

            // Now we build our meta_query
            if( $course_or_project ) {
                $meta_query[] = [
                    \'key\'   => \'course_or_project\',
                    \'value\' => $course_or_project
                ];
            } 

            if( $time_to_complete_project ) {
                $meta_query[] = [
                    \'key\'   => \'time_to_complete_project\',
                    \'value\' => $time_to_complete_project
                ];
            } 

            if( $time_to_complete_course ) {
                $meta_query[] = [
                    \'key\'   => \'time_to_complete_course\',
                    \'value\' => $time_to_complete_course    
                ];
            } 

            if( $difficulty ) {
                $meta_query[] = [
                \'key\'   => \'difficulty\',
                \'value\' => $difficulty
                ];
            }

            // Make sure we have something in $meta_query before setting it
            if ( $meta_query ) 
                $q->set( \'meta_query\', $meta_query );

        }
    }
});
您可以根据需要优化查询,但这应该是最基本的

相关推荐

如何读取WordPress$Query关联数组(散列)键的值

WordPress编程新手(来自更为传统的环境),并试图了解其一些“独特”特性。我们的网站上有一个目录页,此代码驻留在functions.php, 如果条件为true,则调整结果。if( $query->is_post_type_archive( \'directory\' ) ){ ...//do stuff } 我想知道如何获取is_post_type_archive 这就是“目录”当我对值使用测试时。。。var_dumb($query->is_post