WordPress - User Query - Order by Meta Value - wordpress

I am trying to use a WordPress User Query to create a list of users that is ordered by a custom meta value. Its a simple numeric value, going from 1 to 100, so 1 needs to be displayed first, 100 last, etc.
This is my attempt, which has failed miserably:
<?php
$args = array(
'role' => 'Author',
'meta_key' => 'order-number',
'orderby' => 'order-number',
'order' => 'asc',
);
$wp_user_query = new WP_User_Query($args);
$authors = $wp_user_query->get_results();
if (!empty($authors))
{
echo '<div style="float:left;">';
foreach ($authors as $author)
{
$author_info = get_userdata($author->ID);
echo '<div class="post team-member"><div class="image">';
echo get_avatar( $author_info->ID, 91 );
echo '</div>';
echo '<div class="content"><div class="title">' . $author_info->user_firstname . ' ' . $author_info->user_lastname . '</div>';
echo '' . substr( get_the_author_meta('user_description',$author_info->ID) , 0 , 100 ) . '...';
echo '</div></div>';
}
echo '</div>';
} else {
echo 'No authors found';
}
?>
I think the problem is that wp_user_query does not support custom fields in orderby - so I need a solution that works around this.
Any ideas?

Correct. The orderby parameter can only accept possible values of 'login' (default), 'nicename', 'email', 'url', and 'registered'.
A dirty fix would be something like this:
<?php
global $wpdb; //Ignore this line if you're not within a function
$order = $wpdb->get_results("SELECT DISTINCT user_id FROM $wpdb->usermeta WHERE meta_key='order-number' ORDER BY meta_value ASC", "ARRAY_N");
$authors = array();
foreach($order as $aid)
$authors[] = new WP_User($aid[0]);
if (!empty($authors))
{
echo '<div style="float:left;">';
foreach ($authors as $author)
{
$author_info = get_userdata($author->ID);
echo '<div class="post team-member"><div class="image">';
echo get_avatar( $author_info->ID, 91 );
echo '</div>';
echo '<div class="content"><div class="title">' . $author_info->user_firstname . ' ' . $author_info->user_lastname . '</div>';
echo '' . substr( get_the_author_meta('user_description',$author_info->ID) , 0 , 100 ) . '...';
echo '</div></div>';
}
echo '</div>';
} else {
echo 'No authors found';
}
This is largely untested, so I can't guarantee this will work straight out of the gate, but it should get you started.
Hope this helps!

<?php
// prepare arguments this is your query.
$args = array(
'meta_key' => 'last_name',
'query_id' => 'wps_last_name',
);
// Create the WP_User_Query object
$author_query = new WP_User_Query( $args );
?>
Add following lines to functions.php file
<?php
add_action( 'pre_user_query', 'wps_pre_user_query' );
/*
* Modify the WP_User_Query appropriately
*
* Checks for the proper query to modify and changes the default user_login for $wpdb->usermeta.meta_value
*
* #param WP_User_Query Object $query User Query object before query is executed
*/
function wps_pre_user_query( &$query ) {
global $wpdb;
if ( isset( $query->query_vars['query_id'] ) && 'wps_last_name' == $query->query_vars['query_id'] )
$query->query_orderby = str_replace( 'user_login', "$wpdb->usermeta.meta_value", $query->query_orderby );
}
?>

Related

Can't get all author using WP_User_Query

