Add extra details Woocommerce order edit pages in admin - php

Hi I am using Woocommerce version 3.2.6. We have some orders.
I want to add one extra details to orders when the product id is 123 in the order edit page in wordpress backend.
I wanto add this:
Click here to view this
ie: We have order[order id =3723] , and the ordered item id is 123.
Then in http://example.com/wp-admin/post.php?post=3723&action=edit, I want to add the following link below the corresponding item details:
"Click here to view this"
How we can do this ?
Which hook is suitable for this. Actually I am searching in https://docs.woocommerce.com/wc-apidocs/hook-docs.html.
And I found Class WC_Meta_Box_Order_Items. But i don't know how to use this.

The correct code for WooCommerce version 3+ to add a custom link just after line items and only on backend is:
add_action( 'woocommerce_after_order_itemmeta', 'custom_link_after_order_itemmeta', 20, 3 );
function custom_link_after_order_itemmeta( $item_id, $item, $product ) {
// Only for "line item" order items
if( ! $item->is_type('line_item') ) return;
// Only for backend and for product ID 123
if( $product->get_id() == 123 && is_admin() )
echo ''.__("Click here to view this").'';
}
Tested and works
1) Important: Limit the code to order items "line item" type only, to avoid errors on other order items like "shipping", "fee", "discount"...
2) From the WC_Product object to get the product id you will use WC_Data get_id() method.
3) To get the Order ID from WC_Order_Item_Product object you will use WC_Order_Item method get_order_id().
4) You need to add is_admin() in the if statement to restrict the display in backend.

Order Items Meta Box uses html-order-items.php to loop through Order Items which in turn uses html-order-item.php to display each item.
For your purpose you should look inside html-order-item.php for exact place where you would want to insert your code snippet.
I assume woocommerce_after_order_itemmeta action hook is ideal as it will show the link just below meta information of the item. (In case you want to display the link before item meta than use woocommerce_before_order_itemmeta.)
add_action( 'woocommerce_after_order_itemmeta', 'wp177780_order_item_view_link', 10, 3 );
function wp177780_order_item_view_link( $item_id, $item, $_product ){
if( 123 == $_product->id ) {
echo "<a href='http://example.com/new-view/?id=" . $order->id . "'>Click here to view this</a>";
}
}

Related

Show extra sections on a product page ONLY to users who already purchased that product (Elementor, Crocoblock, JetEngine)

I have a website with few WooCommerce products, and the product page is created with Elementor Pro. I want users to be able to click Add to Cart and buy the product normally.
But then when the user goes back to the product page (after buying the product), they would not see the the Add to Cart button (if will be hidden for those that purchased the product) and they will see another extra section.
How can I do this?
I also have Crocoblock and JetEngine that have a Dynamic Visibility functionality built in Elementor.
The easiest way to achieve this would be by creating a child theme. The child theme should contain 2 added functionalities.
For this to fully work you will need all users to be registered and NOT have checkout as a guest enabled. Also, this will only work for new orders. If you want to add compatibility for old orders you'd have to create a script that sets the meta value for all users that have purchased this product before the code was implemented.
First of we create a function that adds metadata to the purchasing user account if the product was in the cart. Add the following code to your child theme functions.php
add_action( 'woocommerce_thankyou', 'custom_add_user_meta');
function custom_add_user_meta( $order_id ){
$user_id = get_current_user_id();
$order = wc_get_order( $order_id );
$items = $order->get_items();
foreach ( $items as $item_id => $item ) {
$product_id = $item->get_variation_id() ? $item->get_variation_id() : $item->get_product_id();
if ( $product_id == 12345 ) {
add_user_meta( $user_id, '_product_xyz_purchased', "true");
}
}
}
Now we add the following code to the same functions.php file to render additional content on the single product page of WooCommerce. NOTE: This step is for a more complete overview that can be implemented outside of Crocoblocks/Jetegine. The following step can be skipped because Jetengine allows setting conditions based on user_meta
add_action("woocommerce_after_single_product", 'render_additional_content', 50);
function render_additional_content() {
$user_id = get_current_user_id();
$product_purchased = get_user_meta( $user_id, '_product_xyz_purchased', true);
if($product_purchased == "true"){
echo "here you can put the HTML you want to display";
}
}

My cart_item_data isn't showing up in the order

