I'm trying to figure this out with no luck, on the ajax list I want to sort the listings so that expired ones are at the end.
I've tried to use this filter
add_filter ( 'get_job_listings_query_args', 'sort_by_expired' );
function sort_by_expired( $query_args ) {
$today = date("Y-m-d", strtotime($date));
$query_args['orderby'] = 'meta_value_num';
$query_args['order'] = 'DESC';
// $query_args['meta_key'] = '_job_expires';
$query_args['meta_query'][] = array(
array(
'key' => '_job_expires',
// 'value' => date('Y-m-d'),
// 'compare' => '>='
)
);
return $query_args;
}
I've noticed that the code changes the order but not in the way I've would have wanted.
I tried to change different parameters (you can see the quoted out parts) changing:
mata_value_num to meta_value adding removing meta query parameters but with no luck.
From what i can understand you want to sort it by _job_expires ASC for the ones that are not expired and then display expired ones by DESC. this will have to be done in 2 separate queries. you can merge both arrays after that
edit: Merge 2 seperate queries' results as follows
//setup your queries as you already do
$query1 = new WP_Query($args_for_query1);
$query2 = new WP_Query($args_for_query2);
//create new empty query and populate it with the other two
$wp_query = new WP_Query();
$wp_query->posts = array_merge( $query1->posts, $query2->posts );
//populate post_count count for the loop to work correctly
$wp_query->post_count = $query1->post_count + $query2->post_count;
This is how I got it to work
public function depcore_custom_orderby( $query_args ) {
// Use meta_value_num for numeric sorting (if issues with meta_value)
$query_args[ 'orderby' ] = 'meta_value';
$query_args[ 'order' ] = 'DESC';
return $query_args;
}
public function depcore_custom_orderby_query_args( $query_args ) {
$query_args[ 'meta_key' ] = '_job_expires';
return $query_args;
}
Because I'm using the plugin boilerplate the filter call is used in the plugin public part
$this->loader->add_filter( 'job_manager_get_listings_args', $plugin_public, 'depcore_custom_orderby', 99 );
$this->loader->add_filter( 'get_job_listings_query_args', $plugin_public,'depcore_custom_orderby_query_args', 99 );
Related
I'm trying to combine several loops into one and sort the final results by relevance.
For the former part, I did this:
// set the variables
$author_id = get_the_author_meta('ID');
$tags_id = wp_get_post_tags($post->ID);
$first_tag = $tags_id[0]->term_id;
$categories_id = wp_get_post_categories($post->ID);
// loop for same author
$by_author = new WP_Query (array(
'author' => $author_id,
'posts_per_page' => '5'
));
// add ids to array
if ($by_author->have_posts()) {
while ($by_author->have_posts()) {
$by_author->the_post();
$add[] = get_the_id();
}
}
// loop for same tag
$by_tag = new WP_Query(array(
'tag__in' => $first_tag,
'posts_per_page' => '5'
));
// add ids to array
if ($by_tag->have_posts()) {
while ($by_tag->have_posts()) {
$by_tag->the_post();
$add[] = get_the_id();
}
}
// loop for same category
$by_category = new WP_Query(array(
'category__in' => $categories_id,
'posts_per_page' => '5'
));
// add ids to array
if ($by_category->have_posts()) {
while ($by_category->have_posts()) {
$by_category->the_post();
$add[] = get_the_id();
}
}
// loop array of combined results
$related = new WP_Query(array(
'post__in' => $add,
'post__not_in' => array($post->ID),
'posts_per_page' => '10',
'orderby' => $weight[$post->ID],
'order' => 'DESC'
));
// show them
if ($related->have_posts()) {
while ($related->have_posts()) {
$related->the_post();
// [template]
}
}
This is working nicely combining the loops into one. For the latter part, what I'm trying to do next is to add an incremental "weight" value to each post as they come up so as to later sort them with something like 'orderby' => $weight,.
For example, if a post comes up in "same author" it gets 3 points, if another one comes up in same tag it gets 2 points and so on. If it comes up in more than one loop, it should get the combined points i.e. 3+2+1=6 hence be boosted to the top of the final query.
I have tried to add a counter to each preliminary loop, like $weight = +3 etc, but this only adds everything up for every post, not individually.
I also tried inserting something like this at the end of each preliminary loop...
$weight = 0;
if ($by_author){
foreach ($by_author as $post){
setup_postdata($post);
$weight = +10;
add_post_meta($post->ID, 'incr_number', $weight, true);
update_post_meta($post->ID, 'incr_number', $weight);
}
}
... and this to the final one
echo get_post_meta($post->ID,'incr_number',true);
But it still doesnt do it right. It assigns a global value, while I want them to be different depending on the actual main posts one is reading.
So is there a way to do this?
If I understand your question right, I think your last solution was close. Instead of a global $weight parameter, however, I think you need to build an array of $weights that's unique to each post:
$weights[$post.id] += 10;
Then, you could sort that array and get your most heavily weighted post IDs from there.
I'm wondering if there exist any faster approaches to count all products in WooCommerce (and their child-variations), than this following code-example:
function total_product_count() {
$product_count = 0;
$args = array(
'post_type' => 'product',
'posts_per_page' => -1
);
/* Initialize WP_Query, and retrieve all product-pages */
$loop = new WP_Query($args);
/* Check if array contains any posts */
if ($loop->have_posts()):
while ($loop->have_posts()):
$loop->the_post();
global $product;
/* Count the children - add count to product_count */
product_count += count($product->get_children());
endwhile;
endif;
return $product_count;
}
On my local XAMPP web-server the function executes in 3 seconds (having 253 products), which is way too long time. The function returns 1269.
$product->get_children() is not always correct in this situation. get_children() return child products as well as grouped products if exist.
I hope the better and fastest way is to use wpdb:: MySQL query method. Try the following code
echo 'Number of main products => '.main_product_count();
echo 'Number of variations => '. variation_product_count();
function main_product_count() {
global $wpdb;
$count = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE `post_type` LIKE 'product'");
return $count;
}
function variation_product_count() {
global $wpdb;
$count = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE `post_type` LIKE 'product_variation'");
return $count;
}
as your naming
$loop =new WP_Query($args);
try this code
$loop->post_count;
while ($loop->have_posts()){
global $product;
/* Count the children - add count to product_count */
$loop->post_count += count($product->get_children());
}
WP_Query has a property which gives you the number of posts found matching the current query parameters:
function total_product_count() {
$args = array( 'post_type' => 'product', 'posts_per_page' => -1 );
$products = new WP_Query( $args );
return $products->found_posts;
}
I have a custom post type called reservation. In it I get the reservation for event/room you name it (not important).
When I go to my custom post type page, I get all the posts nicely displayed. The first column is the reservation date. Now the reservation date can be one - 28.11.2015, but it can also be multiple dates - 28.11.2015, 29.11.2015, 02.12.2015.
I would like to enable the sorting of that column. The problem is, this is a string, not a number so I cannot just create a simple sortable column query like described here.
So far I tried this:
add_filter( 'manage_edit-reservation_sortable_columns', 'reservation_sortable_column' );
if (!function_exists('reservation_sortable_column')) {
function reservation_sortable_column( $columns ) {
$columns['reservation_date'] = 'reservation_date';
return $columns;
}
}
add_filter( 'posts_clauses', 'manage_wp_posts_be_qe_pre_get_posts', 1, 2 );
if (!function_exists('manage_wp_posts_be_qe_pre_get_posts')) {
function manage_wp_posts_be_qe_pre_get_posts( $pieces, $query ) {
global $wpdb;
if ($query->is_main_query() && ( $orderby = $query->get('orderby') ) ) {
$order = strtoupper( $query->get('order') );
if ( !in_array( $order, array('ASC', 'DESC') ) ) {
$order = 'ASC';
switch ($orderby) {
case 'reservation_date':
$pieces[ 'join' ] .= " LEFT JOIN $wpdb->postmeta wp_rd ON wp_rd.post_id = {$wpdb->posts}.ID AND wp_rd.meta_key = 'reservation_date'";
$pieces[ 'orderby' ] = "STR_TO_DATE( wp_rd.meta_value,'%d.%m.%Y' ) $order, " . $pieces[ 'orderby' ];
break;
}
}
return $pieces;
}
}
}
This doesn't work, because I'm working with strings.
Luckily, my dates (when a person picks them), are already sorted lowest to highest date. They are stored in $custom['reservation_date'] array, where $custom = get_post_custom($post->ID). So I can get them like $custom['reservation_date'][0].
I can also separate the first date
preg_match('/^(.+?),/', $custom['reservation_date'][0], $matches);
If it's only one date, without the comma, I can then get them out like:
$first_date = (!empty($matches)) ? $matches[0] : $custom['reservation_date'][0];
Now what's bothering me is how to use this in my custom query? Currently the sorting is done on meta_value reservation_date (string). How do I make it so that I can sort based on these first dates?
Say I have dates like:
19.11.2015, 20.11.2015
28.11.2015
14.11.2015, 15.11.2015
13.11.2015
When I click to sort them in ascending order I'd like to get
13.11.2015
14.11.2015, 15.11.2015
19.11.2015, 20.11.2015
28.11.2015
And another click on the column will order them descending
28.11.2015
19.11.2015, 20.11.2015
14.11.2015, 15.11.2015
13.11.2015
Any help is appreciated.
You will not be able to sort in the WP Query as you have not stored the values in a way WordPress understands.
https://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters
You should store dates as YYYY-mm-dd.
Either change how the dates are stored or use PHP after the database request to sort.
// 1. if you change how "reservation_date" is stored in the db
$posts = get_posts(array(
'posts_per_page' => -1,
'post_type' => 'reservation',
'meta_key' => 'reservation_date',
'orderby' => 'meta_value',
'order' => 'ASC'
));
// 2. if you choose to sort with PHP after pulling the data
$posts = get_posts(array(
'posts_per_page' => -1,
'post_type' => 'reservation'
));
usort($posts, function ($post_a, $post_b) {
$post_a_custom = get_post_custom($post_a->ID);
$post_b_custom = get_post_custom($post_b->ID);
$post_a_date = DateTime::createFromFormat('d.m.Y', $post_a_custom['reservation_date'][0]);
$post_b_date = DateTime::createFromFormat('d.m.Y', $post_b_custom['reservation_date'][0]);
if ($post_a_date == $post_b_date) {
return 0;
} else if ($post_a_date > $post_b_date) {
return -1;
} else {
return 1;
}
});
I'm looking to count the number of posts in the last week then group them by a custom taxonomy called 'topic' So that in the next get_posts equation I can get topics by the number of posts to that area in the last week.
It can be done like this with get posts, but I am concerned that this is unnecessarily expensive on the server. Is there another way?
function count_posts_by_taxanomy($since,$taxonomy){
global $sincer;
$sincer = $since;
function filter_post_count($where = ''){
global $sincer;
$where .= " AND post_date > '" . date('Y-m-d', strtotime($sincer)) . "'";
return $where;
}
$args = array(
'numberposts' => -1,
'post_type' => 'post',
'suppress_filters' => false
);
add_filter('posts_where','filter_post_count');
$posts = get_posts($args);
remove_filter('posts_where','filter_post_count');
$count_term = array();
foreach($posts as $post){
foreach(get_the_terms($post->ID,'topic') as $term){
$count_term[$term->slug] += 1;
}
}
print_r($count_term);
}
Called like this:
count_posts_by_taxanomy('-5 days','topic');
You would be better using a custom database query. See here for more info on that: http://codex.wordpress.org/Class_Reference/wpdb
I would then suggest you store the result in a transient. You don't need to run the query on every load.
http://codex.wordpress.org/Transients_API
You can use WP_Query and call $wp_query->found_posts to find count of posts. And then do a loop and cache values.
More at : http://codex.wordpress.org/Class_Reference/WP_Query
$query = new WP_Query( array('posts_per_page'=>-1,
'post_type'=>array('post'),
'date_query' => array(array('after' => 'YOUR DATE')),
'tax_query' => array(
array(
'taxonomy' => 'YOUR TAX'
))));
When we want to get some relation field we do
$pod = pods( 'pod_name', get_the_id() );
$related = $pod->field( 'relationship_field' );
and I get list of results array 1, 2 ...
but I need to get relationship_field where name="some_name". How can I do that?
The following will retrieve the related field named relationship_field if the related post has a title equal to some_name:
$pod = pods('pod_name', get_the_ID());
$params = array(
'WHERE' => "relationship_field.post_title = 'some_name'",
);
$related = $pod->find($params);
You're example was right, but with a minor tweak this will be more useful as an example:
// get the pod record based on current post ID
$pod = pods( 'pod_name', get_the_ID() );
$params = array(
// be sure to sanitize the value going in, if it's dynamic
'where' => 'relationship_field.post_title = "Some title"'
);
// find records that match $params
$pod->find( $params );
// loop through records found
while ( $pod->fetch() ) {
// do something with $pod->field( 'field_name' )
// or $pod->display( 'field_name' )
}