1
votes

I have a Hotel-bookings site which is made in Wordpress using following plugins:

  • Woocommerce Version 2.4.12
  • WooCommerce-Bookings Version 1.9.3
  • Product-Add-ons Version 2.7.14

End Goal

My end goal would be to show the Start & End Date of a booking on my Shopping Cart/Checkout-page & emails.

Currently i am working on showing the End date in my shopping cart.

in Cart.php (Located in the Woocommerce-plugin) the meta data is shown with the following code:

foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
    echo WC()->cart->get_item_data( $cart_item );
}

Result

Current Cart

When i do a var_dump() of the array above using following code:

echo '<pre>';

foreach( WC()->cart->get_cart() as $cart_item ) {
    var_dump( $cart_item );
}

echo '</pre>';

I Can see that the End Date value is in this array (As an integer, which is strange?):

  ["booking"]=>
  array(19) {
    ["_year"]=>
    int(2016)
    ["_month"]=>
    int(1)
    ["_day"]=>
    int(23)
    ["_persons"]=>
    array(1) {
      [234]=>
      int(1)
    }
    ["_date"]=>
    string(9) "2016-1-23"
    ["date"]=>
    string(16) "January 23, 2016"
    ["_time"]=>
    string(0) ""
    ["_qty"]=>
    int(1)
    ["Adults"]=>
    int(1)
    ["_duration_unit"]=>
    string(3) "day"
    ["_duration"]=>
    int(3)
    ["duration"]=>
    string(8) "3 nights"
    ["_start_date"]=>
    int(1453507200)
    **["_end_date"]=>
    int(1453766399)**
    ["_all_day"]=>
    int(1)
    ["_resource_id"]=>
    int(223)
    ["type"]=>
    string(15) "Suite Saadienne"
    ["_cost"]=>
    int(360)
    ["_booking_id"]=>
    int(870)
  }

Full array code here: http://pastebin.com/1nmJHYMV

You can see that the end date is present, so i tried to echo it out:

echo WC()->cart->get_item_data( $cart_item ["booking"]["_end_date"]);

But this results in : String(0) "";

Question How can i show the end date ? And format it so it is shown as a date?

Research

I found this Question here on stackoverflow: How to retrieve cart_item_data with WooCommerce? But i don't know how to implement it for my case?

The product-add-ons plugin is showing his meta data correctly so i looked at the code used, and the plugin is using Woocommerce Hooks, but i don't understand what those 2 last numbers mean?

function __construct() {
// Add to cart
add_filter( 'woocommerce_add_cart_item', array( $this, 'add_cart_item' ), 20, 1 );

// Load cart data per page load
add_filter( 'woocommerce_get_cart_item_from_session', array( $this, 'get_cart_item_from_session' ), 20, 2 );

// Get item data to display
add_filter( 'woocommerce_get_item_data', array( $this, 'get_item_data' ), 10, 2 );

// Add item data to the cart
add_filter( 'woocommerce_add_cart_item_data', array( $this, 'add_cart_item_data' ), 10, 2 );

// Validate when adding to cart
add_filter( 'woocommerce_add_to_cart_validation', array( $this, 'validate_add_cart_item' ), 999, 3 );

// Add meta to order
add_action( 'woocommerce_add_order_item_meta', array( $this, 'order_item_meta' ), 10, 2 );

// order again functionality
add_filter( 'woocommerce_order_again_cart_item_data', array( $this, 're_add_cart_item_data' ), 10, 3 );
}

I Also found a piece of code located in the Email template received by the Administrator, which correclty shows the Start & End date. The End date is simply echoed like this:

<tr>
            <th style="text-align:left; border: 1px solid #eee;" scope="row"><?php _e( 'Booking End Date', 'woocommerce-bookings' ); ?></th>
            <td style="text-align:left; border: 1px solid #eee;"><?php echo $booking->get_end_date(); ?></td>
        </tr>

Using $booking->get_end_date(); doesn't work when i use it in cart.php(Woocommerce) Because $booking is declared in the controller of the Woocommerce Bookings plugin like so:

public static function get_bookings_in_date_range( $start_date, $end_date, $product_or_resource_id = '', $check_in_cart = true ) {
    $transient_name = 'book_dr_' . md5( http_build_query( array( $start_date, $end_date, $product_or_resource_id, WC_Cache_Helper::get_transient_version( 'bookings' ) ) ) );

if ( false === ( $booking_ids = get_transient( $transient_name ) ) ) {
    $booking_ids = self::get_bookings_in_date_range_query( $start_date, $end_date, $product_or_resource_id, $check_in_cart );
    set_transient( $transient_name, $booking_ids, DAY_IN_SECONDS * 30 );
}

// Get objects
$bookings = array();

foreach ( $booking_ids as $booking_id ) {
    $bookings[] = get_wc_booking( $booking_id );
}

return $bookings;
}
1
+1 for a very well-documented question. I presume $booking->get_end_date() doesn't work yet because you don't have the $booking object, and can't define it until after checkout (so should be able to use it in the order page and emails once you define $booking). But, it seems like the data is in the cart session. Can you specify exactly where you are trying to display the data?helgatheviking
For this question i want to display the data in the shopping cart. Later also on the checkout page & the order email. $booking i can't use because it is a variable made in the woocommerce-bookings plugin. But i want to show the data on page from the woocommerce plugin itself. Here the $booking variable is not declared, but as you can see the end date is available in the $cart_item array.Christophvh
But where in the cart? Where in the order? I'm asking so I know what hook to add the code to.helgatheviking
For the cart after the other meta data, so after this: foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) { echo WC()->cart->get_item_data( $cart_item ); }Christophvh

1 Answers

3
votes

First order of business is displaying the additional meta in the cart. You can see the filter woocommerce_get_item_data is where you can add keys/valules to the definition list that displays the variation information, or product add on information, or in booking's case the start date.

I've copied the date formatting from Bookings' start and end date methods with some slight simplifications:

add_filter( 'woocommerce_get_item_data', 'so_34900999_display_cart_data', 10, 2 );
function so_34900999_display_cart_data( $item_data, $cart_item ){

    if ( ! empty( $cart_item['booking'] ) ) {

        $date_format = apply_filters( 'woocommerce_bookings_date_format', wc_date_format() );
        $time_format = apply_filters( 'woocommerce_bookings_time_format', ', ' . wc_time_format() );
        $end_date = apply_filters( 'woocommerce_bookings_get_end_date_with_time', date_i18n( $date_format . $time_format, $cart_item['booking']['_end_date'] ) );

        $item_data[] = array(
            'key'    => __( 'End Date', 'your-textdomain' ),
            'value'   => $cart_item['booking']['_end_date'],
            'display' => $end_date,
        );
    }
    return $item_data;
}