Make WooCommerce products featured programmatically - php

I've tried:
update_post_meta( $product->ID, '_featured', 'true');
But it didn't seem to work
I'm seeing that that removed this as the way to update the featured status of products in WooCommerce but can't find how to do it now
Im trying to get all of my featured and non featured dokan sellers and then update all of their products as featured or non featured based on their store featured status, through something like this:
$args = array( 'featured' => 'yes' );
$featured = dokan_get_sellers( $args );
$args = array( 'featured' => 'no' );
$not_featured = dokan_get_sellers( $args );
foreach ( $featured['users'] as $seller ) {
$products_f = get_posts( array(
'post_type' => 'product',
'author' => $featured->ID,
'posts_per_page' => -1
) );
}
foreach ( $not_featured['users'] as $seller ) {
$products_nf = get_posts( array(
'post_type' => 'product',
'author' => $not_featured->ID,
'posts_per_page' => -1
) );
}
foreach ( $products_f as $product) {
update_post_meta( $product->ID, '_featured', 'true');
}
foreach ( $products_nf as $product) {
update_post_meta( $product->ID, '_featured', 'false');
}
Current code:
add_action( 'set_featured_hook', 'set_featured' );
function set_featured(){
$args_featured = array( 'featured' => 'yes' );
$featured = dokan_get_sellers( $args_featured );
$args_nf = array( 'featured' => 'no' );
$not_featured = dokan_get_sellers( $args_nf );
foreach ( $featured['users'] as $seller ) {
$products_f = get_posts( array(
'post_type' => 'product',
'author' => $seller->ID,
'posts_per_page' => -1
) );
}
foreach ( $not_featured['users'] as $seller ) {
$products_nf = get_posts( array(
'post_type' => 'product',
'author' => $seller->ID,
'posts_per_page' => -1
) );
}
foreach ($products_f as $product) {
$wc_product_f = wc_get_product($product->ID);
$wc_product_f ->set_featured(1);
$wc_product_f ->save();
}
foreach ($products_nf as $product) {
$wc_product_nf = wc_get_product($product->ID);
$wc_product_nf->set_featured(0);
$wc_product_nf->save();
}
}
Thanks

foreach ($products_f as $product) {
$wc_product = wc_get_product($product->ID);
$wc_product->set_featured(1);
$wc_product->save();
}
foreach ($products_nf as $product) {
$wc_product = wc_get_product($product->ID);
$wc_product->set_featured(0);
$wc_product->save();
}
Use the built-in WooCommerce method set_featured() for updating the product.

Related

Showing product view counter based on product attribute or categories WooCommerce

I used the below snippet to display a product view counter on the shop page based on the ip address and it worked fine.
add_action('wp', 'product_view_counter');
function product_view_counter() {
global $post;
$userip = $_SERVER['REMOTE_ADDR'];
if ( is_product() ){
$meta = get_post_meta( $post->ID, '_total_views_count', TRUE );
$meta = (!$meta) ? array() : explode( ',', $meta );
$meta = array_filter( array_unique( $meta ) );
if( ! in_array( $userip, $meta ) ) {
array_push( $meta, $userip );
update_post_meta( $post->ID, '_total_views_count', implode(',', $meta) );
}
}
}
Show on Shop page,
add_filter( 'woocommerce_loop_add_to_cart_link','show_product_view_counter_on_product_page',5);
function show_product_view_counter_on_product_page() {
global $product;
$id = $product->id;
$meta = get_post_meta( $id, '_total_views_count', true);
if(!$meta) {
$count = 0;
} else {
$count = count(explode(',',$meta));
}
echo '<div class="custom-visitor-count"><i class="fa fa-eye"></i><span class="counter-value">'.$count.' Views</span></div>';
}
The new idea is i want to display which 5 attributes or product categories have the most views on another page.
What I've done so far:
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => -1,
'fields' => 'ids'
);
$get_data = get_posts($args);
foreach ($get_data as $gd){
$product = wc_get_product($gd);
$color = $product->get_attribute('pa_color');
$args_color = array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'pa_color',
'field' => 'slug',
'terms' => $color,
)),
'fields' => 'ids',
);
$att_color = get_posts($args_color);
$att_color_sum = 0;
foreach($att_color as $ac){
$color = $product->get_attribute('pa_color');
$count_total_color = count($att_color);
$productid_color = $product->get_id();
$meta_color = get_post_meta( $productid_color, '_total_views_count', true);
$count_meta = count(explode(',',$meta_color));
$att_color_sum += $count_meta;
$display = $color." ".$att_color_sum;
}
}
echo "<p> Top 3 color attribute views : ".$display."</p>";
Output it gives a view like this :
Top 3 color attribute views : Blue 15
What i want is like this :
Top 3 color attribute views :
Green : 57
Red : 42
Grey : 24
Obviously, I was lost.
Anyone, please guide me so that I am on the right track.
Sincerely