I am trying to show all authors as well as the pagination of the result. So using bellow code it's not returning any users.
// Pagination vars
$current_page = get_query_var('paged') ? (int) get_query_var('paged') : 1;
$users_per_page = 12; // RAISE THIS AFTER TESTING ;)
$args = array(
'number' => $users_per_page,
'paged' => $current_page,
'role' => 'Author',
);
$users = new WP_User_Query( $args );
$total_users = $users->get_total(); // How many users we have in total (beyond the current page)
$num_pages = ceil($total_users / $users_per_page); // How many pages of users we will need
if ( $users->get_results() ) {
foreach( $users->get_results() as $user ) {
// $firstname = $user->first_name;
// $lastname = $user->last_name;
// $email = $user->user_email;
$author_thumb_url = get_avatar_url( $user->ID );
echo '<div class="col-md-6">';
echo '<div class="author-wrapper">';
echo '<div class="author-thumb">';
echo '<img src="'.$author_thumb_url.'">';
echo '</div>';
echo '<div class="author-description">';
echo '<h2>'. $user->first_name . ' ' . $user->last_name . '</h2>';
echo '<p>'. get_the_author_meta( 'description', $user->ID ) . '</p>';
echo '</div>';
echo '</div>';
echo '</div>';
}
}
?>
In args I have also used 'role' => 'author' and 'role__in' => 'author' but no result is showing.
Your loop might be incorrect. This is working for me. I also wrapper your columns in a row and container.
Try
// Pagination vars
$current_page = get_query_var('paged') ? (int) get_query_var('paged') : 1;
$users_per_page = 12; // RAISE THIS AFTER TESTING ;)
$args = array(
'number' => $users_per_page,
'paged' => $current_page,
'role' => 'author',
);
$users = new WP_User_Query( $args );
$total_users = $users->get_total(); // How many users we have in total (beyond the current page)
$num_pages = ceil($total_users / $users_per_page); // How many pages of users we will need
if ( $users->results ) {
echo '<div class="container"><div class="row">';
foreach( $users->results as $user ) {
// $firstname = $user->first_name;
// $lastname = $user->last_name;
// $email = $user->user_email;
$author_thumb_url = get_avatar_url( $user->ID );
echo '<div class="col-md-6">';
echo '<div class="author-wrapper">';
echo '<div class="author-thumb">';
echo '<img src="'.$author_thumb_url.'">';
echo '</div>';
echo '<div class="author-description">';
echo '<h2>'. $user->first_name . ' ' . $user->last_name . '</h2>';
echo '<p>'. get_the_author_meta( 'description', $user->ID ) . '</p>';
echo '</div>';
echo '</div>';
echo '</div>';
}
echo '</div></div>';
}
``

How do I get the woocommerce product price via functions.php

I am curretly trying to create a shortcode that shows 3 products and the snippet looks like this:
function show_recent_products(){
$args = array('posts_per_page' => 3, 'post_type' => 'product');
$custom_query = new WP_Query( $args );
if ( $custom_query->have_posts() ) {
echo '<div id="recent-posts" class="flex space-between">';
while ( $custom_query->have_posts() ) {
$custom_query->the_post();
echo '<div class="woocommerce_recent_products" style="background: url('.get_the_post_thumbnail_url().')">';
echo '<p>';
//echo get_regular_price();
echo'</p>';
echo '</div>';
}
echo '</div>';
}
wp_reset_postdata();
}
How can I get hold of the product price?
Reason why I am not using the default recent products shortcode it because the layout looks completely different and I would not know how to change the default code.
You can fetch product detail from ID. Use wc_get_product(). This will return Product Object.
$current_product = wc_get_product( get_the_ID() );
After that you can use this object $current_product and fetch relevant product information using its methods like get_price(). Example.
echo $current_product->get_price();
I used the global product inside the while loop and with I managed to get hold of all the product information.
function show_recent_products(){
global $post;
$args = array('posts_per_page' => 3, 'post_type' => 'product');
$post_id = $post->ID;
$product = wc_get_product( $post_id );
$custom_query = new WP_Query( $args );
if ( $custom_query->have_posts() ) {
echo '<div id="recent-posts" class="flex space-between">';
while ( $custom_query->have_posts() ) {
$custom_query->the_post();
global $product;
echo '<a href="'. get_the_permalink() .'" class="woocommerce_recent_products flex align-center" style="background: url('.get_the_post_thumbnail_url().')">';
echo '<div class="recent-content-inner">';
echo '<div>';
echo '<p class="recent-add-title">';
echo get_the_title();
echo'</p>';
echo '<p class="recent-add-price">';
echo "R". $product->price;
echo'</p>';
echo '<p class="recent-add-cart">';
echo "ADD CART";
echo'</p>';
echo'</div>';
echo'</div>';
echo "</a>";
}
echo '</div>';
}
wp_reset_postdata();
}

Display Custom Post Type Metabox Data

