PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / 1.10.18
WCPOS – Point of Sale (POS) plugin for WooCommerce v1.10.18
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 1.10.1 1.10.0 1.9.17 1.9.15 1.9.16 1.9.14 1.9.13 All 162 releases
woocommerce-pos / includes / Sync / Order_Search.php

Order_Search.php in WCPOS – Point of Sale (POS) plugin for WooCommerce 1.10.18, at includes/Sync/Order_Search.php

91 lines 3.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Shared order search SQL filters.
4 *
5 * @package WCPOS\WooCommercePOS\Sync
6 */
7
8 namespace WCPOS\WooCommercePOS\Sync;
9
10 /**
11 * Builds the POS order search for both WooCommerce storage engines.
12 *
13 * Malformed UTF-8 deliberately matches zero rows (1=0) on both storage dialects;
14 * unlike the former search body, it never becomes an unconstrained order query.
15 */
16 final class Order_Search {
17 /**
18 * Split a search string into at most ten whitespace-separated terms.
19 *
20 * Unicode-aware: a pasted non-breaking space (U+00A0) separates terms like a
21 * space does, and an all-whitespace string yields no terms. Malformed UTF-8
22 * makes preg_split() return false, which also yields no terms.
23 *
24 * @param string $search Search text.
25 * @param array $rule Declared search carriers and cap.
26 * @return string[]
27 */
28 public static function terms( string $search, array $rule ): array {
29 return array_slice( Collection_Rules::search_terms( $search ), 0, $rule['term_cap'] );
30 }
31 /**
32 * Build an HPOS where fragment with AND-across-terms semantics.
33 *
34 * @param string $search Search text.
35 * @param array $tables Orders and address table names.
36 * @param array $rule Declared search carriers and cap.
37 * @return string
38 */
39 public static function hpos_where( string $search, array $tables, array $rule ): string {
40 global $wpdb;
41 $conditions = array();
42 $orders = $tables['orders'];
43 $addresses = $tables['addresses'];
44 $fields = implode( ' LIKE %s OR ', $rule['hpos']['addresses'] ) . ' LIKE %s';
45 foreach ( self::terms( $search, $rule ) as $term ) {
46 $like = '%' . $wpdb->esc_like( $term ) . '%';
47 $id = ctype_digit( $term ) ? "`{$orders}`.id = %d OR " : '';
48 $args = array_fill( 0, 1 + count( $rule['hpos']['addresses'] ), $like );
49 if ( '' !== $id ) {
50 array_unshift( $args, (int) $term );
51 }
52 // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table names come from WooCommerce.
53 $conditions[] = $wpdb->prepare(
54 "( {$id}`{$orders}`.billing_email LIKE %s OR `{$orders}`.id IN (
55 SELECT order_id FROM `{$addresses}` WHERE address_type = 'billing'
56 AND ( {$fields} )
57 ) )",
58 $args
59 );
60 // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
61 }
62 return false === preg_match( '//u', $search ) ? '1=0' : implode( ' AND ', $conditions );
63 }
64 /**
65 * Build a legacy posts where fragment with AND-across-terms semantics.
66 *
67 * @param string $search Search text.
68 * @param array $rule Declared search carriers and cap.
69 * @return string
70 */
71 public static function posts_where( string $search, array $rule ): string {
72 global $wpdb;
73 $conditions = array();
74 $keys = "'" . implode( "', '", $rule['posts']['meta'] ) . "'";
75 foreach ( self::terms( $search, $rule ) as $term ) {
76 $like = '%' . $wpdb->esc_like( $term ) . '%';
77 $id = ctype_digit( $term ) ? "{$wpdb->posts}.ID = %d OR " : '';
78 $args = '' === $id ? array( $like ) : array( (int) $term, $like );
79 // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table names come from $wpdb.
80 $conditions[] = $wpdb->prepare(
81 "( {$id}EXISTS (
82 SELECT 1 FROM {$wpdb->postmeta} AS wcpos_order_search_meta WHERE wcpos_order_search_meta.post_id = {$wpdb->posts}.ID AND wcpos_order_search_meta.meta_key IN ( {$keys} ) AND wcpos_order_search_meta.meta_value LIKE %s
83 ) )",
84 $args
85 );
86 // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
87 }
88 return false === preg_match( '//u', $search ) ? '1=0' : implode( ' AND ', $conditions );
89 }
90 }
91