PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / trunk
WCPOS – Point of Sale (POS) plugin for WooCommerce vtrunk
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 1.9.12 1.9.11 1.9.10 1.9.9 All 158 releases
woocommerce-pos / includes / API / Order_Search.php

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

81 lines 3.0 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\API
6 */
7
8 namespace WCPOS\WooCommercePOS\API;
9
10 /** Builds the POS order search for both WooCommerce storage engines. */
11 final class Order_Search {
12 /**
13 * Split a search string into at most ten whitespace-separated terms.
14 *
15 * Unicode-aware: a pasted non-breaking space (U+00A0) separates terms like a
16 * space does, and an all-whitespace string yields no terms. Malformed UTF-8
17 * makes preg_split() return false, which also yields no terms.
18 *
19 * @param string $search Search text.
20 * @return string[]
21 */
22 public static function terms( string $search ): array {
23 return array_slice( (array) preg_split( '/[\s\p{Z}]+/u', $search, -1, PREG_SPLIT_NO_EMPTY ), 0, 10 );
24 }
25 /**
26 * Build an HPOS where fragment with AND-across-terms semantics.
27 *
28 * @param string $search Search text.
29 * @param mixed $query Orders table query.
30 * @return string
31 */
32 public static function hpos_where( string $search, $query ): string {
33 global $wpdb;
34 $conditions = array();
35 $orders = $query->get_table_name( 'orders' );
36 $addresses = $query->get_table_name( 'addresses' );
37 foreach ( self::terms( $search ) as $term ) {
38 $like = '%' . $wpdb->esc_like( $term ) . '%';
39 $id = ctype_digit( $term ) ? "`{$orders}`.id = %d OR " : '';
40 $args = array_fill( 0, 6, $like );
41 if ( '' !== $id ) {
42 array_unshift( $args, (int) $term );
43 }
44 // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table names come from WooCommerce.
45 $conditions[] = $wpdb->prepare(
46 "( {$id}`{$orders}`.billing_email LIKE %s OR `{$orders}`.id IN (
47 SELECT order_id FROM `{$addresses}` WHERE address_type = 'billing'
48 AND ( first_name LIKE %s OR last_name LIKE %s OR company LIKE %s OR email LIKE %s OR phone LIKE %s )
49 ) )",
50 $args
51 );
52 // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
53 }
54 return implode( ' AND ', $conditions );
55 }
56 /**
57 * Build a legacy posts where fragment with AND-across-terms semantics.
58 *
59 * @param string $search Search text.
60 * @return string
61 */
62 public static function posts_where( string $search ): string {
63 global $wpdb;
64 $conditions = array();
65 foreach ( self::terms( $search ) as $term ) {
66 $like = '%' . $wpdb->esc_like( $term ) . '%';
67 $id = ctype_digit( $term ) ? "{$wpdb->posts}.ID = %d OR " : '';
68 $args = '' === $id ? array( $like ) : array( (int) $term, $like );
69 // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table names come from $wpdb.
70 $conditions[] = $wpdb->prepare(
71 "( {$id}EXISTS (
72 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 ( '_billing_first_name', '_billing_last_name', '_billing_company', '_billing_email', '_billing_phone' ) AND wcpos_order_search_meta.meta_value LIKE %s
73 ) )",
74 $args
75 );
76 // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
77 }
78 return implode( ' AND ', $conditions );
79 }
80 }
81