WP All Import don't importing values from custom fields - php

I have custom tab for Frequently Bought Together products in my woocommerce site, that shows up on single product page. When i update products via WP All Import, only one product show up in custom tab and should be a two. Here is the settings of custom fields import and actually view of the single product page.
custom-fields-settings
single-product-accessory-tab
I'll provide Single Product Accessories template, just to make it clear
accessorie template function
global $product;
$loop_columns = apply_filters( 'mc_accessories_loop_columns', 4 );
$posts_per_page = 4;
if ( defined( 'WC_VERSION' ) && version_compare( WC_VERSION, '3.3', '<' ) ) {
global $woocommerce_loop;
$woocommerce_loop['columns'] = $loop_columns;
} else {
wc_set_loop_prop( 'columns', $loop_columns );
}
$product_id = mc_wc_get_product_id( $product );
$accessories = MediaCenter_WC_Helper::get_accessories( $product );
array_unshift( $accessories, $product_id );
if ( sizeof( $accessories ) === 0 && !array_filter( $accessories ) ) {
return;
}
$meta_query = WC()->query->get_meta_query();
$args = apply_filters( 'mc_accessories_query_args', array(
'post_type' => 'product',
'ignore_sticky_posts' => 1,
'no_found_rows' => 1,
'posts_per_page' => $posts_per_page,
'orderby' => 'post__in',
'post__in' => $accessories,
'meta_query' => $meta_query
) );
unset( $args['meta_query'] );
$products = new WP_Query( $args );
$add_to_cart_checkbox = '';
$total_price = 0;
$count = 0;
Any help will be appreciated

Solution is so easy, just need to import post Id's, i lost two weeks on that problem.

Related

Extend WooCommerce product search to custom taxonomies and custom fields