I'm having a problem displaying metabox data in a page template wp_query. I get this error:
Notice: Array to string conversion
Here is my code:
<?php
// WP_Query arguments
$args = array (
'post_type' => array( 'portfolio' ),
'ignore_sticky_posts' => true,
'posts_per_page' => '10',
);
// The Query
$portfolio_query = new WP_Query( $args );
// The Loop
if ( $portfolio_query->have_posts() ) {
while ( $portfolio_query->have_posts() ) {
$portfolio_query->the_post();
echo '<div id="portfolio">';
echo '<div class="featured_img">';
echo '' . " " . get_the_post_thumbnail() . '';
echo '</div>';
echo '<div class="portfolio">';
echo the_title( '<h2>', '</h2>' );
echo '<p>' . the_excerpt() . '</p>';
echo '<p>' . get_post_meta( get_the_ID($post->id , 'project_metabox', false) ) . '</p>';
echo '</div>';
echo '</div>';
}
} else {
echo "<h1>There are no portfolio pieces to view.</h1>";
}
// Restore original Post Data
wp_reset_postdata(); ?>
I've tried everything. This is just the latest version of my attempts. What am I doing wrong?
UPDATE:
Alright, so I found out the metadata isn't saving. I'm not exactly sure why, but I tried fixing it, and it's not working. My fixes made it worse. Here is my code:
`
public function save_metabox( $post_id, $post ) {
// Check if it's not an autosave.
if ( wp_is_post_autosave( $post_id ) )
return;
// Sanitize user input.
$project_new_web_design = isset( $_POST[ 'project_web_design' ] ) ? 'checked' : '';
$project_new_web_development = isset( $_POST[ 'project_web_development' ] ) ? 'checked' : '';
$project_new_digital_art = isset( $_POST[ 'project_digital_art' ] ) ? 'checked' : '';
$project_new_graphic_design = isset( $_POST[ 'project_graphic_design' ] ) ? 'checked' : '';
// Update the meta field in the database.
update_post_meta( $post_id, 'project_web_design ', $project_new_web_design );
update_post_meta( $post_id, 'project_web_development ', $project_new_web_development );
update_post_meta( $post_id, 'project_digital_art ', $project_new_digital_art );
update_post_meta( $post_id, 'project_graphic_design ', $project_new_graphic_design );
}
}
I believe the issue you're having is on this line:
echo '<p>' . get_post_meta( get_the_ID($post->id , 'project_metabox', false) ) . '</p>';
You seem to have mixed get_the_ID and $post->ID together. You're also attempting to echo an array.
The third parameter of get_post_meta will determine whether the value returned is a string or an array. Use true to return a single value.
Change it to:
echo '<p>' . get_post_meta( get_the_ID(), 'project_metabox', true ) . '</p>';
On a minor note you're trying to echo functions like the_excerpt(). You'll typically find that functions starting the_ instead of get_the_ will output directly instead of returning a value. Furthermore the_excerpt() will automatically add paragraph tags.
Replace this:
echo '<p>' . the_excerpt() . '</p>';
With this:
the_excerpt();

ob_start() combined with wp_query

I'm making my first plugin and I have a problem with displaying my shortcode.
It shows in the top all the time but I have read some about ob_start(); and trying to use it but the shortcode just returns nothing.
Im using the code below - it seems to have something to do with my posts. Anyone know why how to solve this problem?
My WP_Query:
$query = new WP_Query( array(
'category__in' => $categories,
'posts_per_page' => $whpost_stored_meta_shortcode['whpost_number_of_posts'][0]
));
The code i use to display it:
ob_start();
echo '<div class="whpost_content">';
while($query->have_posts()) : $query->the_post();
// Get the URL to the attached image.
$attached_image = wp_get_attachment_image_src( get_post_thumbnail_id( get_the_ID() ), 'large' );
echo '<div class="whpost_post" style="width: ' . $post_width .'; background-image: url(' . $attached_image[0] . ');">';
the_title();
echo '</div>';
endwhile;
echo '</div>';
return ob_get_clean();
The complete code for the shortcode function:
<?php
function cpt_content_func( $atts ) {
// Get the ID we putted in into [wh-postgrid id="THIS_ID"]
extract( shortcode_atts( array(
'id' => null
), $atts ) );
// Get stored meta data (For the categories - needed to be formatted in
// a certain way)
$categories = get_post_meta( $id, 'whpost_cats', true );
// Get meta data for settings and such.
$whpost_stored_meta_shortcode = get_post_meta( $id );
// Get the correct categories and use the settings we got.
$query = new WP_Query( array(
'category__in' => $categories,
'posts_per_page' => $whpost_stored_meta_shortcode['whpost_number_of_posts'][0]
));
// Set the styles
switch ( $whpost_stored_meta_shortcode['whpost_posts_per_line'][0] ) {
case 1:
$post_width = '100%';
$post_max_height = '';
break;
case 2:
$post_width = '50%';
$post_max_height = '';
break;
case 3:
$post_width = '33.333333%';
$post_max_height = '';
break;
case 4:
$post_width = '25%';
$post_max_height = '';
break;
default:
$post_width = '50%';
}
// Display the front-end
ob_start();
echo '<div class="whpost_content">';
while($query->have_posts()) : $query->the_post();
// Get the URL to the attached image.
$attached_image = wp_get_attachment_image_src( get_post_thumbnail_id( get_the_ID() ), 'large' );
echo '<div class="whpost_post" style="width: ' . $post_width .'; background-image: url(' . $attached_image[0] . ');">';
the_title();
echo '</div>';
endwhile;
echo '</div>';
return ob_get_clean();
}
add_shortcode('wh-postgrid','cpt_content_func');
I think problem with your Query, you can add this line to check
if (!$query->have_posts()) {
return 'Empty result';
} else {
return ob_get_clean();
}
The function must return the output.
Change your code like this and it should work:
$output = '<div class="whpost_content">';
while($query->have_posts()) : $query->the_post();
// Get the URL to the attached image.
$postId = get_the_ID();
$attached_image = wp_get_attachment_image_src( get_post_thumbnail_id( $postId ), 'large' );
$output .= '<div class="whpost_post" style="width: ' . $post_width .'; background-image: url(' . $attached_image[0] . ');">';
$output .= get_the_title( $postId );
$output .= '</div>';
endwhile;
$output .= '</div>';
return $output;

Getting the post ID outside outside of the Wordpress loop

So I have a snippet of code that grabs the categories and their coinciding posts and lists them outside of the loop (Below). I've been trying to get the post to link to #post-[ID] instead of the permalink - but I keep failing. Can anyone help?
<ul id="sidebar">
<?php
foreach( get_categories('orderby=ID&order=desc') as $cat ) :
if( !$cat->parent ) {
echo '<li class="title"><h2>' . $cat->name . '</h2>';
echo '<ul>';
process_cat_tree( $cat->term_id );
}
endforeach;
wp_reset_query(); //to reset all trouble done to the original query
//
function process_cat_tree( $cat) {
$args = array('category__in' => array( $cat ), 'numberposts' => -1);
$cat_posts = get_posts( $args );
$id = $post->ID;
global $post;
if( $cat_posts ) :
foreach( $cat_posts as $menuPost ) :
echo '<li';
if ( $menuPost->ID == $post->ID ) { echo ' class="active"'; }
echo '>';
echo '' . $menuPost->post_title . '';
echo '</li>';
endforeach;
endif;
echo '</ul></li>';
}
?>
The above code is outputting UL/LI tags like this:
CATEGORY
Post
Post
Post
CATEGORY
Post
Post
Post
CATEGORY
Post
Post
Post
Admittedly, I don't exactly understand what you mean by "linking to #post-[ID]", but going with the question title:
If you use get_permalink() when echoing the link, you will get the permalink - that's just what that function does.
Use get_the_ID() instead, if you want the post-ID returned, or the_ID() if you want it displayed (the_ID() is the same as echo get_the_ID()).
Edited from here:
If you're otherwise happy with the above code, changing
echo '' . $menuPost->post_title . '';
to
echo '' . $menuPost->post_title . '';
ought to do it.
However, I'd go about it like so:
echo '<ul>';
$cat_args = array(
'orderby' => 'name',
'order' => 'ASC'
);
$categories = get_categories($cat_args);
foreach($categories as $category) {
echo '<li class="title"><h2>' . $category->name . '</h2><ul>';
// query posts of that category:
$query_args = array(
'cat' => $category->cat_ID,
'posts_per_page' => -1
);
$your_query = new WP_Query( $query_args );
// loop through them:
while ( $your_query->have_posts() ) : $your_query->the_post();
echo '<li><a href="#post-';
the_ID();
echo '">';
the_title();
echo '</a></li>';
endwhile;
echo '</ul></li>';
// Reset Post Data
wp_reset_postdata();
}
echo '</ul>';

Resources