Wordpress - Sorting posts by expiry date - wordpress

I'm trying to show expired posts AFTER non-expired posts. How can I do this?
I've added a custom field "Expiration Date", in which I store the expiration dates in yyyy/mm/dd format. Problem is, if I order my results by this field, future expiry dates come first.
So I created a repeating cron-job which compares the dates and creates a secondary custom field "Expiration Date Passed" for posts whose dates have passed. I tried ordering by this field, but WP only shows posts with a value for this field - IE posts with no expiry date, or expiry dates in the future, don't show. So I tried auto-adding values '99999999' for any post which haven't expired yet. Problem is, WP can't order by custom field values THEN date- IE the first posts with value '99999999' are in a random order.
I also tried doing two queries for posts, one without expired posts, one with, then merging these two arrays. So the data is in the right order - but it screwed up WP's pagination.
Help, I'm running out of ideas!

Since you have an "Expiration Date Passed" custom field , you could first create two sets of Posts using that custom field in your get_posts arguments to differentiate between current & expired Posts
$meta_key and $meta_value
(string) (optional) Only show posts that contain a meta (custom) field with this key and value. Both parameters must be defined, or neither will work.
Default: None
extract from:
http://codex.wordpress.org/Function_Reference/wp_get_recent_posts
then you'll be able to sort each set the way you want

That might work, but I am trying to sort the posts on my category pages. Wp_get_recent_posts function is usually used for creating custom loops, not modifying 'the loop' in category (archive template) pages.
In the end I sorted it with this. I added this code to the top of my archive template:
global $query_string;
query_posts($query_string . "&orderby=meta_value&meta_key=Expiration Date Passed&order=DESC");
I created a "sort" custom field called "Expiration Date Passed". A cron job then looks to see whether the post has an expiration date. If it doesn't, or if the date is in the future, it puts the post's publish date + 20 years in the sort column. If the post's expiration has passed, it puts the post's publish date in the sort column. Thus it results in the order I was after:
1) Posts which haven't expired, in date order
2) Posts which have expired, in date order
Thought I would post that solution in case anyone else wanted to know.

Related

Woocommerce Modify or Reset total_sales

I want to change or reset the total_sales to 0 at worst.
When I modify in phpMyAdmin (wc_product_meta_lookup) nothing happens and everything goes back to the way it was before after a new order.
I searched for 2 hours without finding anything.
thank you in advance.
total_sales is a post meta field, a row in postmeta table. wc_product_meta_lookup just contains consolidated data from postmeta to avoid making multiple postmeta selects when product data are needed.
postmeta is the source of truth in this case, you need to set your desired value in there. Either directly in the database or using a custom field in the product edit view.
Reports (including total sales value in the dashboard widget) are dynamically generated, so I believe the value your setting in the database will just be set back to it's true value when WordPress runs.
According to the docs, you need to delete all prior orders (permanently) and clear your browser cache for new reports.
More info: https://docs.woocommerce.com/document/reports/#section-12

Woocommerce: how do I add metadata to a cart item?

I have a digital product which is described by a quantity and a price, but which also needs 3 more numbers to completely specify it (Unix dates, etc). Problem: how do I get these numbers into the cart?
As far as I can see, there are 2 possible ways to handle this:
A product variation
A product custom field
It looks like variations can only handle discrete values with a limited range (ie. red/yellow/green, S/M/L, etc), and can't handle general integers, like dates. That leaves custom fields. I think I'm right in saying that custom fields are ordinary meta data on the product post page, so I can handle them with get_post_meta and update_post_meta.
So, if I go for custom fields, then I would update the product page field during ordering, and then I would read back the field during checkout, when the WC_Order is created, and add the field to the new order. However, this won't work. I can't change metadata on the product page, because the product is global to all customers, and this operation would interfere with other customers. In other words, you can't store order-specific information in a product, so neither of these options would work.
So, how do I store temporary product metadata and pass it between the ordering and checkout phases (ie. between WC_Cart and WC_Order)?
One option would be to store it as user metadata (or as session data?), but there's got to be a better way - any ideas?
It turns out to be easy to do this with session data. When you're adding an item to the cart (see the source for add_to_cart_action) you create a session variable, containing all your additional meta data:
WC()->session->set(
'my_session_var_name',
array(
'members' => $members,
'start' => $start,
'expiry' => $expiry,
'etc' => $etc));
When the user checks out, the cart data disappears, and a new order is created. You can hook into woocommerce_add_order_item_meta to add the session meta data to the order meta data:
add_action(
'woocommerce_add_order_item_meta', 'hook_new_order_item_meta', 10, 3);
function hook_new_order_item_meta($item_id, $values, $cart_item_key) {
$session_var = 'my_session_var_name';
$session_data = WC()->session->get($session_var);
if(!empty($session_data))
wc_add_order_item_meta($item_id, $session_var, $session_data);
else
error_log("no session data", 0);
}
That's it. You do have to figure out how to get the order metadata out and do something useful with it, though. You may also want to clear the session data, from hooks into woocommerce_before_cart_item_quantity_zero, and woocommerce_cart_emptied. There's gist here which has some example code for this.

