Wp query posts between dates, but any year - wordpress

I'm using ACF pro and need to query posts that have some special ACF fields certain value.
But also I need to get posts that have ANY year, but the date should be between today and + 30 days from today. I cannot use static month number because then if post is made in day 1 it would not find it enough in advance.
Here is my initial query that is not working. It works if only get certain year and month, but that only gets posts from that date.
//$date_month_advance_month = ... month number of today + 30 days
//$date_month_advance_day= ... day number of today + 30 days
// args
$args = array(
'post_type' => 'my_post_type',
'posts_per_page'=> -1,
'meta_key' => 'status',
'meta_value' => 'accepted',
'date_query' => array(
'compare' => 'BETWEEN',
array(
'month' => $date_today_month,
'day' => $date_today_day,
),
array(
'month' => $date_month_advance_month,
'day' => $date_month_advance_day,
),
),
);

You could create a custom query. I made one quickly, tested for the date but not the custom field status as i don't have it. Replace my_post_type with your post type name.
global $wpdb;
$query = "
SELECT * FROM {$wpdb->posts} as p
LEFT JOIN {$wpdb->postmeta} as pm
ON pm.post_id = p.ID
WHERE p.post_type = 'my_post_type'
AND pm.meta_key = 'status'
AND pm.meta_value = 'accepted'
AND REPLACE(SUBSTRING(p.post_date, 6, 10), '-', '') BETWEEN %s AND %s
GROUP BY p.ID
";
// Should replace 0301 and 0331 by variables (date('mO1') and date('m31') for example), I let you handle this.
$prepared_query = $wpdb->prepare($query, array('0301', '0331'));
$result = $wpdb->get_results($prepared_query);
foreach($result as $r) {
$cs_post = get_post($r->ID);
echo '<p>';
echo get_the_title($cs_post->ID) .'<br>';
echo get_the_date('Y-m-d', $cs_post->ID) .'<br>';
echo '</p>';
}
Not sure if it's the proper way but it works.

Related

Average post age in days per taxonomy term

I'm building some stats for a directory website and I got stuck calculating the average age of listings assigned to a particular listing type.
I figured out calculating listing age in days by ID:
$today = date( 'Y-m-d' );
$listing_date = get_the_date( 'Y-m-d', $id );
$diff = strtotime( $today ) - strtotime( $listing_date );
$age = round( $diff / 86400 );
I figured out how to pull listings assigned to a particular listing type by term ID:
$args = array(
'posts_per_page' => -1,
'fields' => 'ids',
'post_type' => 'listing',
'post_status' => 'publish',
'tax_query' => array(
array(
'taxonomy' => 'listing-type',
'field' => 'id',
'terms' => $id
)
)
);
$ids = get_posts( $args );
This gives me an array of IDs of all listings assigned to a particular listing type.
Now I need to calculate the total age in days for all those listings I retrieved IDs for.
I figured $cnt = count( $ids ); to get the total number of retrieved listings (IDs), but I can't figure out calculating the total age in days for those.
With a foreach loop :
<?php
// Your function to get the diff
function get_diff($id) {
$today = date( 'Y-m-d' );
$listing_date = get_the_date( 'Y-m-d', $id );
$diff = strtotime( $today ) - strtotime( $listing_date );
$age = round( $diff / 86400 );
return $age;
}
// We want to store all the diff
$diffs = [];
foreach($ids as $id) {
$diffs[] = get_diff($id);
}
// Get the average | We filter to remove empty values
$diffs = array_filter($diffs);
if(count($diffs)) {
echo $average = array_sum($diffs)/count($diffs);
}

Wordpress : month between 2 dates