Display posts in the order of their selection

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
);

Get products by author id using a WC_Query in WooCommerce?

I trying to get products by post author id using a WC_Query in WooCommerce, so I tried to include a new custom meta_key "_author", with the following:
add_filter( 'woocommerce_product_data_store_cpt_get_products_query', 'handling_custom_meta_query_keys', 10, 3 );
function handling_custom_meta_query_keys( $wp_query_args, $query_vars ) {
$meta_key = '_author';
if ( ! empty( $query_vars[$meta_key] ) ) {
$wp_query_args['meta_query'][] = array(
'key' => $meta_key,
'value' => esc_attr( $query_vars[$meta_key] ),
'operator' => '==',
);
}
return $wp_query_args;
}
Then I tried to use it with wc_get_products():
$product_list = wc_get_products( array('_author' => get_current_user_id()) );
but it return null array. Any idea?
You can simply get products by author Id in a WC_Query using the undocumented parameter "author'" as follow:
$products = wc_get_products( array(
'status' => 'publish',
'limit' => -1,
'author' => get_current_user_id()
) );
You will get an array of WC_Product Objects
You can use custom query like this
<?php
$authorID = get_the_author_meta('ID');
$args = array(
'post_type' => 'product',
'post_status' => 'publish'
'posts_per_page' => 12,
'product_cat' => 'pants'
'author' => $authorID
);
$loop = new WP_Query( $args );
?>
<div class="author_products">
<?php if ( $loop->have_posts() ) { ?>
<ul class="author_pubproducts">
<?php while ( $loop->have_posts() ) : $loop->the_post();
woocommerce_get_template_part( 'content', 'product' );
endwhile; ?>
</ul>
<?php
} else {
echo __( 'No products found', 'textdomain' );
}
wp_reset_postdata();
?>
Hope it's work

Get custom taxonomy's custom meta from outside the loop

I've created a number of custom fields for custom taxonomy. Got no problem pulling their values inside the query. But in this case, I get them repeating as many times as I have posts in this taxonomy.
This is the code with it inside the loop
$tables_terms = $atts['custom'];
$tabargs = array(
'posts_per_page' => -1,
'offset' => 0,
'post_type' => 'customtables',
'tax_query' => array(
array(
'taxonomy' => 'tables',
'field' => 'slug',
'terms' => array(
$tables_terms
)
)
)
);
$tabs = new WP_Query( $tabargs );
if( $tabs->have_posts() ){
while( $tabs->have_posts() ) : $tabs->the_post();
$terms = get_the_terms( get_the_ID(), 'tables' );
foreach ( $terms as $term ) {
$t_id = $term->term_id;
$term_meta = get_option( "taxonomy_$t_id" );
echo $term_meta['term_1'];
}
endwhile;
wp_reset_postdata();
echo $custom;
}
How do I get these to show once, outside the loop?
You can use, get_term_meta;
get_term_meta retrieves metadata for a term.
get_term_meta( $term->term_id, 'your_term_name', true )
So the following code actually worked for me
$term_slug = $tables_terms;
$taxonomies = get_taxonomies();
foreach ( $taxonomies as $tax_type_key => $taxonomy ) {
if ( $term_object = get_term_by( 'slug', $term_slug , $taxonomy ) ) {
break;
}
}
$t_id = $term_object->term_id;
$term_meta = get_option( "taxonomy_$t_id" );
and from there on, I simply echoed each meta like this
echo $term_meta['term_1'];
Try Like that:
Store your output in a array and check when store it that value already exist or not.
$tables_terms = $atts['custom'];
$tabargs = array(
'posts_per_page' => -1,
'offset' => 0,
'post_type' => 'customtables',
'tax_query' => array(
array(
'taxonomy' => 'tables',
'field' => 'slug',
'terms' => array(
$tables_terms
)
)
)
);
$tabs = new WP_Query( $tabargs );
$term_meta_array = array();
if( $tabs->have_posts() ){
while( $tabs->have_posts() ) : $tabs->the_post();
$terms = get_the_terms( get_the_ID(), 'tables' );
foreach ( $terms as $term ) {
$t_id = $term->term_id;
$term_meta = get_option( "taxonomy_$t_id" );
echo $term_meta['term_1'];
if(!in_array($term_meta['term_1'], $term_meta_array)) array_push($$term_meta_array, $term_meta['term_1']);
}
endwhile;
wp_reset_postdata();
echo $custom;
foreach($term_meta_array as $st){
echo $st;
}
}