Pagination in application which use firebase.com as database

Front end application will use firebase.com as database.
Application should work like blog:
Admin add / remove posts.
There are "home" page which show several articles per page with "Next" and "Prev" buttons and page which show single article.
Also I need deep linking.
I.e. when user enter URL http://mysite.com/page/2/ I need that application show last articles from 10 to 20, when user enter URL http://mysite.com/page/20/ application show last articles from 200 to 210. Usual pagination.
Main question - is it possible to achieve this if use firebase.com.
I read docs at firebase.com, I read posts here. "offset()" and "count()" will be in the future, use priority, in order to know count of items and not load all of them use additional counter.
Based on this I suppose this:
ADD POST action:
get value of posts counter
set priority for new post data equals to value of posts counter
increase value of posts counter
DELETE POST action
get value of priority for post data
query posts data which have value of priority more than priority for post data which will be deleted and decrease their value
decrease value for posts counter
GET POSTS FROM x TO y
postsRef.startAt(null, x).endAt(null, y).on(... and so on)
Thing which I not like in this way are actions for DELETE POST. Because index of posts will be from 0 to infinity and post with less priority is considered as post which was created earlier so if I have 100000000 posts and if I need to delete 1st post then I need to load data for 99999999 next posts and update their priority (index).
Is there any another way?
Thanks in advance, Konstantin
As you mentioned, offset() will be coming, which makes your job easier.
In the meantime, rather than using startAt and endAt in combination, you could use startAt and limit in combination to ensure you always get N results. That way, deleted items will be skipped. You then need to check the last id of each page before moving to the next to find the proper id to start on.

Amazon MWS API, listing seller's products that is updated after a specific date

I am trying to list the products of a seller (using marketplaceID) that is created or updated after a specific date.
I tried RequestReport with ReportType "_GET_MERCHANT_LISTINGS_DATA_" and setting StartDate to the target date but the data returned contains products that are created (or lastly updated) before that date.
https://developer.amazonservices.com/
The documentation is not very specific on what 'StartDate' actually does:
Start of a date range used for selecting the data to report.
Type: xs:datetime
Default: Now
If I recall correctly, this date does not relate to a products modification timestamps but to a products existance in the database. As an example, setting StartDate to yesterday should give you a list of products that were in the database within the last 24 hours. This includes products that were recently created and products that were created way before that but still exist.
I don't think it is possible to get a list of products that were modified within a timeframe (again, I'm writing this from my recollection on how this worked when I played with it)

In Wordpress: Group same-day posts on the index page

i'm looking for a way to code the loop in such a way that it places posts that are in the same day within a div. Im doing this so I can put a separator between the different days to show users that they are looking at another day. An example of this in action is in informedlondon.com, where once a days worth of posts ends, there is a little graphic in between to separate the posts. This is what Google's Blogger platform does by default, thats why it was easy for the divider to be put between the different days of posts.
I'm guessing there must be a tutorial about it somewhere but I have checked and can't seem to find one. I have a sneaky suspicion that it's very easy and i'm just being a dunce. Would appreciate some help.
Many thanks in advance.
The simplest method to accomplish things like this is to 'hold' the current date in a variable. Before your loop: var $current_date and then inside your loop, a simple if statement:
if( $current_date != get_the_date('d-m-Y') ){
echo '<h2>Posts for '.get_the_date('d-m-Y').'</h2>';
$current_date = get_the_date('d-m-Y');
}
So in effect, you're checking with each post whether the date of the post is different than the date of the last post rendered (in the 'holding' variable, $current_date). If it is, you print a title with the new date, and set the 'holding' variable to the new date. If not, nothing happens and the post is printed as usual.

Resources