Last active
July 2, 2025 04:45
-
-
Save solaceten/9095bb0b2eb4a6a8baeb95e1955f4720 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
// THIS CODE IS GIVE FREELY WITH NO WARRANTY OR SUPPORT - test in a staging site first. You may need to modify to suit you. | |
// author: Sol @ Purple Dog | |
// Step one, add the below functions code in WPAE > Settings > Function Editor | |
// Step two, in the export order template add a your selected fields then use the Add Field button > Custom export field > and use the following tag: | |
To get Booking Number of Persons | |
Column Name: Booking Persons | |
Custom Export Field Content: | |
[get_single_booking_detail_for_order({Order ID}, "persons")] | |
To get Booking ID | |
Column Name: Booking ID | |
Custom Export Field Content: | |
[get_single_booking_detail_for_order({Order ID}, "id")] | |
To get Booking Start Date | |
Column Name: Booking Start Date | |
Custom Export Field Content: | |
[get_single_booking_detail_for_order({Order ID}, "start_date")] | |
To get Booking End Date | |
Column Name: Booking End Date | |
Custom Export Field Content: | |
[get_single_booking_detail_for_order({Order ID}, "end_date")] | |
To get Booking Total Price | |
Column Name: Booking Cost | |
Custom Export Field Content: | |
[get_single_booking_detail_for_order({Order ID}, "cost")] | |
/* | |
/** | |
* Debug Switch for WP All Export Custom Functions. | |
* Set to 'true' to enable debug logging to wp-content/debug.log. | |
* Set to 'false' to disable debug logging. | |
*/ | |
define( 'WP_ALL_EXPORT_CUSTOM_DEBUG', false ); // Set this to true to enable debug logs, false to disable | |
// use this to see if these functions are working | |
// in the Add Field button, add a Custom Export Field Content: [test_wpallexport_php_execution()] | |
function test_wpallexport_php_execution() { | |
return "PHP Executed OK!"; // this will show if the button is working fine. | |
} | |
/** | |
* Retrieves the WooCommerce Order ID from a given Order Item ID. | |
* This is a helper for other functions. | |
* | |
* @param int $order_item_id The ID of the WooCommerce Order Item. | |
* @return int The WooCommerce Order ID, or 0 if not found. | |
*/ | |
function get_order_id_from_order_item_id( $order_item_id ) { | |
global $wpdb; | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_order_id_from_order_item_id called with item ID: " . $order_item_id); | |
} | |
if ( ! is_numeric( $order_item_id ) || $order_item_id <= 0 ) { | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: Invalid order item ID in get_order_id_from_order_item_id: " . $order_item_id); | |
} | |
return 0; // Invalid order item ID | |
} | |
$order_id = $wpdb->get_var( $wpdb->prepare( | |
"SELECT order_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d", | |
$order_item_id | |
) ); | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_order_id_from_order_item_id returning order ID: " . (int)$order_id); | |
} | |
return (int) $order_id; | |
} | |
/** | |
* Get the Order Item object from the Order Item ID. | |
* This is a helper for other functions. | |
* | |
* @param int $item_id Item ID. | |
* @return object|null Order Item (or null) | |
*/ | |
function wc_get_order_item_object_by_item_id( $item_id ) { | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: wc_get_order_item_object_by_item_id called with item ID: " . $item_id); | |
} | |
// wc_get_order_id_by_order_item_id is a WC core function (introduced in WC 3.0) | |
$order_id = wc_get_order_id_by_order_item_id($item_id); | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: wc_get_order_item_object_by_item_id - order ID from item: " . $order_id); | |
} | |
$order = wc_get_order($order_id); | |
if ( ! is_a($order, 'WC_Order') ) { | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: wc_get_order_item_object_by_item_id - No WC_Order object found for order ID: " . $order_id); | |
} | |
return null; | |
} | |
$order_items = $order->get_items( array( 'line_item', 'coupon', 'shipping', 'fee', 'tax' ) ); | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: wc_get_order_item_object_by_item_id - order items count: " . count($order_items)); | |
} | |
return isset($order_items[$item_id]) ? $order_items[$item_id] : null; | |
} | |
/** | |
* Retrieves the "Booking Type" value from product add-ons associated with an Order Item. | |
* | |
* @param int $order_item_id The ID of the WooCommerce Order Item. | |
* @return string The value of the "Booking Type" add-on, or an empty string if not found. | |
*/ | |
function get_booking_type_from_order_item_addons( $order_item_id ) { | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_booking_type_from_order_item_addons called for order_item_id: " . $order_item_id); | |
} | |
if ( ! is_numeric( $order_item_id ) || $order_item_id <= 0 ) { | |
return ''; | |
} | |
$order_item = wc_get_order_item_object_by_item_id( $order_item_id ); | |
if ( ! $order_item ) { | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_booking_type_from_order_item_addons - No order item object found."); | |
} | |
return ''; | |
} | |
// if you are using addons, you can use this to fetch additional meta just change the data below for the stuff you need to fetch | |
$addons_data = $order_item->get_meta( '_product_addons' ); | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_booking_type_from_order_item_addons - addons_data: " . print_r($addons_data, true)); | |
} | |
if ( ! empty( $addons_data ) && is_array( $addons_data ) ) { | |
foreach ( $addons_data as $addon ) { | |
if ( isset( $addon['name'] ) && strtolower( $addon['name'] ) === 'booking type' ) { | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_booking_type_from_order_item_addons - found by 'name': " . $addon['value']); | |
} | |
return (string) $addon['value']; | |
} | |
if ( isset( $addon['field_name'] ) && strtolower( $addon['field_name'] ) === 'booking type' ) { | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_booking_type_from_order_item_addons - found by 'field_name': " . $addon['value']); | |
} | |
return (string) $addon['value']; | |
} | |
} | |
} | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_booking_type_from_order_item_addons - 'Booking Type' addon not found."); | |
} | |
return ''; | |
} | |
/** | |
* Retrieves an array of Booking Post IDs associated with a given WooCommerce Order ID. | |
* This is the reverse lookup from Order to Booking. | |
* | |
* @param int $order_id The ID of the WooCommerce Order. | |
* @return array An array of booking post IDs, or empty array if none found. | |
*/ | |
function get_booking_ids_for_order( $order_id ) { | |
global $wpdb; | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_booking_ids_for_order called for Order ID: " . $order_id); | |
} | |
if ( ! is_numeric( $order_id ) || $order_id <= 0 ) { | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_booking_ids_for_order - Invalid Order ID: " . $order_id); | |
} | |
return []; | |
} | |
// 1. Get all order_item_ids for the given order_id that are 'line_item' types | |
// (Bookings are typically 'line_item' types in woocommerce_order_items) | |
$order_item_ids = $wpdb->get_col( $wpdb->prepare( | |
"SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d AND order_item_type = 'line_item'", | |
$order_id | |
) ); | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_booking_ids_for_order - Order Item IDs found: " . implode(', ', $order_item_ids)); | |
} | |
if ( empty( $order_item_ids ) ) { | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_booking_ids_for_order - No order items found for order ID: " . $order_id); | |
} | |
return []; | |
} | |
$booking_ids = []; | |
// 2. For each order_item_id, find the wc_booking post that links to it via postmeta | |
// We'll query postmeta for _booking_order_item_id | |
$placeholders = implode( ',', array_fill( 0, count( $order_item_ids ), '%d' ) ); | |
$booking_post_ids_from_meta = $wpdb->get_col( $wpdb->prepare( | |
"SELECT post_id FROM {$wpdb->prefix}postmeta WHERE meta_key = '_booking_order_item_id' AND meta_value IN ({$placeholders})", | |
...$order_item_ids | |
) ); | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_booking_ids_for_order - Booking Post IDs from meta: " . implode(', ', $booking_post_ids_from_meta)); | |
} | |
if ( ! empty( $booking_post_ids_from_meta ) ) { | |
// Ensure these found post_ids are actually 'wc_booking' post types | |
foreach ( $booking_post_ids_from_meta as $b_id ) { | |
$post_type = get_post_type( $b_id ); | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_booking_ids_for_order - Checking post ID {$b_id}, post_type: {$post_type}"); | |
} | |
if ( $post_type === 'wc_booking' ) { | |
$booking_ids[] = $b_id; | |
} | |
} | |
} | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_booking_ids_for_order - Final booking IDs before return: " . implode(', ', $booking_ids)); | |
} | |
return array_unique( $booking_ids ); | |
} | |
/** | |
* Retrieves a specific piece of information (post field or post meta) for a WooCommerce Booking. | |
* This function handles simple post fields and post meta. | |
* | |
* @param int $booking_id The ID of the WooCommerce Booking post. | |
* @param string $info_key The meta key or post field to retrieve (e.g., '_booking_start', 'post_title'). | |
* @return mixed The requested information, or an empty string if not found. | |
*/ | |
function get_booking_info( $booking_id, $info_key ) { | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_booking_info called for Booking ID: {$booking_id}, info_key: {$info_key}"); | |
} | |
if ( ! is_numeric( $booking_id ) || $booking_id <= 0 ) { | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_booking_info - Invalid Booking ID: {$booking_id}"); | |
} | |
return ''; | |
} | |
// Load the post data once. | |
$post_data = get_post( $booking_id ); | |
// Explicitly handle standard WordPress post fields only if needed. | |
// For all other info_keys (especially booking meta like _booking_persons), | |
// we will use get_post_meta. | |
if ( $post_data ) { | |
switch ( $info_key ) { | |
case 'post_title': | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_booking_info - Found post_title: " . $post_data->post_title); | |
} | |
return $post_data->post_title; | |
// Add other standard post fields here if you need them to be retrieved directly from $post_data | |
// case 'post_status': | |
// if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { error_log("DEBUG: get_booking_info - Found post_status: " . $post_data->post_status); } | |
// return $post_data->post_status; | |
// case 'post_date': | |
// if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { error_log("DEBUG: get_booking_info - Found post_date: " . $post_data->post_date); } | |
// return $post_data->post_date; | |
} | |
} | |
// For all other info_keys (which are expected to be post meta for bookings), use get_post_meta. | |
$meta_value = get_post_meta( $booking_id, $info_key, true ); | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_booking_info - Raw meta_value for {$info_key} (from get_post_meta): " . print_r($meta_value, true)); | |
} | |
if ( is_array( $meta_value ) ) { | |
// This is the specific block that handles the '_booking_persons' array correctly. | |
// It now sums up all person counts to give a single total number. | |
if ( $info_key === '_booking_persons' && ! empty( $meta_value ) ) { | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_booking_info - Handling _booking_persons. Raw array (from get_post_meta): " . print_r($meta_value, true)); | |
} | |
$total_persons = 0; | |
foreach ( $meta_value as $person_type_id => $count ) { | |
$total_persons += (int) $count; // Sum up all person counts | |
} | |
$final_persons_output = (string) $total_persons; | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_booking_info - Final persons output (total count): " . $final_persons_output); | |
} | |
return $final_persons_output; | |
} | |
// Fallback for other arrays if they ever occur for other meta keys that are not _booking_persons | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_booking_info - Imploding generic array for {$info_key} (from get_post_meta): " . print_r($meta_value, true)); | |
} | |
return implode( ', ', $meta_value ); | |
} | |
// Return simple string values (e.g., for _booking_start, _booking_end, _booking_cost, _booking_resource_id) | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_booking_info - Returning string meta_value for {$info_key}: " . (string) $meta_value); | |
} | |
return (string) $meta_value; | |
} | |
/** | |
* Retrieves the ID of the first WooCommerce Booking associated with a given Order ID. | |
* This is a helper for getting specific booking details into separate columns. | |
* | |
* @param int $order_id The ID of the WooCommerce Order. | |
* @return int The ID of the first booking found, or 0 if no bookings are found. | |
*/ | |
function get_first_booking_id_for_order( $order_id ) { | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_first_booking_id_for_order called for Order ID: " . $order_id); | |
} | |
$booking_ids = get_booking_ids_for_order( $order_id ); // Reuses our existing function | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_first_booking_id_for_order - Booking IDs from sub-function: " . implode(', ', $booking_ids)); | |
} | |
if ( ! empty( $booking_ids ) ) { | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_first_booking_id_for_order - Returning first booking ID: " . (int)$booking_ids[0]); | |
} | |
return (int) $booking_ids[0]; // Return the first booking ID found | |
} | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_first_booking_id_for_order - No booking IDs found, returning 0."); | |
} | |
return 0; // No booking found | |
} | |
/** | |
* Retrieves a specific booking detail for the first booking associated with a given Order ID. | |
* This simplifies adding individual booking fields to an order export. | |
* | |
* @param int $order_id The ID of the WooCommerce Order. | |
* @param string $detail_key The specific detail to retrieve (e.g., 'start_date', 'end_date', 'persons', 'cost', 'type', 'title', 'id', 'resource_name'). | |
* @return string The formatted booking detail, or empty string if not found. | |
*/ | |
function get_single_booking_detail_for_order( $order_id, $detail_key ) { | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_single_booking_detail_for_order called for Order ID: " . $order_id . ", detail key: " . $detail_key); | |
} | |
$booking_id = get_first_booking_id_for_order( $order_id ); | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_single_booking_detail_for_order - First booking ID found: " . $booking_id); | |
} | |
if ( $booking_id === 0 ) { | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_single_booking_detail_for_order - No booking ID found, returning empty string."); | |
} | |
return ''; | |
} | |
switch ( $detail_key ) { | |
case 'id': | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_single_booking_detail_for_order - Returning booking ID: " . $booking_id); | |
} | |
return (string) $booking_id; // The Booking Post ID itself | |
case 'title': | |
$title = get_booking_info( $booking_id, 'post_title' ); // The booking's post title (usually product title) | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_single_booking_detail_for_order - Returning booking title: " . $title); | |
} | |
return $title; | |
case 'start_date': | |
$date_raw = get_booking_info( $booking_id, '_booking_start' ); | |
if ( ! empty( $date_raw ) ) { | |
$datetime = DateTime::createFromFormat( 'YmdHis', $date_raw ); | |
return $datetime ? $datetime->format( 'Y-m-d H:i' ) : ''; // Formatted date/time | |
} | |
break; | |
case 'end_date': | |
$date_raw = get_booking_info( $booking_id, '_booking_end' ); | |
if ( ! empty( $date_raw ) ) { | |
$datetime = DateTime::createFromFormat( 'YmdHis', $date_raw ); | |
return $datetime ? $datetime->format( 'Y-m-d H:i' ) : ''; // Formatted date/time | |
} | |
break; | |
case 'persons': | |
$persons = get_booking_info( $booking_id, '_booking_persons' ); // Now returns total count | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_single_booking_detail_for_order - Returning persons (total count): " . $persons); | |
} | |
return $persons; | |
break; | |
case 'cost': | |
$cost = get_booking_info( $booking_id, '_booking_cost' ); | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_single_booking_detail_for_order - Returning cost: " . $cost); | |
} | |
return $cost; | |
break; | |
case 'type': | |
// To get Booking Type, we need the order_item_id associated with THIS specific booking. | |
// get_post_meta is safe to call here as the context is within our PHP function. | |
$booking_order_item_id = get_post_meta( $booking_id, '_booking_order_item_id', true ); | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_single_booking_detail_for_order - Booking order item ID: " . $booking_order_item_id); | |
} | |
$booking_type = get_booking_type_from_order_item_addons( $booking_order_item_id ); | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_single_booking_detail_for_order - Returning booking type: " . $booking_type); | |
} | |
return $booking_type; | |
break; | |
case 'resource_label': // This case is now for the actual resource name | |
$resource_id = get_booking_info( $booking_id, '_booking_resource_id' ); | |
$resource_name = ''; | |
if ( ! empty( $resource_id ) ) { | |
$resource_post = get_post( $resource_id ); | |
// Ensure it's a valid post object and of the correct type | |
if ( $resource_post && ! is_wp_error( $resource_post ) && $resource_post->post_type === 'bookable_resource' ) { | |
$resource_name = $resource_post->post_title; | |
} | |
} | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_single_booking_detail_for_order - Returning resource name: " . $resource_name); | |
} | |
return $resource_name; | |
break; | |
} | |
if ( defined('WP_ALL_EXPORT_CUSTOM_DEBUG') && WP_ALL_EXPORT_CUSTOM_DEBUG ) { | |
error_log("DEBUG: get_single_booking_detail_for_order - No detail found for key: " . $detail_key); | |
} | |
return ''; // Default fallback | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment