I'm trying to query WP Users and group them by billing_state, a custom meta key/value but I'm getting some unexpected results where it gives me some empty options but also is only returning one result per billing_state.
Based on some research on SO it was suggested I query all users and then create a new array where I can set the state as the array key then the user object as the value.
Here is what I tried:
add_shortcode('pro_pro_users','pro_pro_users');
function pro_pro_users(){
global $wpdb;
$user_query = new WP_User_Query( array( 'fields' => 'all' ) );
$users = $user_query->get_results();
if (!empty($users)) {
$usersByState = array();
foreach ($users as $user) {
$usersByState[get_user_meta($user->ID, 'billing_state', true)] = $user;
}
foreach ($usersByState as $k => $v){
if(!empty($v)) {
echo '<li><h5>' . $k . '</h5>';
echo '<ul>';
foreach ($v as $user) {
echo '<li>' . get_user_meta($user->ID, 'first_name', true) . ' ' . get_user_meta($user->ID, 'last_name', true) . ' (' . $user->display_name . ')</li>';
}
echo '</ul>';
echo '</li>';
}
}
echo '</ul>';
} else {
echo 'No users found';
}
}
Here is what is happening (note the empty ones and only one per state although I know some of these have more than one
I've checked:
https://codex.wordpress.org/Class_Reference/WP_User_Query
https://codex.wordpress.org/Database_Description#Table:_wp_users
https://codex.wordpress.org/Function_Reference/get_users
https://wordpress.stackexchange.com/questions/105937/group-posts-by-meta-key
https://wordpress.stackexchange.com/questions/205427/group-posts-by-attachment-meta-key
https://usersinsights.com/wordpress-user-meta-query/
What comes to my attention is that the following code will "override" each billing-state with the last user found:
$usersByState = array();
foreach ($users as $user) {
$usersByState[get_user_meta($user->ID, 'billing_state', true)] = $user;
}
From what I understood is that you should rather go for:
$usersByState = array();
foreach ($users as $user) {
$billing_state = get_user_meta($user->ID, 'billing_state', true);
if ($billing_state)
$usersByState[$billing_state][] = $user;
}
So by doing this you would collect several users for different states. Moreover this should take care of empty "states" as you described. Not sure whether this fully solves your issue but it might be a starting point for refining your function.
Related
<?php if( $fields )
{
foreach( $fields as $field)
{
$value = get_field( $field['name'] );
if ($value) {
echo '<dl>';
echo '<dt>' . $field['label'] . '</dt>';
echo '<dd>' . $field['value'] . '</dd>';
echo '</dl>';
}
}
}
?>
This is what I have. If I do a var_dump on acf_get_fields, it apparently sets the value to NULL. I could have known, as it's written here:
https://www.advancedcustomfields.com/resources/get_field_object/
The problem: I have to first get all fields in a specific field_group, hence I am using acf_get_fields.
I thought with using $field['value'] I could get it to work, but apparently this does not work.
Can someone help me to retrieve the values in the foreach per field? Surely there must be a way?
PS:
<?php
$fields = get_fields();
if( $fields ): ?>
<ul>
<?php foreach( $fields as $name => $value ): ?>
<li><b><?php echo $name; ?></b> <?php echo $value; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
This gives me ALL fields. I just need a specific list of fields from a specific field group. That is the problem. Anybody knows how I can solve it?
<?php
$fields = get_field('fieldname');
foreach( $fields as $field)
{
echo '<dl>';
echo '<dd>' . $field . '</dd>';
echo '</dl>';
}
?>
Think the value is always NULL because you're getting it only the group fields, not the fields from a post. Have made a few examples maybe this will help you out.
$post_id = 123;
$group_id = 1234;
// Get post fields
$post_fields = get_fields($post_id);
foreach ($post_fields as $key => $value) {
if ($key == 'my_custom_field') {
echo $value;
}
}
// Get group fields
$group_fields = acf_get_fields($group_id);
foreach ($group_fields as $key => $group_field) {
if ($key == 'my_custom_field') {
echo $value;
}
}
// Get field objects
$field_objects = get_field_objects($post_id);
foreach ($field_objects as $key => $field_object) {
if ($key == 'my_custom_field') {
echo $field_object['value'];
}
if ($field_object['name'] == 'my_custom_field') {
echo $field_object['value'];
}
// only show fields from specific group
if ($field_object['parent'] == $group_id) {
echo $field_object['value'];
}
}
How to loop all records and display all the respective children using HTML <ul></ul>? I tried using PHP Do While but stuck at only 1 level.
MySQL (select * from user)
Desired output
Tree View
List View
The easy was is to do that with the help of array. Hope it helps.
$data = array();
foreach ($result as $item) {
$key = $item['name']; // or $item['info_id']
if (!isset($data[$key])) {
$data[$key] = array();
}
$data[$key][] = $item;
}
You can use this code:
$aResults; // it is your mysql result (array)
$resultSorted = array();
$resultSorted = recursiveList($aResults, '');
function recursiveList(&$aResults, $iKey)
{
$aChilds = '<ul>';
foreach ($aResults as $iLoopKey => $aResult) {
if ($aResult['parent'] == $iKey) {
unset($aResults[$iLoopKey]);
$aChilds .= '<li>' . $aResult['name'] . '</li>';
$aChilds .= recursiveList($aResults, $aResult['name']);
}
}
return $aChilds . '</ul>';
}
// Output example
echo '<pre>';
print_r($resultSorted);
As a result, I recived:
Also you'd better use 'parent_id' instead 'parent' in yours tables.
I have some brands listed against a user in the db which are input as a comma seperated list in the users profile - i get the individual brands associated to the user back by as follows
$brand_name = get_user_meta($user_id, 'brand', true);
$brands = explode(', ', $brand_name);
it works ok.
I am now creating brand pages which list their products, this is easy but i want to prevent users seeing the pages of the brands that they arent subscribed to.
my code that isnt working is below:
foreach ( $results as $result ){
$brand_name = get_user_meta($user_id, 'brand', true);
$brands = explode(', ', $brand_name);
if($brands = $result->brand) {
echo '<h2>Title: ' . $result->title . '</h2><br/>';
} else {
echo 'You can\'t view that brand';
}
}
I think i need to do some sort of nested foreach/for loop but not sure - Thanks in advance.
foreach ( $results as $result )
{
$brand_name = get_user_meta($user_id, 'brand', true);
$brands = explode(', ', $brand_name);
if(in_array($result->brand,$brands))
{
echo '<h2>Title: ' . $result->title . '</h2><br/>';
}
else
{
echo 'You can\'t view that brand';
}
}
use in_array()
I have defined $table_name_employee as a table in my plugin that has a bunch of user info in it. The ID field mirrors the field in wp_users
That being said, I have this code...
$SQLQuery="select * from {$table_name_employee}";
$wpdb->query($SQLQuery);
$results=$wpdb->get_results($SQLQuery,ARRAY_A);
foreach($results as $result)
{
$all_meta_for_user = get_user_meta( $result['ID'] );
$last_name = $all_meta_for_user['last_name'][0];
$first_name = $all_meta_for_user['first_name'][0];
$doc_training_responsibility_option.= "\t<option value='{$result['ID']}'>{$last_name}, {$first_name}</option>\n";
}
Later in my code I use $doc_training_responsibility_option to output the <option> inside the <select>.
It works as expected; however, the results are not sorted. I have tried several ways to add the data into an array instead of defining $doc_training_responsibility_option immediately. My intent was to sort the array by last name and then output that array to $doc_training_responsibility_option but I have failed on each attempt.
**** UPDATE ****
My attempt is below...
$SQLQuery="select * from {$table_name_employee}";
$wpdb->query($SQLQuery);
$results=$wpdb->get_results($SQLQuery,ARRAY_A);
$r=array(); $i=0;
foreach($results as $result)
{
$all_meta_for_user = get_user_meta( $result['ID'] );
$r[$i]['ID']=$result['ID'];
$r[$i]['last_name']=$all_meta_for_user['last_name'][0];
$r[$i]['first_name']=$all_meta_for_user['first_name'][0];
$i++;
}
// ************************************************
// NOT SURE WHAT TO DO HERE TO SORT $r BY last_name
// ************************************************
foreach ($r as $result)
{
$doc_training_responsibility_option.= "\t<option value='{$result['ID']}'>{$result['last_name']}, {$result['first_name']}</option>\n";
}
right now you are getting the user ID in this varible:
$result['ID']
Now you need to get all users from wp_usermeta and order by last name.
So you need to use get users to accomplish your task.
$u = get_users(array('blog_id' => $GLOBALS['blog_id'], 'meta_key' => 'last_name', 'orderby' => 'meta_value'));
foreach ($u as $user) {
$n = get_user_meta( $user->ID, 'last_name', true );
echo "<option>";
echo $n;
echo "</option>";
}
Based on #Mauro comment, I created the code below which worked.
// Create list of plugin users
$SQLQuery="select ID from {$table_name_employee}";
$wpdb->query($SQLQuery);
$results=$wpdb->get_results($SQLQuery,ARRAY_A);
foreach($results as $result)
{
$plugin_user[]=$result[ID];
}
// Get list of WP users (sorted)
$u = get_users(array('blog_id' => $GLOBALS['blog_id'], 'meta_key' => 'last_name', 'orderby' => 'meta_value'));
foreach ($u as $user)
{
// See if WP user is also a plugin user
if(in_array($user->ID,$plugin_user) )
{
$all_meta_for_user = get_user_meta( $user->ID );
$last_name=$all_meta_for_user['last_name'][0];
$first_name=$all_meta_for_user['first_name'][0];
$doc_training_responsibility_option.= "\t<option value='{$user->ID}'>{$last_name}, {$first_name}</option>\n";
}
}
OK, I have a very specific question that I hope someone can shed some light on.
I have a page that lists authors outputting using the following code
<?php
$display_admins = false;
$order_by = 'post_count'; // 'nicename', 'email', 'url', 'registered', 'display_name', or 'post_count'
$role = ''; // 'subscriber', 'contributor', 'editor', 'author' - leave blank for 'all'
$hide_empty = true; // hides authors with zero posts
if(!empty($display_admins)) {
$blogusers = get_users('orderby='.$order_by.'&role='.$role);
} else {
$admins = get_users('role=administrator');
$exclude = array();
foreach($admins as $ad) {
$exclude[] = $ad->ID;
}
$exclude = implode(',', $exclude);
$blogusers = get_users('exclude='.$exclude.'&orderby='.$order_by.'&role='.$role.'&order='.'DESC');
}
$authors = array();
foreach ($blogusers as $bloguser) {
$user = get_userdata($bloguser->ID);
if(!empty($hide_empty)) {
$numposts = count_user_posts($user->ID);
if($numposts < 1) continue;
}
$authors[] = (array) $user;
}
echo '<ul class="contributors">';
foreach($authors as $author) {
$display_name = $author['data']->display_name;
$avatar = get_wp_user_avatar($author['ID'], 'medium');
$author_profile_url = get_author_posts_url($author['ID']);
$filter = get_userdata($author['ID'])->yim;
echo '<li><div class="home ', $filter,' "><div class="feature-image">', $avatar , '</div>
<div class="post-title"><h3>', $display_name, '</h3></div>
</div>
</li>';
}
echo '</ul>';
?>
(I got this from another support topic and tweaked it, although I can't remember where)
At the moment, the $filter variable is just a string I enter in the 'Yahoo IM' profile box (a dirty fix to test the filter). I'd like this to actually be a list of the categories (as slugs that I will output in to the class="" part of the loop) that the author has posted in.
I essentially want to be able to filter the authors by category that they have posted in, and the filter I'm using (Isotope) operates using the class, so outputting the categories in to the class of the markup is what I'm after.
Any suggestions gratefully received!
// Returns the posts made by the author
$authorPosts = get_posts("author={$author['ID']}");
$categoryList = array(); // reset previous values
foreach ($authorPosts as $post) {
$postCategories = get_the_category($post->ID);
// Add to the categories the author has posted in
foreach ($postCategories as $category)
$categoryList[] = $category->slug;
}
// Removes duplicate categories
$categoryList = array_unique($categoryList);
You can then use $filter = implode(' ', $categoryList); and add it to your html.
RE not storing the array from the other answer, you can just echo out the slugs there and then like this:
$authorPosts = get_posts("author={$author['ID']}");
foreach ($authorPosts as $post) {
$postCategories = get_the_category($post->ID);
// Add to the categories the author has posted in
foreach ($postCategories as $category)
echo($category->slug);
}
otherwise if you want to put your PHP at the top and echo out the slugs further down the page pop there where ever you want to echo them:
$i = 0;
foreach($categoryList as $category) {
echo($categoryList[$i]);
$i++;
}