I'm working on a site that lets a user enter data from a form and have it attached to a product. I was originally using:
$cart_item_data ['Entry Link'] = $formUrl;
$woocommerce->cart->add_to_cart($productID,$quantity,0,$cart_item_data);
With $formUrl being a link to the form data. Whenever a user made an order, under the product would be 'Entry Link' with the url.
We later had to add variations to the product so the line looked like:
$woocommerce->cart->add_to_cart($productID,$quantity,$typeID,$cart_item_data);
With $typeID being the variation ID. Once I added the $typeID, only the variation showed up on the order in the backend and not the 'Entry Link'.
If I reset $typeID to '0', the entry link shows up when an order is made. I also tried using the variation id in place of the product id but was still getting the same issue. I looked at the documentation and it should be working.
I need both the variation and the 'Entry Link' to be entered and visible from the backend.
This was the part requested by Vincenzo Di Gaetano in the comments
$formUrl = $_SERVER['SERVER_NAME'].'/wp-admin/admin.php?page=gf_entries&view=entry&id='.$formID.'&lid='.$entryID;
$cart_item_data['Entry Link'] = $formUrl;
$variationAttributes['Per'] = 1000;
$woocommerce->cart->add_to_cart($productID,$quantity,$typeID,$variationAttributes,$cart_item_data);
I added variationAttributes to it with 'Per' lining up with the attribute name, '1000' represents the value of that attribute. I hardcoded it in for testing. When I echo just the $formUrl, it does return the correct url
You are setting only 4 arguments instead of 5 for the add_to_cart method of the WC_Cart class.
Try replacing this:
$woocommerce->cart->add_to_cart( $productID, $quantity, $typeID, $cart_item_data );
with:
$woocommerce->cart->add_to_cart( $productID, $quantity, $typeID, $variation, $cart_item_data );
Here is an example of how to add a variation to the cart:
WordPress WooCommerce - Add a variable product to cart using the WC_Cart class
This will not be enough to display the cart item data as the meta of the order item.
Based on this question Save and display product custom meta on WooCommerce orders and emails you will need to save the value as a order item meta data:
// save the cart item data as custom order item meta data
add_action( 'woocommerce_checkout_create_order_line_item', 'save_cart_item_data_as_order_item_meta_data', 20, 4 );
function save_cart_item_data_as_order_item_meta_data( $item, $cart_item_key, $values, $order ) {
if ( isset( $values['Entry Link'] ) ) {
$item->update_meta_data( __( 'Entry Link'), $values['Entry Link'] );
}
}
The code has been tested and works. Add it to your active theme's functions.php.
Here is the result:

Customization on WooCommerce variable product with custom fields

We have created a site using WooCommerce and WordPress with predefined products.
However, Product A must have variations, to resolve this, we added custom fields such as Colors, Dimensions, etc...
Now once the end-users are navigating to the product, we are able to fetch the custom field values. We also modified the UI so that users can pick and choose from these custom fields. (We have a preview of the modifications done via JS/CSS), so for instance, if they choose a green color we use JS to add a layer of green so that the preview is real time.
Now, we have one challenge.
-> What is the best way to go about adding this product PLUS all modifications done to the cart?
So for instance Product A was modified (on the front-end) using data pulled from the custom fields to include Color: Green and Size: 100x100 instead of defaults values. How do we store this and pass the customized product to the cart?
Appreciate the help!. Glad to add more details if something is not clear.
(There are plugins out there that can provide this functionality; Things similar to WooCommerce Product Add-On, etc... However, we have to custom develop the feature.)
It requires some steps.
1). For your product page:
First you might need to add hidden fields to the add to cart form for each custom field like (example):
add_action( 'woocommerce_before_add_to_cart_button', 'add_hidden_empty_input_fields' );
function add_hidden_empty_input_fields() {
?>
<input type="hidden" name="hidden_color" id="hidden_color" value="">
<input type="hidden" name="hidden_dimensions" id="hidden_dimensions" value="">
<?php
}
Then you will have to make some changes to your Javascript code to set the custom fields chosen values in those hidden fields.
2). Pass the custom fields selected values as custom cart item data (example):
add_filter('woocommerce_add_cart_item_data', 'add_custom_field_data', 10, 3 );
function add_custom_field_data( $cart_item_data, $product_id, $variation_id ) {
if ( isset($_POST['hidden_color']) && ! empty($_POST['hidden_color']) ) {
$cart_item_data['color'] = esc_attr($_POST['hidden_color']);
}
if ( isset($_POST['hidden_dimensions']) && ! empty($_POST['hidden_dimensions']) ) {
$cart_item_data['dimensions'] = esc_attr($_POST['hidden_dimensions']);
}
return $cart_item_data;
}
And optionally display values on cart items (example):
add_filter( 'woocommerce_get_item_data', 'display_custom_cart_item_data', 10, 2 );
function display_custom_cart_item_data( $cart_data, $cart_item ) {
if ( isset($cart_item['color']) ) {
$cart_data[] = array( "name" => __("Color"), "value" => $cart_item['color'] );
}
if ( isset($cart_item['dimensions']) ) {
$cart_data[] = array( "name" => __("Dimensions"), "value" => $cart_item['dimensions'] );
}
return $cart_data;
}
3). Save the custom cart item data as custom order item meta data (example):
add_action( 'woocommerce_checkout_create_order_line_item', 'save_custom_order_item_meta_data' , 10, 4 );
function save_custom_order_item_meta_data( $item, $cart_item_key, $values, $order ) {
if ( isset($values['color']) ) {
$item->add_meta_data( __("Color"), $values['color'] );
}
if ( isset($values['dimensions']) ) {
$item->add_meta_data( __("Dimensions"), $values['dimensions'] );
}
}
Note: The data is going to be displayed on everywhere on orders and email notifications.
Code goes in functions.php file of the active child theme (or active theme). It should work.
The variations have a post_id, you would just use the variation post_id instead of the main product one.