Changing custom field value for WooCommerce order based on product variations in order

In WooCommerce with Advanced Custom Fields plugin, I am creating a function to up date a custom field for subscription orders on a WooCommerce store selling a print magazine. This function will update the 'starting_issue' field for subscription orders with the name for a single issue product depending on whether the user has opted to start their subscription from the previous, current or next issue of the magazine (chosen as a product variation for three different types of subscription products).
I have coded the function as follows but on any test orders I am completing, with changed attempted to the code below, it does not work as required - not updating the 'starting_issue' meta field for orders.
I have built similar functions before to auto-complete orders based on set conditions. I am struggling to see why this particular function is not working but I know I may be missing something very crucial.
The code I have written is:
/*** UPDATE 'STARTING ISSUE' FIELD FOR ORDERS ***/
// Club membership ID = '7968'
// Subscription (non-gift) ID = '13962'
// Subscription (gift) ID = '13966'
add_action( 'first_issue_for_subs', 'first_issue_for_subs' );
function first_issue_for_subs( $order_id ) {
if ( ! $order_id ) { return; }
global $woocommerce;
$order = new WC_Order( $order_id );
foreach( $order->get_items() as $item ) {
if ( ( $item['product_id'] == '7968' ) or ( $item['product_id'] == '13962' ) or ( $item['product_id'] == '13966' ) ) {
$product = wc_get_product( $item['product_id'] );
$variations = $product->children;
foreach ( $variations as $variation ) {
$variation_id = $variation->variation_id;
if ( $variation_id == '16171' or $variation_id == '16174' or $variation_id == '16168' ) {
// Current Issue
$current_args = [
'posts_per_page' => 1,
'post_type' => 'product',
'tax_query' => array( array( 'taxonomy' => 'product_cat', 'field' => 'slug', 'terms' => 'single_issues' ) ),
];
$current_query = get_posts( $current_args );
foreach ( $current_query as $queried_issue ) {
$first_issue = the_title();
$order->update_field( 'starting_issue', $first_issue );
}
}
elseif ( $variation_id == '16167' or $variation_id == '16170' or $variation_id == '16173' ) {
// Next Issue
$next_args = [
'posts_per_page' => 1,
'post_status' => 'draft',
'post_type' => 'product',
'tax_query' => array( array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => 'single_issues'
) ),
'orderby' => 'date',
'order' => 'ASC',
];
$next_query = get_posts( $next_args );
foreach ( $next_query as $queried_issue ) {
$first_issue = the_title();
$order->update_field( 'starting_issue', $first_issue );
}
}
elseif ( $variation_id == '6169' or $variation_id == '16172' or $variation_id == '16166' ) {
// Previous Issue - gift
$previous_args = [
'posts_per_page' => 2,
'offset' => 1,
'post_type' => 'product',
'tax_query' => array( array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => 'single_issues'
) ),
];
$previous_query = get_posts( $previous_args );
foreach ( $previous_query as $queried_issue ) {
$first_issue = the_title();
$order->update_field( 'starting_issue', $first_issue );
}
}
}
} else {
$first_issue = 'NOT_SUBSCRIPTION';
$order->update_field( 'starting_issue', $first_issue );
}
}
}
Can anybody shed some light on this? Many thanks in advance for any help.

Categories