value of the delivery, as the customer saw it. */ function dayslot_app_fields( $order ) { $out = array(); foreach ( dayslot_order_summary_rows( $order ) as $row ) { $label = trim( wp_strip_all_tags( (string) $row['label'] ) ); $value = trim( wp_strip_all_tags( (string) $row['value'] ) ); if ( '' !== $label && '' !== $value && '_' !== $label[0] && ! isset( $out[ $label ] ) ) { $out[ $label ] = $value; } } return $out; } /** * Write the copies on the order (no save()); returns the fields. Old copies that no longer apply are removed. */ function dayslot_app_fields_sync( $order ) { $fields = 'yes' === dayslot_get_settings()['app_fields'] && $order->get_meta( DAYSLOT_META ) ? dayslot_app_fields( $order ) : array(); $old = (array) $order->get_meta( DAYSLOT_APP_KEYS_META ); foreach ( array_diff( $old, array_keys( $fields ) ) as $key ) { $order->delete_meta_data( $key ); } foreach ( $fields as $key => $value ) { if ( (string) $order->get_meta( $key ) !== $value ) { $order->update_meta_data( $key, $value ); } } if ( $fields ) { if ( array_keys( $fields ) !== $old ) { $order->update_meta_data( DAYSLOT_APP_KEYS_META, array_keys( $fields ) ); } } elseif ( $old ) { $order->delete_meta_data( DAYSLOT_APP_KEYS_META ); } return $fields; } // Every save of an order with a delivery (checkout, admin change, calendar drag & drop, rescheduling). add_action( 'woocommerce_before_order_object_save', function ( $order ) { if ( $order instanceof WC_Order && ( $order->get_meta( DAYSLOT_META ) || $order->get_meta( DAYSLOT_APP_KEYS_META ) ) ) { dayslot_app_fields_sync( $order ); } } ); // Older orders: filled in when the mobile app (REST API) opens them. add_filter( 'woocommerce_rest_prepare_shop_order_object', function ( $response, $order ) { if ( 'yes' !== dayslot_get_settings()['app_fields'] || ! $order instanceof WC_Order || ! $order->get_meta( DAYSLOT_META ) || $order->get_meta( DAYSLOT_APP_KEYS_META ) ) { return $response; } $fields = dayslot_app_fields_sync( $order ); $order->save(); $data = $response->get_data(); if ( isset( $data['meta_data'] ) && is_array( $data['meta_data'] ) ) { foreach ( $order->get_meta_data() as $meta ) { if ( isset( $fields[ $meta->key ] ) ) { $data['meta_data'][] = $meta; } } $response->set_data( $data ); } return $response; }, 10, 2 );