I am creating advance woocommerce search and I want to add sku and product_tag and product_category in search query. Below I am using Enable custom taxonomies in WooCommerce product search answer code, that enable search for multiple taxonomies:
add_filter( 'posts_search', 'woocommerce_search_product_tag_extended', 999, 2 );
function woocommerce_search_product_tag_extended( $search, $query ) {
global $wpdb, $wp;
$qvars = $wp->query_vars;
if ( is_admin() || empty($search) || ! ( isset($qvars['s'])
&& isset($qvars['post_type']) && ! empty($qvars['s'])
&& $qvars['post_type'] === 'product' ) ) {
return $search;
}
// Here set your custom taxonomies in the array
$taxonomies = array('product_tag', 'product_cat');
$tax_query = array('relation' => 'OR'); // Initializing tax query
// Loop through taxonomies to set the tax query
foreach( $taxonomies as $taxonomy ) {
$tax_query[] = array(
'taxonomy' => $taxonomy,
'field' => 'name',
'terms' => esc_attr($qvars['s']),
);
}
// Get the product Ids
$ids = get_posts( array(
'posts_per_page' => -1,
'post_type' => 'product',
'post_status' => 'publish',
'fields' => 'ids',
'tax_query' => $tax_query,
) );
if ( sizeof( $ids ) > 0 ) {
$search = str_replace( 'AND (((', "AND ((({$wpdb->posts}.ID IN (" . implode( ',', $ids ) . ")) OR (", $search);
}
return $search;
}
I want to add product sku too in search query, how to add it ?
The following will extend Product search to multiple taxonomies (Product Category and Product tag) and multiple custom fields (as SKU here):
add_filter( 'posts_search', 'woocommerce_search_product_mega_extended', 999, 2 );
function woocommerce_search_product_mega_extended( $search, $query ) {
global $wpdb, $wp;
$qvars = $wp->query_vars;
if ( is_admin() || empty($search) || ! ( isset($qvars['s'])
&& isset($qvars['post_type']) && ! empty($qvars['s'])
&& $qvars['post_type'] === 'product' ) ) {
return $search;
}
// SETTINGS:
$taxonomies = array('product_tag', 'product_cat'); // Here set your custom taxonomies in the array
$meta_keys = array('_sku'); // Here set your product meta key(s) in the array
// Initializing tax query
$tax_query = count($taxonomies) > 1 ? array('relation' => 'OR') : array();
// Loop through taxonomies to set the tax query
foreach( $taxonomies as $taxonomy ) {
$tax_query[] = array(
'taxonomy' => $taxonomy,
'field' => 'name',
'terms' => esc_attr($qvars['s']),
);
}
// Get the product Ids from taxonomy(ies)
$tax_query_ids = (array) get_posts( array(
'posts_per_page' => -1,
'post_type' => 'product',
'post_status' => 'publish',
'fields' => 'ids',
'tax_query' => $tax_query,
) );
// Initializing meta query
$meta_query = count($meta_keys) > 1 ? array('relation' => 'OR') : array();
// Loop through taxonomies to set the tax query
foreach( $taxonomies as $taxonomy ) {
$meta_query[] = array(
'key' => '_sku',
'value' => esc_attr($qvars['s']),
);
}
// Get the product Ids from custom field(s)
$meta_query_ids = (array) get_posts( array(
'posts_per_page' => -1,
'post_type' => 'product',
'post_status' => 'publish',
'fields' => 'ids',
'meta_query' => $meta_query,
) );
$product_ids = array_unique( array_merge( $tax_query_ids, $meta_query_ids ) ); // Merge Ids in one array with unique Ids
if ( sizeof( $product_ids ) > 0 ) {
$search = str_replace( 'AND (((', "AND ((({$wpdb->posts}.ID IN (" . implode( ',', $product_ids ) . ")) OR (", $search);
}
return $search;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
Related: Enable custom taxonomies in WooCommerce product search

Get and display related products in WooCommerce

I have included WooCommerce related products in a theme with the following:
<?php wc_get_template( 'single-product/related.php' ); ?>
This has been copied into my template and is executing.
However, even though I have added various upsells with this product the $related_products variable (used in the loop) is NULL. Is there any other variables at play in order to start showing these related products?
You need much more than that (and the post_id need to be a product):
global $product; // If not set…
if( ! is_a( $product, 'WC_Product' ) ){
$product = wc_get_product(get_the_id());
}
$args = array(
'posts_per_page' => 4,
'columns' => 4,
'orderby' => 'rand',
'order' => 'desc',
);
$args['related_products'] = array_filter( array_map( 'wc_get_product', wc_get_related_products( $product->get_id(), $args['posts_per_page'], $product->get_upsell_ids() ) ), 'wc_products_array_filter_visible' );
$args['related_products'] = wc_products_array_orderby( $args['related_products'], $args['orderby'], $args['order'] );
// Set global loop values.
wc_set_loop_prop( 'name', 'related' );
wc_set_loop_prop( 'columns', $args['columns'] );
wc_get_template( 'single-product/related.php', $args );
Or in a shorter way (which will give you the same):
global $product;
if( ! is_a( $product, 'WC_Product' ) ){
$product = wc_get_product(get_the_id());
}
woocommerce_related_products( array(
'posts_per_page' => 4,
'columns' => 4,
'orderby' => 'rand'
) );
Both ways are tested and works…

Display related products based on subcategory - woocommerce

I would like to display related products in my single product page that are related to the subcategory and not the parent category. Now i have about 100 products and about 90 of them belong to the same parent category (they also belong to other parent categories). So in a single product page you can see pretty much any random product because of that big parent category.
Is there a way to limit this? I did a research and i came accross some answers that were about version 1.6 of woocommerce... Now i use 3.2.6, so it didn't work.
you can use this code or adapted to work for you case,, hope its work..
Add it to your function.php
add_filter( 'woocommerce_product_related_posts', 'woocommerce_get_direct_related_products' );
function woocommerce_get_direct_related_products() {
global $woocommerce, $product;
// Related products are found from category
$cats_array = array(0);
// Get categories
$terms = wp_get_post_terms( $product->id, 'product_cat' );
//Select only the category which doesn't have any children
foreach ( $terms as $term ) {
$children = get_term_children( $term->term_id, 'product_cat' );
if ( !sizeof( $children ) )
$cats_array[] = $term->term_id;
}
// Don't bother if none are set
if ( sizeof( $cats_array ) == 1 ) return array();
// Meta query
$meta_query = array();
$meta_query[] = $woocommerce->query->visibility_meta_query();
$meta_query[] = $woocommerce->query->stock_status_meta_query();
$limit = 5;
// Get the posts
return array(
'orderby' => 'rand',
'posts_per_page'=> $limit,
'post_type' => 'product',
'fields' => 'ids',
'meta_query' => $meta_query,
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => $cats_array
)
)
);
}
This is a possible duplicate of Woocommerce: Only show related products from same subcategory
Another workaround would be to overwrite the template file [your-theme]/woocommerce/single-product/related.php
The following is updated to work with Woocommerce 3.x
<?php
/**
* Related Products
*
* This template can be overridden by copying it to yourtheme/woocommerce/single-product/related.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* #see https://docs.woocommerce.com/document/template-structure/
* #author WooThemes
* #package WooCommerce/Templates
* #version 3.9.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
global $product, $woocommerce_loop;
if ( empty( $product ) || ! $product->exists() ) {
return;
}
if ( ! $related = $product->get_related( $posts_per_page ) ) {
return;
}
// Get ID of current product, to exclude it from the related products query
$current_product_id = $product->get_id();
$cats_array = array(0);
// get categories
$terms = wp_get_post_terms( $product->id, 'product_cat' );
// select only the category which doesn't have any children
foreach ( $terms as $term ) {
$children = get_term_children( $term->term_id, 'product_cat' );
if ( !sizeof( $children ) )
$cats_array[] = $term->term_id;
}
$args = apply_filters( 'woocommerce_related_products_args', array(
'post_type' => 'product',
'post__not_in' => array( $current_product_id ), // exclude current product
'ignore_sticky_posts' => 1,
'no_found_rows' => 1,
'posts_per_page' => $posts_per_page,
'orderby' => $orderby,
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => $cats_array
),
)
));
$products = new WP_Query( $args );
$woocommerce_loop['name'] = 'related';
$woocommerce_loop['columns'] = apply_filters( 'woocommerce_related_products_columns', $columns );
if ( $products->have_posts() ) : ?>
<section class="related products">
<?php
$heading = apply_filters( 'woocommerce_product_related_products_heading', __( 'Related products', 'woocommerce' ) );
if ( $heading ) :
?>
<h2><?php echo esc_html( $heading ); ?></h2>
<?php endif; ?>
<?php woocommerce_product_loop_start(); ?>
<?php while ( $products->have_posts() ) : $products->the_post(); ?>
<?php wc_get_template_part( 'content', 'product' ); ?>
<?php endwhile; // end of the loop. ?>
<?php woocommerce_product_loop_end(); ?>
</section>
<?php endif;
wp_reset_postdata();

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.

Get remaining orders(difference) from orders processing and new cart orders

In my Woocommerce website, I have a maximum order capacity of 50.
I am trying to communicate to the customer in their cart of the orders left before we close the ordering.
I need to get the total number of items already processing in each order + new orders in cart subtracted from the 50 maximum.
I have try it using this code:
function display_woocommerce_order_count() {
global $woocommerce;
$args = array(
'post_type' => 'shop_order',
'post_status' => 'publish',
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'shop_order_status',
'field' => 'slug',
'terms' => array('processing')
)
)
);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
$order_id = $loop->post->ID;
$order = new WC_Order($order_id);
$order_count = 0;
foreach( $order as $product ) {
$order_item = $product['qty'];
if($qty) {
$order_count += $order_item;
}
}
ob_start();
//Echo the number of items in cart.
$count = $woocommerce->cart->cart_contents_count;
//Difference max - orders processing - cart items
$total_diff = 50 - number_format($order_count) - $count;
echo $total_diff;
return ob_get_clean();
}
How can I make this works as expected?
Thanks
To get your remaining order calculation from existing customer "processing" orders items and actual cart items, you can try this custom function (with an optional $user_id argument).
This is the code:
function get_remaining_orders( $user_id = null ){
if( empty($user_id) && is_user_logged_in() )
$user_id = get_current_user_id();
if( ! empty($user_id) && ! is_admin() ){
$order_max = 50;
$processing_orders_items_count = 0;
$cart_count = 0;
$customer_orders = get_posts( array(
'meta_key' => '_customer_user',
'meta_value' => $user_id,
'post_type' => 'shop_order',
'numberposts' => -1,
'post_status' => 'wc-processing' // 'processing' order status only
) );
if(!empty($customer_orders))
foreach($customer_orders as $customer_order_values){
$customer_order = wc_get_order( $customer_order_values->ID );
$processing_orders_items_count += $customer_order->get_item_count('line_item');
}
if(!WC()->cart->is_empty())
$cart_count = WC()->cart->get_cart_contents_count( );
$ouput = $order_max - ($processing_orders_items_count + $cart_count);
return $ouput;
}
}
// USAGE: for a specific user ID (here for example $user_id is 22):
get_remaining_orders( 22 );
// USAGE: returning the value in a variable for current user:
$remaining_orders = get_remaining_orders();
// USAGE: displaying the value for current user (example):
echo 'Total remaining orders are ' . get_remaining_orders();
Code goes in function.php file of your active child theme (or theme). Or also in any plugin php files.
This code is tested and functional.
Update for a "not user specific case":
function get_remaining_orders(){
if( !is_admin() ){
$order_max = 50;
$processing_orders_items_count = 0;
$cart_count = 0;
$customer_orders = get_posts( array(
'post_type' => 'shop_order',
'numberposts' => -1,
'post_status' => 'wc-processing' // 'processing' order status only
) );
if(!empty($customer_orders))
foreach($customer_orders as $customer_order_values){
$customer_order = wc_get_order( $customer_order_values->ID );
$processing_orders_items_count += $customer_order->get_item_count('line_item');
}
if(!WC()->cart->is_empty())
$cart_count = WC()->cart->get_cart_contents_count( );
$ouput = $order_max - ($processing_orders_items_count + $cart_count);
return $ouput;
}
}
// USAGE: returning the value in a variable:
$remaining_orders = get_remaining_orders();
// USAGE: displaying the value (example):
echo 'Total remaining orders are ' . get_remaining_orders();
This should work as you expect…

Categories