This code does not set the object terms. Please help me sort out the issue. The code results in the posts list and doesn't set the terms.
I have checked the below data.
The query results in the list of post.
calculation part in the loop results in the value (lesser or greater than 0)
function set_expired_job_categories() {
global $post;
$current_time = time();
$taxonomy = 'current-status';
$job_expired_id = 368;
$job_ongoing_id = 367;
// Set our query arguments
$args = array(
'fields' => 'ids', // Only get post ID's to improve performance
'post_type' => 'job', // Post type
'post_status' => 'publish',
'posts_per_page' => -1,
'tax_query' => array(
'taxonomy' => 'current-status',
'field' => 'slug',
'terms' => array( 'ongoing' ),
),
);
$job_expiration_query = new WP_Query( $args );
// Check if we have posts to delete, if not, return false
if( $job_expiration_query->have_posts() ){
while( $job_expiration_query->have_posts() ){
$job_expiration_query->the_post();
$postid = get_the_ID();
$expire_timestamp = rwmb_meta( 'deadline_date' );
if ( $expire_timestamp ) {
$seconds_between = ( (int)$expire_timestamp - (int)$current_time );
if ( $seconds_between <= 0 ) {
wp_set_object_terms( $postid, (int)$job_expired_id, $taxonomy, true );
wp_remove_object_terms( $postid, (int)$job_ongoing_id, $taxonomy );
}
}
}wp_reset_postdata();
}
}
add_action( 'set_job_categories', 'set_expired_job_categories', 20, 2 );
As it is in the functions file, I need to set the global $wp_taxonomies to populate the taxonomies data initially. Also, instead of using the tag_ID, I have revised with the slug. These two changes helped to work out the code. The revised code is below for reference.
Thank you all for your efforts.
function set_expired_job_categories() {
global $post;
global $wp_taxonomies;
$current_time = time();
$taxonomy = 'current-status';
$job_expired_id = 'expired';
$job_ongoing_id = 'ongoing';
// Set our query arguments
$args = array(
'fields' => 'ids', // Only get post ID's to improve performance
'post_type' => 'job', // Post type
'post_status' => 'publish',
'posts_per_page' => -1,
'tax_query' => array(
'taxonomy' => 'current-status',
'field' => 'slug',
'terms' => array( 'ongoing' ),
),
);
$job_expiration_query = new WP_Query( $args );
// Check if we have posts to set categories, if not, return false
if( $job_expiration_query->have_posts() ){
while( $job_expiration_query->have_posts() ){
$job_expiration_query->the_post();
$postid = get_the_ID();
$expire_timestamp = rwmb_meta( 'deadline_date' );
if ( $expire_timestamp ) {
$seconds_between = ( (int)$expire_timestamp - (int)$current_time );
if ( $seconds_between >= 0 ) {
}else {
wp_set_object_terms( $postid, (int)$job_expired_id, $taxonomy, true );
wp_remove_object_terms( $postid, (int)$job_ongoing_id, $taxonomy );
}
}
}
wp_reset_postdata();
}
}
// hook it to low priority value, due to CPT and Taxonomies
add_action( 'set_job_categories', 'set_expired_job_categories', 20, 2 );
Reference: https://wordpress.org/support/topic/wp_set_object_terms-in-loop-is-not-work-in-taxonomy-cpt/
Related
I'm working on a WP_Query loop that is suppose to show the list of posts in a following way
+ Custom taxonomy term 1
++ Post 1
++ Post 2
+ Custom taxonomy term 2
++ Post 1
++ Post 2
So in general it will work for CPT called 'career'. In a real life my custom taxonomy (job-category) is like: Drivers, Logistics, HR etc. And to each of such taxonomy/category I've got created specific posts. There is also a custom taxonomy called job-country which suggests the territory.
To achieve the way of showing my posts I am using the following code:
<?php
$terms = get_terms([
'taxonomy' => 'job-category',
'hide_empty' => true,
'orderby' => 'count',
'order' => 'DESC'
]);
usort( $terms, function( $a, $b ) {
$a_ste = (int) get_term_meta( $a->term_id, 'stick_to_end', true );
$b_ste = (int) get_term_meta( $b->term_id, 'stick_to_end', true );
if ($a_ste == $b_ste) return 0;
return ($a_ste < $b_ste) ? -1 : 1;
} );
if ($terms) { //categories exists
foreach ($terms as $category) { ?>
<h2 class="category-title">
<?= $category->name ?>
</h2>
<?php
$posts = get_posts(array(
'posts_per_page' => -1,
'post_type' => 'career',
'tax_query' => [
[
'taxonomy' => 'job-category',
'field' => 'term_id',
'terms' => $category->term_id,
]
]
));
if ( $posts ) {
foreach( $posts as $post ) {
setup_postdata( $post );
include 'JobListThumb.php';
};
wp_reset_postdata();
}
}
} else { //no categories
$posts = get_posts(array(
'posts_per_page' => -1,
'post_type' => 'career'
));
if ( $posts ) {
foreach( $posts as $post ) {
setup_postdata( $post );
include 'JobListThumb.php';
};
wp_reset_postdata();
}
}
?>
And it works. But because of certain reasons (working on an ajax filtering function) I need to achieve the same thing using traditional wp_query.
This is what I've got:
$args = array(
'orderby' => 'date', // we will sort posts by date
'order' => $_POST['date'], // ASC or DESC
'post_type' => 'career',
);
// for taxonomies / categories
if( isset( $_POST['categoryfilter'] ) && isset( $_POST['taxonomyfilter'] ))
$args['tax_query'] = array(
'relation' => 'AND',
array(
'taxonomy' => 'job-category',
'field' => 'id',
'terms' => $_POST['categoryfilter']
),
array(
'taxonomy' => 'job-country',
'field' => 'id',
'terms' => $_POST['taxonomyfilter']
)
);
// if you want to use multiple checkboxes, just duplicate the above 5 lines for each checkbox
$query = new WP_Query( $args );
if( $query->have_posts() ) :
while( $query->have_posts() ): $query->the_post();
echo '<h2>' . $query->post->post_title . '</h2>';
endwhile;
wp_reset_postdata();
else :
echo 'No posts found';
endif;
die();
But I've stucked in a place - how to add those terms / elements to the query? Obviously cannot mix get_terms with wpquery by simply copying instead echo'ing the title.
Do you have any suggestions how to solve this?
I've offert the possibility to my client to choose one by one the related post for each post. I've set up a custom field with ACF and use this to display the choosen posts or random posts :
<?php $terms = get_the_terms( $post->ID , 'custom-taxonomy1' ); if ( !empty( $terms ) ) :?>
<?php
$related_acf = get_field('related_group');
$rel_posts = $related_acf["related posts"];
$related_ids = array();
foreach ( $rel_posts as $rel_post) {
array_push($related_ids, $rel_post['post']);
}
global $post;
$current_post_type = get_post_type( $post );
$terms = get_the_terms( $post->ID , 'custom-taxonomy1' );
$term_ids = array_values( wp_list_pluck( $terms,'term_id' ) );
$post_count_skrn = get_theme_mod('progression_studios_media_more_like_post_count', '3');
if ( count($related_ids) > 0 ) {
$args=array(
'post_type' => array('custompost1', 'custompost2', 'post'),
'post__in' => $related_ids
);
} else {
$args=array(
'post_type' => $current_post_type,
'posts_per_page'=> $post_count_skrn,
'orderby'=>'rand', // Randomize the posts
'post__not_in' => array( $post->ID ),
'tax_query' => array(
array(
'taxonomy' => 'video-genres',
'terms' => $term_ids,
'field' => 'id',
'operator' => 'IN'
)
),
);
}
So I wonder if I can add something like :
if ( count($related_ids) > 0 ) {
$args=array(
'post_type' => array('custompost1', 'custompost2', 'post'),
'orderby'=>'XXXXX', // Ordering the posts with the order of selection
'post__in' => $related_ids
);
Best regards,
Clément
Wordpress have 'orderby'=>'post__in'
Posts will now be displayed according to their position in the $related_ids array
$args=array(
'post_type' => array('custompost1', 'custompost2', 'post'),
'orderby'=>'post__in', // Ordering the posts with the order of selection
'post__in' => $related_ids
);
I have about 25,000 posts here (and rising). All of them under a Custom Post Type "lead".
Each post has meta information, including a variable called "uniqid".
this uniqid is a url parameter. now i need the post id where exactly this uniqid exists.
Now my question is if there is a way to speed up this determination.
I have tried 2 ways once a wp_query and get_results.
I ask because this function that determines the post id is always noted by plugin "query monitor" that it is slow.
These are the 2 approaches, both work. I just wonder if it is possible to speed up here?
The WP_Query solution.
$post_id = false;
$args = array(
'posts_per_page' => -1,
'post_type' => 'lead',
'fields' => 'ids',
'orderby' => 'date',
'order' => 'ASC',
'post_status' => 'publish',
'meta_key' => 'uniqid',
'meta_value' => $uniqid
);
$query = new WP_Query( $args );
if( $query->have_posts() ) {
while( $query->have_posts() ) {
$query->the_post();
// Get Post ID for return
$post_id = get_the_id();
// Break loop, when matching id was found
$uniqidGPM = get_post_meta( $post_id, 'uniqid' , true );
if($uniqidGPM == $uniqid) {
$post_found = true;
break;
}
}
}
wp_reset_postdata();
return $post_id;
The select get_results solution.
$post_id = false;
global $wpdb;
$selectQuery = "SELECT wp_wkdm_posts.ID FROM wp_wkdm_posts INNER JOIN wp_wkdm_postmeta ON ( wp_wkdm_posts.ID = wp_wkdm_postmeta.post_id ) WHERE 1=1 AND ( ( wp_wkdm_postmeta.meta_key = 'uniqid' AND wp_wkdm_postmeta.meta_value = '".$uniqid."' )) AND wp_wkdm_posts.post_type = 'lead' AND ((wp_wkdm_posts.post_status = 'publish')) GROUP BY wp_wkdm_posts.ID ORDER BY wp_wkdm_posts.post_date ASC";
$selectQueryResult = $wpdb->get_results($selectQuery);
if (empty($selectQueryResult)) {
return $post_id;
}else{
$post_id = $selectQueryResult[0]->ID;
return $post_id;
};
Please use this meta_query condition on the same query, it helps you.
$args = array(
'post_type' => 'lead',
'posts_per_page' => -1,
'post_status' => 'publish',
'meta_query' => array(
'key' => 'uniqid',
'value' => 'YOUR_VALUE'
)
);
$query = new WP_Query($args);
I'm using polylang plugin to having multi-languages website.
Using WooCommerce with polylang demands duplicating each product for each language, so assuming I have Hebrew and English, that means 2 duplications for each products.
It works fine with WooCommerce plugin, but when I'm displaying "related products" at the end of the product page, it's mixing products in English and Hebrew together.
I expect to filter the related product by website current language (if(get_locale() == 'en_US') - to check website current locale state, else will represent Hebrew).
Polylang functions
Here is what I have tried, but I got stuck on the part of filtering the product by language:
add_filter( 'woocommerce_product_related_posts', 'custom_related_products' );
function custom_related_products($product){
global $woocommerce;
// Meta query
$meta_query = array();
$meta_query[] = $woocommerce->query->visibility_meta_query();
$meta_query[] = $woocommerce->query->stock_status_meta_query();
$meta_query = array_filter( $meta_query );
// Get the posts
$related_posts = get_posts( array(
'orderby' => 'rand',
'posts_per_page' => '4',
'post_type' => 'product',
'fields' => 'ids',
'meta_query' => $meta_query
) );
if ( $related_posts->have_posts() ) {
while ( $related_posts->have_posts() ) : $related_posts->the_post();
if(pll_get_post_language(get_the_ID())){
//Not sure its the right approach for this..
}
endwhile;
}
$related_posts = array_diff( $related_posts, array( $product->id ), $product->get_upsells() );
return $related_posts;
}
How can I filter Woocommerce related product section by language?
Edit
So after a little bit of research and help in the comments I found out that 'lang' => 'en' argument does exist, but even when I use it, there is no change on related products language display.
Any ideas?
add_filter( 'woocommerce_product_related_posts', 'custom_related_products' );
function custom_related_products($product){
global $woocommerce;
// Meta query
$meta_query = array();
$meta_query[] = $woocommerce->query->visibility_meta_query();
$meta_query[] = $woocommerce->query->stock_status_meta_query();
$meta_query = array_filter( $meta_query );
// Get the posts
$related_posts = get_posts( array(
'orderby' => 'rand',
'posts_per_page' => '4',
'post_type' => 'product',
'fields' => 'ids',
'meta_query' => $meta_query,
'suppress_filters' => false
) );
if ( $related_posts->have_posts() ) {
while ( $related_posts->have_posts() ) : $related_posts->the_post();
if(pll_get_post_language(get_the_ID())){
//Not sure its the right approach for this..
}
endwhile;
}
$related_posts = array_diff( $related_posts, array( $product->id ), $product->get_upsells() );
return $related_posts;
}
suppress_filters There is a way to make get_posts cache the results however, the suppress_filters option is true by default, but if you set it to false, the caching mechanisms inside WordPress will do their work, and results will be saved for later.
You can try this code:
$related_posts = get_posts( array(
'orderby' => 'rand',
'posts_per_page' => '4',
'post_type' => 'product',
'meta_query' => $meta_query,
'lang' => 'en'
) );
if ($related_posts) {
foreach ($related_posts as $post) {
setup_postdata($post);
// something like <li><?php the_title(); ?></li>
}
}
wp_reset_postdata();
This code correctly returns code in selected language on my site
While working on a custom WordPress REST Api end point to fetch post by selected language or device language, this worked. See if it can help you out.
function mycustomplugin_posts($params) {
// get the url params
$page = $params->get_param('page') ? $params->get_param('page') : 0;
$per_page = $params->get_param('per_page') ? $params->get_param('per_page') : 10;
$offset = $params->get_param('offset') ? $params->get_param('offset') : 0;
$order = $params->get_param('order') ? $params->get_param('order') : 'desc';
$order_by = $params->get_param('order_by') ? $params->get_param('order_by') : 'date';
$lang = array_search($params->get_param('lang'),polylang_json_api_languages(), true) ? $params->get_param('lang') : pll_default_language();
$args = [
'post_type' => 'post',
'page' => $page,
'numberposts' => $per_page,
'offset' => $offset,
'order' => $order,
'orderby' => $order_by,
'tax_query' => [
[
'taxonomy' => 'language',
'field' => 'slug',
'terms' => $lang
]
]
];
$posts = get_posts($args);
$data = [];
$i = 0;
foreach($posts as $post) {
// Extract the post data
$data[$i]['id'] = $post->ID;
$data[$i]['title'] = $post->post_title;
$data[$i]['content'] = $post->post_content;
$data[$i]['excerpt'] = e42_the_short_content($post->post_content, 300);
$data[$i]['slug'] = $post->post_name;
$data[$i]['date'] = $post->post_date;
$data[$i]['link'] = get_permalink($post->ID);
$data[$i]['author'] = get_the_author_meta('display_name', $post->post_author);
$data[$i]['categories'] = array();
$data[$i]['featured_image']['thumbnail'] = get_the_post_thumbnail_url($post->ID, 'thumbnail');
$data[$i]['featured_image']['medium'] = get_the_post_thumbnail_url($post->ID, 'medium');
$data[$i]['featured_image']['large'] = get_the_post_thumbnail_url($post->ID, 'large');
foreach(get_the_category($post->ID) as $category){
array_push($data[$i]['categories'],$category->term_id);
}
$i++;
}
// Create the response object
$response = new WP_REST_Response( $data );
// Add a custom status code
$response->set_status( 200 );
return $response;
}
/plugins/woocommerce/templates/single-product/related.php
Move this to child theme
yourtheme/woocommerce/single-product/related.php
And add the following line to the foreach loop
if (pll_current_language()!=pll_get_post_language($post_object->ID)) {
continue;
}
Basically if current language does not match product language we skip over it.
I developed a plugin that reads a csv file in order to create 4 different custom taxonomies (Categories) and 1 custom post type (Post) using PHP and WordPress.
On the Initial import the execution time is less than 6 seconds, however the second time execution takes more than 1 minute in order to reset and re-upload the data.
The issue that I found is on the resetAllPosts function (see code)
public function resetAllPosts() {
$query = new WP_Query( array(
'post_type' => 'psp',
'post_status' => 'publish',
'posts_per_page' => 100
) );
// remove all taxonomies will take too long..
// delete all custom taxonomies terms
$terms_payment = get_terms( 'payment', array( 'fields' => 'ids', 'hide_empty' => false ) );
$terms_country = get_terms( 'country', array( 'fields' => 'ids', 'hide_empty' => false ) );
$terms_currency = get_terms( 'currency', array( 'fields' => 'ids', 'hide_empty' => false ) );
$terms_provider = get_terms( 'provider', array( 'fields' => 'ids', 'hide_empty' => false ) );
foreach ( $terms_payment as $value ) {
wp_delete_term( $value, 'payment' );
}
foreach ( $terms_country as $value ) {
wp_delete_term( $value, 'country' );
}
foreach ( $terms_currency as $value ) {
wp_delete_term( $value, 'currency' );
}
foreach ( $terms_provider as $value ) {
wp_delete_term( $value, 'provider' );
}
while ( $query->have_posts() ) {
$query->the_post();
$post_id = get_the_ID();
// remove the relation between the post and the taxonomies
//wp_delete_object_term_relationships(get_the_ID(),array("provider","payment","currency","country"));
// Remove the feature image from Media gallery
//$post_thumbnail_id = get_post_thumbnail_id( $post_id );
//wp_delete_attachment( $post_thumbnail_id, true );
// delete the post
wp_delete_post( $post_id, "true" );
}
echo "Reset of all data success..";
}
I would like to know the best/fastest way to delete all terms data.