如何创建适当的查询以获取具有与分类相关的元键的用户列表

时间:2020-04-09 作者:Emma Expat

我想根据子类别(即taxonmy)列出用户。它显示所有子类别的用户,而不是我从后端选择子类别的用户。代码如下,请告知我做错了什么:

options.php

<?php

if (!defined(\'FW\'))
    die(\'Forbidden\');



$options = array(
    \'heading\' => array(
        \'label\' => esc_html__(\'Heading\', \'listingo\'),
        \'desc\' => esc_html__(\'Add heading. Leave it empty to hide\', \'listingo\'),
        \'type\' => \'text\',
    ),
    \'sub_heading\' => array(
        \'label\' => esc_html__(\'Sub Heading\', \'listingo\'),
        \'desc\' => esc_html__(\'Add sub heading. Leave it empty to hide\', \'listingo\'),
        \'type\' => \'text\',
    ),
    \'view\' => array(
        \'type\' => \'select\',
        \'value\' => \'list\',
        \'desc\' => esc_html__(\'Select listing View\', \'listingo\'),
        \'label\' => esc_html__(\'Listing View\', \'listingo\'),
        \'choices\' => array(
            \'list\' => esc_html__(\'List\', \'listingo\'),
            \'grid\' => esc_html__(\'Grid\', \'listingo\'),
        ),
    ), 
    \'sub_category\' => array(
        \'type\' => \'multi-select\',
        \'label\'     => esc_html__(\'Select Sub Categories\', \'listingo\'),
        \'population\' => \'taxonomy\',
        \'source\' => \'sub_category\',
        \'limit\' => 500,
        \'desc\' => esc_html__(\'Show users by sub category selection. Leave it empty to show from all categories\', \'listingo\'),
    ),
    \'show_posts\' => array(
        \'type\' => \'slider\',
        \'value\' => 8,
        \'properties\' => array(
            \'min\' => 1,
            \'max\' => 100,
            \'sep\' => 1,
        ),
        \'label\' => esc_html__(\'Show No of Posts\', \'listingo\'),
    ),
    \'show_pagination\' => array(
        \'type\' => \'select\',
        \'value\' => \'no\',
        \'label\' => esc_html__(\'Show Pagination\', \'listingo\'),
        \'desc\' => esc_html__(\'\', \'listingo\'),
        \'choices\' => array(
            \'yes\' => esc_html__(\'Yes\', \'listingo\'),
            \'no\' => esc_html__(\'No\', \'listingo\'),
        ),
        \'no-validate\' => false,
    ),
);

view.php

