I want to list user based on the sub category (which is a taxonmy). It displays users from all the sub category rather than the one I select the sub category from the back end. The code is below, please advise what I am doing wrong:
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>
I want to list user based on the sub category (which is a taxonmy). It displays users from all the sub category rather than the one I select the sub category from the back end. The code is below, please advise what I am doing wrong:
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>
Share
Improve this question
edited Apr 17, 2020 at 7:16
西門 正 Code Guy - JingCodeGuy
1,5911 gold badge13 silver badges15 bronze badges
asked Apr 9, 2020 at 21:26
Emma ExpatEmma Expat
256 bronze badges
4
- what result or error message do you see? – 西門 正 Code Guy - JingCodeGuy Commented Apr 10, 2020 at 0:06
- @simongcc There is no error but it lists users from all the sub categories rather than listing users only of the sub category that I have selected from the backend wp editor. I don't understand where it compares the selection that I choose from backend. – Emma Expat Commented Apr 10, 2020 at 7:57
- I updated the code of view.php as below, but result is still same: if( !empty( $cat_sepration ) ) { foreach( $cat_sepration as $key => $value ){ $meta_category[] = get_terms( array( 'taxonomy' => 'sub_category', 'meta_query' => array( array( 'key' => 'sub_category', 'value' => 'cardio', 'compare' => '=' ) ), )); } } – Emma Expat Commented Apr 10, 2020 at 11:33
- I suggest you to back to a simple test first. I have added a suggested code that might help you to figure it out. – 西門 正 Code Guy - JingCodeGuy Commented Apr 10, 2020 at 23:11
1 Answer
Reset to default 1Objective
I want to list
sp_provider
(hospital,clinics,doctors) whosesub_category
is suppose'neurology'
rephrasing the words:
I want to list users with sp provider category(meta value) such as "hospital" and the user have a sub category(meta value) "neurology"
- sp_provider is a meta value in user profile (sp-provider maybe a post-type or something for user management screen to edit)
- sub category is also a meta value stored in user profile, the list is believed to link up to post type
sub_categories
with taxonomysub_category
List out all the users with selected sp provider
, sub category
and the user account is verified
and activated
The steps to create proper query
- convert the selected terms ID to slug
- create the query based on terms slug
Notes on your meta data and caution notes Your sub_category data is serialized. I believed that it is an array and for ease of handling, the whole array is being serialized before storing. It make it difficult to operate such as searching. To accurately handle it is to unserialize it first. In some cases such as yours, if it is for read only purpose without any saving operation, it would be fine and your data is a simple array of values.
Speaking of the data, it is still safe although it is not the best choice. If it involves data update, then it would be very dangerous because a serialized data is very easy to break. It will render your data, at least that field completely into useless state or if error handling is not enough, it will break your php, some worse cases will even rendering a blank page which is not rare when the template relies on the data to output template. You may take it into account.
Notes on query keyword 'IN'
// IN
does not work when the stored data is a serialized array, originally IN work for array() when comparing a list of data to your provided array.
// $meta_query_args[] = array(
// 'key' => 'sub_category',
// 'value' => array( 'cardiology', 'neurology', 'oncology' ),
// 'compare' => 'IN'
// );
The following list users based on category and sub category provided that user is verified and activated
// 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