I have a json file with data for custom taxonomy.
And then I need to filter that.. I do not have any problem with postmeta link and other fields. But i can't get the category into json. And then can't filtering that.
I know the answer must be very simple but i can't figure it out for 2 days.
function getItems( $meta_query ) {
$params = array(
'post_type' => 'property',
'nopaging' => true,
'post_status' => 'publish',
'meta_query' => array(),
$meta_query = array('meta_query'=>array(), 'relation' => 'AND');
if (!empty($_POST['city']))
{
$params['meta_query'][] =array(
'key' => 'property_city',
'value' => $_POST['city'],
'compare' => 'LIKE'
);
}
if(!empty($_POST['parish']))
{
$params['meta_query'][] = array(
'key' => 'property_state',
'value' => $_POST['parish'],
'compare' => 'LIKE'
);
}
//..................ETC..........................
What i have for category now:
//if (!empty($_POST['category']))
/*{
$params['meta_query'][] = array(
'taxonomy' => 'pcategory',
'field' => 'slug',
'terms' => $_POST['category']->slug
);
}*/
$itemsQuery = new WP_Query();
$properties = $itemsQuery -> query($params);
// add property details
foreach ($properties as $key => $property) {
// options
$property->optionsDir = get_post_meta($property->ID, 'property', true);
$city = get_post_meta($property->ID, 'property_city', true);
$parish = get_post_meta($property->ID, 'property_state', true);
$link = get_permalink($property->ID);
$category = get_the_terms($property->ID,'pcategory' );
$properties[$key]->link = array(
'link' => $link,
);
//postmeta
$properties[$key]->postmeta = array(
'city' => $city,
'parish' => $parish,
'region' => $region,
'link' => $link,
'category' => $category,
);
}
return $properties;
}
$category = get_the_terms($property->ID,'pcategory' );
Above code will return, all details like, term id, name, slug etc. information about that term, as an array object.
You need to extract the required details.
Also, "pcategory" is custom taxonomy.
Therefore, in below code,
$properties[$key]->postmeta = array(
'city' => $city,
'parish' => $parish,
'region' => $region,
'link' => $link,
'category' => $category,
);
'category' will not be interpreted properly, as it is custom taxonomy and not default wordpress taxonomy.
If these parameters are sent to WP_Query(), you can mention 'tax_query' as below,
'tax_query' => array(
array(
'taxonomy' => 'pcategory',
'field' => 'slug',
'terms' => 'demo'
)
Here, "demo" is example slug for custom taxonomy.
Even, single post can have multiple category associated with it. Therefore, you need to extract desired category details.
In 'tax_query' you can also specify, "term_id" or other details.
Related
I have a custom post type "events" with a custom taxonomy "events_cat" which has category-1, category-2 etc.
This is my code in taxonomy.php
<?php
$today = date('Ymd');
$cat_slug = get_queried_object()->slug;
$args = array(
'post_type' => 'events',
'nopaging' => true,
'meta_key' => 'expiry',
'tax_query' => array(
array(
'taxonomy' => 'events_cat',
'field' => 'slug',
'terms' => $cat_slug
)
),
'meta_query' => array(
array(
'key' => 'expiry',
'value' => $today,
'compare' => '>='
)
)
);
$events = new WP_Query( $args );
if ( $events->have_posts() ) :
?>
<?php while ( $events->have_posts() ) : $events->the_post(); ?>
// my code
<?php endwhile; wp_reset_postdata(); ?>
<?php endif; ?>
What I need is to filter my post by category and if it is expired or not at the same time.
I explain better: I have one page with all expired posts and another one with all not expired posts.
What I need is that if I click on a category in the "expired page" I just want the list of the expired posts and vice versa.
I was thinking of a condition to change the compare value depending on whether or not the post has expired but I can't figure out how I can do it.
EDIT
I tried such a thing but of course it doesn't work because $expiry is null.
if($expiry >= $today) {
$compare = '>=';
} else {
$compare = '<';
}
$args = array(
'post_type' => 'events',
'nopaging' => true,
'meta_key' => 'expiry',
'tax_query' => array(
array(
'taxonomy' => 'events_cat',
'field' => 'slug',
'terms' => $cat_slug
)
),
'meta_query' => array(
array(
'key' => 'expiry',
'value' => $today,
'compare' => $compare
)
)
);
Does anyone have a better idea on how this can be done or point me in the right direction?
I finally solved the problem by using the $_GET super global variable. I don't know if it's the most correct method but it's the only one I've found. If anyone has a better idea please let me know.
I added "?expired" to the category links of expired posts so I can do this:
$today = date('Ymd');
$compare = '>=';
if( isset($_GET['expired'])) {
$compare = '<';
}
args = array(
'post_type' => 'events',
'nopaging' => true,
'meta_key' => 'expiry',
'tax_query' => array(
array(
'taxonomy' => 'events_cat',
'field' => 'slug',
'terms' => $cat_slug
)
),
'meta_query' => array(
array(
'key' => 'expiry',
'value' => $today,
'compare' => $compare
)
)
);
My question is similar to this one, but it's now 7 years old, so I thought I'd ask again.
I'm using the get_posts() function but it seems that whatever is passed as the 's' parameter is only matched against the post title. For example, this code only returns posts containing 'sunflower' in the title, not posts containing 'sunflower' in one of their tags
$args = array( 'numberposts' => 99, 's' => 'sunflower');
$postslist = get_posts( $args );
I'm just starting out with WP development, so maybe I'm overlooking something or using the wrong function... Any pointers will be greatly appreciated!
To additionally get posts with 'sunflower' as a tag you need to add taxonomy parameters like so:
$args = [
'numberposts' => 99,
's' => 'sunflower',
'tax_query' => [
[
'taxonomy' => 'post_tag',
'field' => 'slug',
'terms' => 'sunflower'
]
]
];
$postslist = get_posts( $args );
Official docs: https://developer.wordpress.org/reference/functions/get_posts/
IMHO this is much more complicated than it should be, but I managed to get what I want with the following code:
$searchTerm = trim($_REQUEST['search']);
// Get all slugs that are a partial match in tags
$matching_terms_tags = get_terms( array( 'taxonomy' => 'post_tag', 'fields' => 'slugs', 'name__like' => $searchTerm ) );
// Get all slugs that are a partial match in categories
$matching_terms_categories = get_terms( array( 'taxonomy' => 'category', 'fields' => 'slugs', 'name__like' => $searchTerm ) );
// Build taxonomy query
$argsTax = array('numberposts' => 999, 'posts_per_page' => -1, 'nopaging' => true);
$argsTax['tax_query'] = array
(
array
(
'relation' => 'OR',
array ('taxonomy' => 'category', 'field' => 'slug', 'terms' => $matching_terms_categories,'operator' => 'IN',),
array ('taxonomy' => 'post_tag', 'field' => 'slug', 'terms' => $matching_terms_tags, 'operator' => 'IN', ),
),
);
// Get all posts with matching tags and/or matching categories
$postsTax = get_posts($argsTax);
// Also get all posts matching the term, using the regular WP argument 's'
$argsTerms = array('numberposts' => 999, 'posts_per_page' => -1, 'nopaging' => true, 's' => $searchTerm);
$postsSearch = get_posts($argsTerms);
// Merge the 2 result sets and remove duplicates
$postsAll = array_merge($postsSearch, $postsTax);
$postAllNoDupes = array_map("unserialize", array_unique(array_map("serialize", $postsAll)));
foreach ($postAllNoDupes as $post)
{
echo get_the_title($post);
}
wp_reset_query();
I have the following code:
add_action( 'woocommerce_product_query', array($this, 'b2bking_hide_products_category_visibility') );
function b2bking_hide_products_category_visibility($q ){
$tax_query = (array) $q->get( 'tax_query' );
$tax_query[] = array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $visiblecategories,
'operator' => 'IN'
);
$q->set( 'tax_query', $tax_query );
// Set query to only select products that are in "default" category mode, not manual visibility mode
$q->set('meta_query', array(
array(
'key' => 'b2bking_product_visibility_override',
'value' => 'default',
)
));
/* SEPARATE META QUERY
$q->set('meta_query', array(
'relation' => 'AND',
array(
'relation' => 'OR',
array(
'key' => 'b2bking_group_'.$currentusergroupidnr,
'value' => '1'
),
array(
'key' => 'b2bking_user_'.$currentuserlogin,
'value' => '1'
)
),
array(
'key' => 'b2bking_product_visibility_override',
'value' => 'manual',
)
));
*/
}
}
I currently have (tax query AND meta query)
I would like to have (tax query AND meta query) OR (separate meta query)
How can I achieve this? Can it be done within the "woocommerce_product_query" action? If so, what is the right syntax?
Thank you
I figured it out:
You use
$q->set('post__in', $postIDs);
This makes WooCommerce show the exact array of products in the $postIDs array;
The final code looks like this:
add_action( 'woocommerce_product_query', array($this, 'your_product_function') );
function your_product_function(){
/* MAKE YOUR 2 CUSTOM PRODUCT QUERIES AS WP QUERIES */
$queryA = new WP_Query($queryAparams);
$queryB = new WP_Query($queryBparams);
$postIDs= array_merge($queryA->posts,$queryB->posts);
/* IMPORTANT, if the ARRAY is EMPTY, ALL PRODUCTS WILL BE SHOWN. A quick bypass is to pass an array of invalid ids as you can see below */
if(!empty($allTheIDs)){
$q->set('post__in',$postIDs);
} else {
$q->set('post__in',array('invalidid'));
}
}
Very important is to pass 'fields'->'ids' in the parameters to get only IDs
this is how the individual queries look like
$queryBparams = array(
'posts_per_page' => -1,
'post_type' => 'product',
'fields' => 'ids',
'meta_query'=> array(
'relation' => 'AND',
array(
'relation' => 'OR',
array(
'key' => 'b2bking_group_'.$currentusergroupidnr,
'value' => '1'
),
array(
'key' => 'b2bking_user_'.$currentuserlogin,
'value' => '1'
)
),
array(
'key' => 'b2bking_product_visibility_override',
'value' => 'manual',
)
));
We have 10 categories, say A, B, C, D, etc
We have 1 tag, say tag
The function get_categories will get all categories that have posts in them (by default), but what we need is that same function, only we need to get only categories with posts that have a certain tag.
So category A has 5 posts with tag tag, Category B has none, Category C has 3. Then I want to see A and C in this list.
Is it possible to filter get_categories by tag?
Update 1
Tried
$terms = get_terms( array(
'taxonomy' => 'category',
'hide_empty' => true,
'meta_query' => array(
array(
'key' => 'tag',
'value' => 'my-tag-slug',
'compare' => '=',
),
),
) );
Also tried with Tag ID. It's the standard post categories and tags that I'm using.
Use get_terms() instead and make use of the meta_query args you can use: https://developer.wordpress.org/reference/functions/get_terms/
Something like:
$terms = get_terms( array(
'taxonomy' => 'category',
'hide_empty' => true,
'meta_query' => array(
array(
'key' => 'tag',
'value' => 'tag',
'compare' => '=',
),
),
) );
This does differ depending on what version of WordPress you are using - so check the documentation.
Look at https://codex.wordpress.org/Class_Reference/WP_Query for more on the 'meta_query' part of the arguments.
UPDATE
Try something like this (note change {tag-slug} to your required tag slug
// Get the categories
$terms = get_terms( array(
'taxonomy' => 'category',
) );
// Loop through them
foreach($terms as $term) {
// Get the posts in that category with the required tag
$args = array(
'category_name' => $term->name,
'tax_query' => array(
array(
'taxonomy' => 'post_tag',
'field' => 'slug',
'terms' => '{tag-slug}'
)
)
);
$posts_array = get_posts( $args );
foreach ($posts_array as $value) {
// save what you need here - maybe an array for each category with the posts so you can run a count on them?
}
}
My issue is pretty simple, I'm trying to get both portfolio posts (from a plugin) and articles that have the "portfolio" category (made myself).
$args = array(
'post_type' => 'portfolio',
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => 'portfolio',
)
)
);
$query = new WP_Query($args);
It looks like the relationship between post_type and tax_query is an AND, I'd need an OR, how can I do that?
I tried following the official documentation but I'm stuck. (https://codex.wordpress.org/Class_Reference/WP_Query)
Thanks for the help.
Here is an example with a relation 'OR':
$args = array(
'post_type' => 'portfolio',
'meta_query' => array(
'relation' => 'OR', /* <-- here */
array(
'key' => 'color',
'value' => 'blue',
'compare' => 'NOT LIKE'
),
array(
'key' => 'price',
'value' => array( 20, 100 ),
'type' => 'numeric',
'compare' => 'BETWEEN'
)
)
);
$query = new WP_Query( $args );
I haven't found any solution using only one query. (couldn't change the AND to OR).
So I've made two queries instead:
$query1 = new WP_Query(array('post_type' => 'portfolio'));
$query2 = new WP_Query(array(
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => 'portfolio',
)
)));
$query = merge_WP_queries($query1, $query2);
function merge_WP_queries(WP_Query $query1, WP_Query $query2){
$wp_query_returned = new WP_Query();
$wp_query_returned->posts = array_merge( $query1->posts, $query2->posts );
//populate post_count count for the loop to work correctly
$wp_query_returned->post_count = $query1->post_count + $query2->post_count;
return $wp_query_returned;
}
It works correctly, even though it's not what I'd like to use.