From b218b966c887ca48009dfac1f91362d83d86effd Mon Sep 17 00:00:00 2001 From: Paul Kilmurray Date: Fri, 18 Aug 2023 19:35:05 +0100 Subject: [PATCH] limit 'include' query length for WC REST API --- includes/API.php | 34 ++++++++++++++++++++++++++++++++++ includes/API/Customers.php | 2 +- includes/Logger.php | 18 ++++++++++++++---- package.json | 2 +- readme.txt | 5 +++-- woocommerce-pos.php | 4 ++-- 6 files changed, 55 insertions(+), 10 deletions(-) diff --git a/includes/API.php b/includes/API.php index 13178cde..fc112f12 100644 --- a/includes/API.php +++ b/includes/API.php @@ -78,6 +78,9 @@ public function __construct() { add_filter( 'rest_request_before_callbacks', array( $this, 'rest_request_before_callbacks' ), 5, 3 ); add_filter( 'rest_dispatch_request', array( $this, 'rest_dispatch_request' ), 10, 4 ); + // + add_filter( 'rest_pre_dispatch', array( $this, 'rest_pre_dispatch' ), 10, 3 ); + $this->prevent_messages(); } @@ -244,6 +247,37 @@ public function rest_index( WP_REST_Response $response ): WP_REST_Response { * @return mixed */ public function rest_pre_dispatch( $result, $server, $request ) { + // Get 'include' parameter from request + $include = $request->get_param( 'include' ); + + if ( $include ) { + // Convert to array if it's not + $include_array = is_array( $include ) ? $include : explode( ',', $include ); + $include_string = implode( ',', $include_array ); + + // If the length of the 'include' string exceeds 10,000 characters, create a new array + if ( strlen( $include_string ) > 10000 ) { + shuffle( $include_array ); // Shuffle the IDs to randomize + + // Construct a random array of no more than 10,000 characters + $max_include_length = 10000; + $new_include_string = ''; + $random_include_array = array(); + + foreach ( $include_array as $id ) { + if ( strlen( $new_include_string . $id ) < $max_include_length ) { + $new_include_string .= $id . ','; + $random_include_array[] = $id; + } else { + break; // Stop when we reach the maximum length + } + } + + // Set modified 'include' parameter back to request + $request->set_param( 'include', $random_include_array ); + } + } + return $result; } diff --git a/includes/API/Customers.php b/includes/API/Customers.php index 61de9139..b8a70748 100644 --- a/includes/API/Customers.php +++ b/includes/API/Customers.php @@ -28,7 +28,7 @@ public function __construct( WP_REST_Request $request ) { add_filter( 'woocommerce_rest_customer_query', array( $this, 'customer_query' ), 10, 2 ); add_filter( 'woocommerce_rest_prepare_customer', array( $this, 'customer_response' ), 10, 3 ); add_filter( 'users_where', array( $this, 'users_where' ), 10, 2 ); - } + } /** * Filters the response before executing any REST API callbacks. diff --git a/includes/Logger.php b/includes/Logger.php index aeb3e64b..998ef35b 100644 --- a/includes/Logger.php +++ b/includes/Logger.php @@ -2,9 +2,16 @@ namespace WCPOS\WooCommercePOS; +use function is_string; + class Logger { public const WC_LOG_FILENAME = 'woocommerce-pos'; public static $logger; + public static $log_level; + + public static function set_log_level( $level ): void { + self::$log_level = $level; + } /** * Utilize WC logger class. @@ -20,14 +27,17 @@ public static function log( $message ): void { if ( empty( self::$logger ) ) { self::$logger = wc_get_logger(); } - $settings = get_option( 'woocommerce_pos_settings' ); - $level = $settings['debug_level'] ?? 'info'; - if ( ! \is_string( $message ) ) { + if ( is_null( self::$log_level ) ) { + $settings = get_option( 'woocommerce_pos_settings' ); + self::$log_level = $settings['debug_level'] ?? 'info'; + } + + if ( ! is_string( $message ) ) { $message = print_r( $message, true ); } - self::$logger->log( $level, $message, array( 'source' => self::WC_LOG_FILENAME ) ); + self::$logger->log( self::$log_level, $message, array( 'source' => self::WC_LOG_FILENAME ) ); } } } diff --git a/package.json b/package.json index 6d10964f..3f5be0f5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@wcpos/woocommerce-pos", - "version": "1.3.8", + "version": "1.3.9", "description": "A simple front-end for taking WooCommerce orders at the Point of Sale.", "main": "index.js", "workspaces": { diff --git a/readme.txt b/readme.txt index 81eecb5b..877c8fc5 100644 --- a/readme.txt +++ b/readme.txt @@ -3,7 +3,7 @@ Contributors: kilbot Tags: cart, e-commerce, ecommerce, inventory, point-of-sale, pos, sales, sell, shop, shopify, store, vend, woocommerce, wordpress-ecommerce Requires at least: 5.6 & WooCommerce 5.3 Tested up to: 6.3 -Stable tag: 1.3.8 +Stable tag: 1.3.9 License: GPL-3.0 License URI: http://www.gnu.org/licenses/gpl-3.0.html @@ -63,7 +63,8 @@ There is more information on our website at [https://wcpos.com](https://wcpos.co == Changelog == -= 1.3.9 - 2023/08/XX = += 1.3.9 - 2023/08/18 = +* Fix: limit query length for WC REST API, this was resulting in 0 products being returned for some users * Fix: pos meta data showing in WP Admin order quick view * Fix: cashier uuid not unique for multisite installs diff --git a/woocommerce-pos.php b/woocommerce-pos.php index 44562821..85c688cb 100644 --- a/woocommerce-pos.php +++ b/woocommerce-pos.php @@ -3,7 +3,7 @@ * Plugin Name: WooCommerce POS * Plugin URI: https://wordpress.org/plugins/woocommerce-pos/ * Description: A simple front-end for taking WooCommerce orders at the Point of Sale. Requires WooCommerce. - * Version: 1.3.8 + * Version: 1.3.9 * Author: kilbot * Author URI: http://wcpos.com * Text Domain: woocommerce-pos @@ -24,7 +24,7 @@ use function define; // Define plugin constants. -const VERSION = '1.3.8'; +const VERSION = '1.3.9'; const PLUGIN_NAME = 'woocommerce-pos'; const SHORT_NAME = 'wcpos'; define( __NAMESPACE__ . '\PLUGIN_FILE', plugin_basename( __FILE__ ) ); // 'woocommerce-pos/woocommerce-pos.php'