PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / 1.10.24
WCPOS – Point of Sale (POS) plugin for WooCommerce v1.10.24
1.10.25 1.10.24 1.10.23 1.10.22 1.10.21 1.10.20 1.10.19 1.10.18 1.10.17 1.10.16 1.10.15 1.10.13 1.10.14 1.10.12 1.10.11 1.10.10 1.10.9 1.10.8 untagged-3d9b7ccddc54df87c672 1.10.7 1.10.6 1.10.5 1.10.3 1.10.4 1.10.2 All 169 releases
← All changes | includes/Sync/Order_Write_Payload.php +38 -0 1.10.19 → 1.10.24 View file →
@@ -633,8 +633,23 @@
633 633 if ( ! $order ) {
634 634 return $payload;
635 635 }
636 636
637 + // `{ id, code: null }` is the POS's deletion marker for a synced coupon line —
638 + // the `<key>: null` shape wc/v3's item_is_null() honours for every other line
639 + // collection, and the one remove_omitted_order_items() mints for them. wc/v3
640 + // keys coupon_lines by code instead, so the marker must be dropped here: the
641 + // remaining codes then differ from the stored set and the remove-and-reapply
642 + // below removes the coupon, or match it (a retried push) and nothing is sent.
643 + $payload['coupon_lines'] = array_values(
644 + array_filter(
645 + $payload['coupon_lines'],
646 + static function ( $line ) {
647 + return ! self::is_coupon_deletion_marker( $line );
648 + }
649 + )
650 + );
651 +
637 652 $requested_codes = array();
638 653 $all_lines_valid = true;
639 654 foreach ( $payload['coupon_lines'] as $line ) {
640 655 $code = is_array( $line ) ? ( $line['code'] ?? null ) : null;
@@ -667,6 +682,29 @@
667 682 }
668 683 $payload['coupon_lines'] = array_values( $payload['coupon_lines'] );
669 684
670 685 return $payload;
686 + }
687 +
688 + /**
689 + * Whether a posted coupon line is a deletion marker: a synced line (a canonical
690 + * positive integer id, as an int or a digit string) whose `code` key is present
691 + * and null. Anything else — no `code` key, an empty code, a missing, zero,
692 + * negative, fractional or exponent id — is malformed and still reaches wc/v3,
693 + * whose own validation answers ("Coupon code is required" / "Coupon item ID is
694 + * readonly").
695 + *
696 + * @param mixed $line A posted coupon line.
697 + *
698 + * @return bool
699 + */
700 + public static function is_coupon_deletion_marker( $line ): bool {
701 + if ( ! is_array( $line ) || ! array_key_exists( 'code', $line ) || null !== $line['code'] ) {
702 + return false;
703 + }
704 + $id = $line['id'] ?? null;
705 + if ( is_int( $id ) ) {
706 + return $id > 0;
707 + }
708 + return is_string( $id ) && ctype_digit( $id ) && (int) $id > 0;
671 709 }
672 710 }