WordPress - WP_QUERY limit findings to posts with exact same values - php

I am facing some issues with my custom taxonomies in one of my custom post types : I have a page that retrieves my custom posts that have the same taxonomy fields as the page.
For example, one of the custom taxonomies shared between the page and the CPT is 'categorie'. Using a tax_query field in a WP_QUERY, I am able to retrieve the posts that do have the same categorie fields checked as my page's, but I can't seem to find how to get posts that have the EXACT same values.
Here are some visuals in case you're confused :
Page taxonomy with values checked
CPT taxonomy with values checked
So they both have the 'chauffage' value checked and no other one.
Let's say now that I have an other custom post that has 'chauffage' checked, but also 'sanitaire'. How do I tell my WP_QUERY not to retrieve it ?
I've tried to use the operator 'AND' inside of my tax_query array (since it is 'IN' by default) but it didn't work.
The idea I had now was to retrieve all of the taxonomy values and say that the unchecked ones use the operator 'NOT IN', which would work I guess if only I managed to do so. I am only able to get the checked ones, even when using wp_get_post_terms with 'hide_empty' set to 0.
Here's my code :
$page_id = $wp_query->get_queried_object()->ID;
$page_category = wp_get_post_terms($page_id, 'categorie', array(
'hide_empty' => 0
));
// var_dump($page_category);
$page_client = wp_get_post_terms($page_id, 'client', array(
'hide_empty' => 0
));
if($page_category) {
$buffer = array();
foreach ($page_category as $category) {
array_push($buffer, $category->slug);
}
$page_category = $buffer;
}
// var_dump($page_client);
if($page_client) {
$buffer = array();
foreach ($page_client as $client) {
array_push($buffer, $client->slug);
}
$page_client = $buffer;
}
$tax_query = array(
'relation' => 'AND'
);
array_push($tax_query, array(
'taxonomy' => 'categ_article_activite',
'field' => 'slug',
'terms' => $page_category,
'operator' => 'AND'
));
// var_dump($page_client);
array_push($tax_query, array(
'taxonomy' => 'client_article_activite',
'field' => 'slug',
'terms' => $page_client,
'operator' => 'AND'
));
// var_dump($tax_query);
$args = array(
'post_type' => 'article_activite',
'meta_key' => '_article_principal',
'posts_per_page' => 1,
'meta_value' => 'on',
'tax_query' => $tax_query,
'order' => 'ASC'
);
$query = new WP_Query($args);
EDIT : I forgot to mention, I also thought about using the operator 'NOT IN' for the values I do not want to retrieve but since the people that are going to use the website may add taxonomy values, it would require to go in the code add this specific value which is not an option

Related

How to get all post categories without custom post type categories?

I am creating a Blog in wordpress.
I have a list of categories:
Technology,
Art,
fashion,
Home,
Lifetime,
Education,
Business,
Religion,
Design and home,
Marketing
In which some of these categories I am using only in Custom Post Type (Technology, Art, Fashion) and others only in Normal Posts (Home, Life, Education, Business, Religion, Design and home, Marketing).
Now I need to get the list of categories that are only being used from normal posts to show them on my blog ().
I tried to do the following but it returns all categories including CPTs:
$categories = get_categories();
foreach($categories as $category) {
echo '<li class="cat-name" . '>' . $category->name . '</li>';
}
I just need to show the categories:
Home, Life, Education, Business, Religion, Design & Home, Marketing.
And exclude those that are being used in CPT.
Please Help!
You need to pass in the arguments and exclude the term_ids or include on the term_ids you want. You can use one of the following: 'exclude', 'exclude_tree', or 'include'.
$args = array(
'taxonomy' => 'category',
'exclude' => array(65,23,98,23,78), // term_ids you want to exclude
'exclude_tree' => (65,23,98,23,78), // term_ids you want to exclude and their descendants/children
'include' => (11,51,90,57,29), // only the term_ids you want to include
'orderby' => 'name',
'order' => 'ASC',
"hide_empty" => 1,
);
$cats = get_categories($args);
foreach ($cats as $cat){
echo $cat_slug = $cat->slug;
}
'include'
Array or comma/space-separated string of term IDs to include. Default empty array.
'exclude'
Array or comma/space-separated string of term IDs to exclude. If $include is non-empty, $exclude is ignored. Default empty array.
'exclude_tree'
Array or comma/space-separated string of term IDs to exclude along with all of their descendant terms. If $include is non-empty, $exclude_tree is ignored. Default empty array.
Learn more about all the arguments you can pass to get_categories() or get_terms(), get_posts() etc
https://developer.wordpress.org/reference/classes/wp_term_query/__construct/
Try WP_Query if the above isn't working
$args = array(
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => array( 'home', 'life', 'education', 'business', 'religion', 'design-and-home', 'marketing' ),
'operator' => 'IN'
),
array(
'taxonomy' => 'custom_taxonomy_registerd_to_cpt_slug', // again make sure in your cpt plugin that this taxonomy is unique and not just 'category'
'field' => 'slug',
'terms' => array( 'technology', 'art', 'fashion' ),
'include_children' => false,
'operator' => 'NOT IN'
)
)
);
$cats = new WP_Query($args);
foreach ($cats as $cat){
print_r($cat); // use this to find the values you need. Remove after you build the link html
}
This function with shortcode is tested and work for me
<?php
function list_categories_func($atts) {
$a = shortcode_atts( array('' => '',), $atts );
$args = array('taxonomy'=>'category','parent'=>0,'orderby'=>'name','order'=>'ASC', 'hide_empty'=>0,);
$categories=get_categories($args);
echo "<ul>";
foreach($categories as $category){
$name=$category->slug;
echo "<li>$id</li>";
}
echo "</ul>";
$output = ob_get_contents();
ob_end_clean();
return $output;
}
add_shortcode( 'ni_categories_row', 'list_categories_func' );
?>