<?php
if (!defined(\'FW\'))
    die(\'Forbidden\');

global $paged;

$per_page = intval(8);
if (!empty($atts[\'show_posts\'])) {
    $per_page = $atts[\'show_posts\'];
}

$pg_page = get_query_var(\'page\') ? get_query_var(\'page\') : 1; //rewrite the global var
$pg_paged = get_query_var(\'paged\') ? get_query_var(\'paged\') : 1; //rewrite the global var
$cat_sepration  = !empty( $atts[\'sub_category\'] ) ? $atts[\'sub_category\'] : \'\';


//paged works on single pages, page - works on homepage
$paged = max($pg_page, $pg_paged);
$limit  = (int) $per_page;

$meta_query_args = array();
$query_args = array(
    \'role__in\' => array(\'professional\', \'business\'),
    \'post_type\' => \'sp-provider\',
    \'orderby\' => \'meta_value_num\',
    \'order\' => \'DESC\',
);

//Verify user
$meta_query_args[] = array(
    \'key\' => \'verify_user\',
    \'value\' => \'on\',
    \'compare\' => \'=\'
);
//active users filter
$meta_query_args[] = array(
    \'key\' => \'activation_status\',
    \'value\' => \'active\',
    \'compare\' => \'=\'
);



if (!empty($meta_query_args)) {
    $query_relation = array(\'relation\' => \'AND\',);
    $meta_query_args = array_merge($query_relation, $meta_query_args);
    $query_args[\'meta_query\'] = $meta_query_args;
}

if( !empty( $cat_sepration ) ) {
    foreach( $cat_sepration as $key => $value ){
        $meta_category[] = get_terms( array(
                        \'taxonomy\'      => \'sub_category\',
                        \'include\'       => $value,
                        \'hide_empty\'    => 0

        ));
    }

}

//By Sub Categories
if( !empty( $meta_category ) ) {
    $query_relations = array( \'relation\' => \'OR\',);
    $meta_query_args    = array_merge( $query_relations, $meta_category );
    $query_args[\'meta_query\'][] = $meta_query_args;
}

if( !empty( $atts[\'show_pagination\'] ) && $atts[\'show_pagination\'] === \'yes\'){
    $offset = ($paged - 1) * $limit;
} else{
    $offset = 0;
}

$query_args[\'number\'] = $limit;
$query_args[\'offset\'] = $offset;

$user_query = new WP_User_Query($query_args);
$total_users = $user_query->total_users;
?>
<div class="sc-listing-bycat-grid sp-featured-providers-v2 tg-haslayout spv4-listing">
    <?php if (!empty($atts[\'heading\']) || !empty($atts[\'sub_heading\'])) { ?>
        <div class="col-xs-12 col-sm-12 col-md-10 col-md-push-1 col-lg-8 col-lg-push-2">
            <div class="tg-sectionheadvtwo">
                <div class="tg-sectiontitle">
                    <?php if (!empty($atts[\'heading\'])) { ?><span><?php echo esc_attr($atts[\'heading\']); ?></span><?php } ?>
                    <?php if (!empty($atts[\'sub_heading\'])) { ?><h2><?php echo esc_attr($atts[\'sub_heading\']); ?></h2><?php } ?>
                </div>
            </div>
        </div>
    <?php } ?>
    <div class="tg-featuredproviders tg-listview">
        <div class="tg-featuredproviders">
            <div class="row">
                <?php
                if (!empty($user_query->results)) {
                    foreach ($user_query->results as $user) {
                        $username = listingo_get_username($user->ID);
                        $category = get_user_meta($user->ID, \'sub_category\', true);
                        $avatar = apply_filters(
                                \'listingo_get_media_filter\', listingo_get_user_avatar(array(\'width\' => 92, \'height\' => 92), $user->ID), array(\'width\' => 92, \'height\' => 92)
                        );
                        ?>
                        <div class="col-xs-12 col-sm-6 col-md-3 col-lg-3 tg-verticaltop">
                            <div class="tg-featuredad">
                                <?php do_action(\'listingo_result_avatar_v2\', $user->ID,\'\',array(\'width\' => 275, \'height\' => 152)); ?>
                                <div class="tg-featuredetails">
                                    <?php do_action(\'listingo_result_tags_v2\', $user->ID); ?>
                                    <div class="tg-title">
                                        <h2><a href="<?php echo esc_url(get_author_posts_url($user->ID)); ?>"><?php echo esc_attr($username); ?></a></h2>
                                    </div>
                                    <?php do_action(\'sp_get_rating_and_votes\', $user->ID); ?>
                                </div>
                                <ul class="tg-phonelike">
                                    <?php do_action(\'listingo_get_user_meta\',\'phone\',$user);?>
                                    <?php do_action(\'listingo_add_to_wishlist\', $user->ID); ?>
                                </ul>
                            </div>
                        </div>
                        <?php
                    }
                }
                ?>
            </div>
        </div>
    </div>
    <?php if (!empty($total_users) && !empty($limit) && $total_users > $limit && isset($atts[\'show_pagination\']) && $atts[\'show_pagination\'] == \'yes\') { ?>
        <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
            <?php listingo_prepare_pagination($total_users, $limit); ?>
        </div>
    <?php } ?>
</div>

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

客观的

我想列出sp_provider (医院、诊所、医生)sub_category 假设是\'neurology\'

重新措辞:

我想列出sp提供者类别(meta值)的用户,如“医院”,用户有子类别(meta值)“神经病学”

sp\\u provider是用户配置文件中的一个元值(sp provider可能是帖子类型或供用户管理屏幕编辑的内容)

  • 子类别也是存储在用户配置文件中的一个元值,该列表被认为链接到帖子类型sub_categories 使用分类法sub_category
  • 列出所有选择sp provider, sub category 用户帐户为verifiedactivated

    创建正确查询的步骤

    将所选术语ID转换为slug创建基于术语slug的查询Notes on your meta data and caution notes您的sub\\u类别数据已序列化。我认为它是一个数组,为了便于处理,整个数组在存储之前都在序列化。这使得搜索等操作变得困难。要准确地处理它,首先要取消序列化。在某些情况下(例如您的情况),如果它是只读的,没有任何保存操作,那么就可以了,并且您的数据是一个简单的值数组。

    说到数据,它仍然是安全的,尽管它不是最好的选择。如果它涉及数据更新,那么这将是非常危险的,因为序列化的数据很容易被破坏。它将使您的数据,至少该字段完全处于无用状态,或者如果错误处理不够,它将破坏您的php,一些更糟糕的情况甚至会呈现一个空白页面,当模板依赖于数据输出模板时,这种情况并不罕见。你可以考虑一下。

    关于查询关键字“IN”的注释IN 当存储的数据是序列化数组时不起作用,最初在将数据列表与提供的数组进行比较时,该数组用于array()。

    // $meta_query_args[] = array(
    //     \'key\' => \'sub_category\',
    //     \'value\' => array( \'cardiology\', \'neurology\', \'oncology\' ),
    //     \'compare\' => \'IN\'
    // );
    
    以下列出了基于类别和子类别的用户,前提是用户已被验证和激活

    // suppose you get a value somewhere
    $cat_sepration = array(
        "48", "50"
    );
    
    $query_args = array(
        // \'post_type\' => \'sp-provider\', // ignored by user query, it is for post query
        \'role__in\' => array(\'professional\', \'business\'),
        \'orderby\' => \'meta_value_num\',
        \'order\' => \'DESC\',
    );
    
    // prepare term slug from term id for searching
    // because the $cat_separation is a list of ID, you need to convert to slugs before putting into user query to search
    $terms = get_terms( array(
        \'taxonomy\' => \'sub_category\',
        \'include\' => $cat_sepration, // it takes the selected id here and convert to slugs
        \'fields\' => \'slugs\',
        \'hide-empty\' => false,
    ) );
    
    // check point
    var_dump( $terms ); // a list of terms slug for use to search for user in related category 
    
    $meta_query_args = array();
    
    // Verify user
    $meta_query_args[] = array(
        \'key\' => \'verify_user\',
        \'value\' => \'on\',
        \'compare\' => \'=\'
    );
    
    // active users filter
    $meta_query_args[] = array(
        \'key\' => \'activation_status\',
        \'value\' => \'active\',
        \'compare\' => \'=\'
    );
    
    // sp category
    // since your data is single value, IN will also work
    $meta_query_args[] = array(
        \'key\' => \'spcategory_search\',
        \'value\' => array( \'Hospital\', \'Clinic\' ), // case sensitive, array is for multiple
        \'compare\' => \'IN\' // = is for one value, IN is for multiple
    );
    
    // ** this is how to the `category query` is properly created
    // sub category
    // the following can search the serialized data in database
    // this comparing method using LIKE operator is similar to those used in role__in comparison in WordPress Core
    $category_query_args = [];
    foreach ($terms as $key => $term) {
        $category_query_args[] = array(
            \'key\' => \'sub_category\',
    
    // without :" is also work, :" increase the accuracy because it relies on the LIKE operator comparing to the serialized data. A text inside serialized data is beginning with :"something" so it helps to match
    
            \'value\' => \':"\' . $term, 
            \'compare\' => \'LIKE\',
        );
    }
    
    $meta_query_args[] = array(
        array(
            // to ensure the user have all the categories at the same time, so the operator is AND
            \'relation\' => \'AND\',
            $category_query_args,
    
            // the following is proved to work in test data, it is written as a foreach above for programatic reason
    
            // here is an expanded version of $category_query_args (the above for-each loop for reference)
            // because \'LIKE\' is used, it searches based on similar keywords
            // array(
            //  \'key\' => \'sub_category\',
            //  \'value\' => \'cardiology\', // or \':"cardiology\', means beginning with :"cardiology
            //  \'compare\' => \'LIKE\',
            // ),
            // array(
            //  \'key\' => \'sub_category\',
            //  \'value\' => \'neurology\',
            //  \'compare\' => \'LIKE\',
            // ),
            // array(
            //  \'key\' => \'sub_category\',
            //  \'value\' => \'Oncology\',
            //  \'compare\' => \'LIKE\',
            // )
        ),
    );
    
    if (!empty($meta_query_args)) {
        $query_relation = array(\'relation\' => \'AND\',);
        $meta_query_args = array_merge($query_relation, $meta_query_args);
        $query_args[\'meta_query\'] = $meta_query_args;
    }
    $user_query = new WP_User_Query($query_args);
    
    // for debugging purpose
    // var_dump($query_args);
    
    // check point
    var_dump($user_query->request); // you may confirm the SQL query and run in sql platform/tools
    
    $users = $user_query->get_results(); // if result is result, you may do any operation hereafter
    
    // check point
    foreach ($users as $key => $user) {
        print_r(get_user_meta($user->ID)); // confirm the meta value
    }
    
    // each of the above step proved to be working with simulated data
    

    相关推荐

    What does this shortcode do?

    function my_shortcode($atts, $content = null){ extract(shortcode_atts(array(\"type\" => \"warrning\"), $atts)); return \".$content.\"; } add_shortcode(\"warrning_dialog\", \"my_shortcode\"); 我知道它会创建短代码[warning\\u dialo