get_table_name( 'orders' ); $addresses = $query->get_table_name( 'addresses' ); foreach ( self::terms( $search ) as $term ) { $like = '%' . $wpdb->esc_like( $term ) . '%'; $id = ctype_digit( $term ) ? "`{$orders}`.id = %d OR " : ''; $args = array_fill( 0, 6, $like ); if ( '' !== $id ) { array_unshift( $args, (int) $term ); } // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table names come from WooCommerce. $conditions[] = $wpdb->prepare( "( {$id}`{$orders}`.billing_email LIKE %s OR `{$orders}`.id IN ( SELECT order_id FROM `{$addresses}` WHERE address_type = 'billing' AND ( first_name LIKE %s OR last_name LIKE %s OR company LIKE %s OR email LIKE %s OR phone LIKE %s ) ) )", $args ); // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared } return implode( ' AND ', $conditions ); } /** * Build a legacy posts where fragment with AND-across-terms semantics. * * @param string $search Search text. * @return string */ public static function posts_where( string $search ): string { global $wpdb; $conditions = array(); foreach ( self::terms( $search ) as $term ) { $like = '%' . $wpdb->esc_like( $term ) . '%'; $id = ctype_digit( $term ) ? "{$wpdb->posts}.ID = %d OR " : ''; $args = '' === $id ? array( $like ) : array( (int) $term, $like ); // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table names come from $wpdb. $conditions[] = $wpdb->prepare( "( {$id}EXISTS ( 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 ) )", $args ); // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared } return implode( ' AND ', $conditions ); } }