$description, 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), 'optional' => true, ); }; woocommerce_store_api_register_endpoint_data( array( 'endpoint' => CheckoutSchema::IDENTIFIER, 'namespace' => 'dayslot', 'schema_callback' => function () use ( $field ) { return array( 'date' => $field( 'Delivery date (Y-m-d)' ), 'slot' => $field( 'Time (HH:MM-HH:MM or HH:MM)' ), 'variant' => $field( 'Delivery option id' ), 'mode' => $field( 'delivery or pickup' ), 'location' => $field( 'Pickup location id' ), 'fields' => $field( 'Extra fields (JSON)' ), ); }, 'schema_type' => ARRAY_A, ) ); // Data the block script reads back after each cart update (e.g. the distance message). woocommerce_store_api_register_endpoint_data( array( 'endpoint' => CartSchema::IDENTIFIER, 'namespace' => 'dayslot', 'data_callback' => function () { return array( 'notice' => dayslot_checkout_notice(), ); }, 'schema_callback' => function () { return array( 'notice' => array( 'description' => 'Message under the date picker', 'type' => 'object', 'context' => array( 'view' ), 'readonly' => true, ), ); }, 'schema_type' => ARRAY_A, ) ); woocommerce_store_api_register_update_callback( array( 'namespace' => 'dayslot', 'callback' => function ( $data ) { dayslot_session_set( dayslot_read_choice( (array) $data ) ); }, ) ); } if ( did_action( 'woocommerce_blocks_loaded' ) ) { dayslot_register_store_api_data(); } else { add_action( 'woocommerce_blocks_loaded', 'dayslot_register_store_api_data' ); } /** * Validate + save when the block checkout is submitted. */ add_action( 'woocommerce_store_api_checkout_update_order_from_request', function ( $order, $request ) { if ( ! dayslot_order_needs_date( $order ) ) { return; } $data = isset( $request['extensions']['dayslot'] ) && is_array( $request['extensions']['dayslot'] ) ? $request['extensions']['dayslot'] : array(); $choice = dayslot_read_choice( $data ); $error = dayslot_validate_choice( $choice, dayslot_ctx_for_choice( $choice, dayslot_order_products( $order ) ) ); if ( $error ) { throw new RouteException( 'dayslot_invalid_delivery_date', esc_html( $error ), 400 ); } // The price shown must belong to what is being submitted. $session = dayslot_session_get(); foreach ( array( 'date', 'slot', 'variant', 'mode', 'location' ) as $key ) { if ( (string) $session[ $key ] !== (string) $choice[ $key ] ) { dayslot_session_set( $choice ); throw new RouteException( 'dayslot_price_changed', esc_html__( 'The delivery price has been updated for your choice. Please check the total and place the order again.', 'dayslot' ), 409 ); } } dayslot_save_order_values( $order, $choice ); }, 10, 2 ); /** * Is the current page a Checkout block page? */ function dayslot_is_block_checkout() { $post = get_post(); return $post && function_exists( 'has_block' ) && has_block( 'woocommerce/checkout', $post ); } /** * Load the block helper on Checkout block pages only. */ add_action( 'wp_enqueue_scripts', function () { if ( ! dayslot_is_checkout_page() || ! dayslot_is_block_checkout() || ! dayslot_cart_needs_date() ) { return; } $deps = array( 'dys-picker', 'wp-data' ); foreach ( array( 'wc-blocks-checkout', 'wc-blocks-data-store' ) as $handle ) { if ( wp_script_is( $handle, 'registered' ) ) { $deps[] = $handle; } } wp_enqueue_script( 'dys-blocks', dayslot_asset( 'assets/blocks.js' ), $deps, DAYSLOT_VERSION, true ); wp_add_inline_script( 'dys-blocks', 'window.dayslotBlock = ' . wp_json_encode( array( 'initial' => dayslot_session_get(), 'placement' => dayslot_get_settings()['placement'], 'manual' => dayslot_manual_placement(), ) ) . ';', 'before' ); }, 20 );