Wordpress posts count with comman tags within specific category

i have two categories 'A' and 'B'. Both have 5 posts(each) with tag 'C'. How i can display the number of posts as 5 in Category 'A' or 'B' page. It showing total number of post with tag 'C' as 10. I need to show it as 5. How i can pass category variable to display exact count with tag within specific category. Here is my current code:
$tag = get_term_by('name', $tags,'post_tag');
$count = $tag->count;
reference: https://codex.wordpress.org/Function_Reference/get_term_by
This is not possible with the get_term_by() method.
Try this:
$args = array(
'posts_per_page' => -1,
'tax_query' => array(
'relation' => 'AND', // only posts that have both taxonomies will return.
array(
'taxonomy' => 'post_tag',
'field' => 'name',
'terms' => 'TAG_C', // you can also use an array with tags.
),
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => 'CATEGORY_B', // you can also use an array with categories.
),
),
);
$posts = get_posts($args);
$count = count($posts);
I haven't tested this code, but it should work. Ofcourse you do have
to set the correct terms.
UPDATE
When dealing with many posts I would create a $wpdb sql query that counts the rows, so only a number is returned and not all the posts. You can find an sql count example here.
You can use "found_posts" property of the WP_Query class object.
$args = array(
'posts_per_page' => 10,
'category_name' => 'aaa', // category slug
'tag' => 'ccc' // tag slug
);
$wp_query = new WP_Query( $args );
echo "Total posts count: ".$wp_query->found_posts;

related post by taxonomy custom plugin developement issue

I am facing issue with a custom plugin, which will show related post by taxonomy from a particular category(mobile). If there are no post matching taxonomy, it should display other posts from that particular category. First I fetched all taxonomies and terms for the current post(single.php). Then I prepare a query argument using loop. The code works for the below cases,
a) I have not added any post tag(current post), then it's showing other posts from the same category(mobile),
b) If I have added a post tag, and there are other post matching the terms of that post tag.
But, it's don't work when I have added a post tag, and there are no post matching those terms. But, here I want, if there are no matching post by the terms, then just display other posts irrespective of terms. I can do this, using a new query when have_posts fails, but I am thinking if there are any other way to do this withing the same query args, please help
I am placing the code which I am trying to develop.
$post_args = array();
$taxonomies = get_post_taxonomies( $post );
foreach ($taxonomies as $key => $taxonomy) {
# code...
if($taxonomy == 'category') continue;
$terms = wp_get_post_terms( get_the_ID(), $taxonomy );
$term_array = array();
if($terms){
foreach ($terms as $key => $value) {
array_push($term_array, $value->slug);
}
array_push($post_args,
array(
'taxonomy' => $taxonomy,
'field' => 'slug',
'terms' => $term_array,
)
);
}
}
$tax_query = array();
$tax_query['relation'] = 'OR';
foreach ($post_args as $key => $value) {
# code...
array_push($tax_query, $value);
}
$args = array(
'post_type' => 'post',
// 'category_name' => 'mobiles',
'post__not_in' => array($curr_post_id),
'posts_per_page' => 10,
'orderby' => 'relevance',
'order' => 'ASC',
'tax_query' =>
array(
'relation' => 'AND',
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => 'mobiles',
)
,
array($tax_query)
)
);
$the_query = new WP_Query( $args );
After trying a lot, I just decided to use another post loop. Say, if there are no result from first loop, just select random post from the category. If there are few posts(Max 10 posts) from the first loop, then user another loop to select random posts excluding the post ids we get from first loop.

