9
9
use WC_Order_Item ;
10
10
use WCPOS \WooCommercePOS \Logger ;
11
11
use WP_User ;
12
+ use WC_Product ;
13
+ use WC_Product_Variation ;
14
+ use WC_Abstract_Order ;
15
+ use Automattic \WooCommerce \Utilities \OrderUtil ;
12
16
use function get_user_meta ;
13
17
use function update_user_meta ;
14
18
@@ -33,21 +37,25 @@ function ( WC_Meta_Data $meta ) {
33
37
$ uuids
34
38
);
35
39
36
- // If there is no uuid, add one, i.e., new product
37
- if ( empty ( $ uuid_values ) ) {
38
- $ object ->update_meta_data ( '_woocommerce_pos_uuid ' , $ this ->create_uuid () );
39
- }
40
-
41
- // Check if there's more than one uuid, if so, delete and regenerate
40
+ // Check if there's more than one uuid, if so, keep the first and delete the rest.
42
41
if ( \count ( $ uuid_values ) > 1 ) {
43
- foreach ( $ uuids as $ uuid_meta ) {
44
- $ object ->delete_meta_data ( $ uuid_meta ->key );
42
+ // Keep the first UUID and remove the rest.
43
+ for ( $ i = 1 ; $ i < count ( $ uuid_values ); $ i ++ ) {
44
+ $ object ->delete_meta_data_by_mid ( $ uuids [ $ i ]->id );
45
45
}
46
+ $ uuid_values = array ( reset ( $ uuid_values ) ); // Keep only the first UUID in the array.
47
+ }
48
+
49
+ // Check conditions for updating the UUID.
50
+ $ should_update_uuid = empty ( $ uuid_values )
51
+ || ( isset ( $ uuid_values [0 ] ) && ! Uuid::isValid ( $ uuid_values [0 ] ) )
52
+ || ( isset ( $ uuid_values [0 ] ) && $ this ->uuid_postmeta_exists ( $ uuid_values [0 ], $ object ) );
53
+
54
+ if ( $ should_update_uuid ) {
46
55
$ object ->update_meta_data ( '_woocommerce_pos_uuid ' , $ this ->create_uuid () );
47
56
}
48
57
}
49
58
50
-
51
59
/**
52
60
* @param WP_User $user
53
61
*
@@ -56,7 +64,21 @@ function ( WC_Meta_Data $meta ) {
56
64
private function maybe_add_user_uuid ( WP_User $ user ): void {
57
65
$ uuids = get_user_meta ( $ user ->ID , '_woocommerce_pos_uuid ' , false );
58
66
59
- if ( empty ( $ uuids ) || empty ( $ uuids [0 ] ) ) {
67
+ // Check if there's more than one uuid, if so, keep the first and delete the rest.
68
+ if ( count ( $ uuids ) > 1 ) {
69
+ // Keep the first UUID and remove the rest.
70
+ for ( $ i = 1 ; $ i < count ( $ uuids ); $ i ++ ) {
71
+ delete_user_meta ( $ user ->ID , '_woocommerce_pos_uuid ' , $ uuids [ $ i ] );
72
+ }
73
+ $ uuids = array ( $ uuids [0 ] );
74
+ }
75
+
76
+ // Check conditions for updating the UUID.
77
+ $ should_update_uuid = empty ( $ uuids )
78
+ || ( isset ( $ uuids [0 ] ) && ! Uuid::isValid ( $ uuids [0 ] ) )
79
+ || ( isset ( $ uuids [0 ] ) && $ this ->uuid_usermeta_exists ( $ uuids [0 ], $ user ->ID ) );
80
+
81
+ if ( $ should_update_uuid ) {
60
82
update_user_meta ( $ user ->ID , '_woocommerce_pos_uuid ' , $ this ->create_uuid () );
61
83
}
62
84
}
@@ -84,14 +106,30 @@ private function maybe_add_order_item_uuid( WC_Order_Item $item ): void {
84
106
*
85
107
* @return string
86
108
*/
87
- private function get_term_uuid ( object $ item ): string {
88
- $ uuid = get_term_meta ( $ item ->term_id , '_woocommerce_pos_uuid ' , true );
89
- if ( ! $ uuid ) {
90
- $ uuid = Uuid::uuid4 ()->toString ();
91
- add_term_meta ( $ item ->term_id , '_woocommerce_pos_uuid ' , $ uuid , true );
109
+ private function get_term_uuid ( $ term ): string {
110
+ $ uuids = get_term_meta ( $ term ->term_id , '_woocommerce_pos_uuid ' , false );
111
+
112
+ // Check if there's more than one uuid, if so, keep the first and delete the rest.
113
+ if ( count ( $ uuids ) > 1 ) {
114
+ // Keep the first UUID and remove the rest.
115
+ for ( $ i = 1 ; $ i < count ( $ uuids ); $ i ++ ) {
116
+ delete_term_meta ( $ term ->term_id , '_woocommerce_pos_uuid ' , $ uuids [ $ i ] );
117
+ }
118
+ $ uuids = array ( $ uuids [0 ] );
119
+ }
120
+
121
+ // Check conditions for updating the UUID.
122
+ $ should_update_uuid = empty ( $ uuids )
123
+ || ( isset ( $ uuids [0 ] ) && ! Uuid::isValid ( $ uuids [0 ] ) )
124
+ || ( isset ( $ uuids [0 ] ) && $ this ->uuid_termmeta_exists ( $ uuids [0 ], $ term ->term_id ) );
125
+
126
+ if ( $ should_update_uuid ) {
127
+ $ uuid = $ this ->create_uuid ();
128
+ add_term_meta ( $ term ->term_id , '_woocommerce_pos_uuid ' , $ uuid , true );
129
+ return $ uuid ;
92
130
}
93
131
94
- return $ uuid ;
132
+ return $ uuids [ 0 ] ;
95
133
}
96
134
97
135
/**
@@ -108,4 +146,82 @@ private function create_uuid(): string {
108
146
return 'fallback-uuid- ' . time ();
109
147
}
110
148
}
149
+
150
+ /**
151
+ * Check if the given UUID is unique.
152
+ *
153
+ * @param string $uuid The UUID to check.
154
+ * @param WC_Data $object The WooCommerce data object.
155
+ * @return bool True if unique, false otherwise.
156
+ */
157
+ private function uuid_postmeta_exists ( string $ uuid , WC_Data $ object ): bool {
158
+ global $ wpdb ;
159
+
160
+ if ( $ object instanceof WC_Abstract_Order && OrderUtil::custom_orders_table_usage_is_enabled () ) {
161
+ // Check the orders meta table.
162
+ $ result = $ wpdb ->get_var (
163
+ $ wpdb ->prepare (
164
+ "SELECT 1 FROM {$ wpdb ->prefix }wc_ordermeta WHERE meta_key = '_woocommerce_pos_uuid' AND meta_value = %s AND order_id != %d LIMIT 1 " ,
165
+ $ uuid ,
166
+ $ object ->get_id ()
167
+ )
168
+ );
169
+ } else {
170
+ // Check the postmeta table.
171
+ $ result = $ wpdb ->get_var (
172
+ $ wpdb ->prepare (
173
+ "SELECT 1 FROM {$ wpdb ->postmeta } WHERE meta_key = '_woocommerce_pos_uuid' AND meta_value = %s AND post_id != %d LIMIT 1 " ,
174
+ $ uuid ,
175
+ $ object ->get_id ()
176
+ )
177
+ );
178
+ }
179
+
180
+ // Convert the result to a boolean.
181
+ return (bool ) $ result ;
182
+ }
183
+
184
+ /**
185
+ * Check if the given UUID already exists for any user.
186
+ *
187
+ * @param string $uuid The UUID to check.
188
+ * @param int $exclude_id The user ID to exclude from the check.
189
+ * @return bool True if unique, false otherwise.
190
+ */
191
+ private function uuid_usermeta_exists ( string $ uuid , int $ exclude_id ): bool {
192
+ global $ wpdb ;
193
+
194
+ $ result = $ wpdb ->get_var (
195
+ $ wpdb ->prepare (
196
+ "SELECT 1 FROM {$ wpdb ->usermeta } WHERE meta_key = '_woocommerce_pos_uuid' AND meta_value = %s AND user_id != %d LIMIT 1 " ,
197
+ $ uuid ,
198
+ $ exclude_id
199
+ )
200
+ );
201
+
202
+ // Convert the result to a boolean.
203
+ return (bool ) $ result ;
204
+ }
205
+
206
+ /**
207
+ * Check if the given UUID already exists for any term.
208
+ *
209
+ * @param string $uuid The UUID to check.
210
+ * @param int $exclude_term_id The term ID to exclude from the check.
211
+ * @return bool True if unique, false otherwise.
212
+ */
213
+ private function uuid_termmeta_exists ( string $ uuid , int $ exclude_term_id ): bool {
214
+ global $ wpdb ;
215
+
216
+ $ result = $ wpdb ->get_var (
217
+ $ wpdb ->prepare (
218
+ "SELECT 1 FROM {$ wpdb ->termmeta } WHERE meta_key = '_woocommerce_pos_uuid' AND meta_value = %s AND term_id != %d LIMIT 1 " ,
219
+ $ uuid ,
220
+ $ exclude_term_id
221
+ )
222
+ );
223
+
224
+ // Convert the result to a boolean.
225
+ return (bool ) $ result ;
226
+ }
111
227
}
0 commit comments