Display WooCommerce products in specific order - wordpress

I need to display WooCommerce products in a specific order by listing the SKU's/ID's. Either using a shortcode or a custom loop.
For example I want to show the following products in this exact order:
[products ids="1,3,2"]
I cannot use menu order because the order will be different depending on page:
Page 1:
[products ids="1,3,2"]
Page 2:
[products ids="3,2,1"]
I have tried the below suggestion, but it doesn't seem to change anything:
[products ids="1,3,2" orderby="post__in"]
The products still come through in the default order.

You can embed the woocommerce default product by extending like that -
add_shortcode( 'custom-products-ordering', 'custom_products_ordering_callback' );
function custom_products_ordering_callback( $attr ) {
global $wpdb;
$orderby = $attr['orderby'];
$columns = $attr['columns'];
$limit = $attr['limit'];
$paginate = $attr['paginate'];
$current_user = wp_get_current_user();
$current_user_id = $current_user->ID;
$query = $wpdb->get_results("SELECT post.`ID` FROM `wp_posts` AS post, `wp_postmeta` AS postmeta WHERE post.`ID` = postmeta.`post_id` AND post.`post_type` = 'shop_order' AND postmeta.`meta_key` = '_customer_user' AND postmeta.`meta_value` = '".$current_user_id."'");
foreach( $query as $key => $value ){
$filter = $value->ID;
}
$product_ids_str = implode( ",", $filter );
return do_shortcode("[products ids='".$product_ids_str."' columns='".$columns."' limit='".$limit."' paginate='".$paginate."' orderby = '".$orderby."']");
}
How you use is -
[custom-products-ordering column="4" limit="12" paginate="true" orderby="post__in"]
You can extend or sort anything you want by modifying the query.

Related

WooCommerce auto assign shipping class based on user role [WooCommerce Product Vendors]

I'm stuck on a task where I need to make WooCommerce automatically apply a shipping class to products uploaded by "Vendor Admins" user role (as set by WooCommerce Product Vendors). I tried to adapt a code snippet I fond here, but apparently this isn't for my usage case. I appreciate your help & comments!
`
if( isset($_GET['update_products']) && is_wc_product_vendors_admin_vendor() ){
add_action( 'init', 'add_shipping_terms_on_all_products' );
}
function add_shipping_terms_on_all_products(){
global $wpdb;
// Here you need to edit the slug_to_edit with your custom slug
$shipping_terms = get_term_by( 'slug', 'old-books', 'product_shipping_class' );
// If can't find the terms, return
if( empty($shipping_terms) ){
return;
}
// Request all product
$products = $wpdb->get_results( "
SELECT p.ID as ID
FROM wp_posts AS p
WHERE p.post_status = 'publish'
AND p.post_type = 'product'
" );
foreach($products as $_product){
$product = new WC_Product($_product->ID);
$product_shipping_class = $product->get_shipping_class();
if( !empty($product_shipping_class) ){
continue;
}
wp_set_post_terms( $product->id, array( $shipping_terms->term_id ), 'product_shipping_class' );
}
}
`
I tried to adapt the snippet and unfortunately nothing happened. I don't know how to proceed.

WordPress How can I get post_id from thumbnail_id?

I'm developing wordpress plugin.
I need to find out post_id from thumbnail_id(not reverse !).
How can I do this?
You can get result by this code
global $wpdb;
$_thumbnail_id = {thumbnail id};
$sql = "SELECT `post_id` FROM `wp_postmeta` WHERE `meta_value` = $_thumbnail_id";
$result = $wpdb->get_results( $sql, ARRAY_A );
//access first returned post id
var_dump($result[0]['post_id']);
If you added same image for multiple posts there will be multiple returns.
You can use get_the_ID() to get the post id. You can find this function in wp-includes/post-template.php
function get_the_ID() {
$post = get_post();
return ! empty( $post ) ? $post->ID : false;
}

Get Woocommerce variation attributes

