I'm using this slightly modified script (inside a loop) which helps me generate two links which I use to add products to the cart:
<?php
// Get the ID of the product
$id = $_POST["post_var"];
// Get variations
$args = array(
'post_type' => 'product_variation',
'post_status' => array( 'publish' ),
'numberposts' => 2,
'orderby' => 'menu_order',
'order' => 'asc',
'post_parent' => $product->id
);
$variations = get_posts( $args );
$loop = 0;
if ( $variations ) {
foreach ( $variations as $variation ) {
$formats[$loop]["id"] = absint( $variation->ID );
$formats[$loop]["data"] = get_post_meta( $variation->ID );
$variation_label = "?????????";
$loop++;
}
foreach ( $formats as $type )
$response .= '' . $variation_label . '';
} ?>
<?php echo $response; ?>
The only thing I can't figure out is how to get the variation labels.
Every product has variation called "Format' with the options "Electronic" and "Physical" and I need those to be output into the link. So the $response would look something like this:
<a href="http://example.com/checkout?add-to-cart=93&variation_id=94&quantity=1&attribute_pa_format=Electronic">Electronic</a
Physical
You can see I've added a variable called $variation_label as a placeholder.
Stumped.
Related
so I got a working shortcode that outputs the selected product attribute name and id alongside, however, I have no idea how to obtain the same product variable name and id which is essentially from the same attribute.
This means that my current product form URL slug cannot add to cart the selected variable e.g. ( ?add-to-cart=18395&quantity=1&?variation_id=407 ) because the variation id is fetched from the attribute, and it is wrong I know.
add_shortcode ('color_attribute', function (){
$color_attributes = get_the_terms($post->ID, 'pa_pla_color', array(
'hide_empty' => false,
));
foreach ($color_attributes as $k => $color_attribute):
if( $k > 0 ) echo "\n";
echo $color_attribute->name . ' | ' . $color_attribute->term_id;
endforeach;
} );
Any help is really appreciated!
Check this out
add_shortcode ('color_attribute', function (){
$color_attributes = get_the_terms($post->ID, 'pa_pla_color', array(
'hide_empty' => false,
));
$product = wc_get_product( $post->ID );
echo $product->get_name();
// Get Product Variations and Attributes
$product->get_children(); // get variations
$product->get_attributes();
$product->get_default_attributes();
$product->get_attribute( 'attributeid' ); //get specific attribute value
foreach ($color_attributes as $k => $color_attribute):
if( $k > 0 ) echo "\n";
echo $color_attribute->name . ' | ' . $color_attribute->term_id;
endforeach;
});
For anyone else looking for similar solutions, this is how I achieved to solve my problem:
add_shortcode ('color_attribute', function (){
$color_attributes = get_the_terms($post->ID, 'pa_pla_color', array(
'hide_empty' => false,
));
$args = array(
'post_type' => 'product_variation',
'post_status' => array( 'private', 'publish' ),
'numberposts' => -1,
'orderby' => 'menu_order',
'order' => 'asc',
'post_parent' => get_the_ID() // get parent post-ID
);
$variations = get_posts( $args );
foreach ( $variations as $variation ) {
if( $variation_ID > 0 ) echo "\n";
// get variation ID
$variation_ID = $variation->ID;
$product_variation = new WC_Product_Variation( $variation_ID );
$variation_attribute = $product_variation->get_attribute('pa_pla_color');
echo $variation_attribute . ' | ' . $variation_ID;
};
});
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'm having trouble displaying the loop category correctly. Need display only one category in lit posts. Why the first post gets all selected categories and the next posts already have the correct display of one category. How can I make only the current selected category displayed in the first post? My code looks like this. I attached the picture.
My loop custom post
<?php
/* Start the Loop */
$args = array( 'post_type' => 'database',
'posts_per_page' => 10,
'paged' => $paged,
'post_status' => 'publish',
'ignore_sticky_posts' => true,
'order' => 'DESC',
'orderby' => 'date');
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
This is for display one category in loop post
<?php
// Get terms for post
$terms = wp_get_post_terms( $post->ID , 'database_categories' ,$args2);
$args2 = array( 'parent' => 39,
'fields' => 'all');
// Loop over each item since it's an array
if ( $terms != null ) {
foreach( $terms as $term ) {
$term_link = get_term_link( $term, 'database_categories' );
// Print the name and URL
echo '' . $term->name . ' ';
// Get rid of the other data stored in the object, since it's not needed
unset($term);
}
}
?>
If the object here is to get the first term and ignore the rest then I would just shift off the first array element and no need for a loop on terms.
$args2 = array('parent' => 39, 'fields' => 'all');
$terms = wp_get_post_terms( $post->ID , 'database_categories' ,$args2);
if (!empty($terms)) {
$term = array_shift($terms);
echo sprintf('%s', get_term_link( $term, 'database_categories' ), $term->name);
}
i want to display product by category with dropdown
and i made this code but why the value not going inside the ?
function rakitpc() {
$args = array(
'posts_per_page' => -1,
'product_cat' => 'Tshirts',
'hide_empty' => 0,
'post_status' => 'publish',
'post_type' => 'product',
'orderby' => 'title',
'echo' => '0'
);
$products = new WP_Query( $args );
$output = '<select>';
// foreach ( $products as $product ) {
while ( $products->have_posts() ) {
$products->the_post();
$aa = the_permalink($post);
echo $aa;
$bb = the_title($post);
$output .= "<option value=\"<?php the_permalink(); ?>\"> <?php the_permalink(); ?></option>";
}
wp_reset_query();
$output .='</select>';
return $output;
}
add_shortcode( 'gege', 'rakitpc' );
This is the output That I get:
My reference: How do I display a "category products drop down in a wordpress page" in Woocommerce 2.5.2
Try the following that will give you a dropdown with the permalinks as <option> values displaying the product names (see the screenshot at the end).
You will need to set your category name (or categories names) in the array inside the funtion.
function rakitpc() {
// HERE below, define your Product category names
$term_names = array('T-shirts');
// The WP_Query
$query = new WP_Query( array(
'posts_per_page' => -1,
'post_type' => 'product',
'post_status' => 'publish',
'hide_empty' => 0,
'orderby' => 'title',
'tax_query' => array( array(
'taxonomy' => 'product_cat', // for a Product category (or 'product_tag' for a Product tag)
'field' => 'name', // can be 'name', 'slug' or 'term_id'
'terms' => $term_names,
) ),
'echo' => '0'
) );
$output = '<select>';
// foreach ( $products as $product ) {
if ( $query->have_posts() ) :
while ( $query->have_posts() ) : $query->the_post();
$permalink = get_permalink($query->post->ID);
$title = $query->post->post_title;
$output .= '<option value="' . $permalink . '">' . $title . '</option>';
endwhile;
wp_reset_postdata();
$output .='</select>';
else :
$output = '<p>No products found<p>';
endif;
return $output;
}
add_shortcode( 'gege', 'rakitpc' );
Code goes in function.php file of your active child theme (or active theme). Tested and works.
I have a WooCommerce shop that holds variable products.
I want to create some sort of export (on a page) that shows me all products including variations in a table.
I am viewing all products and created a loop to get the variations but it only shows me one product variation.
<?php
/*
Template Name: Store Management
*/
if (!is_user_logged_in() || !current_user_can('manage_options')) wp_die('This page is private.');
// Get
$args = array(
'post_type' => 'product',
'numberposts' => -1,
);
$products = get_posts( $args );
echo '<pre>';
print_r($products);
echo '</pre>';
foreach($products as $product):
$args = array(
'post_parent' => $plan->ID,
'post_type' => 'product_variation',
'numberposts' => -1,
);
$product = wc_get_product( $product->ID );
$variations = $product->get_available_variations();
echo '<pre>';
print_r($variations);
echo '</pre>';
endforeach;
?>
Can anyone tell me how to get all variations for all products?
M.
Here is my code, to get all products and variations in WooCommerce v3+ :
<?php
$args = [
'status' => 'publish',
'orderby' => 'name',
'order' => 'ASC',
'limit' => -1,
];
$all_products = wc_get_products($args);
foreach ($all_products as $key => $product) {
echo $product->get_title();
if ($product->get_type() == "variable") {
foreach ($product->get_variation_attributes() as $variations) {
foreach ($variations as $variation) {
echo $product->get_title() . " - " . $variation;
}
}
}
}
First of all don't override the product variable inside loop. Secondly you have to check weather product is simple or variable. Because simple product will not have variants. So your code will be like this :
foreach($products as $product):
$product_s = wc_get_product( $product->ID );
if ($product_s->product_type == 'variable') {
$args = array(
'post_parent' => $plan->ID,
'post_type' => 'product_variation',
'numberposts' => -1,
);
$variations = $product_s->get_available_variations();
echo '<pre>';
print_r($variations);
echo '</pre>';
}
endforeach;