PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / 1.10.17
WCPOS – Point of Sale (POS) plugin for WooCommerce v1.10.17
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/wcpos-functions.php +2 -91 1.10.21 → 1.10.17 View file →
@@ -229,113 +229,24 @@
229 229 return (bool) apply_filters( 'woocommerce_pos_is_pro_active', \defined( 'WCPOS\WooCommercePOSPro\VERSION' ) );
230 230 }
231 231 }
232 232
233 -if ( ! \function_exists( 'wcpos_get_site_identity_home' ) ) {
234 - /**
235 - * Get the site address as an identity: no scheme, no `www.`, no trailing
236 - * slash; the host lower-cased; the port and the case-sensitive path kept,
237 - * so `example.com/staging` is another site and `www.example.com` is not.
238 - *
239 - * @return string Normalised home address.
240 - */
241 - function wcpos_get_site_identity_home(): string { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- uses wcpos_ prefix.
242 - $parts = wp_parse_url( '//' . preg_replace( '#^(?:https?:)?//#i', '', home_url() ) );
243 - $host = preg_replace( '#^www\.#', '', strtolower( (string) ( $parts['host'] ?? '' ) ) );
244 - $port = isset( $parts['port'] ) ? ':' . $parts['port'] : '';
245 -
246 - return untrailingslashit( $host . $port . ( $parts['path'] ?? '' ) );
247 - }
248 -}
249 -
250 -if ( ! \function_exists( 'wcpos_site_identity_home_row' ) ) {
251 - /**
252 - * Read the persisted home marker straight from the options table.
253 - *
254 - * The option cache answers get_option() for the rest of the request, and a
255 - * same-value update_option() leaves it untouched; this is the only read that can tell a
256 - * marker another request already advanced from one whose write failed.
257 - *
258 - * @return string|null The stored marker, or null when absent.
259 - */
260 - function wcpos_site_identity_home_row(): ?string { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- uses wcpos_ prefix.
261 - global $wpdb;
262 - $row = $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- bypasses the option cache on purpose, see docblock.
263 - $wpdb->prepare( "SELECT option_value FROM {$wpdb->options} WHERE option_name = %s LIMIT 1", 'woocommerce_pos_uuid_home' ) // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- core table name.
264 - );
265 -
266 - return \is_string( $row ) ? $row : null;
267 - }
268 -}
269 -
270 233 /*
271 - * Get the site UUID (Plugin State), tied to the site address.
234 + * Get the site UUID (Plugin State), generating and persisting it on first use.
272 235 *
273 236 * @return string Site UUID.
274 237 */
275 238 if ( ! \function_exists( 'wcpos_get_site_uuid' ) ) {
276 239 /**
277 - * Get the site UUID, generating it on first use or when the address changes.
240 + * Get the site UUID, generating and persisting it on first use.
278 241 *
279 242 * Single owner for the woocommerce_pos_uuid option — the
280 243 * generate-if-missing logic previously lived in three places (REST index,
281 244 * POS frontend, analytics) and could race.
282 - * The saved home prevents database clones sharing a live store's identity.
283 - * On upgrade, an absent home is recorded without changing the existing UUID.
284 245 *
285 246 * @return string Site UUID.
286 247 */
287 248 function wcpos_get_site_uuid(): string { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- uses wcpos_ prefix.
288 - $home = wcpos_get_site_identity_home();
289 - $stored_home = get_option( 'woocommerce_pos_uuid_home' );
290 - if ( false === $stored_home ) {
291 - // Keep the first writer's home if another request wins the race.
292 - $stored_home = add_option( 'woocommerce_pos_uuid_home', $home )
293 - ? $home
294 - : get_option( 'woocommerce_pos_uuid_home' );
295 - }
296 -
297 - if ( $stored_home !== $home ) {
298 - // A moved address is a new identity. Two requests can both land
299 - // here; the last write wins and each returns what is stored, so the
300 - // REST response never advertises a uuid the database does not hold.
301 - // The home marker advances only behind a persisted uuid: a vetoed or
302 - // failed write would otherwise hand out an identity that the next
303 - // call, seeing a matching home, no longer returns.
304 - $previous = get_option( 'woocommerce_pos_uuid', '' );
305 - $minted = \Ramsey\Uuid\Uuid::uuid4()->toString();
306 - if ( update_option( 'woocommerce_pos_uuid', $minted ) ) {
307 - // update_option() also answers false when the row already holds
308 - // $home: a concurrent request finished the move between this one's
309 - // read and its write. That is a completed move, not a failed one,
310 - // and rolling back would leave the old uuid behind the new marker
311 - // for good, since every later call sees a matching home. This
312 - // request's option cache still holds the old marker (the same-value
313 - // UPDATE touched no row, so nothing refreshed it), so the check
314 - // reads the row itself and, when the move is confirmed, drops the
315 - // stale cache so a later call in this request does not mint again,
316 - // and drops the uuid this request cached from its own write so the
317 - // value returned below is the one the other request left stored.
318 - $marker_moved = update_option( 'woocommerce_pos_uuid_home', $home ) || wcpos_site_identity_home_row() === $home;
319 - if ( $marker_moved && get_option( 'woocommerce_pos_uuid_home' ) !== $home ) {
320 - wp_cache_delete( 'woocommerce_pos_uuid', 'options' );
321 - wp_cache_delete( 'woocommerce_pos_uuid_home', 'options' );
322 - wp_cache_delete( 'alloptions', 'options' );
323 - }
324 - if ( ! $marker_moved && \is_string( $previous ) && '' !== $previous ) {
325 - // The marker did not move: put the previous uuid back so the next
326 - // call retries the whole move, rather than minting again on top of
327 - // a rotation the marker never recorded.
328 - update_option( 'woocommerce_pos_uuid', $previous );
329 - }
330 - }
331 -
332 - $stored = get_option( 'woocommerce_pos_uuid', '' );
333 - if ( \is_string( $stored ) && '' !== $stored ) {
334 - return $stored;
335 - }
336 - }
337 -
338 249 $uuid = get_option( 'woocommerce_pos_uuid', '' );
339 250 if ( \is_string( $uuid ) && '' !== $uuid ) {
340 251 return $uuid;
341 252 }