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/Sync/Collection_Rules.php +7 -79 1.10.25 → 1.10.17 View file →
@@ -34,11 +34,11 @@
34 34 * collection yields an EMPTY plan whose `filter()` is the identity and whose
35 35 * `around()` merely runs its callable. That is the adoption mechanism: a collection
36 36 * can be routed through the module before it has any rows, and nothing changes.
37 37 * - `Collection_Rules_Plan::filter()` — the direct lane. Type-preserving clause
38 - * bodies; it NEVER touches global filter state. Legacy callbacks can still delegate
39 - * to it; collection reads use `around()` for search and visibility.
40 - * - `Collection_Rules_Plan::around()` — the scoped read lanes, and the ONLY install path.
38 + * bodies; it NEVER touches global filter state, so a v1 controller keeps owning its
39 + * own `add_filter` topology (Pro subclasses those callbacks).
40 + * - `Collection_Rules_Plan::around()` — the proxy lane, and the ONLY install path.
41 41 * Callbacks are installed, the forward runs, and every binding is unwound in reverse
42 42 * in a `finally`.
43 43 * - `orderby_enum()` / `collection_params()` — schema PROJECTIONS of the same rows, so
44 44 * the REST schema and the proxy's claim list cannot disagree with the clause logic.
@@ -78,30 +78,9 @@
78 78 * @var string
79 79 */
80 80 public const STORAGE_HPOS = 'hpos';
81 81
82 - /** Shared search bound; over-limit policies remain collection-specific. */
83 - public const SEARCH_TERM_CAP = 10;
84 -
85 82 /**
86 - * Split literal terms. Orders now also drop Unicode control characters between terms.
87 - *
88 - * Existing defaults: product phrase null uses WP_Query terms; orders use the supplied
89 - * string; variation args/discovery default to '', and validation casts null to ''.
90 - * Product phrases collapse over-cap terms; orders slice; v2 variations reject.
91 - * Every product/variation lane uses this splitter; v1 collapses over-cap, v2 flat variations reject.
92 - * Malformed UTF-8 yields an empty array, including offset-capture callers.
93 - *
94 - * @param string $search Search text.
95 - * @param int $flags Split flags.
96 - * @return array
97 - */
98 - public static function search_terms( $search, $flags = PREG_SPLIT_NO_EMPTY ) {
99 - $terms = preg_split( '/[\s\p{Z}\p{C}]+/u', $search, -1, $flags );
100 - return false === $terms ? array() : $terms;
101 - }
102 -
103 - /**
104 83 * Legacy storage — `wp_posts` plus `wp_postmeta`.
105 84 *
106 85 * @var string
107 86 */
@@ -107,9 +86,9 @@
107 86 */
108 87 public const STORAGE_POSTS = 'posts';
109 88
110 89 /**
111 - * Memoized plans, keyed by collection, request identity/content, storage and param map.
90 + * Memoized plans, keyed by collection, request identity, storage and param map.
112 91 *
113 92 * Each entry is `array( WP_REST_Request, Collection_Rules_Plan )`; the request is
114 93 * kept so a recycled `spl_object_id` can never serve another request's plan.
115 94 *
@@ -138,9 +117,9 @@
138 117 * @return Collection_Rules_Plan
139 118 */
140 119 public static function for_request( string $collection, WP_REST_Request $request, array $param_map = array(), ?string $storage = null ) {
141 120 $storage = $storage ?? self::detect_storage( $collection );
142 - $key = $collection . '|' . spl_object_id( $request ) . '|' . $storage . '|' . md5( (string) wp_json_encode( array( $param_map, $request->get_route(), $request->get_params() ) ) );
121 + $key = $collection . '|' . spl_object_id( $request ) . '|' . $storage . '|' . md5( (string) wp_json_encode( $param_map ) );
143 122
144 123 if ( isset( self::$plans[ $key ] ) && self::$plans[ $key ][0] === $request ) {
145 124 return self::$plans[ $key ][1];
146 125 }
@@ -237,27 +216,13 @@
237 216 * @internal
238 217 *
239 218 * @param string $collection Collection slug.
240 219 *
241 - * @return array{sorts?: array<string, array>, filters?: array<string, array>, search?: array<string, mixed>, visibility?: array<string, mixed>}
220 + * @return array{sorts?: array<string, array>, filters?: array<string, array>}
242 221 */
243 222 public static function rules( string $collection ): array {
244 223 $rules = array(
245 224 'orders' => array(
246 - 'search' => array(
247 - 'param' => 'search',
248 - 'term_cap' => self::SEARCH_TERM_CAP,
249 - 'rank_exact' => false,
250 - 'carriers' => array( 'id', 'billing_email', 'first_name', 'last_name', 'company', 'email', 'phone' ),
251 - 'hpos' => array(
252 - 'orders' => array( 'id', 'billing_email' ),
253 - 'addresses' => array( 'first_name', 'last_name', 'company', 'email', 'phone' ),
254 - ),
255 - 'posts' => array(
256 - 'id' => 'ID',
257 - 'meta' => array( '_billing_first_name', '_billing_last_name', '_billing_company', '_billing_email', '_billing_phone' ),
258 - ),
259 - ),
260 225 'sorts' => array(
261 226 'status' => array(
262 227 'hpos' => array( 'column' => 'status' ),
263 228 'posts' => array( 'posts_orderby' => 'post_status' ),
@@ -346,48 +311,11 @@
346 311 * Neither collection is ever HPOS — both are posts on every store — so there is
347 312 * no `hpos` half to these rows.
348 313 */
349 314 'products' => array(
350 - 'search' => array(
351 - 'param' => 'search',
352 - // Both product lanes use the literal splitter and collapse over-cap terms to the phrase.
353 - 'term_cap' => self::SEARCH_TERM_CAP,
354 - 'rank_exact' => true,
355 - 'carriers' => array_merge( array( 'post_title' ), Barcode_Field::search_keys() ),
356 - 'posts' => array( 'meta' => Barcode_Field::search_keys() ),
357 - 'hpos' => null,
358 - ),
359 - 'visibility' => array(
360 - 'type' => array(
361 - 'direct' => Pos_Visibility::PRODUCTS,
362 - 'proxy' => Pos_Visibility::CATALOG,
363 - ),
364 - 'where_backstop' => true,
365 - ),
366 315 'sorts' => self::catalog_meta_sorts(),
367 316 ),
368 317 'variations' => array(
369 - 'search' => array(
370 - 'param' => 'search',
371 - 'term_cap' => self::SEARCH_TERM_CAP,
372 - 'rank_exact' => false,
373 - 'carriers' => Barcode_Field::search_keys(),
374 - 'posts' => array( 'meta' => Barcode_Field::search_keys() ),
375 - 'hpos' => null,
376 - 'query' => 'meta_query',
377 - 'exact_sku_param' => 'sku',
378 - // Both lanes split literal terms; v1 keeps over-cap collapse/EXISTS, v2 rejects/meta_query.
379 - 'lanes' => array(
380 - 'direct' => array(
381 - 'query' => 'wp_terms',
382 - 'exact_sku_param' => null,
383 - ),
384 - ),
385 - ),
386 - 'visibility' => array(
387 - 'type' => Pos_Visibility::VARIATIONS,
388 - 'where_backstop' => true,
389 - ),
390 318 'sorts' => self::catalog_meta_sorts(),
391 319 ),
392 320
393 321 /*
@@ -474,9 +402,9 @@
474 402 * @param string $collection Collection slug.
475 403 *
476 404 * @return string
477 405 */
478 - public static function detect_storage( string $collection ): string {
406 + private static function detect_storage( string $collection ): string {
479 407 if ( 'orders' !== $collection ) {
480 408 return self::STORAGE_POSTS;
481 409 }
482 410