I am trying to get variations of a variable product on custom product page. I have two attributes, one for sizes as select and the other for colors as swatches. The problem that I cannot display the attribute that I need to display, and when I use the following code it returns a text names of sizes or colors not the select dropdown for sizes or the colors swatches. Any help please ?!
echo implode(', ', wc_get_product_terms( $product_id, 'pa_colors' ));
This is a brief code to solve your question, I let you entire code, you can use only that you need.
The first is check if get_product function exists, and check the product type, to create a correct product object with the id (in my case $idProduct).
It work on woocommerce 3.x, I don't test it on woocommerce < 3.x.
if( function_exists('get_product') ) {
$product = get_product( $idProduct );
if ( $product->is_type( 'variable' ) ) {
$product = new WC_Product_Variable( $idProduct );
$available_variations = $product->get_available_variations(); //get all child variations
$variation_variations = $product- >get_variation_attributes(); // get all attributes by variations
// taxonomy => terms
// pa_attribute-color => array('blue', 'red', green)
// Use ex: get_taxonomy('pa_attribute-color')->labels; to get the Name and not the slug to attributes, it can be the taxonomy
// Use ex: get_term_by('name', 'pa_attribute-color', 'pa_attribute-color); to get the Name/label
$result = array( $available_variations , $attributes); // only to see the result you can use var_dump, error_log, etc.
//...
//...
}elseif ( $product->is_type( 'bundle' ) && class_exists( 'WC_Product_Bundle' ) ) {
$product = new WC_Product_Bundle( $idProduct );
}else{
$product = new WC_Product( $idProduct );
}
}
Also you try with:
$product->get_attribute( $key );
wc_attribute_label($key);
where $key can be pa_color , pa_size, etc
I hope help you.

sort wordpress posts by title, ignore articles like “the”, “a”, “an”

I'm sorting my posts alphabetically by Title, like so:
<?php
{
$posts = get_posts($query_string .
'&orderby=title&order=asc&posts_per_page=-1');
}
get_template_part( 'loop', 'category' );
?>
I'd like to exclude articles such as "the", "a", and "an" from the sort.
What would be the best way to accomplish this?
Thanks!
I don't know any simple way to do that but you can do this,
For achieving this you need to add a custom meta field to the post. Name it mytitle (say).
For the new posts you add, it is simple, you have to add your modified title(removing a, an, the from the title) in the mytitle custom field in the add posts page.
For old posts it is a bit tricky, you have to write a php code to retrieve the titles of the post remove 'a','an','the' from them using php preg_replace and add it to the postmeta table of your wordpress database using something like this:
<?php //inside loop
$query=INSERT INTO xyz_postmeta (post_id, meta_key, meta_value) VALUES ($postid, 'mytitle' $title);
$wpdb->query('$query'); ?>
where $postid is the post id inside the loop and $title is your modified title.
Now you have updated all the previous posts with custom mytitle field.
Now to display, you have to use a custom loop (not the loop included in the theme).
Here is how you can make a basic custom loop to display posts sorted in order of mytitle.
$querystr = "
SELECT wposts.*
FROM $wpdb->posts wposts, $wpdb->postmeta wpostmeta
WHERE wposts.ID = wpostmeta.post_id
AND wpostmeta.meta_key = 'mytitle'
AND wposts.post_type = 'post'
AND wposts.post_status = 'publish'
ORDER BY wpostmeta.meta_value ASC
";
Now you can execute the query by any means you want. Wordpres provides various methods to do so. Here's a link
For example you can do something like this
$pageposts = $wpdb->get_results($querystr, OBJECT);
foreach ( $pageposts as $pagepost )
{
echo $pagepost->post_title;
//do other stuff to display content, meta etc..
}
You can actually achieve this by manipulating the ORDERBY clause using the posts_orderby_request filter, and using TRIM to ignore articles "the", "a", and "an". Here's an example:
<?php
add_filter( 'posts_orderby_request', 'myproject_title_sort', 10, 2 );
/**
* Ignore opening articles when sorting by Title.
*
* #param string $orderby Order by parameter.
* #param WP_Query $query WP Query object.
*
* #return string
*/
function myproject_title_sort( $orderby, $query ) {
global $wpdb;
// Be sure to add a condition that matches your criteria (post type, archive, etc).
// In this example, we bail early if it's an Admin query, or not a main query.
if ( is_admin() || ! $query->is_main_query() ) {
return $orderby;
}
// This is another check to see if we're on a particular post type archive.
if ( ! $query->is_post_type_archive( 'my-post-type' ) ) {
return $orderby;
}
$title_col = $wpdb->posts . '.post_title';
// Check if we are sorting by post_title.
// You may need to use a separate `pre_get_posts` filter to sort by "title" if not already doing so.
if ( false === strpos( $orderby, $title_col ) ) {
return $orderby;
}
$ignore = "TRIM( LEADING 'the ' FROM LOWER( TRIM( LEADING 'a ' FROM LOWER( TRIM( LEADING 'an ' FROM LOWER( $title_col ) ) ) ) ) )";
$orderby = str_replace( $title_col, $ignore, $orderby );
return $orderby;
}