I would like to retrieve posts based on the current month.
My customs post type has a start date and an end date.
If the current month is between this period, then retrieve the items.
Someone can help me ?
$date_month = (new DateTime)->format('m');
$start = get_field('start_date');
$end = get_field('start_end');
// parameters of $upcoming
$args_upcoming_period = array(
'posts_per_page' => 10,
'post_type' => array('sports', 'culture'),
'meta_query' => array(
array(
'key' => $date_month,
'compare' => 'BETWEEN',
'value' => array($start, $end),
)
),
);
$upcoming_period = new WP_Query($args_upcoming_period);
you can use this code:
$start_date = "here_value"; //e.g. 2019-01-01
$end_date = "here_value"; //e.g. 2019-02-01
$metaKey = "here_value"; //e.g. date
$args = array(
'post_type' => 'post',
'posts_per_page' => 10,
'meta_query' => array(
array(
'key' => $metaKey,
'value' => array($start_date, $end_date),
'compare' => 'BETWEEN',
'type' => 'DATE'
),
)
);
$result = new WP_Query($args);
Please note, var start_date & end_date they must be in the sql format (e.g. YYYY-MM-DD).
And meta_key compile with field you want filter. (e.g. date)

Wordpress meta_query

I'm struggling with a wp_query and i need your help.
I have 3 custom fields called "Agenda_day", "Agenda_month", "Agenda_year", representing the day, month and year of an event.
I want to order the results of my query by day, then month, and finally year, ascendingly.
Here is my query :
$query_agenda = new WP_Query(
array(
'posts_per_page' => 8,
'cat' => 4,
'meta_query' =>
array(
'relation' => 'AND',
'day' => array('key' => 'Agenda_day', 'compare' => 'EXISTS'),
'month' => array('key' => 'Agenda_month', 'compare' => 'EXISTS'),
'year' => array('key' => 'Agenda_year', 'compare' => 'EXISTS')
),
'orderby' => array('day' => 'ASC', 'month' => 'ASC', 'year' => 'ASC')
)
);
And this does not work ... can you explain me why and show me how to fix it ?
Thank you !
EDIT
Here is the executed query (results are returned but not well ordered)
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id ) INNER JOIN wp_postmeta AS mt1 ON ( wp_posts.ID = mt1.post_id ) INNER JOIN wp_postmeta AS mt2 ON ( wp_posts.ID = mt2.post_id ) WHERE 1=1 AND ( wp_term_relationships.term_taxonomy_id IN (4) ) AND ( wp_postmeta.meta_key = 'Agenda_jour' AND mt1.meta_key = 'Agenda_mois' AND mt2.meta_key = 'Agenda_annee' ) AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') GROUP BY wp_posts.ID ORDER BY CAST(wp_postmeta.meta_value AS CHAR) ASC, CAST(mt1.meta_value AS CHAR) ASC, CAST(mt2.meta_value AS CHAR) ASC LIMIT 0, 8
https://codex.wordpress.org/Class_Reference/WP_Query
https://codex.wordpress.org/Class_Reference/WP_Meta_Query
please check above both links you will get your answer and your orderby arguments which you are passing it's wrong
Problem solved !
i was dealing with different formats in the custom fields : some days and months were on 1 character ("6") and others on two ("06"), so the system couldn't sort it well
second point is, as i'm dealing with dates, i have to reorder the "orderby" instruction from "day, month, year" to "year, month, day"

Find time between order marked as processing to order marked as completed

I want to find the time from order processing to order marked as complete for every order. How can I get that? I have read this and it only gives time for last modified.
This will get all the orders and return the number of seconds between the order being placed and if it is currently at a completed status. You haven't specified a format for the time difference so I have just returned it as a string with the corresponding order id.
$query = new WC_Order_Query( array(
'limit' => -1,
'orderby' => 'date',
'order' => 'DESC',
'return' => 'ids',
) );
foreach( $query->get_orders() as $order_id ) {
$order = wc_get_order($order_id);
if( $order->get_status() === 'completed') {
$order_data = $order->get_data();
$timestamp = $order_data['date_modified']->getTimestamp() - $order_data['date_created']->getTimestamp();
$d1 = new DateTime();
$d2 = new DateTime();
$d2->add(new DateInterval('PT'.$timestamp.'S'));
$order_interval = $d2->diff($d1);
echo 'Order ID : ' . $order->get_id() . ' ' . $order_interval->format('%a days, %h hours, %i minutes and %s seconds');
}
}
have you tried this?
$order_id = 1945;
$order = new WC_Order($order_id);
$order_data = $order->get_data();
$date1 = $order_data['date_created']->date( 'Y-m-d G:i:s' );
$date2 = $order_data['date_modified']->date( 'Y-m-d G:i:s' );
$diff = abs(strtotime($date2) - strtotime($date1));
$years = floor($diff / (365*60*60*24));
$months = floor(($diff - $years * 365*60*60*24) / (30*60*60*24));
$days = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24)/ (60*60*24));
printf("%d years, %d months, %d days\n", $years, $months, $days);
You can improved this by adding a check for the status of the order.

