Woocommerce related product array with user input - php

I am using the following code as the footer of my single-product.php page in Woocommerce (I've created a "Related Products" section) and I am wondering if there is a way that I can alter it to make it possible for admin to be able to add values from the product admin page; I want certain products to show closer related products instead of totally random ones.
Is there a way I can create a custom field for something like product ID or tag and then add that custom field as the orderby value so those products/tags have a better change of showing up vs. random products?
If not, is there anything else I can do? I am simply looking for a way to allow an admin to choose closer related products to appear.
$args = apply_filters( 'woocommerce_related_products_args', array(
'post_type' => 'product',
'ignore_sticky_posts' => 1,
'no_found_rows' => 1,
'posts_per_page' => 5,
'orderby' => rand,
'post__in' => $related,
'post__not_in' => array( $product->id )
) );
Here is my related-footer.php file with the complete code that includes the above snippet.

Yes you can achieve this task as with the following approach:
Create a custom field for the product you want to display a set of your desired related products say the custom field name be "wdm_related_products" set the value to a comma separated list of Product ids eg. 46,15,687,21,48.
Update the product.
Add the following code in functions.php of user child theme or a custom Plugin.
add_filter('woocommerce_related_products_args','wdm_custom_related_products',99,1);
function wdm_custom_related_products($array){
global $product;
if(get_post_meta($product->,'wdm_related_products',true)){
$related=get_post_meta($product->id,'wdm_related_products',true);
$array=array(
'post_type' => 'product',
'ignore_sticky_posts' => 1,
'no_found_rows' => 1,
'posts_per_page' => 5,
'orderby' => rand,
'post__in' => $related,
'post__not_in' => array( $product->id )
);
}
return $array;
}
Let me know it it resolved your issue.

Related

Woocommerce: Dynamically change attributes / parameters of a WC Render-Block

I use the Woocommerce “Handpicked products” Block in Wordpress Gutenberg to create a showcase of 3 products on my Frontpage. I saw that Woocommerce does not use Shortcodes for that, but that the page itself includes a paragraph which looks like this:
<!-- wp:woocommerce/handpicked-products {"contentVisibility":{"image":true,"title":true,"price":false,"rating":false,"button":false},"orderby":"menu_order","products":[181,225,179]} /-->"
I want to dynamically change the products (randomly shuffle) upon page load. Unfortunately, in the whole PHP-classes HandpickedProducts, AbstractProductGrid, AbstractDynamicBlock etc I do not see a Hook to change the Render parameter dynamically...
So what I found as possible solution is: To directly replace the product attribute in the Wordpress Post itself, therefore I implemented this hook:
function my_the_post_action(&$pobj) {
$pobj->post_content = str_replace('[181,225,179]', '[225, 220, 222]', $pobj->post_content );
}
add_action('the_post', 'my_the_post_action' );
It is actually replaced in the wp:woocommerce/handpicked-products paragraph, but doesnt take effect. Why does Woocommerce not consider the new Product IDs as parameters to his rendered block?
Thanks!!
Instead of modifying the "Blocks" entered via Pageeditor upon Pageload within the Frontpage - I came up with a better and cleaner option IMHO - by simply rendering such a Block within a customer Shortcode.
The following code consists of first the part where I randomly pick 3 products from the Database which have the Product-Tag "Featured" set so that the user can decide himself which products are open for selection ... and then I create my "Handpicked Products" block and render it:
add_shortcode('my_featured_prods', function($atts, $content = null)
{
// Get list of all Woocommerce products by Tag
$args = array(
'post_type' => 'product',
'posts_per_page' => 3,
'orderby' => 'rand',
'tax_query' => array(
array(
'taxonomy' => 'product_tag',
'field' => 'slug',
'terms' => 'featured'
)
)
);
$products = new WP_Query($args);
$ids = [$fix];
foreach($products->posts as $p)
$ids[] = $p->ID;
// Shuffle array:
shuffle($ids);
// Output Hand Picked Products Widget with my settings ...
$args = (object) [
'editMode' => 0,
'contentVisibility' => (object) [
'image' => 1,
'title' => 1,
'price' => 0,
'rating' => 0,
'button' => 0,
],
'orderby' => 'random',
'products' => $ids,
'alignButtons' => 1,
];
$args = sprintf(
'<!-- wp:woocommerce/handpicked-products %s /-->',
json_encode( $args )
);
return do_blocks($args);
});

How can I sort woocommerce grouped products by post date instead of menu order?

What code/filter can I add to my wordpress functions.php file to modify the order of grouped products by post date instead of menu_order? class-wc-product-grouped.php
$args = apply_filters( 'woocommerce_grouped_children_args', array(
'post_parent' => $this->id,
'post_type' => 'product',
'orderby' => 'menu_order',
'order' => 'ASC',
'fields' => 'ids',
'post_status' => 'publish',
'numberposts' => -1,
) );
I'm pretty sure you can hook into it but just not sure how to configure the following filter/hook woocommerce_grouped_children_args
As you have mentioned, you just need to filter the $args being passed through the woocommerce_grouped_children_args filter.
add_filter( 'woocommerce_grouped_children_args', 'so_29973708_grouped_children_args' );
function so_29973708_grouped_children_args( $args ){
$args['orderby'] = 'date';
$args['order'] = 'DESC';
return $args;
}
If you need help understanding filters, I wrote what I think is a pretty good tutorial on how to use filters
Update If you aren't seeing any changes, chances are that the grouped product's children have already been stored in a transient. You will need to delete this transient to see changes right away. You can clear all WooCommerce product transients via the Admin. Navigate to WooCommerce>System Status>Tools and click on the button to clear transients.

How to Show Related Products by Attribute - WooCommerce

WooCommerce provides documentation on how to change the number of related products shown on a product page. Is there a way to change how they are related? It seems they are currently being related by category. Is there a way to show related products based on a single attribute?
Filter Below:
<?php
/**
* WooCommerce Extra Feature
* --------------------------
*
* Change number of related products on product page
* Set your own value for 'posts_per_page'
*
*/
function woo_related_products_limit() {
global $product;
$args = array(
'post_type' => 'product',
'no_found_rows' => 1,
'posts_per_page' => 6,
'ignore_sticky_posts' => 1,
'orderby' => $orderby,
'post__in' => $related,
'post__not_in' => array($product->id)
);
return $args;
}
add_filter( 'woocommerce_related_products_args', 'woo_related_products_limit' );
The filter woocommerce_related_products_args does not exist anymore. You can look into the function wc_get_related_products() to find which filters are currently available.
To replace categories by a single product attribute, I used the following code in my functions.php:
add_filter( 'woocommerce_get_related_product_cat_terms', 'my_attribute_relation', 10, 2);
/** Find related products using the attribute `pa_myAttrib`, throw away product categories. */
function my_attribute_relation( $original_term_ids, $product_id ) {
return wc_get_product_term_ids( $product_id, 'pa_myAttrib' );
}
In this case, product related by tags are kept. If you want to alter those, add a filter for woocommerce_get_related_product_tag_terms, too.
You should be able to do it by the taxonomy feature in wp_query... link
The attribute you want to target is 'woocommerce_attributes', not tested but this should work:
$args = array(
'post_type' => 'product',
'no_found_rows' => 1,
'posts_per_page' => 6,
'ignore_sticky_posts' => 1,
'orderby' => $orderby,
'post__in' => $related,
'post__not_in' => array($product->id),
'woocommerce_attributes' => 'attribute_slug',
);
return $args;

Hide specific posts from category list in wordpress

I'm having some trouble displaying a list of posts from a Wordpress Category that will exclude a certain number of post based on a custom field using Advance Custom Fields.
Here's the current code I'm using that hides it nicely:
while ( have_posts() ) : the_post();
$is_taken = get_field('taken_check', $this_id);
if ($is_taken!=1) {
get_template_part( 'basket_selection' );
}
endwhile;
However, it simply just hides the post but still considers it as a post on the "posts_per_page" function.
For example, There are 20 posts in total and I've set the limit to 10 posts per page. If I hide 3 posts with the code above, it will only display 7 posts in page 1 and 10 posts in page 2.
Is there a way to simply just ignore the hidden posts and not count it as a "post"?
Try this:
Apply Custom Fields Parameters in get_post query itself.
$posts = get_posts(array(
'posts_per_page' => 10,
'post_type' => '<YOUR_POST_TYP>',
'meta_key' => 'taken_check',
'meta_value' => '<DEFAULT_VALUE_OF_taken_check>'
));
Lots to read here: http://codex.wordpress.org/Template_Tags/get_posts
I've managed to solve it by changing the get_posts to wp_query within the category.php.
I first added this code to detect the current category viewed and filter the query to only display taken_check = 0.
$this_cat = get_category(get_query_var('cat'), 'ARRAY_A', false);
foreach ($this_cat as $this_cat){
$this_catid = $this_cat;
break;
}
$args = array(
'posts_per_page' => 10,
'post_type' => 'post',
'cat' => $this_catid,
'orderby' => 'title',
'order' => 'ASC',
'paged' => $paged,
'meta_query' => array(
array(
'key' => 'taken_check',
'value' => '0',
)
)
);
$wp_query = new WP_Query($args);
I then just continued with the default loop sequence. The only weird code is the unnecessary foreach loop to detect the current category based on the current page and not from a post. Still puzzled as to why I can't just use $this_cat[0] since it's an array. It keep returning blank.
Oh well, but it works now with pagination, so I'm happy :)
Thanks for all the help!

Sorting posts in a customized order

I have a "custom Page" set up and I am trying to figure out how I can make it arrange the posts it pulls in a specific order...I am thinking of using the custom fields. But not sure how to add a listing of a numeric value.
For Lease and For Sale
List item Size List item (ie 1 br, 2br, 3br) (least expensive
first)
List item Price (Cheapest to most expensive)
You can order order posts by custom fields. The query will be something like this:
$query = new WP_Query( array ( 'post_type' => 'custom_page', 'order' => 'DESC', 'orderby' => 'meta_value', 'meta_key' => 'price' ) );
In your case, you will have to convert price and size to pure numeric values for the sorting to work. For Lease and Sale, I would suggest you should not rely on sorting but use it to query, something like this:
$query = new WP_Query( array( 'post_type' => 'custom_page', 'meta_key' => 'deed', 'meta_value' => 'lease' ) );

Categories