Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save solaceten/9095bb0b2eb4a6a8baeb95e1955f4720 to your computer and use it in GitHub Desktop.
Save solaceten/9095bb0b2eb4a6a8baeb95e1955f4720 to your computer and use it in GitHub Desktop.
<?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