getting Woocommerce order number into Gravity Perks Nested Form - php

I am using Woocommerce + Gravity forms with the WooCommerce Gravity Forms Product Add-Ons. My form contains a Nested Gravity Perks Form. I need to add the Woocommerce Order number to both the parent and the child gravity form. I have accomplished this with the following code:
add_action( 'woocommerce_checkout_order_processed', 'wc_add_order_id' );<br>function wc_add_order_id( $order_id ) {
$order = wc_get_order( $order_id );
foreach ( $order->get_items() as $item ){
$product_id = $item['product_id'];
if ( has_term( 'camp', 'product_cat', $product_id ) ) { //my woocommerce category
$meta_data = $item->get_formatted_meta_data();
$meta_data_items = $item->get_meta_data();
foreach ( $meta_data_items as $meta ) {
$entry_id = $meta->value['_gravity_form_linked_entry_id'];
$entry = GFAPI::get_entry( $entry_id );
$entry['40'] = $order_id ; //40 is the id of a single field reserved for the Order #
$result = GFAPI::update_entry( $entry );
return $result;
}
}
}
};
I then tried the following to add the order number to my child form (this works if I manually update the parent form entry. It does not work automatically from the update_entry trigger above:
add_action( 'gform_after_update_entry_82', function ( $form, $entry_id ) { //82 is the parent form id<br>
$entry = GFAPI::get_entry( $entry_id );
$entry_child_order = rgar( $entry, '2' ); //2 is the field that contains the entry id of the child
$order_id = rgar( $entry, '40' ); //this has the Woocommerce Order #
$entry2 = GFAPI::get_entry( $entry_child_order);
$entry2['147'] = $order_id ; //147 is the single field reserved for the order number
$result = GFAPI::update_entry( $entry2 );
return $result;
}, 10, 2 );
Does anyone know why "GFAPI::update_entry( $entry );" doesn't automatically trigger the second half of this code?

Ok. I figured it out. I was able to put everything into the same function and it is working.
//add order number to gravity forms
add_action( 'woocommerce_checkout_order_processed', 'wc_add_order_id' );
function wc_add_order_id( $order_id ) {
$order = wc_get_order( $order_id );
$cart_reg = $order->get_items();
$entry_id = array();
$entry_id2 = array();
$entry_id[] = $linked_entry;
$entry_id2[] = $linked_nested_value;
foreach( $cart_reg as $key => $value) {
$linked_entry=$value->get_meta( '_gravity_forms_history')["_gravity_form_linked_entry_id"];
$entry_id = $linked_entry;
$entry = GFAPI::get_entry( $entry_id );
$entry['40'] = $order_id; //40 is my field number that will contain orede number
$result = GFAPI::update_entry( $entry );
$linked_nested_value=$value->get_meta( '_gravity_forms_history')["_gravity_form_lead"]['2'];
if(!$linked_nested_value == ''){
$nested_value_array = preg_split ("/\,/", $linked_nested_value); //array of child entries
$child_entry_amt = substr_count($linked_nested_value, ",") + 1;
}//child entries
if ($child_entry_amt > 0){
for ($n = 0; $n < $child_entry_amt; $n++) {
$entry_id2=$nested_value_array[$n];
$entry2 = GFAPI::get_entry( $entry_id2 );
$entry2['147'] = $order_id;//this is my field number on my child form that will contain order number
$result2 = GFAPI::update_entry( $entry2 );
}
}
}
};

Related

Add column total order weight to WooCommerce My account Orders

I want to add weight metadata to an order in the Frontend: My Account - Orders. I tried some things but it is not working.
I want to add is $order->get_weight(); as meta data to the order but I am getting an error.
I am already half way using this code to add a new column and show product description and quantity:
add_filter( 'woocommerce_my_account_my_orders_columns', 'additional_my_account_orders_column', 10, 1 );
function additional_my_account_orders_column( $columns ) {
$new_columns = [];
foreach ( $columns as $key => $name ) {
$new_columns[ $key ] = $name;
if ( 'order-status' === $key ) {
$new_columns['order-items'] = __( 'Descripción', 'woocommerce' );
}
}
return $new_columns;
}
add_action( 'woocommerce_my_account_my_orders_column_order-items', 'additional_my_account_orders_column_content', 10, 1 );
function additional_my_account_orders_column_content( $order ) {
$details = array();
foreach( $order->get_items() as $item )
$details[] = $item->get_name() . ' × ' . $item->get_quantity();
echo count( $details ) > 0 ? implode( '<br>', $details ) : '–';
}
Hope someone can help me get in the right direction.
This snippet inserts a new, custom column in the table of orders shown in My Account > Orders populated with the total weight of the order so the customer is aware how heavy their order was.
Specifically, this snippet has two blocks of code. The first block inserts the column. In this example, we have inserted this column between the Order Total and Order Actions column. This can be changed by changing the column key in the code. Your custom will appear after the column key you define.
The second block of code is where the magic happens. It first loops through each item in the order and gets it weight and times this by the quantity of this product. It then adds this weight of each product to a variable we have called $total_weight. The total weight is then output to the new column followed by the weight unit you have defined in your store settings under WordPress Dashboard > WooCommerce > Settings > Products > General > Measurements > Weight Unit.
/**
* Snippet Name: WooCommerce Show Order Weight Column In My Account Order View Table
* Snippet Author: ecommercehints.com
*/
// First, create the new table column between Total and Actions columns
add_filter( 'woocommerce_my_account_my_orders_columns', 'ecommercehints_weight_column_my_account_orders_table', 10, 1 );
function ecommercehints_weight_column_my_account_orders_table( $columns ) {
$weight_column = [];
foreach ( $columns as $key => $name ) {
$weight_column[ $key ] = $name;
if ( 'order-total' === $key ) { // Insert new column after Total column
$weight_column['order-items'] = __( 'Order Weight', 'woocommerce' );
}
}
return $weight_column;
}
// Second, insert the data from the order into the new column
add_action( 'woocommerce_my_account_my_orders_column_order-items', 'ecommercehints_get_order_weight', 10, 1 );
function ecommercehints_get_order_weight( $order ) {
$weight_unit = get_option('woocommerce_weight_unit');
$total_weight = 0;
foreach( $order->get_items() as $item_id => $item ){
$quantity = $item->get_quantity();
$product = $item->get_product();
$product_weight = $product->get_weight();
$total_weight += floatval( $product_weight * $quantity );
}
echo $total_weight . $weight_unit;
}
Just came across this, have you tried it? https://gist.github.com/kloon/5299119?permalink_comment_id=1415838
Here is a copy of the code in case the link eventually dies:
<?php
add_filter( 'manage_edit-shop_order_columns', 'woo_order_weight_column' );
function woo_order_weight_column( $columns ) {
$columns['total_weight'] = __( 'Weight', 'woocommerce' );
return $columns;
}
add_action( 'manage_shop_order_posts_custom_column', 'woo_custom_order_weight_column', 2 );
function woo_custom_order_weight_column( $column ) {
global $post, $woocommerce, $the_order;
if ( empty( $the_order ) || $the_order->get_id() !== $post->ID )
$the_order = new WC_Order( $post->ID );
if ( $column == 'total_weight' ) {
$weight = 0;
if ( sizeof( $the_order->get_items() ) > 0 ) {
foreach( $the_order->get_items() as $item ) {
if ( $item['product_id'] > 0 ) {
$_product = $item->get_product();
if ( ! $_product->is_virtual() ) {
$weight += $_product->get_weight() * $item['qty'];
}
}
}
}
if ( $weight > 0 ) {
print $weight . ' ' . esc_attr( get_option('woocommerce_weight_unit' ) );
} else {
print 'N/A';
}
}
}
?>

Adding prefix to WooCommerce order number if order has items from a specific product category

In a webshop that can only have one item in the cart, I need to add a prefix to the order number when the order contains an item from a specific category
For this I wrote the following code:
add_action( 'woocommerce_prefix', 'check_product_category_in_order', 5 );
function check_product_category_in_order( $order_id ) {
if ( ! $order_id ) {
return;
}
$order = wc_get_order( $order_id );
$category_in_order = false;
$items = $order->get_items();
foreach ( $items as $item ) {
$product_id = $item['product_id'];
if ( has_term( 'MY-PRODUCT-CATEGORY', 'product_cat', $product_id ) ) {
$category_in_order = true;
break;
}
}
if ( $category_in_order ) {
*New funtion here*
}
}
Now I need the following function to run if $category_in_order:
add_filter( 'woocommerce_order_number', 'change_woocommerce_order_number' );
function change_woocommerce_order_number( $order_id ) {
$prefix = 'AB-';
$new_order_id = $prefix . $order_id;
return $new_order_id;
}
But I cant seem to find out. Can I add a filter and function whitin an if statement?
There is no need to use a filter hook in the if condition.
You can immediately add all logic in the correct filter hook.
So to add a prefix to the order number when the order contains an item from a specific category you only have to use:
function filter_woocommerce_order_number( $order_id, $order ) {
// Prefix
$prefix = 'AB-';
// Specific categories: the term name/term_id/slug. Several could be added, separated by a comma
$categories = array( 'categorie-1', 'categorie-2', 15, 16 );
// Flag
$found = false;
// Loop through order items
foreach ( $order->get_items() as $item ) {
// Product ID
$product_id = $item->get_variation_id() > 0 ? $item->get_variation_id() : $item->get_product_id();
// Has term (product category)
if ( has_term( $categories, 'product_cat', $product_id ) ) {
$found = true;
break;
}
}
// true
if ( $found ) {
$order_number = $prefix . $order_id;
} else {
$order_number = $order_id;
}
return $order_number;
}
add_filter( 'woocommerce_order_number', 'filter_woocommerce_order_number', 10, 2 );
Related: Adding prefix to WooCommerce order number based on multiple categories

Get the order item Id in WooCommerce order items

With WooCommerce, I am trying to change the download URLs for order items. Originally I was using the order ID but that only allows one subscription per order. So I need the customer to be able to purchase more than one subscription.
Here is the code I currently have:
if ( !class_exists( 'pl_wcdf_extention' ) ) {
class pl_wcdf_extention {
public function __construct() {
add_filter( 'woocommerce_order_get_downloadable_items', array( $this, 'download_link' ), 10, 2 );
add_filter( 'woocommerce_customer_get_downloadable_products', array( $this, 'download_link' ), 10, 1 );
}
public function download_link( $downloads, $order = null ) {
$download_url_base = 'https://xxxx.com/';
// retrieve Order ID from Download array
$order_id = $downloads [0]['order_id'];
// retrieve Order data
$order = wc_get_order( $order_id );
// retrieve Order Items
$order_item = $order->get_items();
// retrieve first Order Item ID
$order_item_id = $order_item [0][order_item_id];
foreach ( $downloads as $download ) {
$download['download_url'] = $download_url_base . "xxxx-" . $order_item_id . ".svg";
$tag_item = array(
'--native-libs-dir' => '/home/Lib/',
'--type' => 'template0001style1',
'--data'=> $order_item_id,
'--join' => 'horizontal',
'--output-file' => '/home/public_html/xxxx-' . $order_item_id . '.svg'
);
$args = "";
foreach ($tag_item as $k=>$v) {
$args .= " $k " . " $v ";
}
shell_exec("/home/Python-2.7.14/Python-3.6.3/python /home/Lib/generate-code.py $args");
}
return $downloads;
}
}
}
if ( class_exists( 'pl_wcdf_extention' ) ) {
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
global $wpdb;
define( 'PL_WCDFE_DIR_PATH', plugin_dir_path( __FILE__ ) );
define( 'PL_WCDFE_PLUGIN_FILE', __FILE__ );
new pl_wcdf_extention();
}
Everything works except I am not able to get the order item ID.
Any help would be appreciated.
To retrieve order item id from the WC_Order_Item Object, please use the get_id() method.
So in your script, you should replace this section:
// retrieve first Order Item ID
$order_item_id = $order_item [0][order_item_id];
with this:
// retrieve first Order Item ID
$order_item_id = $order_item[0]->get_id();

How to create product category column in woocommerce orders panel?

How can I manage columns in wordpress for add new column getting product category in woocommerce orders panel. I already found a way to create new columns in entire panel but I don't know how to add.
//MANAGE COLUMNS
add_filter( 'manage_pagamento_posts_columns', 'green_filter_posts_columns' );
function green_filter_posts_columns( $columns ) {
$columns = array(
'cb' => $columns['cb'],
'title' => __( 'Title' ),
'pacote' => __( 'Pacote', 'green' ),
'temporada' => __( 'Temporada', 'green' )
);
return $columns;
}
I can't add comment to the answer above so I post a new one. The answer from doughfabris is almost working. I test on my dev-site and found the code will work after remove "$item_cats = array_unique($item_cats);" below "$order_data = $order->get_data();"
The code here tested and work fine for me. Thanks dougfabris!
BTW, how to make it only show the top level?
// ADDING A NEW COLUMN (keeping "Total" and "Actions" columns at the end)
add_filter( 'manage_edit-shop_order_columns', 'custom_shop_order_column', 20 );
function custom_shop_order_column($columns)
{
$reordered_columns = array();
// Inserting columns to a specific location
foreach( $columns as $key => $column){
$reordered_columns[$key] = $column;
if( $key == 'order_status' ){
// Inserting after "Status" column
$reordered_columns['my-column1'] = __( 'Categorias','theme_domain');
}
}
return $reordered_columns;
}
// Adding custom fields meta data for each new column (example)
add_action( 'manage_shop_order_posts_custom_column' , 'custom_orders_list_column_content', 20, 2 );
function custom_orders_list_column_content( $column, $post_id )
{
switch ( $column )
{
case 'my-column1' :
$cats = '';
$cats_final = '';
$item_cats = array();
$order = wc_get_order( $post_id );
$order_data = $order->get_data();
foreach ($order->get_items() as $item_key => $item_values):
## Using WC_Order_Item methods ##
// Item ID is directly accessible from the $item_key in the foreach loop or
$item_id = $item_values->get_product_id();
$item_cat = get_the_terms($item_id, 'product_cat');
foreach ( $item_cat as $term ) {
array_push($item_cats, $term->name);
}
endforeach;
$item_cats = array_unique($item_cats);
foreach($item_cats as $item_final){
$cats_final .= $item_final.', ';
}
echo rtrim($cats_final,", ");
break;
}
}
I found a way to add columns in woocommerce orders panel. In this code I show how to add products categories in each order line filtering by product and removing repeated categories when it happen.
// ADDING A NEW COLUMN (keeping "Total" and "Actions" columns at the end)
add_filter( 'manage_edit-shop_order_columns', 'custom_shop_order_column', 20 );
function custom_shop_order_column($columns)
{
$reordered_columns = array();
// Inserting columns to a specific location
foreach( $columns as $key => $column){
$reordered_columns[$key] = $column;
if( $key == 'order_status' ){
// Inserting after "Status" column
$reordered_columns['my-column1'] = __( 'Categorias','theme_domain');
}
}
return $reordered_columns;
}
// Adding custom fields meta data for each new column (example)
add_action( 'manage_shop_order_posts_custom_column' , 'custom_orders_list_column_content', 20, 2 );
function custom_orders_list_column_content( $column, $post_id )
{
switch ( $column )
{
case 'my-column1' :
$cats = '';
$cats_final = '';
$item_cats = array();
$order = wc_get_order( $post_id );
$order_data = $order->get_data();
foreach ($order->get_items() as $item_key => $item_values):
## Using WC_Order_Item methods ##
// Item ID is directly accessible from the $item_key in the foreach loop or
$item_id = $item_values->get_product_id();
$item_cat = get_the_terms($item_id, 'product_cat');
$item_cat = array_unique($item_cat);
foreach ( $item_cat as $term ) {
array_push($item_cats, $term->name);
}
endforeach;
$item_cats = array_unique($item_cats);
foreach($item_cats as $item_final){
$cats_final .= $item_final.', ';
}
echo rtrim($cats_final,", ");
break;
}
}

How to get order items ids to get some product meta data?

I'm trying to extract item meta value from Woocommerce's orders by using:
$data = wc_get_order_item_meta( $item, '_tmcartepo_data', true );
However, I can't find a way to get order_item_id as the first parameter (using get_items)
global $woocommerce, $post, $wpdb;
$order = new WC_Order($post->ID);
$items = $order->get_items();
foreach ( $items as $item ) {
$item_id = $item['order_item_id']; //???
$data = wc_get_order_item_meta( $item_id, '_tmcartepo_data', true );
$a = $data[0]['value'];
$b = $data[1]['value'];
echo $a;
echo $b;
}
And I mean this order item_id (1 and 2)
Order_item_id in database - Image
How can I don that?
Thanks.
2018 Update:
Clarifying the answer with 2 possible cases
Added compatibility for woocommerce 3+
So There can be 2 cases:
1) Get product meta data (not set in order item meta data):
You will need to get the product ID in the foreach loop for a WC_Order and to get some metadata for this product you wil use get_post_meta() function ( but NOT wc_get_order_item_meta() ).
So here is your code:
global $post;
$order = wc_get_order( $post->ID );
$items = $order->get_items();
foreach ( $order->get_items() => $item ) {
// Compatibility for woocommerce 3+
$product_id = version_compare( WC_VERSION, '3.0', '<' ) ? $item['product_id'] : $item->get_product_id();
// Here you get your data
$custom_field = get_post_meta( $product_id, '_tmcartepo_data', true);
// To test data output (uncomment the line below)
// print_r($custom_field);
// If it is an array of values
if( is_array( $custom_field ) ){
echo implode( '<br>', $custom_field ); // one value displayed by line
}
// just one value (a string)
else {
echo $custom_field;
}
}
2) Get order item meta data (custom field value):
global $post;
$order = wc_get_order( $post->ID );
$items = $order->get_items();
foreach ( $order->get_items() as $item_id => $item ) {
// Here you get your data
$custom_field = wc_get_order_item_meta( $item_id, '_tmcartepo_data', true );
// To test data output (uncomment the line below)
// print_r($custom_field);
// If it is an array of values
if( is_array( $custom_field ) ){
echo implode( '<br>', $custom_field ); // one value displayed by line
}
// just one value (a string)
else {
echo $custom_field;
}
}
If the custom field data is an array, you can access the data in a foreach loop:
// Iterating in an array of keys/values
foreach( $custom_field as $key => $value ){
echo '<p>key: '.$key.' | value: '.$value.'</p>';
}
All code is tested and works.
Reference related to data in orders:
How to get WooCommerce order details (also for woocommerce 3)
Get Order items and WC_Order_Item_Product in Woocommerce 3
When doing the foreach on $order->get_items(), their key is actually the orderline ID. So:
foreach ( $order->get_items() as $key => $item ) {
$data = wc_get_order_item_meta( $key, '_tmcartepo_data' );
...
}
Late to the party, but being working with the same point with TM Extra Product Options plugin, I think this is what answers your question:
$order = wc_get_order( $post->ID );
$items = $order->get_items();
foreach( $items as $item ){
$data = unserialize($item['item_meta']['_tmcartepo_data'][0]);
$a = $data[0]['value'];
$b = $data[1]['value'];
echo $a;
echo $b;
}
Tested and works in my case.
Use this <pre><?php print_r($items); ?></pre> to check all the contents of the $items array/object.
foreach ( $order->get_items() as $key => $item ) {
$data = wc_get_order_item_meta( $key, '_tmcartepo_data' );
...
This solution was worth to me, change "_tmcartepo_data" for your meta_key.
A simple way to get order items from database;
/**
* #param $order_id
*
* #return array|null|object
*/
function get_order_items( $order_id ) {
global $wpdb, $table_prefix;
$items = $wpdb->get_results( "SELECT * FROM `{$table_prefix}woocommerce_order_items` WHERE `order_id` = {$order_id}" );
$item_name = array();
foreach ( $items as $item ) {
$item_name[] = $item->order_item_name;
}
return $item_name;
}

Categories