Display "Related Posts" based on ACF Relationship Field

I want to display "Related posts" of a single post page with custom post type named 'property' which is using the ACF Relationship Field for another custom post type.
That other post type is 'contact' and in the Single Properties post type, the relationship field is calling out for that. I have been trying to understand ACF's documentation here, but I was not able to really comprehend why my code isn't working.
I need to show related properties based on the brokers. I don't fully understand SQL statements and table joining.
$properties = get_posts(array(
'post_type' => 'property', // Page Custom Post Type
'posts_per_page' => 6,
'meta_query' => array(
// 'relation' => 'AND',
// array(
'key' => 'contact', // Field name with 2nd custom post type, 'contact'
'value' => '"' . get_the_ID() . '"',
'compare' => 'LIKE'
// )
)
));
Turns out the reason that this was messed up was due to the way ACF stored the array. Their documentation, while it works for their case, was off in mine due to a nester array.
This is what worked for me.
// This is the start of figuring out the array issue
$contact = get_field( 'contact' );
// This showed me the first array
$contact_array = $contact[0];
// This showed me the ACF array and allowed me to return the ID
$contact_ID = $contact_array->ID;
$properties = get_posts(array(
'post_type' => 'property',
'posts_per_page' => 6,
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'contact',
// Had to call the value like this as the array was nested like
// a:2:{i:0;s:3:"123";i:1;s:3:"321";} or something.
'value' => '"' . $contact_ID . '"',
'compare' => 'LIKE'
)
)
));
A more complex query with an additional taxonomy called medienform
// Shortcode for ACF - Add Relationship ACF field [sc_acf_fields]
//
add_shortcode( 'sc_acf_fields', 'related_relationship' ); // Add your shortcode here
function related_relationship() {
// get the taxonomy medienform
$cat_taxonomies = get_terms( 'medienform', $args );
$count = count($cat_taxonomies); // wird nicht verwendet
//
/// foreach category as $form_category - medienform
//
foreach ( $cat_taxonomies as $form_category ):
// check the arguments of the post_type, orderby
$args =array(
'posts_per_page' => -1,
'post_type' => 'materialien', // the CPT
'orderby' => 'title', // menu_order
'order' => 'ASC', // DESC
'tax_query' => array( // the tax_query is important to list the posttypes to its taxonomies
'relation' => 'AND',
array(
'taxonomy' => 'medienform',
'field' => 'slug',
'terms' => $form_category->slug
)
),
'meta_query' => array( // the meta_query is important to list only the related posts of the key
array(
'key' => 'post-relationship', // name of custom field Relationship in: https://qualitaetsoffensive-teilhabe.de/wp-admin/post.php?post=12067&action=edit&classic-editor=1
'value' => '"' . get_the_ID() . '"', // matches exactly "123", not just 123. This prevents a match for "1234"
'compare' => 'LIKE'
)
),
);
//
// make an own WP_Query from the $args
$materials = new WP_Query( $args );
//
// let´s give the category ->name here and the term_link().
// actually a category should only be displayed when it has some child // here we build the accordeon
//
if ($materials->have_posts() ) {
echo '<h4>' . $form_category->name . '</h4>';
};
//
// while schleife
while ( $materials->have_posts() ) {
//
//// use variable as the_post() query
$materials->the_post();
?>
<div class="post-loop-single">
<div class="thumbnail-img"><span><?php the_post_thumbnail('post-thumb'); ?> </span></div>
<div class="post-loop">
<div class="post-loop-title"><?php the_title(); ?></div>
</div>
</div>
<?php } wp_reset_query();
endforeach;

Wordpress filter tag by category (grab category from uri)

I know there are many question about how to filter tags by category, but I need some help.
$args = array(
'tag' => get_queried_object()->slug,
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => 'interior',
),
)
);
//get all posts
$posts_new = get_posts($args);
It work, but I would like to grab the category from the URL when it's like example.com/tag/lexington/?category=interior or example.com/tag/lexington/category/interior, to use it in the terms parameter from the above query.
Thanks for your attention.
In the last hours I've tries to do this in my functions.php:
function category_tag_rewrite_rule()
{
add_rewrite_tag('%tag_category%', '([^&]+)');
add_rewrite_rule('^tag/([^/]+)/?', 'index.php?tag=$matches[1]&tag_category=$matches[2]');
}
add_action('init', 'category_tag_rewrite_rule');
Now it's sending me to the tag page (tag.php template), but get_query_var('tag_category') returns me nothing from this template.
Something may be wrong with my regexp.

Categories