Offset and AND terms
-
Hi Hector, great plugin. I have two questions.
- Is there a way to offset the posts returned by the shortcode? Like say I have sidebar widget showing the 3 most popular posts 1-3. Then at the end of each post I have another section showing popular posts. That second widget I don’t want it to show the 3 most popular posts because they are already in the sidebar I want the second widget to show posts 4,5,6, in popularity……
- For the shortcode [wpp cat=’1, 55′], this appears to be an OR on the categories. I need to do AND so that it would return only posts in category 1 AND category 55 not posts in either one. Can I do that?
Thank you.
-
This topic was modified 1 year, 5 months ago by
Brad.
-
Hey @saskso,
Is there a way to offset the posts returned by the shortcode?
So here’s the thing: unlike recent posts lists, posts within a popular posts list -pardon the redundancy- might (and most likely will) change positions at any time (even between page loads) so there’s a good chance that this won’t work as you expect it to.
With that being said and since I’m believe you may still want to give it a try, there’s an undocumented
offsetparameter that’s exactly for this use case since someone else requested it a long time ago and I didn’t see a reason to not implement it at the time (and didn’t put a lot of thought into it either.) Hopefully this explains why the parameter isn’t documented anywhere πFor the shortcode [wpp cat=β1, 55β²], this appears to be an OR on the categories. I need to do AND so that it would return only posts in category 1 AND category 55 not posts in either one. Can I do that?
You asked about this 3 years ago (wow, time sure flies!) and I did look into it back then but wasn’t happy with the end result so I abandoned that experiment. Might revisit it again in the future.
For the time being this should do the trick:
/**
* Alters WPP's database query so the category filter uses an "AND" relationship.
*
* @param string $where The original WHERE string
* @param array $options Array of options generated by the shortcode
* @return string $where The (modified) WHERE string
*/
add_filter('wpp_query_where', function($where, $options) {
if ( ! is_admin() && isset($options['term_id']) && $options['term_id'] ) {
global $wpdb;
$term_IDs = explode(',', $options['term_id']);
$pattern = '/AND p.ID IN (.*) AND p.post_password/s';
$replacement = 'AND ( ( SELECT COUNT(1) FROM ' . $wpdb->term_relationships . ' WHERE term_taxonomy_id IN (' . $options['term_id'] . ') AND object_id = p.ID ) = ' . count($term_IDs) . ' ) AND p.post_password';
return preg_replace($pattern, $replacement, $where);
}
// ELSE
return $where;
}, 10, 2);-
This reply was modified 1 year, 5 months ago by
Hector Cabrera. Reason: Updated subquery so term count isn't fixed
I did ask about the AND function before. Maybe at the time WP_QUERY didn’t have
category__andparameter and it does now so it would be easier to implement in the shortcode?Thank you for the code this should work and I will experiment with the offset! I see your point with the changes in what is popular but with larger traffic and a 30 day window they don’t change that frequently for what I have seen.
Hi Hector @hcabrera ,
Something strange is happening with the code you provided above for the AND relationship.
Background, I have a WPP shortcode in some tag pages and the shortcode uses taxonomy=’post_tag’ term_id=’XX’ (just one id, same as the tag page the shortcode is in). I wasn’t wanting to use the AND here with tags (just with categories) and just noticed the below was off when testing.Just pasting your code into the functions.php is causing the shortcode with post_tag to show show posts from a totally different tag than they were before. The category pages where I want to use the AND seems to be fine for now, haven’t fully tested.
Not sure why it would do that…..
An example would be wpp stats_views=0 limit=4 range=’last30days’ taxonomy=’post_tag’ term_id=’201′ on a tag page is working fine. Then I paste in your code from above to functions.php and the same shortcode is now return only showing things from term_id 197! Very strange. Remove AND relationship code and its back to showing the right posts. So your code seem to affect tags and categories and tags unpredictably?
-
This reply was modified 1 year, 4 months ago by
Brad.
I didn’t really test that code snippet with only one term ID since you mentioned that you were using two π I’ll give it a try as soon as I can and adjust where/if needed.
See my edit above for an example of what is happening. I only need it for categories not tags if that matters.
So the plugin builds its own SQL queries and its not as easy as making the plugin use the
category__andparameter from wp_query?Yup, the plugin uses a custom PHP class to build its own DB queries. It doesn’t rely on WP_Query at all (hence the need to write custom code to have the AND relationship stuff going.)
So I’m not really much of programmer but what if I added to the if statement in your code:
&& str_contains($options['term_id'], ',')So if there is a comma then there is more than one term_id so use the replacement code with AND relationship. This should then skip replacing the code when there is only 1 term. Too much of a hack?
Will that work? Fail in way you can see that I’m not anticipating?
-
This reply was modified 1 year, 4 months ago by
Brad.
So my hack doesn’t bomb and the single tag queries are working again but I think maybe something is wrong with the replacement SQL query being built by your code example because whenever I have two categories specified I get WPPs no data message.
I tested with the two biggest categories which probably have over 100 posts common between them and some of the most popular ones on the site and I still get no data with a shortcode like wpp stats_views=0 limit=6 range=’last30days’ cat=’XX,YY’. And a regular single category shortcode shows at least one of the posts that I confirmed are in both categories but that post doesn’t appear when both the categories it is in are specified, just WPPs no data message.I’d have to test with some actual data in order to confirm whether there’s a problem with the code snippet. From my testing with dummy data it seemed to work fine so can’t really say what’s going on on your end.
Anyways, I have some free time now so I’ll do some more testing and will report back once I’m done.
Alright, re-tested the code snippet and these were my results:
- Providing just one term ID returned results as expected
- Using
taxonomy='post_tag' term_id='XX'(where XX is a single term ID as instructed) and this also returned the posts I expected to see
Mind you, all this with the same code snippet from above. No modifications at all.
To answer one of your previous questions, if you don’t want the AND-relationship mod to run with post tags you can do this instead:
/**
* Alters WPP's database query so the category filter uses an "AND" relationship.
*
* @param string $where The original WHERE string
* @param array $options Array of options generated by the shortcode
* @return string $where The (modified) WHERE string
*/
add_filter('wpp_query_where', function($where, $options) {
if (
! is_admin()
&& isset($options['term_id'])
&& $options['term_id']
&& isset($options['taxonomy'])
&& 'category' === $options['taxonomy']
) {
global $wpdb;
$term_IDs = explode(',', $options['term_id']);
$pattern = '/AND p.ID IN (.*) AND p.post_password/s';
$replacement = 'AND ( ( SELECT COUNT(1) FROM ' . $wpdb->term_relationships . ' WHERE term_taxonomy_id IN (' . $options['term_id'] . ') AND object_id = p.ID ) = ' . count($term_IDs) . ' ) AND p.post_password';
return preg_replace($pattern, $replacement, $where);
}
// ELSE
return $where;
}, 10, 2); -
This reply was modified 1 year, 5 months ago by
The topic ‘Offset and AND terms’ is closed to new replies.