So, this one has my head in for a loop. I've contacted the Support of the plugin and they basically told me I'm SOL, but I refuse to believe there isn't a way to do this.
I'm using AffiliateWP to attribute sales to a single location. Each Affiliate feeds off of a Wordpress User, and for their nickname I've used their address/location.
Unfortunately, the plugin doesn't include this in the Order Details screen or Order Emails, which is a BIG problem. I've frankensteined some code together but keep getting all kinds of undefined errors because they do everything inside classes, which I guess makes sure that people like me can't fiddle in there?
Function for assigning an affiliate to an order: https://github.com/AffiliateWP/AffiliateWP/blob/master/includes/integrations/class-woocommerce.php#L78
Function for retrieving the Affiliates User ID: https://github.com/AffiliateWP/AffiliateWP/blob/master/includes/affiliate-functions.php#L204
Function for retrieving the Affiliates Name: https://github.com/AffiliateWP/AffiliateWP/blob/master/includes/affiliate-functions.php#L132
[Edit] And finally, my Frankenstein:
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
global $Affiliate_WP_WooCommerce;
echo '<p><strong>'.__('My Field').':</strong> ' . affiliate_wp()->affiliates->get_affiliate_name( $affiliate_id ) . '</p>';
}
This doesn't throw me an error, but it does throw me a blank area...
Try this:
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
global $Affiliate_WP_WooCommerce;
$order_id = $order->get_id();
$referrals = affiliate_wp()->referrals->get_by( 'reference', $order_id);
$affiliate_id = $referrals->affiliate_id;
echo '<p><strong>'.__('My Field').':</strong> ' . affiliate_wp()->affiliates->get_affiliate_name( $affiliate_id ) . '</p>';
}
the affwp_get_affiliate_name method returns blank on three conditions:
if ( ! $affiliate = affwp_get_affiliate( $affiliate ) ) {
return '';
}
if ( ! $user_info = get_userdata( $affiliate->user_id ) ) {
return '';
}
...
// If neither are set, return an empty string.
if ( empty( $first_name ) && empty( $last_name ) ) {
return '';
}
Start by manually passing an affiliate id you know to be associated with a record that contains a $first_name and/or $last_name, for example:
echo '<p><strong>'.__('My Field').':</strong> ' . affiliate_wp()->affiliates->get_affiliate_name(5) . '</p>';
This will rule out if the problem is with the $affiliate_id that you're currently passing it. If you get values returned, it should be a simple matter to fix.
After trying that I would experiment with changing the priority of the add_action(), raising it to 999 or something because it could possibly be executing before the relevant hooks in the plugin.
Related
I want to change the layout of table present in orders.php. Specifically, instead of having rows containing the data (name, date, status, etc.), I want separate horizontal cards for each product.
Example: https://i.stack.imgur.com/itdGU.png. I'm trying to do this with a shortcode, but I'm not sure if that's the right way. Can anyone give me directions ?
For now I'm trying this way: The code below works and returns all order numbers correctly. However I am getting all the order numbers side by side as a simple line of text: https://i.stack.imgur.com/RqdVC.png. I don't know how to insert div, or css classes to change the layout.
Even if I add css classes, the question that remains is how to add other elements such as name, price, status etc. Not sure it can all be done in one shortcode. Advice ?
// GET ALL ORDERS NUMBER OF CURRENT USER
// Give the callback function a clear and descriptive name.
add_shortcode( 'prcsed_order_numbers' , 'prcsed_order_1' );
function prcsed_order_1() {
// Get all orders for the current user.
$customer_orders = wc_get_orders([
'customer_id' => get_current_user_id(),
]);
// Transform the array of order objects into an array of order names.
$order_numbers = array_map( function( $order ) {
return $order->get_order_number();
}, $customer_orders );
// Return as a string, ready for output,
return implode( ', ', $order_numbers );
}
Expanding on what I was typing before. You can access more order variables using what you were already doing in $order_numbers. Here is what I have tested on standalone WooCommerce test site. You will need to input your customer ID function and modify the return HTML structure for styling and editing simplicity. What I have is not clean but does work.
$results = wc_get_orders([ 'cutomer_id'=>1 ]);
foreach ( $results as $order ) {
$first_name = $order->get_billing_first_name();
$last_name = $order->get_billing_last_name();
$status = $order->get_status();
echo '<h1>' . $first_name . ' ' . $last_name . '</h1><p>' . $status . '</p>';
}
The following link gives you the functions/hooks for the order object that you will need accessing to. https://www.businessbloomer.com/woocommerce-easily-get-order-info-total-items-etc-from-order-object/
I would like to have an 'Edit product' link in the 'No stock' emails that the admin receives after a sale/ product is changed to out of stock.
This type of code works fine for getting all post meta/custom fields, but for post edit link it only works intermittently, really struggling to figure out what i'm doing wrong, tried various ways i know of getting edit_post and googled 100s of posts here on stack but only this one works now and then, need it to work all the time. Many thanks in advance if anyone can help..
function filter_woocommerce_email_content_edit_me_link( $message, $product ) {
$id = $product->get_id();
$edit_link = get_edit_post_link( $id, $product );
$string .= '<p class="edit-this">Edit Product</p>';
return $string;
}
// add the filter
add_filter( 'woocommerce_email_content_no_stock', 'filter_woocommerce_email_content_edit_me_link', 10, 12 );
// by various ways i mean with message or string as per all the returns as below, with a backslash ed/edi/edit it also worked but only upon manually placing an order, not when other users place an order.
//return get_edit_post_link($this->ID);
//echo get_edit_post_link($post->ID);
//return $message."\nEdit ".$edit_link;
//return $message. " \n " .get_edit_post_link(intval($product->product_id)) .$edit_link;
//return $edit_link. " edit\ " .get_edit_post_link(intval($product->product_id)) .$edit_link;
//return $message." \nedit " .$edit_link;
//return $message. " \ " .$edit_link;
//return $string .= ' ' .get_edit_post_link($product->product_id) .'';
Code below works fine for admin user who places the order but if others place the order, there is no edit link in the admin no stock email..
Using the global $product doesn't seem to help.
function filter_woocommerce_email_content_edit_me_link( $message, $product ) {
$id = $product->get_id();
$edit_link = get_edit_post_link( $id, $product );
return $message." edit product " .$edit_link;
}
// add the filter
add_filter( 'woocommerce_email_content_no_stock','filter_woocommerce_email_content_edit_me_link', 10, 12 );
I have a problem right now. I have a plugin that allows me to quickly change the status of my orders from the admin order list.
Unfortunately the name of the shop manager is not transmitted.
I think I've found the right code, but I don't know exactly how to do it.
Would be grateful for any help.
public function save_comment($order, $status_comment) {
$order->add_order_note("[[" . wc_get_order_status_name($order->post_status) . "|" . $status_comment . "]]");
}
Right now it looks like this :
I'd like to see which user changed the status as shown in this picture:
To add the username of the shop manager that has updated the Order to the order note, use the following:
add_filter( 'woocommerce_new_order_note_data', 'filter_woocommerce_new_order_note_data', 10, 2 );
function filter_woocommerce_new_order_note_data( $args, $args2 ) {
if( ! $args2['is_customer_note'] && is_user_logged_in() && current_user_can( 'edit_shop_order', $args2['order_id'] ) ){
$user = get_user_by( 'id', get_current_user_id() );
$args['comment_author'] = $user->display_name;
$args['comment_author_email'] = $user->user_email;
}
return $args;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works..
I am trying to change certain elements for a certain user, in the back administration area of WordPress.
I have found the following code which works for a specific role, but how do I change it to target a specific user?
function wpa66834_role_admin_body_class( $classes ) {
global $current_user;
foreach( $current_user->roles as $role )
$classes .= ' role-' . $role;
return trim( $classes );
}
add_filter( 'admin_body_class', 'wpa66834_role_admin_body_class' );
To clarify: instead of identifying role in the foreach section and then adding the role to the class name, I would like it to identify the user by their specific name or ID, and then add that name or ID to the class name.
You should be able to use get_current_user_id() to (as the name of the function suggests) get the current user's id, and then perform a simple if statement to compare it with a specific ID number.
Example:
function wpa66834_role_admin_body_class( $classes ) {
$user_id = get_current_user_id();
// Assuming 13 is the user's ID you're targeting
if( $user_id == 13 )
$classes .= ' custom-class-for-user-13';
return trim( $classes );
}
add_filter( 'admin_body_class', 'wpa66834_role_admin_body_class' );
More info on how to use the function can be found here.
I am working on woocommerce api to add order manually.
I have ordered variation product manually and it shows good in edit order page in admin side.
Now, problem is the site using polylang plugin.
In that, there is two language. I can successfully add order in english language.
But when I tried to add product in another language(arabic). It returns some order details in weird text format. In my API it returns :
"product_variation_details": "%d8%a7%d9%84%d8%ad%d8%ac%d9%85: صغير"
In edit order page it shows in proper way:
I have used below code to get order details in API:
$variation_id = $single_items['item_meta']['_variation_id'][0];
if ($variation_id != 0) {
$variation = wc_get_product($variation_id);
$product_variation_details = wc_get_formatted_variation($variation->get_variation_attributes(), true);
}
I have search a lot but cant get better solution. any help would be apriciated. thanks in advance.
It seems that there is some decoding going on.
Urldecode
If I'm taking the given string and print it urldecoded it returns this:
print urldecode("%d8%a7%d9%84%d8%ad%d8%ac%d9%85");
الحجم
I hope this helps
Try replacing everything inside your if with:
$variation = wc_get_product( $variation_id );
$variation_attributes = $variation->get_variation_attributes();
$variation_attributes_decoded = array();
foreach ( $variation_attributes as $name => $value ) {
$decoded_name = rawurldecode( $name );
$variation_attributes_decoded[ $decoded_name ] = $value;
}
$product_variation_details = wc_get_formatted_variation( $variation_attributes_decoded, true );
This is untested.
This is the line from wc_get_formatted_variation() that is outputting your text in question:
$variation_list[] = wc_attribute_label( str_replace( 'attribute_', '', $name ) ) . ': ' . rawurldecode( $value );
As you can see, it's decoding the $value but not the $name. My solution should decode the $name ahead of time.
Edit: just fixed a code error.