Skip to content

Commit

Permalink
BUGFIX: empty products
Browse files Browse the repository at this point in the history
  • Loading branch information
kilbot committed Jun 25, 2023
1 parent 21ebc62 commit 639ab16
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 32 deletions.
144 changes: 116 additions & 28 deletions includes/API/Products.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Ramsey\Uuid\Uuid;
use WC_Data;
use WC_Product;
use WCPOS\WooCommercePOS\Logger;
use WP_Query;
use WP_REST_Request;
Expand All @@ -18,6 +19,7 @@
*/
class Products {
private $request;
private $uuids;

/**
* Products constructor.
Expand All @@ -26,6 +28,7 @@ class Products {
*/
public function __construct( WP_REST_Request $request ) {
$this->request = $request;
$this->uuids = $this->get_all_uuids();

add_filter( 'rest_request_before_callbacks', array( $this, 'rest_request_before_callbacks' ), 10, 3 );
add_filter( 'woocommerce_rest_prepare_product_object', array( $this, 'product_response' ), 10, 3 );
Expand All @@ -35,6 +38,82 @@ public function __construct( WP_REST_Request $request ) {
add_filter( 'woocommerce_rest_product_schema', array( $this, 'add_barcode_to_product_schema' ) );
add_action( 'woocommerce_rest_insert_product_object', array( $this, 'insert_product_object' ), 10, 3 );
add_filter( 'wp_get_attachment_image_src', array( $this, 'product_image_src' ), 10, 4 );

// add_filter('rest_pre_echo_response', function($result, $server, $request) {
// $logger = wc_get_logger();
// $test = wp_json_encode( $result, 0 );
// if(is_array($result)) {
// foreach($result as $record) {
// if(is_array($record) && isset($record['meta_data'])) {
// $test = wp_json_encode( $record, 0 );
// $logger->info($test, array('source' => 'wcpos-support-3'));
// }
// }
// }
// return $result;
// }, 10, 3);

// add_filter('rest_pre_serve_request', function($served, $result, $request, $server) {
// $logger = wc_get_logger();
//// $logger->info(wp_json_encode($result), array('source' => 'wcpos-support'));
// $data = $result->get_data();
// if(is_array($data)) {
// foreach($data as $record) {
// if(isset($record['meta_data'])) {
// $logger->info(wp_json_encode($record['meta_data']), array('source' => 'wcpos-support'));
// }
// }
// }
// return $served;
// }, 10, 4);
}

/**
* Note: this gets all postmeta uuids, including orders, we're just interested in doing a check sanity check
* This addresses a bug where I have seen two products with the same uuid
*
* @return array
*/
private function get_all_uuids() : array {
global $wpdb;
$result = $wpdb->get_col(
"
SELECT meta_value
FROM $wpdb->postmeta
WHERE meta_key = '_woocommerce_pos_uuid'
"
);
return $result;
}

/**
* Make sure the product has a uuid
*/
private function maybe_add_uuid( WC_Product $product ) {
$uuids = get_post_meta( $product->get_id(), '_woocommerce_pos_uuid', false );
$uuid_counts = array_count_values( $this->uuids );

if ( empty( $uuids ) ) {
$this->add_uuid_meta_data( $product );
}

if ( count( $uuids ) > 1 || count( $uuids ) === 1 && $uuid_counts[ $uuids[0] ] > 1 ) {
delete_post_meta( $product->get_id(), '_woocommerce_pos_uuid' );
$this->add_uuid_meta_data( $product );
}
}

/**
*
*/
private function add_uuid_meta_data( WC_Product $product ) {
$uuid = Uuid::uuid4()->toString();
while ( in_array( $uuid, $this->uuids ) ) { // ensure the new UUID is unique
$uuid = Uuid::uuid4()->toString();
}
$this->uuids[] = $uuid; // update the UUID list
$product->update_meta_data( '_woocommerce_pos_uuid', $uuid );
$product->save_meta_data();
}

/**
Expand Down Expand Up @@ -133,24 +212,18 @@ public function insert_product_object( WC_Data $object, WP_REST_Request $request
* Filter the product response.
*
* @param WP_REST_Response $response The response object.
* @param WC_Data $product Product data.
* @param WC_Product $product Product data.
* @param WP_REST_Request $request Request object.
*
* @return WP_REST_Response $response The response object.
*/
public function product_response( WP_REST_Response $response, WC_Data $product, WP_REST_Request $request ): WP_REST_Response {
public function product_response( WP_REST_Response $response, WC_Product $product, WP_REST_Request $request ): WP_REST_Response {
$data = $response->get_data();

/**
* Make sure the product has a uuid
*/
$uuid = $product->get_meta( '_woocommerce_pos_uuid' );
if ( ! $uuid ) {
$uuid = Uuid::uuid4()->toString();
$product->update_meta_data( '_woocommerce_pos_uuid', $uuid );
$product->save_meta_data();
$data['meta_data'] = $product->get_meta_data();
}
$this->maybe_add_uuid( $product );

/**
* Add barcode field
Expand All @@ -172,7 +245,7 @@ public function product_response( WP_REST_Response $response, WC_Data $product,
* Check the response size and log a debug message if it is over the maximum size.
*/
$response_size = strlen( serialize( $response->data ) );
$max_response_size = 10000;
$max_response_size = 100000;
if ( $response_size > $max_response_size ) {
Logger::log( "Product ID {$product->get_id()} has a response size of {$response_size} bytes, exceeding the limit of {$max_response_size} bytes." );
}
Expand All @@ -182,29 +255,44 @@ public function product_response( WP_REST_Response $response, WC_Data $product,
* @TODO - only need to update if there is a change
*/
if ( $product->is_type( 'variable' ) ) {
$product->update_meta_data( '_woocommerce_pos_variable_prices', wp_json_encode(
array(
'price' => array(
'min' => $product->get_variation_price(),
'max' => $product->get_variation_price( 'max' ),
),
'regular_price' => array(
'min' => $product->get_variation_regular_price(),
'max' => $product->get_variation_regular_price( 'max' ),
),
'sale_price' => array(
'min' => $product->get_variation_sale_price(),
'max' => $product->get_variation_sale_price( 'max' ),
),
)
) );
$product->save_meta_data();
$data['meta_data'] = $product->get_meta_data();
// Initialize price variables
$price_array = array(
'price' => array(
'min' => $product->get_variation_price(),
'max' => $product->get_variation_price( 'max' ),
),
'regular_price' => array(
'min' => $product->get_variation_regular_price(),
'max' => $product->get_variation_regular_price( 'max' ),
),
'sale_price' => array(
'min' => $product->get_variation_sale_price(),
'max' => $product->get_variation_sale_price( 'max' ),
),
);

// Try encoding the array into JSON
$encoded_price = wp_json_encode( $price_array );

// Check if the encoding was successful
if ( $encoded_price === false ) {
// JSON encode failed, log the original array for debugging
Logger::log( 'JSON encoding of price array failed: ' . json_last_error_msg(), $price_array );
} else {
// Update the meta data with the successfully encoded price data
$product->update_meta_data( '_woocommerce_pos_variable_prices', $encoded_price );
$product->save_meta_data();
}
}


/**
* Reset the new response data
* BUG FIX: some servers are not returning the correct meta_data if it is left as WC_Meta_Data objects
*/
$data['meta_data'] = array_map( function( $meta_data ) {
return $meta_data->get_data();
}, $product->get_meta_data());
$response->set_data( $data );

return $response;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@wcpos/woocommerce-pos",
"version": "1.2.3",
"version": "1.2.4",
"description": "A simple front-end for taking WooCommerce orders at the Point of Sale.",
"main": "index.js",
"workspaces": {
Expand Down
5 changes: 4 additions & 1 deletion readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.2
Stable tag: 1.2.3
Stable tag: 1.2.4
License: GPL-3.0
License URI: http://www.gnu.org/licenses/gpl-3.0.html

Expand Down Expand Up @@ -63,6 +63,9 @@ There is more information on our website at [https://wcpos.com](https://wcpos.co

== Changelog ==

= 1.2.4 - 2023/07/25 =
* Fix: empty products effecting some users due to malformed meta_data

= 1.2.3 - 2023/06/21 =
* Fix: coupon form on POS payment modal
* Fix: use woocommerce_gallery_thumbnail instead of full sized images for products and variations
Expand Down
4 changes: 2 additions & 2 deletions woocommerce-pos.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 <a href="http://wordpress.org/plugins/woocommerce/">WooCommerce</a>.
* Version: 1.2.3
* Version: 1.2.4
* Author: kilbot
* Author URI: http://wcpos.com
* Text Domain: woocommerce-pos
Expand All @@ -24,7 +24,7 @@
use function define;

// Define plugin constants.
const VERSION = '1.2.3';
const VERSION = '1.2.4';
const PLUGIN_NAME = 'woocommerce-pos';
const SHORT_NAME = 'wcpos';
define( __NAMESPACE__ . '\PLUGIN_FILE', plugin_basename( __FILE__ ) ); // 'woocommerce-pos/woocommerce-pos.php'
Expand Down

0 comments on commit 639ab16

Please sign in to comment.