Is there a possibility to make custom prices?

I'm selling Gift Cards via WooCommerce on Wordpress. My customer should be able to set a value for the gift card amount by himself. I just was able to do this via a plugin. Is there a possibilty to do this by changing some code or via functions.php?
Installed Pimwick Gift Card Pro
Yes, but it's a fairly complex process if doing so from a completely fresh WooCommerce installation with no additional plugins. You will need to do the following things to achieve it:
Add a custom input field to the product to add the custom price
Save the data from the custom input field to the session (cart) when that product is added to the cart
Add the cart meta (created above in #2) to the order when the order is created
Adjust the cost of the product based on the custom price meta (added above in #3).
Step 1: Add a custom input field:
You can add the input field using the woocommerce_before_add_to_cart_button filter as shown below.
Alternatively you can use the woocommerce_wp_text_input - here's an example.
add_action( 'woocommerce_before_add_to_cart_button', 'add_custom_price_input', 100 );
function add_custom_price_input() {
if(get_the_ID() != 123) { //use the product ID of your gift card here, otherwise all products will get this additional field
return;
}
echo '<input type="number" min="50" placeholder="50" name="so_57140247_price">';
}
Step 2: Save custom price to Cart/Session
Next, we need to make sure that your custom input field data is carried over to the cart/session data. We can make use of the woocommerce_add_cart_item_data ( docs | example ) filter to that:
add_filter( 'woocommerce_add_cart_item_data', 'add_custom_meta_to_cart', 10, 3 );
function add_custom_meta_to_cart( $cart_item_data, $product_id, $variation_id ) {
$custom_price = intval(filter_input( INPUT_POST, 'so_57140247_price' ));
if ( !empty( $custom_price ) && $product_id == 123 ) { //check that the custom_price variable is set, and that the product is your gift card
$cart_item_data['so_57140247_price'] = $custom_price; //this will add your custom price data to the cart item data
}
return $cart_item_data;
}
Step 3: Add cart meta to the order
Next we have to add the meta from the cart/session to the order itself so that it can be used in the order-total calculations. We use the woocommerce_checkout_create_order_line_item ( docs | example ) to do this:
add_action( 'woocommerce_checkout_create_order_line_item', 'add_custom_meta_to_order', 10, 4 );
function add_custom_meta_to_order( $item, $cart_item_key, $values, $order ) {
//check if our custom meta was set on the line item of inside the cart/session
if ( !empty( $values['so_57140247_price'] ) ) {
$item->add_meta_data( '_custom_price', $values['so_57140247_price'] ); //add the value to order line item
}
return;
}
Step 4: Adjust total of gift card line item
Finally, we simply adjust the cost of the line item of the gift card based on the value entered into the input field. We can hook into woocommerce_before_calculate_totals ( docs | example ) to do this.
add_action( 'woocommerce_before_calculate_totals', 'calculate_cost_custom', 10, 1);
function calculate_cost_custom( $cart_obj ) {
foreach ( $cart_obj->get_cart() as $key => $value ) {
$price = intval($value['_custom_price']);
$value['data']->set_price( $price );
}
}

Change WooCommerce variable product title based on variations

I've coded in a custom select box to a group of my products that changes the price based on the user's selection. It works well, but now I need to change the product title too based on their selection.
Basically if option 1 is chosen, the product name stays the same. But is option 2 is chosen, I need to add "-RZ" to the end of the product title.
I'm not sure if I can do this in the 'woocommerce_before_calculate_totals' hook where I altered the prices, but if anyone knows the hook I should use and the code to access the current product's title via PHP that would be great.
Here is the code that alters the price if it's helpful:
function calculate_core_fee( $cart_object ) {
if( !WC()->session->__isset( "reload_checkout" )) {
/* core price */
//echo $additionalPrice;
//$additionalPrice = 100;
foreach ( $cart_object->cart_contents as $key => $value ) {
$product_id = $value['product_id'];
if( isset( $value["addOn"] ) && $value["addOn"] == $product_id) {
$additionalPrice = $value['core'];
/* Woocommerce 3.0 + */
$orgPrice = floatval( $value['data']->get_price() );
//echo $additionalPrice;
//echo $orgPrice;
$value['data']->set_price( $orgPrice + $additionalPrice );
}
}
}
}
add_action( 'woocommerce_before_calculate_totals', 'calculate_core_fee', 99 );
I know may have to get the name and store it in a SESSION variable to use later if the hook to do this is on the cart, checkout, or order page rather than the single-product page.
Yes this is possible in the same hook. You can manipulate the product title with class WC_Product get_name() and set_name() methods. But as for the price, you should set and get a custom cart field value to make it (just as $additionalPrice = $value['core'];).
See here a simple related answer: Changing WooCommerce cart item names
So you could have something like (just a fake example):
// Get your custom field cart value for the user selection
$userSelection = $value['user_selection'];
// Get original title
$originalTitle = $value['data']->get_name();
// Conditionally set the new item title
if($userSelection == 'option2')
$value['data']->set_name( $originalTitle . '-RZ' );

Categories