WP_Query: Filter tax_query OR meta_query

How can I combine the result of the tax_query and meta_query?
ex:
tax_query results to:
Post1, Post2.
and meta_query results to:
Post3.
I want to combine the results of the 2 queries.
Here is my partial code:
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'tax1',
'field' => 'term_id',
'terms' => array(1,2,3),
),
array(
'taxonomy' => 'tax2',
'field' => 'term_id',
'terms' => array(1,2,3),
),
),
'meta_query' => array(
array(
'key' => 'meta1',
'value' => '1',
'compare' => '=',
),
),
The same question was asked here but wasn't answered. So I'm re-opening it.
Thanks!
It sounds like you are wanting it to act like an 'OR' where a post that matches either the tax_query or meta_query is returned.
Unfortunately, that's not possible using WP_Query.
You'll either need to write a custom database call, or just query them separately and do your checking on the PHP end (that's ok if you know you'll have a relatively small number of results, but be warned this won't necessarily scale to a huge site).
The only way to achieve a query like that is creating a custom query to the db using the $wpdb global and SQL statements. I think it would be something like this:
global $wpdb;
$querystr =
"
SELECT * FROM $wpdb->posts
LEFT JOIN $wpdb->postmeta ON ($wpdb->posts.ID = $wpdb->postmeta.post_id)
LEFT JOIN $wpdb->term_relationships ON($wpdb->posts.ID = $wpdb->term_relationships.object_id)
LEFT JOIN $wpdb->term_taxonomy as term_taxonomy1 ON($wpdb->term_relationships.term_taxonomy_id = term_taxonomy1.term_taxonomy_id)
LEFT JOIN $wpdb->term_taxonomy as term_taxonomy2 ON($wpdb->term_relationships.term_taxonomy_id = term_taxonomy2.term_taxonomy_id)
LEFT JOIN $wpdb->terms as tax1_term1 ON(term_taxonomy1.term_id = tax1_term1.term_id)
LEFT JOIN $wpdb->terms as tax1_term2 ON(term_taxonomy1.term_id = tax1_term2.term_id)
LEFT JOIN $wpdb->terms as tax1_term3 ON(term_taxonomy1.term_id = tax1_term3.term_id)
LEFT JOIN $wpdb->terms as tax2_term1 ON(term_taxonomy2.term_id = tax2_term1.term_id)
LEFT JOIN $wpdb->terms as tax2_term2 ON(term_taxonomy2.term_id = tax2_term2.term_id)
LEFT JOIN $wpdb->terms as tax2_term3 ON(term_taxonomy2.term_id = tax2_term3.term_id)
WHERE
(
(
(term_taxonomy1.taxonomy = 'tax1')
AND
(tax1_term1.term_id = 1 AND tax1_term2.term_id = 2 AND tax1_term3.term_id = 3)
)
OR
(
(term_taxonomy2.taxonomy = 'tax2')
AND
(tax2_term1.term_id = 1 AND tax2_term2.term_id = 2 AND tax2_term3.term_id = 3)
)
)
OR
(
$wpdb->postmeta.meta_key = 'meta1' AND $wpdb->postmeta.meta_value = '1'
)
ORDER BY $wpdb->postmeta.meta_value ASC
"
$pageposts = $wpdb->get_results($querystr, OBJECT);
Then you could iterate over $pageposts as with a WP_Query loop.

Resources