wordpress get_terms function not working in my plugin

hello again from a far far away place.
you know i`m trying to list all of terms from a custom taxonomy , when i use below code :
$terms = get_terms($taxonomy , 'hide_empty=0');
print_r($terms);
$count = count($terms);
if ( $count > 0 ){
echo "<ul>";
foreach ( $terms as $term ) {
echo "<li>" . $term->name . "</li>";
}
echo "</ul>";
wp return a crazy error that says : INVALID TAXONOMY :
WP_Error Object
(
[errors] => Array
(
[invalid_taxonomy] => Array
(
[0] => Invalid Taxonomy
)
)
[error_data] => Array
(
)
)
it is very interesting that you know , when i use above code in single.php, i have not see any error and it works fine.
somebody please help me !
Resolved
I am trying to use:
get_terms( 'event_category', array('hide_empty'=>FALSE) );
to use my admin theme option and face same problem when using:
add_action( 'init', 'register_features_taxonomy_event_category' );
But now its resolved using:
add_action( 'after_setup_theme', 'register_features_taxonomy_event_category' );
get_terms return invalid taxonomy error because:
you have a custom taxonomy registered in the "init" hook
so in the wp-admin it doesn´t work -> your taxonomy is registered after you call "get_term"
https://wordpress.stackexchange.com/questions/13480/get-terms-return-errors/13482#13482
Oh my ... i solve this by a crazy solution temporary.look below :
function load_terms($taxonomy){
global $wpdb;
$query = 'SELECT DISTINCT
t.name
FROM
`wp-cls`.wp_terms t
INNER JOIN
`wp-cls`.wp_term_taxonomy tax
ON
`tax`.term_id = `t`.term_id
WHERE
( `tax`.taxonomy = \'' . $taxonomy . '\')';
$result = $wpdb->get_results($query , ARRAY_A);
return $result;
}
As you can see i use a query, but i cant apply this plugin to my programming team.i still awaiting for a correct solution/usage for get_terms function in wordpress plugins.
regards.
Nothing really to add but to make it clear: get_terms()doesn't work in "admin_init" action hook!
I did like bizzr3. Just put my code here because I was a bit confuse with bizzr3's code:
function load_terms($taxonomy){
global $wpdb;
$query = 'SELECT DISTINCT
t.name
FROM
wp_terms t
INNER JOIN
wp_term_taxonomy tax
ON
tax.term_id = t.term_id
WHERE
( tax.taxonomy = \'' . $taxonomy . '\')';
$result = $wpdb->get_results($query , ARRAY_A);
return $result;
}
then just call load_terms() in your "admin_init" function:
//get all terms from taxonomy Category
$terms = load_terms('category');
and thanks, works like a charm.
I know I'm late to the party.
To optimise bizzr3's code just a bit; You should use the $wpdb object properties for your table names, as "wp_" is just the default but it could change from site to site. Using the object property you make sure it should work for other WordPress sites as well if they have a different table prefix.
function load_terms( $taxonomy ){
global $wpdb;
$query = "SELECT DISTINCT
t.name
FROM
{$wpdb->terms} t
INNER JOIN
{$wpdb->term_taxonomy} tax
ON
tax.term_id = t.term_id
WHERE
( tax.taxonomy = '{$taxonomy}')";
$result = $wpdb->get_results( $query , ARRAY_A );
return $result;
}
Also changed the single quotes to double quotes to use {$variables}

Resources