Plugin Directory

Changeset 3102003


Ignore:
Timestamp:
06/12/2024 07:47:59 PM (10 months ago)
Author:
kilbot
Message:

Update to version 1.6.0 from GitHub

Location:
woocommerce-pos
Files:
414 added
6 deleted
42 edited
1 copied

Legend:

Unmodified
Added
Removed
  • woocommerce-pos/tags/1.6.0/includes/API/Customers_Controller.php

    r3096777 r3102003  
    6969         */
    7070        if ( $request->get_param( 'posts_per_page' ) == -1 && $request->get_param( 'fields' ) !== null ) {
    71             return $this->wcpos_get_all_posts( $request->get_param( 'fields' ) );
     71            return $this->wcpos_get_all_posts( $request );
    7272        }
    7373
     
    237237     * Also, querying by role is not as simple as querying by post type.
    238238     *
    239      * @param array $fields Fields to return. Default is ID.
    240      *
    241      * @return array|WP_Error
    242      */
    243     public function wcpos_get_all_posts( array $fields = array() ): array {
     239     * @param WP_REST_Request $request Full details about the request.
     240     *
     241     * @return WP_REST_Response|WP_Error
     242     */
     243    public function wcpos_get_all_posts( $request ) {
    244244        global $wpdb;
    245245
     246        // Start timing execution
     247        $start_time = microtime( true );
     248
     249        $modified_after = $request->get_param( 'modified_after' );
     250        $dates_are_gmt = true;
     251        $fields = $request->get_param( 'fields' );
    246252        $id_with_modified_date = array( 'id', 'date_modified_gmt' ) === $fields;
    247253
    248254        $args = array(
    249             'fields' => array( 'ID', 'registered' ), // Return only the ID and registered date.
     255            'fields' => array( 'ID', 'user_registered' ), // Return only the ID and registered date.
    250256            // 'role__in' => 'all', // @TODO: could be an array of roles, like ['customer', 'cashier']
    251257        );
     
    263269
    264270            if ( $id_with_modified_date ) {
    265                 $last_update_results = $wpdb->get_results(
    266                     "
    267             SELECT user_id, meta_value
    268             FROM $wpdb->usermeta
    269             WHERE meta_key = 'last_update'",
    270                     OBJECT_K
    271                 );
    272 
    273                 foreach ( $last_update_results as $user_id => $meta ) {
    274                     $last_updates[ $user_id ] = $meta->meta_value;
     271                $query = "
     272                    SELECT user_id, meta_value
     273                    FROM $wpdb->usermeta
     274                    WHERE meta_key = 'last_update'
     275                ";
     276
     277                // If modified_after param is set, add the condition to the query
     278                if ( $modified_after ) {
     279                    $modified_after_timestamp = strtotime( $modified_after );
     280                    $query .= $wpdb->prepare( ' AND meta_value > %d', $modified_after_timestamp );
     281                }
     282
     283                $last_update_results = $wpdb->get_results( $query );
     284
     285                // Manually create the associative array of user_id => last_update
     286                foreach ( $last_update_results as $result ) {
     287                    $last_updates[ $result->user_id ] = is_numeric( $result->meta_value ) ? gmdate( 'Y-m-d\TH:i:s', (int) $result->meta_value ) : null;
    275288                }
    276289            }
    277290
    278             // Merge user IDs with their corresponding 'last_updated' values or fallback to user_registered.
    279             $user_data = array_map(
    280                 function ( $user ) use ( $last_updates, $id_with_modified_date ) {
    281                     $user_info = array( 'id' => (int) $user->ID );
    282                     if ( $id_with_modified_date ) {
    283                         if ( isset( $last_updates[ $user->ID ] ) ) {
    284                             $user_info['date_modified_gmt'] = wc_rest_prepare_date_response( $last_updates[ $user->ID ] );
    285                         } else {
    286                             $user_info['date_modified_gmt'] = wc_rest_prepare_date_response( $user->user_registered );
     291            /**
     292             * Performance notes:
     293             * - Using a generator is faster than array_map when dealing with large datasets.
     294             * - If date is in the format 'Y-m-d H:i:s' we just do preg_replace to 'Y-m-d\TH:i:s',
     295             * rather than using wc_rest_prepare_date_response
     296             *
     297             * This resulted in execution time of 10% of the original time.
     298             *
     299             * If the modified_after param is set, we don't need to loop through the entire user list.
     300             * The last_update_results array will only contain the users that have been modified after the given date.
     301             * We just need to check they are valid user ids, this sucks, but there could be orphaned last_update meta values.
     302             */
     303            $formatted_results = array();
     304
     305            if ( $modified_after ) {
     306                foreach ( $users as $user ) {
     307                    if ( isset( $last_updates[ $user->ID ] ) ) {
     308                        $user_info = array( 'id' => (int) $user->ID );
     309                        if ( $id_with_modified_date ) {
     310                            $user_info['date_modified_gmt'] = $last_updates[ $user->ID ];
    287311                        }
     312                        $formatted_results[] = $user_info;
    288313                    }
    289                     return $user_info;
    290                 },
    291                 $users
    292             );
    293 
    294             return $user_data;
     314                }
     315            } else {
     316                function format_results( $users, $last_updates, $id_with_modified_date ) {
     317                    foreach ( $users as $user ) {
     318                        $user_info = array( 'id' => (int) $user->ID );
     319                        if ( $id_with_modified_date ) {
     320                            if ( isset( $last_updates[ $user->ID ] ) && ! empty( $last_updates[ $user->ID ] ) ) {
     321                                $user_info['date_modified_gmt'] = $last_updates[ $user->ID ];
     322                            } else {
     323                                $user_info['date_modified_gmt'] = null; // users can have null date_modified_gmt
     324                            }
     325                        }
     326                        yield $user_info;
     327                    }
     328                }
     329
     330                $formatted_results = iterator_to_array( format_results( $users, $last_updates, $id_with_modified_date ) );
     331            }
     332
     333            // Get the total number of orders for the given criteria.
     334            $total = count( $formatted_results );
     335
     336            // Collect execution time and server load.
     337            $execution_time = microtime( true ) - $start_time;
     338            $execution_time_ms = number_format( $execution_time * 1000, 2 );
     339            $server_load = sys_getloadavg();
     340
     341            $response = rest_ensure_response( $formatted_results );
     342            $response->header( 'X-WP-Total', (int) $total );
     343            $response->header( 'X-Execution-Time', $execution_time_ms . ' ms' );
     344            $response->header( 'X-Server-Load', json_encode( $server_load ) );
     345
     346            return $response;
    295347        } catch ( Exception $e ) {
    296348            Logger::log( 'Error fetching order IDs: ' . $e->getMessage() );
  • woocommerce-pos/tags/1.6.0/includes/API/Orders_Controller.php

    r3096777 r3102003  
    2020use WP_REST_Server;
    2121use Automattic\WooCommerce\Utilities\OrderUtil;
     22use WCPOS\WooCommercePOS\Services\Cache;
    2223use WP_Error;
    2324
     
    102103         */
    103104        if ( $request->get_param( 'posts_per_page' ) == -1 && $request->get_param( 'fields' ) !== null ) {
    104             return $this->wcpos_get_all_posts( $request->get_param( 'fields' ) );
     105            return $this->wcpos_get_all_posts( $request );
    105106        }
    106107
     
    194195    /**
    195196     * Create a single order.
     197     * - Validate billing email.
     198     * - Do a sanity check on the UUID, if the internet connection is bad, several requests can be made with the same UUID.
    196199     *
    197200     * @param WP_REST_Request $request Full details about the request.
     
    200203     */
    201204    public function create_item( $request ) {
     205        // check if the UUID is already in use.
     206        if ( isset( $request['meta_data'] ) && is_array( $request['meta_data'] ) ) {
     207            foreach ( $request['meta_data'] as $meta ) {
     208                if ( $meta['key'] === '_woocommerce_pos_uuid' ) {
     209                    $uuid = $meta['value'];
     210                    $ids = $this->get_order_ids_by_uuid( $uuid );
     211
     212                    /**
     213                     * If the UUID is already in use, and there is only one order with that UUID, return the existing order.
     214                     * This can happen if the internet connection is bad and the request is made several times.
     215                     *
     216                     * @NOTE: This means that $request data is lost, but we can't update existing order because it has resource ids now.
     217                     * The alternative would be to update the existing order, but that would require a lot of extra work.
     218                     * Or return an error, which would be a bad user experience.
     219                     */
     220                    if ( count( $ids ) === 1 ) {
     221                        Logger::log( 'UUID already in use, return existing order.', $ids[0] );
     222
     223                        // Create a new WP_REST_Request object for the GET request.
     224                        $get_request = new WP_REST_Request( 'GET', $this->namespace . '/' . $this->rest_base . '/' . $ids[0] );
     225                        $get_request->set_param( 'id', $ids[0] );
     226
     227                        return $this->get_item( $get_request );
     228                    }
     229                    if ( count( $ids ) > 1 ) {
     230                        Logger::log( 'UUID already in use for multiple orders. This should not happen.', $ids );
     231                        return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'UUID already in use.', 'woocommerce' ), array( 'status' => 400 ) );
     232                    }
     233                }
     234            }
     235        }
     236
    202237        $valid_email = $this->wcpos_validate_billing_email( $request );
    203238        if ( is_wp_error( $valid_email ) ) {
     
    321356     */
    322357    public function wcpos_validate_billing_email( WP_REST_Request $request ) {
    323         // Your custom validation logic for the request data
    324358        $billing = $request['billing'] ?? null;
    325359        $email   = \is_array( $billing ) ? ( $billing['email'] ?? null ) : null;
     
    637671     * Returns array of all order ids.
    638672     *
    639      * @param array $fields Fields to return.
    640      *
    641      * @return array|WP_Error
    642      */
    643     public function wcpos_get_all_posts( array $fields = array() ): array {
     673     * @param WP_REST_Request $request Full details about the request.
     674     *
     675     * @return WP_REST_Response|WP_Error
     676     */
     677    public function wcpos_get_all_posts( $request ) {
    644678        global $wpdb;
    645679
     680        // Start timing execution.
     681        $start_time = microtime( true );
     682
     683        $modified_after = $request->get_param( 'modified_after' );
     684        $dates_are_gmt = true; // Dates are always in GMT.
     685        $fields = $request->get_param( 'fields' );
    646686        $id_with_modified_date = array( 'id', 'date_modified_gmt' ) === $fields;
    647687
     
    662702            $sql .= ' AND status IN (' . implode( ',', $statuses ) . ')';
    663703
     704            // Add modified_after condition if provided.
     705            if ( $modified_after ) {
     706                $modified_after_date = date( 'Y-m-d H:i:s', strtotime( $modified_after ) );
     707                $sql .= $wpdb->prepare( ' AND date_updated_gmt > %s', $modified_after_date );
     708            }
     709
    664710            // Order by date_created_gmt DESC to maintain order consistency.
    665711            $sql .= " ORDER BY {$wpdb->prefix}wc_orders.date_created_gmt DESC";
     
    669715            $sql .= ' AND post_status IN (' . implode( ',', $statuses ) . ')';
    670716
     717            // Add modified_after condition if provided.
     718            if ( $modified_after ) {
     719                $modified_after_date = date( 'Y-m-d H:i:s', strtotime( $modified_after ) );
     720                $sql .= $wpdb->prepare( ' AND post_modified_gmt > %s', $modified_after_date );
     721            }
     722
    671723            // Order by post_date DESC to maintain order consistency.
    672724            $sql .= " ORDER BY {$wpdb->posts}.post_date DESC";
     
    674726
    675727        try {
    676             $results = $wpdb->get_results( $sql );
    677             return $this->wcpos_format_all_posts_response( $results );
     728            $results = $wpdb->get_results( $sql, ARRAY_A );
     729            $formatted_results = $this->wcpos_format_all_posts_response( $results );
     730
     731            // Get the total number of orders for the given criteria.
     732            $total = count( $formatted_results );
     733
     734            // Collect execution time and server load.
     735            $execution_time = microtime( true ) - $start_time;
     736            $execution_time_ms = number_format( $execution_time * 1000, 2 );
     737            $server_load = sys_getloadavg();
     738
     739            $response = rest_ensure_response( $formatted_results );
     740            $response->header( 'X-WP-Total', (int) $total );
     741            $response->header( 'X-Execution-Time', $execution_time_ms . ' ms' );
     742            $response->header( 'X-Server-Load', json_encode( $server_load ) );
     743
     744            return $response;
    678745        } catch ( Exception $e ) {
    679746            Logger::log( 'Error fetching order data: ' . $e->getMessage() );
  • woocommerce-pos/tags/1.6.0/includes/API/Product_Categories_Controller.php

    r3096777 r3102003  
    5757         */
    5858        if ( $request->get_param( 'posts_per_page' ) == -1 && $request->get_param( 'fields' ) !== null ) {
    59             return $this->wcpos_get_all_posts( $request->get_param( 'fields' ) );
     59            return $this->wcpos_get_all_posts( $request );
    6060        }
    6161
     
    142142     * Returns array of all product category ids.
    143143     *
    144      * @param array $fields
     144     * @param WP_REST_Request $request Full details about the request.
    145145     *
    146      * @return array|WP_Error
     146     * @return WP_REST_Response|WP_Error
    147147     */
    148     public function wcpos_get_all_posts( array $fields = array() ): array {
     148    public function wcpos_get_all_posts( $request ) {
     149        // Start timing execution.
     150        $start_time = microtime( true );
     151        $modified_after = $request->get_param( 'modified_after' );
     152
    149153        $args = array(
    150154            'taxonomy'   => 'product_cat',
     
    154158
    155159        try {
    156             $results = get_terms( $args );
     160            /**
     161             * @TODO - terms don't have a modified date, it would be good to add a term_meta for last_update
     162             * - ideally WooCommerce would provide a modified_after filter for terms
     163             * - for now we'll just return empty for modified terms
     164             */
     165            $results = $modified_after ? array() : get_terms( $args );
    157166
    158167            // Format the response.
    159             return array_map(
    160                 function ( $item ) {
    161                     return array( 'id' => (int) $item );
     168            $formatted_results = array_map(
     169                function ( $id ) {
     170                    return array( 'id' => (int) $id );
    162171                },
    163172                $results
    164173            );
     174
     175            // Get the total number of orders for the given criteria.
     176            $total = count( $formatted_results );
     177
     178            // Collect execution time and server load.
     179            $execution_time = microtime( true ) - $start_time;
     180            $execution_time_ms = number_format( $execution_time * 1000, 2 );
     181            $server_load = sys_getloadavg();
     182
     183            $response = rest_ensure_response( $formatted_results );
     184            $response->header( 'X-WP-Total', (int) $total );
     185            $response->header( 'X-Execution-Time', $execution_time_ms . ' ms' );
     186            $response->header( 'X-Server-Load', json_encode( $server_load ) );
     187
     188            return $response;
    165189        } catch ( Exception $e ) {
    166190            Logger::log( 'Error fetching product category IDs: ' . $e->getMessage() );
  • woocommerce-pos/tags/1.6.0/includes/API/Product_Tags_Controller.php

    r3096777 r3102003  
    5757         */
    5858        if ( $request->get_param( 'posts_per_page' ) == -1 && $request->get_param( 'fields' ) !== null ) {
    59             return $this->wcpos_get_all_posts( $request->get_param( 'fields' ) );
     59            return $this->wcpos_get_all_posts( $request );
    6060        }
    6161
     
    142142     * Returns array of all product tag ids.
    143143     *
    144      * @param array $fields
     144     * @param WP_REST_Request $request Full details about the request.
    145145     *
    146      * @return array|WP_Error
     146     * @return WP_REST_Response|WP_Error
    147147     */
    148     public function wcpos_get_all_posts( array $fields = array() ): array {
     148    public function wcpos_get_all_posts( $request ): array {
     149        // Start timing execution.
     150        $start_time = microtime( true );
     151        $modified_after = $request->get_param( 'modified_after' );
     152
    149153        $args = array(
    150154            'taxonomy'   => 'product_tag',
     
    154158
    155159        try {
    156             $results = get_terms( $args );
     160            /**
     161             * @TODO - terms don't have a modified date, it would be good to add a term_meta for last_update
     162             * - ideally WooCommerce would provide a modified_after filter for terms
     163             * - for now we'll just return empty for modified terms
     164             */
     165            $results = $modified_after ? array() : get_terms( $args );
    157166
    158167            // Format the response.
    159             return array_map(
    160                 function ( $item ) {
    161                     return array( 'id' => (int) $item );
     168            $formatted_results = array_map(
     169                function ( $id ) {
     170                    return array( 'id' => (int) $id );
    162171                },
    163172                $results
    164173            );
     174
     175            // Get the total number of orders for the given criteria.
     176            $total = count( $formatted_results );
     177
     178            // Collect execution time and server load.
     179            $execution_time = microtime( true ) - $start_time;
     180            $execution_time_ms = number_format( $execution_time * 1000, 2 );
     181            $server_load = sys_getloadavg();
     182
     183            $response = rest_ensure_response( $formatted_results );
     184            $response->header( 'X-WP-Total', (int) $total );
     185            $response->header( 'X-Execution-Time', $execution_time_ms . ' ms' );
     186            $response->header( 'X-Server-Load', json_encode( $server_load ) );
     187
     188            return $response;
    165189        } catch ( Exception $e ) {
    166190            Logger::log( 'Error fetching product tags IDs: ' . $e->getMessage() );
  • woocommerce-pos/tags/1.6.0/includes/API/Product_Variations_Controller.php

    r3096777 r3102003  
    6666         */
    6767        if ( $request->get_param( 'posts_per_page' ) == -1 && $request->get_param( 'fields' ) !== null ) {
    68             return $this->wcpos_get_all_posts( $request->get_param( 'fields' ) );
     68            return $this->wcpos_get_all_posts( $request );
    6969        }
    7070
     
    367367     * Returns array of all product ids, name.
    368368     *
    369      * @param array $fields
    370      *
    371      * @return array|WP_Error
    372      */
    373     public function wcpos_get_all_posts( array $fields = array() ): array {
     369     * @param WP_REST_Request $request Full details about the request.
     370     *
     371     * @return WP_REST_Response|WP_Error
     372     */
     373    public function wcpos_get_all_posts( $request ) {
    374374        global $wpdb;
    375375
     376        // Start timing execution.
     377        $start_time = microtime( true );
     378
     379        $modified_after = $request->get_param( 'modified_after' );
     380        $fields = $request->get_param( 'fields' );
    376381        $parent_id = (int) $this->wcpos_request->get_param( 'product_id' );
    377382        $id_with_modified_date = array( 'id', 'date_modified_gmt' ) === $fields;
     
    391396        }
    392397
     398        // Add modified_after condition if provided.
     399        if ( $modified_after ) {
     400            $modified_after_date = date( 'Y-m-d H:i:s', strtotime( $modified_after ) );
     401            $sql .= $wpdb->prepare( ' AND post_modified_gmt > %s', $modified_after_date );
     402        }
     403
    393404        // Dynamically add the post_parent clause if a parent ID is provided.
    394405        if ( $parent_id ) {
     
    398409        try {
    399410            // Execute the query.
    400             $results = $wpdb->get_results( $sql );
    401             // Format and return the results.
    402             return $this->wcpos_format_all_posts_response( $results );
     411            $results = $wpdb->get_results( $sql, ARRAY_A );
     412            $formatted_results = $this->wcpos_format_all_posts_response( $results );
     413
     414            // Get the total number of orders for the given criteria.
     415            $total = count( $formatted_results );
     416
     417            // Collect execution time and server load.
     418            $execution_time = microtime( true ) - $start_time;
     419            $execution_time_ms = number_format( $execution_time * 1000, 2 );
     420            $server_load = sys_getloadavg();
     421
     422            $response = rest_ensure_response( $formatted_results );
     423            $response->header( 'X-WP-Total', (int) $total );
     424            $response->header( 'X-Execution-Time', $execution_time_ms . ' ms' );
     425            $response->header( 'X-Server-Load', json_encode( $server_load ) );
     426
     427            return $response;
    403428        } catch ( Exception $e ) {
    404429            Logger::log( 'Error fetching product variation IDs: ' . $e->getMessage() );
  • woocommerce-pos/tags/1.6.0/includes/API/Products_Controller.php

    r3096777 r3102003  
    7676         */
    7777        if ( $request->get_param( 'posts_per_page' ) == -1 && $request->get_param( 'fields' ) !== null ) {
    78             return $this->wcpos_get_all_posts( $request->get_param( 'fields' ) );
     78            return $this->wcpos_get_all_posts( $request );
    7979        }
    8080
     
    430430     * Returns array of all product ids, name.
    431431     *
    432      * @param array $fields Fields to return.
    433      *
    434      * @return array|WP_Error
    435      */
    436     public function wcpos_get_all_posts( array $fields = array() ): array {
     432     * @param WP_REST_Request $request Full details about the request.
     433     *
     434     * @return WP_REST_Response|WP_Error
     435     */
     436    public function wcpos_get_all_posts( $request ) {
    437437        global $wpdb;
    438438
     439        // Start timing execution.
     440        $start_time = microtime( true );
     441
     442        $modified_after = $request->get_param( 'modified_after' );
     443        $dates_are_gmt = true; // Dates are always in GMT.
     444        $fields = $request->get_param( 'fields' );
    439445        $id_with_modified_date = array( 'id', 'date_modified_gmt' ) === $fields;
    440446        $select_fields = $id_with_modified_date ? 'ID as id, post_modified_gmt as date_modified_gmt' : 'ID as id';
     
    451457        }
    452458
     459        // Add modified_after condition if provided.
     460        if ( $modified_after ) {
     461            $modified_after_date = date( 'Y-m-d H:i:s', strtotime( $modified_after ) );
     462            $sql .= $wpdb->prepare( ' AND post_modified_gmt > %s', $modified_after_date );
     463        }
     464
    453465        // Order by post_date DESC to maintain order consistency.
    454466        $sql .= " ORDER BY {$wpdb->posts}.post_date DESC";
    455467
    456468        try {
    457             $results = $wpdb->get_results( $sql );
    458             return $this->wcpos_format_all_posts_response( $results );
     469            $results = $wpdb->get_results( $sql, ARRAY_A );
     470            $formatted_results = $this->wcpos_format_all_posts_response( $results );
     471
     472            // Get the total number of orders for the given criteria.
     473            $total = count( $formatted_results );
     474
     475            // Collect execution time and server load.
     476            $execution_time = microtime( true ) - $start_time;
     477            $execution_time_ms = number_format( $execution_time * 1000, 2 );
     478            $server_load = sys_getloadavg();
     479
     480            $response = rest_ensure_response( $formatted_results );
     481            $response->header( 'X-WP-Total', (int) $total );
     482            $response->header( 'X-Execution-Time', $execution_time_ms . ' ms' );
     483            $response->header( 'X-Server-Load', json_encode( $server_load ) );
     484
     485            return $response;
    459486        } catch ( Exception $e ) {
    460487            Logger::log( 'Error fetching product data: ' . $e->getMessage() );
  • woocommerce-pos/tags/1.6.0/includes/API/Taxes_Controller.php

    r3096777 r3102003  
    99}
    1010
     11use Exception;
    1112use WC_REST_Taxes_Controller;
     13use WCPOS\WooCommercePOS\Logger;
    1214use WP_REST_Request;
     15use WP_REST_Response;
    1316
    1417/**
     
    5457         */
    5558        if ( $request->get_param( 'posts_per_page' ) == -1 && $request->get_param( 'fields' ) !== null ) {
    56             return $this->wcpos_get_all_posts( $request->get_param( 'fields' ) );
     59            return $this->wcpos_get_all_posts( $request );
    5760        }
    5861
     
    207210     * Returns array of all tax_rate ids.
    208211     *
    209      * @param array $fields
    210      *
    211      * @return array|WP_Error
    212      */
    213     public function wcpos_get_all_posts( array $fields = array() ): array {
     212     * @param WP_REST_Request $request Full details about the request.
     213     *
     214     * @return WP_REST_Response|WP_Error
     215     */
     216    public function wcpos_get_all_posts( $request ) {
    214217        global $wpdb;
    215218
    216         $results = $wpdb->get_results(
    217             '
    218             SELECT tax_rate_id as id FROM ' . $wpdb->prefix . 'woocommerce_tax_rates
    219         ',
    220             ARRAY_A
    221         );
    222 
    223         // Format the response.
    224         return array_map(
    225             function ( $item ) {
    226                 return array( 'id' => (int) $item['id'] );
    227             },
    228             $results
    229         );
     219        // Start timing execution.
     220        $start_time = microtime( true );
     221        $modified_after = $request->get_param( 'modified_after' );
     222
     223        try {
     224            /**
     225             * @TODO - taxes doen't have a modified date, so we can't filter by modified_after
     226             * - ideally WooCommerce would provide a modified_after filter for terms
     227             * - for now we'll just return empty for modified terms
     228             */
     229            $results = $modified_after ? array() : $wpdb->get_results(
     230                '
     231                SELECT tax_rate_id as id FROM ' . $wpdb->prefix . 'woocommerce_tax_rates
     232            ',
     233                ARRAY_A
     234            );
     235
     236            // Format the response.
     237            $formatted_results = array_map(
     238                function ( $item ) {
     239                    return array( 'id' => (int) $item['id'] );
     240                },
     241                $results
     242            );
     243
     244            // Get the total number of orders for the given criteria.
     245            $total = count( $formatted_results );
     246
     247            // Collect execution time and server load.
     248            $execution_time = microtime( true ) - $start_time;
     249            $execution_time_ms = number_format( $execution_time * 1000, 2 );
     250            $server_load = sys_getloadavg();
     251
     252            $response = rest_ensure_response( $formatted_results );
     253            $response->header( 'X-WP-Total', (int) $total );
     254            $response->header( 'X-Execution-Time', $execution_time_ms . ' ms' );
     255            $response->header( 'X-Server-Load', json_encode( $server_load ) );
     256
     257            return $response;
     258        } catch ( Exception $e ) {
     259            Logger::log( 'Error fetching product tax rate IDs: ' . $e->getMessage() );
     260
     261            return new \WP_Error(
     262                'woocommerce_pos_rest_cannot_fetch',
     263                'Error fetching product tax rate IDs.',
     264                array( 'status' => 500 )
     265            );
     266        }
    230267    }
    231268}
  • woocommerce-pos/tags/1.6.0/includes/API/Traits/Uuid_Handler.php

    r3042209 r3102003  
    197197
    198198    /**
     199     *
     200     */
     201    private function get_order_ids_by_uuid( string $uuid ) {
     202        global $wpdb;
     203
     204        if ( class_exists( OrderUtil::class ) && OrderUtil::custom_orders_table_usage_is_enabled() ) {
     205            // Check the orders meta table.
     206            $result = $wpdb->get_col(
     207                $wpdb->prepare(
     208                    "SELECT order_id FROM {$wpdb->prefix}wc_orders_meta WHERE meta_key = '_woocommerce_pos_uuid' AND meta_value = %s",
     209                    $uuid
     210                )
     211            );
     212        } else {
     213            // Check the postmeta table.
     214            $result = $wpdb->get_col(
     215                $wpdb->prepare(
     216                    "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_woocommerce_pos_uuid' AND meta_value = %s",
     217                    $uuid
     218                )
     219            );
     220        }
     221
     222        return $result;
     223    }
     224
     225    /**
    199226     * Check if the given UUID already exists for any user.
    200227     *
  • woocommerce-pos/tags/1.6.0/includes/API/Traits/WCPOS_REST_API.php

    r3096777 r3102003  
    1515     */
    1616    public function wcpos_format_all_posts_response( $results ) {
    17         $formatted_results = array_map(
    18             function ( $result ) {
    19                 // Initialize the formatted result as an associative array.
    20                 $formatted_result = array(
    21                     'id' => (int) $result->id, // Cast ID to integer for consistency.
    22                 );
     17        /**
     18         * Performance notes:
     19         * - Using a generator is faster than array_map when dealing with large datasets.
     20         * - If date is in the format 'Y-m-d H:i:s' we just do preg_replace to 'Y-m-d\TH:i:s', rather than using wc_rest_prepare_date_response
     21         *
     22         * This resulted in execution time of 10% of the original time.
     23         */
     24        function format_results( $results ) {
     25            foreach ( $results as $result ) {
     26                $result['id'] = (int) $result['id'];
    2327
    24                 // Check if post_modified_gmt exists and is not null, then set date_modified_gmt.
    25                 if ( isset( $result->date_modified_gmt ) && ! empty( $result->date_modified_gmt ) ) {
    26                     $formatted_result['date_modified_gmt'] = wc_rest_prepare_date_response( $result->date_modified_gmt );
     28                if ( isset( $result['date_modified_gmt'] ) ) {
     29                    if ( preg_match( '/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/', $result['date_modified_gmt'] ) ) {
     30                            $result['date_modified_gmt'] = preg_replace( '/(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2})/', '$1T$2', $result['date_modified_gmt'] );
     31                    } else {
     32                            $result['date_modified_gmt'] = wc_rest_prepare_date_response( $result['date_modified_gmt'] );
     33                    }
    2734                }
    2835
    29                 return $formatted_result;
    30             },
    31             $results
    32         );
     36                yield $result;
     37            }
     38        }
    3339
    34         return $formatted_results;
     40        return iterator_to_array( format_results( $results ) );
    3541    }
    3642
  • woocommerce-pos/tags/1.6.0/includes/Templates.php

    r3042209 r3102003  
    150150     */
    151151    public function order_received_url( string $order_received_url, WC_Abstract_Order $order ): string {
     152        global $wp;
     153
    152154        // check is pos
    153         if ( ! woocommerce_pos_request() ) {
     155        if ( ! woocommerce_pos_request() || ! isset( $wp->query_vars['order-pay'] ) ) {
    154156            return $order_received_url;
    155157        }
  • woocommerce-pos/tags/1.6.0/includes/Templates/Frontend.php

    r3096777 r3102003  
    1313use const WCPOS\WooCommercePOS\SHORT_NAME;
    1414use const WCPOS\WooCommercePOS\VERSION;
     15use const WCPOS\WooCommercePOS\PLUGIN_URL;
    1516
    1617/**
     
    8788        $development    = isset( $_ENV['DEVELOPMENT'] ) && $_ENV['DEVELOPMENT'];
    8889        $user           = wp_get_current_user();
    89         $github_url     = 'https://cdn.jsdelivr.net/gh/wcpos/web-bundle@1.5/';
     90        $github_url     = 'https://cdn.jsdelivr.net/gh/wcpos/web-bundle@1.6/';
    9091        $auth_service   = Auth::instance();
    9192        $stores         = array_map(
     
    149150        $dev_bundle    = 'http://localhost:8081/index.bundle?platform=web&dev=true&hot=false';
    150151
    151         // getScript helper and initialProps
     152        /**
     153         * Add path to worker scripts
     154         */
     155        $idbWorker = PLUGIN_URL . 'assets/js/indexeddb.worker.js';
     156
     157        /**
     158         * getScript helper and initialProps
     159         */
    152160        echo "<script>
    153161    function getScript(source, callback) {
     
    169177    }
    170178
    171     var initialProps={$initial_props};
     179    var idbWorker = '{$idbWorker}';
     180    var initialProps = {$initial_props};
    172181</script>" . "\n";
    173182
     183        /**
     184         * The actual app bundle
     185         */
    174186        if ( $development ) {
    175187            // Development
  • woocommerce-pos/tags/1.6.0/includes/Templates/Login.php

    r3020971 r3102003  
    7979        echo '<script>
    8080    (function() {
    81         // Parse the order JSON from PHP
    8281        var credentials = ' . $credentials . "
    8382
  • woocommerce-pos/tags/1.6.0/readme.txt

    r3096870 r3102003  
    44Requires at least: 5.6
    55Tested up to: 6.5
    6 Stable tag: 1.5.1
     6Stable tag: 1.6.0
    77License: GPL-3.0
    88License URI: http://www.gnu.org/licenses/gpl-3.0.html
     
    2929* Add new customers or checkout via Guest account
    3030* Add miscellaneous products to cart, ie: products not in WooCommerce
     31* Live chat support within the application
    3132* **Pro:** Use any WooCommerce gateway
    3233* **Pro:** Create multiple POS Stores
     
    8081== Changelog ==
    8182
     83= 1.6.0 - 2024/06/12 =
     84* Improved: Performance for large stores
     85* Added: Log screen for insights into the POS performance and events
     86* Added: Cart setting to enable/disable show receipt after checkout
     87* Added: Cart setting to enable/disable auto-print receipt after checkout
     88* Fix: Prevent order create duplication from the POS
     89* Fix: Cart subtotal showing tax when tax display is not enabled
     90
    8291= 1.5.1 - 2024/06/03 =
    8392* Fix: "Sorry, you cannot list resources." error for cashier role
    84 
    8593
    8694= 1.5.0 - 2024/06/03 =
  • woocommerce-pos/tags/1.6.0/vendor/autoload.php

    r3096869 r3102003  
    2323require_once __DIR__ . '/composer/autoload_real.php';
    2424
    25 return ComposerAutoloaderInit048927fcd0f6e1bd2ab86d49767e2e77::getLoader();
     25return ComposerAutoloaderInitf0c7d8ce923efae83025b27d0c5bc6c0::getLoader();
  • woocommerce-pos/tags/1.6.0/vendor/composer/autoload_classmap.php

    r3096777 r3102003  
    2525    'CURLStringFile' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php',
    2626    'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
    27     'Handlebars\\Autoloader' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Autoloader.php',
    28     'Handlebars\\Cache' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Cache.php',
    29     'Handlebars\\Cache\\APC' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Cache/APC.php',
    30     'Handlebars\\Cache\\Disk' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Cache/Disk.php',
    31     'Handlebars\\Cache\\Dummy' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Cache/Dummy.php',
    32     'Handlebars\\Context' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Context.php',
    33     'Handlebars\\Handlebars' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Handlebars.php',
    34     'Handlebars\\HandlebarsString' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/HandlebarsString.php',
    35     'Handlebars\\Helpers' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Helpers.php',
    36     'Handlebars\\Loader' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Loader.php',
    37     'Handlebars\\Loader\\FilesystemLoader' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Loader/FilesystemLoader.php',
    38     'Handlebars\\Loader\\StringLoader' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Loader/StringLoader.php',
    39     'Handlebars\\Parser' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Parser.php',
    40     'Handlebars\\Template' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Template.php',
    41     'Handlebars\\Tokenizer' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Tokenizer.php',
    4227    'Parsedown' => $vendorDir . '/erusev/parsedown/Parsedown.php',
    4328    'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
     
    183168    'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
    184169    'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
    185     'WCPOS\\Vendor\\Firebase\\JWT\\BeforeValidException' => $baseDir . '/vendor_prefixed/vendor/firebase/php-jwt/src/BeforeValidException.php',
    186     'WCPOS\\Vendor\\Firebase\\JWT\\CachedKeySet' => $baseDir . '/vendor_prefixed/vendor/firebase/php-jwt/src/CachedKeySet.php',
    187     'WCPOS\\Vendor\\Firebase\\JWT\\ExpiredException' => $baseDir . '/vendor_prefixed/vendor/firebase/php-jwt/src/ExpiredException.php',
    188     'WCPOS\\Vendor\\Firebase\\JWT\\JWK' => $baseDir . '/vendor_prefixed/vendor/firebase/php-jwt/src/JWK.php',
    189     'WCPOS\\Vendor\\Firebase\\JWT\\JWT' => $baseDir . '/vendor_prefixed/vendor/firebase/php-jwt/src/JWT.php',
    190     'WCPOS\\Vendor\\Firebase\\JWT\\JWTExceptionWithPayloadInterface' => $baseDir . '/vendor_prefixed/vendor/firebase/php-jwt/src/JWTExceptionWithPayloadInterface.php',
    191     'WCPOS\\Vendor\\Firebase\\JWT\\Key' => $baseDir . '/vendor_prefixed/vendor/firebase/php-jwt/src/Key.php',
    192     'WCPOS\\Vendor\\Firebase\\JWT\\SignatureInvalidException' => $baseDir . '/vendor_prefixed/vendor/firebase/php-jwt/src/SignatureInvalidException.php',
    193170    'WCPOS\\WooCommercePOS\\AJAX' => $baseDir . '/includes/AJAX.php',
    194171    'WCPOS\\WooCommercePOS\\API' => $baseDir . '/includes/API.php',
     
    241218    'WCPOS\\WooCommercePOS\\Server' => $baseDir . '/includes/Server.php',
    242219    'WCPOS\\WooCommercePOS\\Services\\Auth' => $baseDir . '/includes/Services/Auth.php',
     220    'WCPOS\\WooCommercePOS\\Services\\Cache' => $baseDir . '/includes/Services/Cache.php',
    243221    'WCPOS\\WooCommercePOS\\Services\\Settings' => $baseDir . '/includes/Services/Settings.php',
    244222    'WCPOS\\WooCommercePOS\\Templates' => $baseDir . '/includes/Templates.php',
  • woocommerce-pos/tags/1.6.0/vendor/composer/autoload_namespaces.php

    r3020668 r3102003  
    88return array(
    99    'Parsedown' => array($vendorDir . '/erusev/parsedown'),
    10     'Handlebars' => array($vendorDir . '/salesforce/handlebars-php/src'),
    1110);
  • woocommerce-pos/tags/1.6.0/vendor/composer/autoload_real.php

    r3096869 r3102003  
    33// autoload_real.php @generated by Composer
    44
    5 class ComposerAutoloaderInit048927fcd0f6e1bd2ab86d49767e2e77
     5class ComposerAutoloaderInitf0c7d8ce923efae83025b27d0c5bc6c0
    66{
    77    private static $loader;
     
    2323        }
    2424
    25         spl_autoload_register(array('ComposerAutoloaderInit048927fcd0f6e1bd2ab86d49767e2e77', 'loadClassLoader'), true, true);
     25        spl_autoload_register(array('ComposerAutoloaderInitf0c7d8ce923efae83025b27d0c5bc6c0', 'loadClassLoader'), true, true);
    2626        self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
    27         spl_autoload_unregister(array('ComposerAutoloaderInit048927fcd0f6e1bd2ab86d49767e2e77', 'loadClassLoader'));
     27        spl_autoload_unregister(array('ComposerAutoloaderInitf0c7d8ce923efae83025b27d0c5bc6c0', 'loadClassLoader'));
    2828
    2929        require __DIR__ . '/autoload_static.php';
    30         call_user_func(\Composer\Autoload\ComposerStaticInit048927fcd0f6e1bd2ab86d49767e2e77::getInitializer($loader));
     30        call_user_func(\Composer\Autoload\ComposerStaticInitf0c7d8ce923efae83025b27d0c5bc6c0::getInitializer($loader));
    3131
    3232        $loader->register(true);
    3333
    34         $filesToLoad = \Composer\Autoload\ComposerStaticInit048927fcd0f6e1bd2ab86d49767e2e77::$files;
     34        $filesToLoad = \Composer\Autoload\ComposerStaticInitf0c7d8ce923efae83025b27d0c5bc6c0::$files;
    3535        $requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
    3636            if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
  • woocommerce-pos/tags/1.6.0/vendor/composer/autoload_static.php

    r3096869 r3102003  
    55namespace Composer\Autoload;
    66
    7 class ComposerStaticInit048927fcd0f6e1bd2ab86d49767e2e77
     7class ComposerStaticInitf0c7d8ce923efae83025b27d0c5bc6c0
    88{
    99    public static $files = array (
     
    7373            array (
    7474                0 => __DIR__ . '/..' . '/erusev/parsedown',
    75             ),
    76         ),
    77         'H' =>
    78         array (
    79             'Handlebars' =>
    80             array (
    81                 0 => __DIR__ . '/..' . '/salesforce/handlebars-php/src',
    8275            ),
    8376        ),
     
    10396        'CURLStringFile' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php',
    10497        'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
    105         'Handlebars\\Autoloader' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Autoloader.php',
    106         'Handlebars\\Cache' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Cache.php',
    107         'Handlebars\\Cache\\APC' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Cache/APC.php',
    108         'Handlebars\\Cache\\Disk' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Cache/Disk.php',
    109         'Handlebars\\Cache\\Dummy' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Cache/Dummy.php',
    110         'Handlebars\\Context' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Context.php',
    111         'Handlebars\\Handlebars' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Handlebars.php',
    112         'Handlebars\\HandlebarsString' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/HandlebarsString.php',
    113         'Handlebars\\Helpers' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Helpers.php',
    114         'Handlebars\\Loader' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Loader.php',
    115         'Handlebars\\Loader\\FilesystemLoader' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Loader/FilesystemLoader.php',
    116         'Handlebars\\Loader\\StringLoader' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Loader/StringLoader.php',
    117         'Handlebars\\Parser' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Parser.php',
    118         'Handlebars\\Template' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Template.php',
    119         'Handlebars\\Tokenizer' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Tokenizer.php',
    12098        'Parsedown' => __DIR__ . '/..' . '/erusev/parsedown/Parsedown.php',
    12199        'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
     
    261239        'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
    262240        'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
    263         'WCPOS\\Vendor\\Firebase\\JWT\\BeforeValidException' => __DIR__ . '/../..' . '/vendor_prefixed/vendor/firebase/php-jwt/src/BeforeValidException.php',
    264         'WCPOS\\Vendor\\Firebase\\JWT\\CachedKeySet' => __DIR__ . '/../..' . '/vendor_prefixed/vendor/firebase/php-jwt/src/CachedKeySet.php',
    265         'WCPOS\\Vendor\\Firebase\\JWT\\ExpiredException' => __DIR__ . '/../..' . '/vendor_prefixed/vendor/firebase/php-jwt/src/ExpiredException.php',
    266         'WCPOS\\Vendor\\Firebase\\JWT\\JWK' => __DIR__ . '/../..' . '/vendor_prefixed/vendor/firebase/php-jwt/src/JWK.php',
    267         'WCPOS\\Vendor\\Firebase\\JWT\\JWT' => __DIR__ . '/../..' . '/vendor_prefixed/vendor/firebase/php-jwt/src/JWT.php',
    268         'WCPOS\\Vendor\\Firebase\\JWT\\JWTExceptionWithPayloadInterface' => __DIR__ . '/../..' . '/vendor_prefixed/vendor/firebase/php-jwt/src/JWTExceptionWithPayloadInterface.php',
    269         'WCPOS\\Vendor\\Firebase\\JWT\\Key' => __DIR__ . '/../..' . '/vendor_prefixed/vendor/firebase/php-jwt/src/Key.php',
    270         'WCPOS\\Vendor\\Firebase\\JWT\\SignatureInvalidException' => __DIR__ . '/../..' . '/vendor_prefixed/vendor/firebase/php-jwt/src/SignatureInvalidException.php',
    271241        'WCPOS\\WooCommercePOS\\AJAX' => __DIR__ . '/../..' . '/includes/AJAX.php',
    272242        'WCPOS\\WooCommercePOS\\API' => __DIR__ . '/../..' . '/includes/API.php',
     
    319289        'WCPOS\\WooCommercePOS\\Server' => __DIR__ . '/../..' . '/includes/Server.php',
    320290        'WCPOS\\WooCommercePOS\\Services\\Auth' => __DIR__ . '/../..' . '/includes/Services/Auth.php',
     291        'WCPOS\\WooCommercePOS\\Services\\Cache' => __DIR__ . '/../..' . '/includes/Services/Cache.php',
    321292        'WCPOS\\WooCommercePOS\\Services\\Settings' => __DIR__ . '/../..' . '/includes/Services/Settings.php',
    322293        'WCPOS\\WooCommercePOS\\Templates' => __DIR__ . '/../..' . '/includes/Templates.php',
     
    333304    {
    334305        return \Closure::bind(function () use ($loader) {
    335             $loader->prefixLengthsPsr4 = ComposerStaticInit048927fcd0f6e1bd2ab86d49767e2e77::$prefixLengthsPsr4;
    336             $loader->prefixDirsPsr4 = ComposerStaticInit048927fcd0f6e1bd2ab86d49767e2e77::$prefixDirsPsr4;
    337             $loader->prefixesPsr0 = ComposerStaticInit048927fcd0f6e1bd2ab86d49767e2e77::$prefixesPsr0;
    338             $loader->classMap = ComposerStaticInit048927fcd0f6e1bd2ab86d49767e2e77::$classMap;
     306            $loader->prefixLengthsPsr4 = ComposerStaticInitf0c7d8ce923efae83025b27d0c5bc6c0::$prefixLengthsPsr4;
     307            $loader->prefixDirsPsr4 = ComposerStaticInitf0c7d8ce923efae83025b27d0c5bc6c0::$prefixDirsPsr4;
     308            $loader->prefixesPsr0 = ComposerStaticInitf0c7d8ce923efae83025b27d0c5bc6c0::$prefixesPsr0;
     309            $loader->classMap = ComposerStaticInitf0c7d8ce923efae83025b27d0c5bc6c0::$classMap;
    339310
    340311        }, null, ClassLoader::class);
  • woocommerce-pos/tags/1.6.0/vendor/composer/installed.json

    r3048280 r3102003  
    312312        },
    313313        {
    314             "name": "salesforce/handlebars-php",
    315             "version": "3.0.1",
    316             "version_normalized": "3.0.1.0",
    317             "source": {
    318                 "type": "git",
    319                 "url": "https://github.com/salesforce/handlebars-php.git",
    320                 "reference": "d3a0552d85472249617ef6b56197c844d62d2ac3"
    321             },
    322             "dist": {
    323                 "type": "zip",
    324                 "url": "https://api.github.com/repos/salesforce/handlebars-php/zipball/d3a0552d85472249617ef6b56197c844d62d2ac3",
    325                 "reference": "d3a0552d85472249617ef6b56197c844d62d2ac3",
    326                 "shasum": ""
    327             },
    328             "require": {
    329                 "php": ">=5.4.0"
    330             },
    331             "require-dev": {
    332                 "phpunit/phpunit": "^9"
    333             },
    334             "time": "2023-01-12T16:24:23+00:00",
    335             "type": "library",
    336             "installation-source": "dist",
    337             "autoload": {
    338                 "psr-0": {
    339                     "Handlebars": "src/"
    340                 }
    341             },
    342             "notification-url": "https://packagist.org/downloads/",
    343             "license": [
    344                 "MIT"
    345             ],
    346             "authors": [
    347                 {
    348                     "name": "fzerorubigd",
    349                     "email": "[email protected]"
    350                 },
    351                 {
    352                     "name": "Behrooz Shabani (everplays)",
    353                     "email": "[email protected]"
    354                 },
    355                 {
    356                     "name": "Mardix",
    357                     "homepage": "https://github.com/mardix"
    358                 }
    359             ],
    360             "description": "Handlebars processor for php",
    361             "homepage": "http://www.github.com/salesforce/handlebars-php",
    362             "keywords": [
    363                 "handlebars",
    364                 "mustache",
    365                 "templating"
    366             ],
    367             "support": {
    368                 "issues": "https://github.com/salesforce/handlebars-php/issues",
    369                 "source": "https://github.com/salesforce/handlebars-php/tree/3.0.1"
    370             },
    371             "install-path": "../salesforce/handlebars-php"
    372         },
    373         {
    374314            "name": "symfony/polyfill-ctype",
    375315            "version": "v1.29.0",
  • woocommerce-pos/tags/1.6.0/vendor/composer/installed.php

    r3096869 r3102003  
    22    'root' => array(
    33        'name' => 'wcpos/woocommerce-pos',
    4         'pretty_version' => 'v1.5.1',
    5         'version' => '1.5.1.0',
    6         'reference' => '9eea9f85c69bc5a569f86994f6d03582ed87177e',
     4        'pretty_version' => 'v1.6.0',
     5        'version' => '1.6.0.0',
     6        'reference' => '561cf10f1312c6951c577048394f6f198652652b',
    77        'type' => 'wordpress-plugin',
    88        'install_path' => __DIR__ . '/../../',
     
    5353            ),
    5454        ),
    55         'salesforce/handlebars-php' => array(
    56             'pretty_version' => '3.0.1',
    57             'version' => '3.0.1.0',
    58             'reference' => 'd3a0552d85472249617ef6b56197c844d62d2ac3',
    59             'type' => 'library',
    60             'install_path' => __DIR__ . '/../salesforce/handlebars-php',
    61             'aliases' => array(),
    62             'dev_requirement' => false,
    63         ),
    6455        'symfony/polyfill-ctype' => array(
    6556            'pretty_version' => 'v1.29.0',
     
    9081        ),
    9182        'wcpos/woocommerce-pos' => array(
    92             'pretty_version' => 'v1.5.1',
    93             'version' => '1.5.1.0',
    94             'reference' => '9eea9f85c69bc5a569f86994f6d03582ed87177e',
     83            'pretty_version' => 'v1.6.0',
     84            'version' => '1.6.0.0',
     85            'reference' => '561cf10f1312c6951c577048394f6f198652652b',
    9586            'type' => 'wordpress-plugin',
    9687            'install_path' => __DIR__ . '/../../',
  • woocommerce-pos/tags/1.6.0/woocommerce-pos.php

    r3096869 r3102003  
    44 * Plugin URI:        https://wordpress.org/plugins/woocommerce-pos/
    55 * Description:       A simple front-end for taking WooCommerce orders at the Point of Sale. Requires <a href="http://wordpress.org/plugins/woocommerce/">WooCommerce</a>.
    6  * Version:           1.5.1
     6 * Version:           1.6.0
    77 * Author:            kilbot
    88 * Author URI:        http://wcpos.com
     
    1818 * WC requires at least: 5.3
    1919 *
    20  * @author    Paul Kilmurray <[email protected]>
    21  *
    2220 * @see      http://wcpos.com
    23  * @package   WCPOS\WooCommercePOS
     21 * @package  WCPOS\WooCommercePOS
    2422 */
    2523
     
    2725
    2826// Define plugin constants.
    29 const VERSION     = '1.5.1';
     27const VERSION     = '1.6.0';
    3028const PLUGIN_NAME = 'woocommerce-pos';
    3129const SHORT_NAME  = 'wcpos';
     
    3432\define( __NAMESPACE__ . '\PLUGIN_URL', trailingslashit( plugins_url( basename( plugin_dir_path( __FILE__ ) ), basename( __FILE__ ) ) ) );
    3533
    36 // minimum requirements.
     34// Minimum requirements.
    3735const WC_MIN_VERSION  = '5.3';
    3836const PHP_MIN_VERSION = '7.4';
    3937const MIN_PRO_VERSION = '1.5.0';
    4038
    41 // load .env flags (for development).
     39// Load .env flags (for development).
    4240function load_env( $file ) {
    4341    if ( ! file_exists( $file ) ) {
    44             return;
     42        return;
    4543    }
    4644
     
    4846    foreach ( $lines as $line ) {
    4947        if ( strpos( trim( $line ), '#' ) === 0 ) {
    50                 continue;
     48            continue;
    5149        }
    5250
     
    5654
    5755        if ( ! array_key_exists( $name, $_SERVER ) && ! array_key_exists( $name, $_ENV ) ) {
    58                 putenv( sprintf( '%s=%s', $name, $value ) );
    59                 $_ENV[ $name ] = $value;
     56            putenv( sprintf( '%s=%s', $name, $value ) );
     57            $_ENV[ $name ] = $value;
    6058        }
    6159    }
    6260}
    6361
    64 // Autoloader.
    65 if ( file_exists( __DIR__ . '/vendor/autoload.php' ) ) {
    66     require_once __DIR__ . '/vendor/autoload.php';
     62// Autoload vendor and prefixed libraries.
     63function wcpos_load_autoloaders() {
     64    $vendor_autoload = __DIR__ . '/vendor/autoload.php';
     65    $vendor_prefixed_autoload = __DIR__ . '/vendor_prefixed/autoload.php';
    6766
    68     // Environment variables.
    69     load_env( __DIR__ . '/.env' );
     67    if ( file_exists( $vendor_autoload ) ) {
     68        require_once $vendor_autoload;
     69    }
     70    if ( file_exists( $vendor_prefixed_autoload ) ) {
     71        require_once $vendor_prefixed_autoload;
     72    }
     73}
    7074
    71     // Activate plugin.
    72     new Activator();
     75wcpos_load_autoloaders();
    7376
    74     // Deactivate plugin.
    75     new Deactivator();
    76 } else {
     77// Environment variables.
     78load_env( __DIR__ . '/.env' );
     79
     80// Error handling for autoload failure.
     81if ( ! class_exists( \WCPOS\WooCommercePOS\Activator::class ) || ! class_exists( \WCPOS\WooCommercePOS\Deactivator::class ) ) {
    7782    add_action(
    7883        'admin_notices',
    7984        function (): void {
    8085            ?>
    81         <div class="notice notice-error">
    82             <p><?php esc_html_e( 'The WooCommerce POS plugin failed to load correctly.', 'woocommerce-pos' ); ?></p>
    83         </div>
     86            <div class="notice notice-error">
     87                <p><?php esc_html_e( 'The WooCommerce POS plugin failed to load correctly.', 'woocommerce-pos' ); ?></p>
     88            </div>
    8489            <?php
    8590        }
    8691    );
     92    return; // Exit early if classes are not found.
    8793}
     94
     95// Activate plugin.
     96new Activator();
     97
     98// Deactivate plugin.
     99new Deactivator();
    88100
    89101// Declare HPOS compatible.
  • woocommerce-pos/trunk/includes/API/Customers_Controller.php

    r3096777 r3102003  
    6969         */
    7070        if ( $request->get_param( 'posts_per_page' ) == -1 && $request->get_param( 'fields' ) !== null ) {
    71             return $this->wcpos_get_all_posts( $request->get_param( 'fields' ) );
     71            return $this->wcpos_get_all_posts( $request );
    7272        }
    7373
     
    237237     * Also, querying by role is not as simple as querying by post type.
    238238     *
    239      * @param array $fields Fields to return. Default is ID.
    240      *
    241      * @return array|WP_Error
    242      */
    243     public function wcpos_get_all_posts( array $fields = array() ): array {
     239     * @param WP_REST_Request $request Full details about the request.
     240     *
     241     * @return WP_REST_Response|WP_Error
     242     */
     243    public function wcpos_get_all_posts( $request ) {
    244244        global $wpdb;
    245245
     246        // Start timing execution
     247        $start_time = microtime( true );
     248
     249        $modified_after = $request->get_param( 'modified_after' );
     250        $dates_are_gmt = true;
     251        $fields = $request->get_param( 'fields' );
    246252        $id_with_modified_date = array( 'id', 'date_modified_gmt' ) === $fields;
    247253
    248254        $args = array(
    249             'fields' => array( 'ID', 'registered' ), // Return only the ID and registered date.
     255            'fields' => array( 'ID', 'user_registered' ), // Return only the ID and registered date.
    250256            // 'role__in' => 'all', // @TODO: could be an array of roles, like ['customer', 'cashier']
    251257        );
     
    263269
    264270            if ( $id_with_modified_date ) {
    265                 $last_update_results = $wpdb->get_results(
    266                     "
    267             SELECT user_id, meta_value
    268             FROM $wpdb->usermeta
    269             WHERE meta_key = 'last_update'",
    270                     OBJECT_K
    271                 );
    272 
    273                 foreach ( $last_update_results as $user_id => $meta ) {
    274                     $last_updates[ $user_id ] = $meta->meta_value;
     271                $query = "
     272                    SELECT user_id, meta_value
     273                    FROM $wpdb->usermeta
     274                    WHERE meta_key = 'last_update'
     275                ";
     276
     277                // If modified_after param is set, add the condition to the query
     278                if ( $modified_after ) {
     279                    $modified_after_timestamp = strtotime( $modified_after );
     280                    $query .= $wpdb->prepare( ' AND meta_value > %d', $modified_after_timestamp );
     281                }
     282
     283                $last_update_results = $wpdb->get_results( $query );
     284
     285                // Manually create the associative array of user_id => last_update
     286                foreach ( $last_update_results as $result ) {
     287                    $last_updates[ $result->user_id ] = is_numeric( $result->meta_value ) ? gmdate( 'Y-m-d\TH:i:s', (int) $result->meta_value ) : null;
    275288                }
    276289            }
    277290
    278             // Merge user IDs with their corresponding 'last_updated' values or fallback to user_registered.
    279             $user_data = array_map(
    280                 function ( $user ) use ( $last_updates, $id_with_modified_date ) {
    281                     $user_info = array( 'id' => (int) $user->ID );
    282                     if ( $id_with_modified_date ) {
    283                         if ( isset( $last_updates[ $user->ID ] ) ) {
    284                             $user_info['date_modified_gmt'] = wc_rest_prepare_date_response( $last_updates[ $user->ID ] );
    285                         } else {
    286                             $user_info['date_modified_gmt'] = wc_rest_prepare_date_response( $user->user_registered );
     291            /**
     292             * Performance notes:
     293             * - Using a generator is faster than array_map when dealing with large datasets.
     294             * - If date is in the format 'Y-m-d H:i:s' we just do preg_replace to 'Y-m-d\TH:i:s',
     295             * rather than using wc_rest_prepare_date_response
     296             *
     297             * This resulted in execution time of 10% of the original time.
     298             *
     299             * If the modified_after param is set, we don't need to loop through the entire user list.
     300             * The last_update_results array will only contain the users that have been modified after the given date.
     301             * We just need to check they are valid user ids, this sucks, but there could be orphaned last_update meta values.
     302             */
     303            $formatted_results = array();
     304
     305            if ( $modified_after ) {
     306                foreach ( $users as $user ) {
     307                    if ( isset( $last_updates[ $user->ID ] ) ) {
     308                        $user_info = array( 'id' => (int) $user->ID );
     309                        if ( $id_with_modified_date ) {
     310                            $user_info['date_modified_gmt'] = $last_updates[ $user->ID ];
    287311                        }
     312                        $formatted_results[] = $user_info;
    288313                    }
    289                     return $user_info;
    290                 },
    291                 $users
    292             );
    293 
    294             return $user_data;
     314                }
     315            } else {
     316                function format_results( $users, $last_updates, $id_with_modified_date ) {
     317                    foreach ( $users as $user ) {
     318                        $user_info = array( 'id' => (int) $user->ID );
     319                        if ( $id_with_modified_date ) {
     320                            if ( isset( $last_updates[ $user->ID ] ) && ! empty( $last_updates[ $user->ID ] ) ) {
     321                                $user_info['date_modified_gmt'] = $last_updates[ $user->ID ];
     322                            } else {
     323                                $user_info['date_modified_gmt'] = null; // users can have null date_modified_gmt
     324                            }
     325                        }
     326                        yield $user_info;
     327                    }
     328                }
     329
     330                $formatted_results = iterator_to_array( format_results( $users, $last_updates, $id_with_modified_date ) );
     331            }
     332
     333            // Get the total number of orders for the given criteria.
     334            $total = count( $formatted_results );
     335
     336            // Collect execution time and server load.
     337            $execution_time = microtime( true ) - $start_time;
     338            $execution_time_ms = number_format( $execution_time * 1000, 2 );
     339            $server_load = sys_getloadavg();
     340
     341            $response = rest_ensure_response( $formatted_results );
     342            $response->header( 'X-WP-Total', (int) $total );
     343            $response->header( 'X-Execution-Time', $execution_time_ms . ' ms' );
     344            $response->header( 'X-Server-Load', json_encode( $server_load ) );
     345
     346            return $response;
    295347        } catch ( Exception $e ) {
    296348            Logger::log( 'Error fetching order IDs: ' . $e->getMessage() );
  • woocommerce-pos/trunk/includes/API/Orders_Controller.php

    r3096777 r3102003  
    2020use WP_REST_Server;
    2121use Automattic\WooCommerce\Utilities\OrderUtil;
     22use WCPOS\WooCommercePOS\Services\Cache;
    2223use WP_Error;
    2324
     
    102103         */
    103104        if ( $request->get_param( 'posts_per_page' ) == -1 && $request->get_param( 'fields' ) !== null ) {
    104             return $this->wcpos_get_all_posts( $request->get_param( 'fields' ) );
     105            return $this->wcpos_get_all_posts( $request );
    105106        }
    106107
     
    194195    /**
    195196     * Create a single order.
     197     * - Validate billing email.
     198     * - Do a sanity check on the UUID, if the internet connection is bad, several requests can be made with the same UUID.
    196199     *
    197200     * @param WP_REST_Request $request Full details about the request.
     
    200203     */
    201204    public function create_item( $request ) {
     205        // check if the UUID is already in use.
     206        if ( isset( $request['meta_data'] ) && is_array( $request['meta_data'] ) ) {
     207            foreach ( $request['meta_data'] as $meta ) {
     208                if ( $meta['key'] === '_woocommerce_pos_uuid' ) {
     209                    $uuid = $meta['value'];
     210                    $ids = $this->get_order_ids_by_uuid( $uuid );
     211
     212                    /**
     213                     * If the UUID is already in use, and there is only one order with that UUID, return the existing order.
     214                     * This can happen if the internet connection is bad and the request is made several times.
     215                     *
     216                     * @NOTE: This means that $request data is lost, but we can't update existing order because it has resource ids now.
     217                     * The alternative would be to update the existing order, but that would require a lot of extra work.
     218                     * Or return an error, which would be a bad user experience.
     219                     */
     220                    if ( count( $ids ) === 1 ) {
     221                        Logger::log( 'UUID already in use, return existing order.', $ids[0] );
     222
     223                        // Create a new WP_REST_Request object for the GET request.
     224                        $get_request = new WP_REST_Request( 'GET', $this->namespace . '/' . $this->rest_base . '/' . $ids[0] );
     225                        $get_request->set_param( 'id', $ids[0] );
     226
     227                        return $this->get_item( $get_request );
     228                    }
     229                    if ( count( $ids ) > 1 ) {
     230                        Logger::log( 'UUID already in use for multiple orders. This should not happen.', $ids );
     231                        return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'UUID already in use.', 'woocommerce' ), array( 'status' => 400 ) );
     232                    }
     233                }
     234            }
     235        }
     236
    202237        $valid_email = $this->wcpos_validate_billing_email( $request );
    203238        if ( is_wp_error( $valid_email ) ) {
     
    321356     */
    322357    public function wcpos_validate_billing_email( WP_REST_Request $request ) {
    323         // Your custom validation logic for the request data
    324358        $billing = $request['billing'] ?? null;
    325359        $email   = \is_array( $billing ) ? ( $billing['email'] ?? null ) : null;
     
    637671     * Returns array of all order ids.
    638672     *
    639      * @param array $fields Fields to return.
    640      *
    641      * @return array|WP_Error
    642      */
    643     public function wcpos_get_all_posts( array $fields = array() ): array {
     673     * @param WP_REST_Request $request Full details about the request.
     674     *
     675     * @return WP_REST_Response|WP_Error
     676     */
     677    public function wcpos_get_all_posts( $request ) {
    644678        global $wpdb;
    645679
     680        // Start timing execution.
     681        $start_time = microtime( true );
     682
     683        $modified_after = $request->get_param( 'modified_after' );
     684        $dates_are_gmt = true; // Dates are always in GMT.
     685        $fields = $request->get_param( 'fields' );
    646686        $id_with_modified_date = array( 'id', 'date_modified_gmt' ) === $fields;
    647687
     
    662702            $sql .= ' AND status IN (' . implode( ',', $statuses ) . ')';
    663703
     704            // Add modified_after condition if provided.
     705            if ( $modified_after ) {
     706                $modified_after_date = date( 'Y-m-d H:i:s', strtotime( $modified_after ) );
     707                $sql .= $wpdb->prepare( ' AND date_updated_gmt > %s', $modified_after_date );
     708            }
     709
    664710            // Order by date_created_gmt DESC to maintain order consistency.
    665711            $sql .= " ORDER BY {$wpdb->prefix}wc_orders.date_created_gmt DESC";
     
    669715            $sql .= ' AND post_status IN (' . implode( ',', $statuses ) . ')';
    670716
     717            // Add modified_after condition if provided.
     718            if ( $modified_after ) {
     719                $modified_after_date = date( 'Y-m-d H:i:s', strtotime( $modified_after ) );
     720                $sql .= $wpdb->prepare( ' AND post_modified_gmt > %s', $modified_after_date );
     721            }
     722
    671723            // Order by post_date DESC to maintain order consistency.
    672724            $sql .= " ORDER BY {$wpdb->posts}.post_date DESC";
     
    674726
    675727        try {
    676             $results = $wpdb->get_results( $sql );
    677             return $this->wcpos_format_all_posts_response( $results );
     728            $results = $wpdb->get_results( $sql, ARRAY_A );
     729            $formatted_results = $this->wcpos_format_all_posts_response( $results );
     730
     731            // Get the total number of orders for the given criteria.
     732            $total = count( $formatted_results );
     733
     734            // Collect execution time and server load.
     735            $execution_time = microtime( true ) - $start_time;
     736            $execution_time_ms = number_format( $execution_time * 1000, 2 );
     737            $server_load = sys_getloadavg();
     738
     739            $response = rest_ensure_response( $formatted_results );
     740            $response->header( 'X-WP-Total', (int) $total );
     741            $response->header( 'X-Execution-Time', $execution_time_ms . ' ms' );
     742            $response->header( 'X-Server-Load', json_encode( $server_load ) );
     743
     744            return $response;
    678745        } catch ( Exception $e ) {
    679746            Logger::log( 'Error fetching order data: ' . $e->getMessage() );
  • woocommerce-pos/trunk/includes/API/Product_Categories_Controller.php

    r3096777 r3102003  
    5757         */
    5858        if ( $request->get_param( 'posts_per_page' ) == -1 && $request->get_param( 'fields' ) !== null ) {
    59             return $this->wcpos_get_all_posts( $request->get_param( 'fields' ) );
     59            return $this->wcpos_get_all_posts( $request );
    6060        }
    6161
     
    142142     * Returns array of all product category ids.
    143143     *
    144      * @param array $fields
     144     * @param WP_REST_Request $request Full details about the request.
    145145     *
    146      * @return array|WP_Error
     146     * @return WP_REST_Response|WP_Error
    147147     */
    148     public function wcpos_get_all_posts( array $fields = array() ): array {
     148    public function wcpos_get_all_posts( $request ) {
     149        // Start timing execution.
     150        $start_time = microtime( true );
     151        $modified_after = $request->get_param( 'modified_after' );
     152
    149153        $args = array(
    150154            'taxonomy'   => 'product_cat',
     
    154158
    155159        try {
    156             $results = get_terms( $args );
     160            /**
     161             * @TODO - terms don't have a modified date, it would be good to add a term_meta for last_update
     162             * - ideally WooCommerce would provide a modified_after filter for terms
     163             * - for now we'll just return empty for modified terms
     164             */
     165            $results = $modified_after ? array() : get_terms( $args );
    157166
    158167            // Format the response.
    159             return array_map(
    160                 function ( $item ) {
    161                     return array( 'id' => (int) $item );
     168            $formatted_results = array_map(
     169                function ( $id ) {
     170                    return array( 'id' => (int) $id );
    162171                },
    163172                $results
    164173            );
     174
     175            // Get the total number of orders for the given criteria.
     176            $total = count( $formatted_results );
     177
     178            // Collect execution time and server load.
     179            $execution_time = microtime( true ) - $start_time;
     180            $execution_time_ms = number_format( $execution_time * 1000, 2 );
     181            $server_load = sys_getloadavg();
     182
     183            $response = rest_ensure_response( $formatted_results );
     184            $response->header( 'X-WP-Total', (int) $total );
     185            $response->header( 'X-Execution-Time', $execution_time_ms . ' ms' );
     186            $response->header( 'X-Server-Load', json_encode( $server_load ) );
     187
     188            return $response;
    165189        } catch ( Exception $e ) {
    166190            Logger::log( 'Error fetching product category IDs: ' . $e->getMessage() );
  • woocommerce-pos/trunk/includes/API/Product_Tags_Controller.php

    r3096777 r3102003  
    5757         */
    5858        if ( $request->get_param( 'posts_per_page' ) == -1 && $request->get_param( 'fields' ) !== null ) {
    59             return $this->wcpos_get_all_posts( $request->get_param( 'fields' ) );
     59            return $this->wcpos_get_all_posts( $request );
    6060        }
    6161
     
    142142     * Returns array of all product tag ids.
    143143     *
    144      * @param array $fields
     144     * @param WP_REST_Request $request Full details about the request.
    145145     *
    146      * @return array|WP_Error
     146     * @return WP_REST_Response|WP_Error
    147147     */
    148     public function wcpos_get_all_posts( array $fields = array() ): array {
     148    public function wcpos_get_all_posts( $request ): array {
     149        // Start timing execution.
     150        $start_time = microtime( true );
     151        $modified_after = $request->get_param( 'modified_after' );
     152
    149153        $args = array(
    150154            'taxonomy'   => 'product_tag',
     
    154158
    155159        try {
    156             $results = get_terms( $args );
     160            /**
     161             * @TODO - terms don't have a modified date, it would be good to add a term_meta for last_update
     162             * - ideally WooCommerce would provide a modified_after filter for terms
     163             * - for now we'll just return empty for modified terms
     164             */
     165            $results = $modified_after ? array() : get_terms( $args );
    157166
    158167            // Format the response.
    159             return array_map(
    160                 function ( $item ) {
    161                     return array( 'id' => (int) $item );
     168            $formatted_results = array_map(
     169                function ( $id ) {
     170                    return array( 'id' => (int) $id );
    162171                },
    163172                $results
    164173            );
     174
     175            // Get the total number of orders for the given criteria.
     176            $total = count( $formatted_results );
     177
     178            // Collect execution time and server load.
     179            $execution_time = microtime( true ) - $start_time;
     180            $execution_time_ms = number_format( $execution_time * 1000, 2 );
     181            $server_load = sys_getloadavg();
     182
     183            $response = rest_ensure_response( $formatted_results );
     184            $response->header( 'X-WP-Total', (int) $total );
     185            $response->header( 'X-Execution-Time', $execution_time_ms . ' ms' );
     186            $response->header( 'X-Server-Load', json_encode( $server_load ) );
     187
     188            return $response;
    165189        } catch ( Exception $e ) {
    166190            Logger::log( 'Error fetching product tags IDs: ' . $e->getMessage() );
  • woocommerce-pos/trunk/includes/API/Product_Variations_Controller.php

    r3096777 r3102003  
    6666         */
    6767        if ( $request->get_param( 'posts_per_page' ) == -1 && $request->get_param( 'fields' ) !== null ) {
    68             return $this->wcpos_get_all_posts( $request->get_param( 'fields' ) );
     68            return $this->wcpos_get_all_posts( $request );
    6969        }
    7070
     
    367367     * Returns array of all product ids, name.
    368368     *
    369      * @param array $fields
    370      *
    371      * @return array|WP_Error
    372      */
    373     public function wcpos_get_all_posts( array $fields = array() ): array {
     369     * @param WP_REST_Request $request Full details about the request.
     370     *
     371     * @return WP_REST_Response|WP_Error
     372     */
     373    public function wcpos_get_all_posts( $request ) {
    374374        global $wpdb;
    375375
     376        // Start timing execution.
     377        $start_time = microtime( true );
     378
     379        $modified_after = $request->get_param( 'modified_after' );
     380        $fields = $request->get_param( 'fields' );
    376381        $parent_id = (int) $this->wcpos_request->get_param( 'product_id' );
    377382        $id_with_modified_date = array( 'id', 'date_modified_gmt' ) === $fields;
     
    391396        }
    392397
     398        // Add modified_after condition if provided.
     399        if ( $modified_after ) {
     400            $modified_after_date = date( 'Y-m-d H:i:s', strtotime( $modified_after ) );
     401            $sql .= $wpdb->prepare( ' AND post_modified_gmt > %s', $modified_after_date );
     402        }
     403
    393404        // Dynamically add the post_parent clause if a parent ID is provided.
    394405        if ( $parent_id ) {
     
    398409        try {
    399410            // Execute the query.
    400             $results = $wpdb->get_results( $sql );
    401             // Format and return the results.
    402             return $this->wcpos_format_all_posts_response( $results );
     411            $results = $wpdb->get_results( $sql, ARRAY_A );
     412            $formatted_results = $this->wcpos_format_all_posts_response( $results );
     413
     414            // Get the total number of orders for the given criteria.
     415            $total = count( $formatted_results );
     416
     417            // Collect execution time and server load.
     418            $execution_time = microtime( true ) - $start_time;
     419            $execution_time_ms = number_format( $execution_time * 1000, 2 );
     420            $server_load = sys_getloadavg();
     421
     422            $response = rest_ensure_response( $formatted_results );
     423            $response->header( 'X-WP-Total', (int) $total );
     424            $response->header( 'X-Execution-Time', $execution_time_ms . ' ms' );
     425            $response->header( 'X-Server-Load', json_encode( $server_load ) );
     426
     427            return $response;
    403428        } catch ( Exception $e ) {
    404429            Logger::log( 'Error fetching product variation IDs: ' . $e->getMessage() );
  • woocommerce-pos/trunk/includes/API/Products_Controller.php

    r3096777 r3102003  
    7676         */
    7777        if ( $request->get_param( 'posts_per_page' ) == -1 && $request->get_param( 'fields' ) !== null ) {
    78             return $this->wcpos_get_all_posts( $request->get_param( 'fields' ) );
     78            return $this->wcpos_get_all_posts( $request );
    7979        }
    8080
     
    430430     * Returns array of all product ids, name.
    431431     *
    432      * @param array $fields Fields to return.
    433      *
    434      * @return array|WP_Error
    435      */
    436     public function wcpos_get_all_posts( array $fields = array() ): array {
     432     * @param WP_REST_Request $request Full details about the request.
     433     *
     434     * @return WP_REST_Response|WP_Error
     435     */
     436    public function wcpos_get_all_posts( $request ) {
    437437        global $wpdb;
    438438
     439        // Start timing execution.
     440        $start_time = microtime( true );
     441
     442        $modified_after = $request->get_param( 'modified_after' );
     443        $dates_are_gmt = true; // Dates are always in GMT.
     444        $fields = $request->get_param( 'fields' );
    439445        $id_with_modified_date = array( 'id', 'date_modified_gmt' ) === $fields;
    440446        $select_fields = $id_with_modified_date ? 'ID as id, post_modified_gmt as date_modified_gmt' : 'ID as id';
     
    451457        }
    452458
     459        // Add modified_after condition if provided.
     460        if ( $modified_after ) {
     461            $modified_after_date = date( 'Y-m-d H:i:s', strtotime( $modified_after ) );
     462            $sql .= $wpdb->prepare( ' AND post_modified_gmt > %s', $modified_after_date );
     463        }
     464
    453465        // Order by post_date DESC to maintain order consistency.
    454466        $sql .= " ORDER BY {$wpdb->posts}.post_date DESC";
    455467
    456468        try {
    457             $results = $wpdb->get_results( $sql );
    458             return $this->wcpos_format_all_posts_response( $results );
     469            $results = $wpdb->get_results( $sql, ARRAY_A );
     470            $formatted_results = $this->wcpos_format_all_posts_response( $results );
     471
     472            // Get the total number of orders for the given criteria.
     473            $total = count( $formatted_results );
     474
     475            // Collect execution time and server load.
     476            $execution_time = microtime( true ) - $start_time;
     477            $execution_time_ms = number_format( $execution_time * 1000, 2 );
     478            $server_load = sys_getloadavg();
     479
     480            $response = rest_ensure_response( $formatted_results );
     481            $response->header( 'X-WP-Total', (int) $total );
     482            $response->header( 'X-Execution-Time', $execution_time_ms . ' ms' );
     483            $response->header( 'X-Server-Load', json_encode( $server_load ) );
     484
     485            return $response;
    459486        } catch ( Exception $e ) {
    460487            Logger::log( 'Error fetching product data: ' . $e->getMessage() );
  • woocommerce-pos/trunk/includes/API/Taxes_Controller.php

    r3096777 r3102003  
    99}
    1010
     11use Exception;
    1112use WC_REST_Taxes_Controller;
     13use WCPOS\WooCommercePOS\Logger;
    1214use WP_REST_Request;
     15use WP_REST_Response;
    1316
    1417/**
     
    5457         */
    5558        if ( $request->get_param( 'posts_per_page' ) == -1 && $request->get_param( 'fields' ) !== null ) {
    56             return $this->wcpos_get_all_posts( $request->get_param( 'fields' ) );
     59            return $this->wcpos_get_all_posts( $request );
    5760        }
    5861
     
    207210     * Returns array of all tax_rate ids.
    208211     *
    209      * @param array $fields
    210      *
    211      * @return array|WP_Error
    212      */
    213     public function wcpos_get_all_posts( array $fields = array() ): array {
     212     * @param WP_REST_Request $request Full details about the request.
     213     *
     214     * @return WP_REST_Response|WP_Error
     215     */
     216    public function wcpos_get_all_posts( $request ) {
    214217        global $wpdb;
    215218
    216         $results = $wpdb->get_results(
    217             '
    218             SELECT tax_rate_id as id FROM ' . $wpdb->prefix . 'woocommerce_tax_rates
    219         ',
    220             ARRAY_A
    221         );
    222 
    223         // Format the response.
    224         return array_map(
    225             function ( $item ) {
    226                 return array( 'id' => (int) $item['id'] );
    227             },
    228             $results
    229         );
     219        // Start timing execution.
     220        $start_time = microtime( true );
     221        $modified_after = $request->get_param( 'modified_after' );
     222
     223        try {
     224            /**
     225             * @TODO - taxes doen't have a modified date, so we can't filter by modified_after
     226             * - ideally WooCommerce would provide a modified_after filter for terms
     227             * - for now we'll just return empty for modified terms
     228             */
     229            $results = $modified_after ? array() : $wpdb->get_results(
     230                '
     231                SELECT tax_rate_id as id FROM ' . $wpdb->prefix . 'woocommerce_tax_rates
     232            ',
     233                ARRAY_A
     234            );
     235
     236            // Format the response.
     237            $formatted_results = array_map(
     238                function ( $item ) {
     239                    return array( 'id' => (int) $item['id'] );
     240                },
     241                $results
     242            );
     243
     244            // Get the total number of orders for the given criteria.
     245            $total = count( $formatted_results );
     246
     247            // Collect execution time and server load.
     248            $execution_time = microtime( true ) - $start_time;
     249            $execution_time_ms = number_format( $execution_time * 1000, 2 );
     250            $server_load = sys_getloadavg();
     251
     252            $response = rest_ensure_response( $formatted_results );
     253            $response->header( 'X-WP-Total', (int) $total );
     254            $response->header( 'X-Execution-Time', $execution_time_ms . ' ms' );
     255            $response->header( 'X-Server-Load', json_encode( $server_load ) );
     256
     257            return $response;
     258        } catch ( Exception $e ) {
     259            Logger::log( 'Error fetching product tax rate IDs: ' . $e->getMessage() );
     260
     261            return new \WP_Error(
     262                'woocommerce_pos_rest_cannot_fetch',
     263                'Error fetching product tax rate IDs.',
     264                array( 'status' => 500 )
     265            );
     266        }
    230267    }
    231268}
  • woocommerce-pos/trunk/includes/API/Traits/Uuid_Handler.php

    r3042209 r3102003  
    197197
    198198    /**
     199     *
     200     */
     201    private function get_order_ids_by_uuid( string $uuid ) {
     202        global $wpdb;
     203
     204        if ( class_exists( OrderUtil::class ) && OrderUtil::custom_orders_table_usage_is_enabled() ) {
     205            // Check the orders meta table.
     206            $result = $wpdb->get_col(
     207                $wpdb->prepare(
     208                    "SELECT order_id FROM {$wpdb->prefix}wc_orders_meta WHERE meta_key = '_woocommerce_pos_uuid' AND meta_value = %s",
     209                    $uuid
     210                )
     211            );
     212        } else {
     213            // Check the postmeta table.
     214            $result = $wpdb->get_col(
     215                $wpdb->prepare(
     216                    "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_woocommerce_pos_uuid' AND meta_value = %s",
     217                    $uuid
     218                )
     219            );
     220        }
     221
     222        return $result;
     223    }
     224
     225    /**
    199226     * Check if the given UUID already exists for any user.
    200227     *
  • woocommerce-pos/trunk/includes/API/Traits/WCPOS_REST_API.php

    r3096777 r3102003  
    1515     */
    1616    public function wcpos_format_all_posts_response( $results ) {
    17         $formatted_results = array_map(
    18             function ( $result ) {
    19                 // Initialize the formatted result as an associative array.
    20                 $formatted_result = array(
    21                     'id' => (int) $result->id, // Cast ID to integer for consistency.
    22                 );
     17        /**
     18         * Performance notes:
     19         * - Using a generator is faster than array_map when dealing with large datasets.
     20         * - If date is in the format 'Y-m-d H:i:s' we just do preg_replace to 'Y-m-d\TH:i:s', rather than using wc_rest_prepare_date_response
     21         *
     22         * This resulted in execution time of 10% of the original time.
     23         */
     24        function format_results( $results ) {
     25            foreach ( $results as $result ) {
     26                $result['id'] = (int) $result['id'];
    2327
    24                 // Check if post_modified_gmt exists and is not null, then set date_modified_gmt.
    25                 if ( isset( $result->date_modified_gmt ) && ! empty( $result->date_modified_gmt ) ) {
    26                     $formatted_result['date_modified_gmt'] = wc_rest_prepare_date_response( $result->date_modified_gmt );
     28                if ( isset( $result['date_modified_gmt'] ) ) {
     29                    if ( preg_match( '/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/', $result['date_modified_gmt'] ) ) {
     30                            $result['date_modified_gmt'] = preg_replace( '/(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2})/', '$1T$2', $result['date_modified_gmt'] );
     31                    } else {
     32                            $result['date_modified_gmt'] = wc_rest_prepare_date_response( $result['date_modified_gmt'] );
     33                    }
    2734                }
    2835
    29                 return $formatted_result;
    30             },
    31             $results
    32         );
     36                yield $result;
     37            }
     38        }
    3339
    34         return $formatted_results;
     40        return iterator_to_array( format_results( $results ) );
    3541    }
    3642
  • woocommerce-pos/trunk/includes/Templates.php

    r3042209 r3102003  
    150150     */
    151151    public function order_received_url( string $order_received_url, WC_Abstract_Order $order ): string {
     152        global $wp;
     153
    152154        // check is pos
    153         if ( ! woocommerce_pos_request() ) {
     155        if ( ! woocommerce_pos_request() || ! isset( $wp->query_vars['order-pay'] ) ) {
    154156            return $order_received_url;
    155157        }
  • woocommerce-pos/trunk/includes/Templates/Frontend.php

    r3096777 r3102003  
    1313use const WCPOS\WooCommercePOS\SHORT_NAME;
    1414use const WCPOS\WooCommercePOS\VERSION;
     15use const WCPOS\WooCommercePOS\PLUGIN_URL;
    1516
    1617/**
     
    8788        $development    = isset( $_ENV['DEVELOPMENT'] ) && $_ENV['DEVELOPMENT'];
    8889        $user           = wp_get_current_user();
    89         $github_url     = 'https://cdn.jsdelivr.net/gh/wcpos/web-bundle@1.5/';
     90        $github_url     = 'https://cdn.jsdelivr.net/gh/wcpos/web-bundle@1.6/';
    9091        $auth_service   = Auth::instance();
    9192        $stores         = array_map(
     
    149150        $dev_bundle    = 'http://localhost:8081/index.bundle?platform=web&dev=true&hot=false';
    150151
    151         // getScript helper and initialProps
     152        /**
     153         * Add path to worker scripts
     154         */
     155        $idbWorker = PLUGIN_URL . 'assets/js/indexeddb.worker.js';
     156
     157        /**
     158         * getScript helper and initialProps
     159         */
    152160        echo "<script>
    153161    function getScript(source, callback) {
     
    169177    }
    170178
    171     var initialProps={$initial_props};
     179    var idbWorker = '{$idbWorker}';
     180    var initialProps = {$initial_props};
    172181</script>" . "\n";
    173182
     183        /**
     184         * The actual app bundle
     185         */
    174186        if ( $development ) {
    175187            // Development
  • woocommerce-pos/trunk/includes/Templates/Login.php

    r3020971 r3102003  
    7979        echo '<script>
    8080    (function() {
    81         // Parse the order JSON from PHP
    8281        var credentials = ' . $credentials . "
    8382
  • woocommerce-pos/trunk/readme.txt

    r3096870 r3102003  
    44Requires at least: 5.6
    55Tested up to: 6.5
    6 Stable tag: 1.5.1
     6Stable tag: 1.6.0
    77License: GPL-3.0
    88License URI: http://www.gnu.org/licenses/gpl-3.0.html
     
    2929* Add new customers or checkout via Guest account
    3030* Add miscellaneous products to cart, ie: products not in WooCommerce
     31* Live chat support within the application
    3132* **Pro:** Use any WooCommerce gateway
    3233* **Pro:** Create multiple POS Stores
     
    8081== Changelog ==
    8182
     83= 1.6.0 - 2024/06/12 =
     84* Improved: Performance for large stores
     85* Added: Log screen for insights into the POS performance and events
     86* Added: Cart setting to enable/disable show receipt after checkout
     87* Added: Cart setting to enable/disable auto-print receipt after checkout
     88* Fix: Prevent order create duplication from the POS
     89* Fix: Cart subtotal showing tax when tax display is not enabled
     90
    8291= 1.5.1 - 2024/06/03 =
    8392* Fix: "Sorry, you cannot list resources." error for cashier role
    84 
    8593
    8694= 1.5.0 - 2024/06/03 =
  • woocommerce-pos/trunk/vendor/autoload.php

    r3096869 r3102003  
    2323require_once __DIR__ . '/composer/autoload_real.php';
    2424
    25 return ComposerAutoloaderInit048927fcd0f6e1bd2ab86d49767e2e77::getLoader();
     25return ComposerAutoloaderInitf0c7d8ce923efae83025b27d0c5bc6c0::getLoader();
  • woocommerce-pos/trunk/vendor/composer/autoload_classmap.php

    r3096777 r3102003  
    2525    'CURLStringFile' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php',
    2626    'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
    27     'Handlebars\\Autoloader' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Autoloader.php',
    28     'Handlebars\\Cache' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Cache.php',
    29     'Handlebars\\Cache\\APC' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Cache/APC.php',
    30     'Handlebars\\Cache\\Disk' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Cache/Disk.php',
    31     'Handlebars\\Cache\\Dummy' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Cache/Dummy.php',
    32     'Handlebars\\Context' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Context.php',
    33     'Handlebars\\Handlebars' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Handlebars.php',
    34     'Handlebars\\HandlebarsString' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/HandlebarsString.php',
    35     'Handlebars\\Helpers' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Helpers.php',
    36     'Handlebars\\Loader' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Loader.php',
    37     'Handlebars\\Loader\\FilesystemLoader' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Loader/FilesystemLoader.php',
    38     'Handlebars\\Loader\\StringLoader' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Loader/StringLoader.php',
    39     'Handlebars\\Parser' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Parser.php',
    40     'Handlebars\\Template' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Template.php',
    41     'Handlebars\\Tokenizer' => $vendorDir . '/salesforce/handlebars-php/src/Handlebars/Tokenizer.php',
    4227    'Parsedown' => $vendorDir . '/erusev/parsedown/Parsedown.php',
    4328    'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
     
    183168    'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
    184169    'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
    185     'WCPOS\\Vendor\\Firebase\\JWT\\BeforeValidException' => $baseDir . '/vendor_prefixed/vendor/firebase/php-jwt/src/BeforeValidException.php',
    186     'WCPOS\\Vendor\\Firebase\\JWT\\CachedKeySet' => $baseDir . '/vendor_prefixed/vendor/firebase/php-jwt/src/CachedKeySet.php',
    187     'WCPOS\\Vendor\\Firebase\\JWT\\ExpiredException' => $baseDir . '/vendor_prefixed/vendor/firebase/php-jwt/src/ExpiredException.php',
    188     'WCPOS\\Vendor\\Firebase\\JWT\\JWK' => $baseDir . '/vendor_prefixed/vendor/firebase/php-jwt/src/JWK.php',
    189     'WCPOS\\Vendor\\Firebase\\JWT\\JWT' => $baseDir . '/vendor_prefixed/vendor/firebase/php-jwt/src/JWT.php',
    190     'WCPOS\\Vendor\\Firebase\\JWT\\JWTExceptionWithPayloadInterface' => $baseDir . '/vendor_prefixed/vendor/firebase/php-jwt/src/JWTExceptionWithPayloadInterface.php',
    191     'WCPOS\\Vendor\\Firebase\\JWT\\Key' => $baseDir . '/vendor_prefixed/vendor/firebase/php-jwt/src/Key.php',
    192     'WCPOS\\Vendor\\Firebase\\JWT\\SignatureInvalidException' => $baseDir . '/vendor_prefixed/vendor/firebase/php-jwt/src/SignatureInvalidException.php',
    193170    'WCPOS\\WooCommercePOS\\AJAX' => $baseDir . '/includes/AJAX.php',
    194171    'WCPOS\\WooCommercePOS\\API' => $baseDir . '/includes/API.php',
     
    241218    'WCPOS\\WooCommercePOS\\Server' => $baseDir . '/includes/Server.php',
    242219    'WCPOS\\WooCommercePOS\\Services\\Auth' => $baseDir . '/includes/Services/Auth.php',
     220    'WCPOS\\WooCommercePOS\\Services\\Cache' => $baseDir . '/includes/Services/Cache.php',
    243221    'WCPOS\\WooCommercePOS\\Services\\Settings' => $baseDir . '/includes/Services/Settings.php',
    244222    'WCPOS\\WooCommercePOS\\Templates' => $baseDir . '/includes/Templates.php',
  • woocommerce-pos/trunk/vendor/composer/autoload_namespaces.php

    r3020668 r3102003  
    88return array(
    99    'Parsedown' => array($vendorDir . '/erusev/parsedown'),
    10     'Handlebars' => array($vendorDir . '/salesforce/handlebars-php/src'),
    1110);
  • woocommerce-pos/trunk/vendor/composer/autoload_real.php

    r3096869 r3102003  
    33// autoload_real.php @generated by Composer
    44
    5 class ComposerAutoloaderInit048927fcd0f6e1bd2ab86d49767e2e77
     5class ComposerAutoloaderInitf0c7d8ce923efae83025b27d0c5bc6c0
    66{
    77    private static $loader;
     
    2323        }
    2424
    25         spl_autoload_register(array('ComposerAutoloaderInit048927fcd0f6e1bd2ab86d49767e2e77', 'loadClassLoader'), true, true);
     25        spl_autoload_register(array('ComposerAutoloaderInitf0c7d8ce923efae83025b27d0c5bc6c0', 'loadClassLoader'), true, true);
    2626        self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
    27         spl_autoload_unregister(array('ComposerAutoloaderInit048927fcd0f6e1bd2ab86d49767e2e77', 'loadClassLoader'));
     27        spl_autoload_unregister(array('ComposerAutoloaderInitf0c7d8ce923efae83025b27d0c5bc6c0', 'loadClassLoader'));
    2828
    2929        require __DIR__ . '/autoload_static.php';
    30         call_user_func(\Composer\Autoload\ComposerStaticInit048927fcd0f6e1bd2ab86d49767e2e77::getInitializer($loader));
     30        call_user_func(\Composer\Autoload\ComposerStaticInitf0c7d8ce923efae83025b27d0c5bc6c0::getInitializer($loader));
    3131
    3232        $loader->register(true);
    3333
    34         $filesToLoad = \Composer\Autoload\ComposerStaticInit048927fcd0f6e1bd2ab86d49767e2e77::$files;
     34        $filesToLoad = \Composer\Autoload\ComposerStaticInitf0c7d8ce923efae83025b27d0c5bc6c0::$files;
    3535        $requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
    3636            if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
  • woocommerce-pos/trunk/vendor/composer/autoload_static.php

    r3096869 r3102003  
    55namespace Composer\Autoload;
    66
    7 class ComposerStaticInit048927fcd0f6e1bd2ab86d49767e2e77
     7class ComposerStaticInitf0c7d8ce923efae83025b27d0c5bc6c0
    88{
    99    public static $files = array (
     
    7373            array (
    7474                0 => __DIR__ . '/..' . '/erusev/parsedown',
    75             ),
    76         ),
    77         'H' =>
    78         array (
    79             'Handlebars' =>
    80             array (
    81                 0 => __DIR__ . '/..' . '/salesforce/handlebars-php/src',
    8275            ),
    8376        ),
     
    10396        'CURLStringFile' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php',
    10497        'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
    105         'Handlebars\\Autoloader' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Autoloader.php',
    106         'Handlebars\\Cache' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Cache.php',
    107         'Handlebars\\Cache\\APC' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Cache/APC.php',
    108         'Handlebars\\Cache\\Disk' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Cache/Disk.php',
    109         'Handlebars\\Cache\\Dummy' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Cache/Dummy.php',
    110         'Handlebars\\Context' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Context.php',
    111         'Handlebars\\Handlebars' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Handlebars.php',
    112         'Handlebars\\HandlebarsString' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/HandlebarsString.php',
    113         'Handlebars\\Helpers' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Helpers.php',
    114         'Handlebars\\Loader' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Loader.php',
    115         'Handlebars\\Loader\\FilesystemLoader' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Loader/FilesystemLoader.php',
    116         'Handlebars\\Loader\\StringLoader' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Loader/StringLoader.php',
    117         'Handlebars\\Parser' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Parser.php',
    118         'Handlebars\\Template' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Template.php',
    119         'Handlebars\\Tokenizer' => __DIR__ . '/..' . '/salesforce/handlebars-php/src/Handlebars/Tokenizer.php',
    12098        'Parsedown' => __DIR__ . '/..' . '/erusev/parsedown/Parsedown.php',
    12199        'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
     
    261239        'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
    262240        'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
    263         'WCPOS\\Vendor\\Firebase\\JWT\\BeforeValidException' => __DIR__ . '/../..' . '/vendor_prefixed/vendor/firebase/php-jwt/src/BeforeValidException.php',
    264         'WCPOS\\Vendor\\Firebase\\JWT\\CachedKeySet' => __DIR__ . '/../..' . '/vendor_prefixed/vendor/firebase/php-jwt/src/CachedKeySet.php',
    265         'WCPOS\\Vendor\\Firebase\\JWT\\ExpiredException' => __DIR__ . '/../..' . '/vendor_prefixed/vendor/firebase/php-jwt/src/ExpiredException.php',
    266         'WCPOS\\Vendor\\Firebase\\JWT\\JWK' => __DIR__ . '/../..' . '/vendor_prefixed/vendor/firebase/php-jwt/src/JWK.php',
    267         'WCPOS\\Vendor\\Firebase\\JWT\\JWT' => __DIR__ . '/../..' . '/vendor_prefixed/vendor/firebase/php-jwt/src/JWT.php',
    268         'WCPOS\\Vendor\\Firebase\\JWT\\JWTExceptionWithPayloadInterface' => __DIR__ . '/../..' . '/vendor_prefixed/vendor/firebase/php-jwt/src/JWTExceptionWithPayloadInterface.php',
    269         'WCPOS\\Vendor\\Firebase\\JWT\\Key' => __DIR__ . '/../..' . '/vendor_prefixed/vendor/firebase/php-jwt/src/Key.php',
    270         'WCPOS\\Vendor\\Firebase\\JWT\\SignatureInvalidException' => __DIR__ . '/../..' . '/vendor_prefixed/vendor/firebase/php-jwt/src/SignatureInvalidException.php',
    271241        'WCPOS\\WooCommercePOS\\AJAX' => __DIR__ . '/../..' . '/includes/AJAX.php',
    272242        'WCPOS\\WooCommercePOS\\API' => __DIR__ . '/../..' . '/includes/API.php',
     
    319289        'WCPOS\\WooCommercePOS\\Server' => __DIR__ . '/../..' . '/includes/Server.php',
    320290        'WCPOS\\WooCommercePOS\\Services\\Auth' => __DIR__ . '/../..' . '/includes/Services/Auth.php',
     291        'WCPOS\\WooCommercePOS\\Services\\Cache' => __DIR__ . '/../..' . '/includes/Services/Cache.php',
    321292        'WCPOS\\WooCommercePOS\\Services\\Settings' => __DIR__ . '/../..' . '/includes/Services/Settings.php',
    322293        'WCPOS\\WooCommercePOS\\Templates' => __DIR__ . '/../..' . '/includes/Templates.php',
     
    333304    {
    334305        return \Closure::bind(function () use ($loader) {
    335             $loader->prefixLengthsPsr4 = ComposerStaticInit048927fcd0f6e1bd2ab86d49767e2e77::$prefixLengthsPsr4;
    336             $loader->prefixDirsPsr4 = ComposerStaticInit048927fcd0f6e1bd2ab86d49767e2e77::$prefixDirsPsr4;
    337             $loader->prefixesPsr0 = ComposerStaticInit048927fcd0f6e1bd2ab86d49767e2e77::$prefixesPsr0;
    338             $loader->classMap = ComposerStaticInit048927fcd0f6e1bd2ab86d49767e2e77::$classMap;
     306            $loader->prefixLengthsPsr4 = ComposerStaticInitf0c7d8ce923efae83025b27d0c5bc6c0::$prefixLengthsPsr4;
     307            $loader->prefixDirsPsr4 = ComposerStaticInitf0c7d8ce923efae83025b27d0c5bc6c0::$prefixDirsPsr4;
     308            $loader->prefixesPsr0 = ComposerStaticInitf0c7d8ce923efae83025b27d0c5bc6c0::$prefixesPsr0;
     309            $loader->classMap = ComposerStaticInitf0c7d8ce923efae83025b27d0c5bc6c0::$classMap;
    339310
    340311        }, null, ClassLoader::class);
  • woocommerce-pos/trunk/vendor/composer/installed.json

    r3048280 r3102003  
    312312        },
    313313        {
    314             "name": "salesforce/handlebars-php",
    315             "version": "3.0.1",
    316             "version_normalized": "3.0.1.0",
    317             "source": {
    318                 "type": "git",
    319                 "url": "https://github.com/salesforce/handlebars-php.git",
    320                 "reference": "d3a0552d85472249617ef6b56197c844d62d2ac3"
    321             },
    322             "dist": {
    323                 "type": "zip",
    324                 "url": "https://api.github.com/repos/salesforce/handlebars-php/zipball/d3a0552d85472249617ef6b56197c844d62d2ac3",
    325                 "reference": "d3a0552d85472249617ef6b56197c844d62d2ac3",
    326                 "shasum": ""
    327             },
    328             "require": {
    329                 "php": ">=5.4.0"
    330             },
    331             "require-dev": {
    332                 "phpunit/phpunit": "^9"
    333             },
    334             "time": "2023-01-12T16:24:23+00:00",
    335             "type": "library",
    336             "installation-source": "dist",
    337             "autoload": {
    338                 "psr-0": {
    339                     "Handlebars": "src/"
    340                 }
    341             },
    342             "notification-url": "https://packagist.org/downloads/",
    343             "license": [
    344                 "MIT"
    345             ],
    346             "authors": [
    347                 {
    348                     "name": "fzerorubigd",
    349                     "email": "[email protected]"
    350                 },
    351                 {
    352                     "name": "Behrooz Shabani (everplays)",
    353                     "email": "[email protected]"
    354                 },
    355                 {
    356                     "name": "Mardix",
    357                     "homepage": "https://github.com/mardix"
    358                 }
    359             ],
    360             "description": "Handlebars processor for php",
    361             "homepage": "http://www.github.com/salesforce/handlebars-php",
    362             "keywords": [
    363                 "handlebars",
    364                 "mustache",
    365                 "templating"
    366             ],
    367             "support": {
    368                 "issues": "https://github.com/salesforce/handlebars-php/issues",
    369                 "source": "https://github.com/salesforce/handlebars-php/tree/3.0.1"
    370             },
    371             "install-path": "../salesforce/handlebars-php"
    372         },
    373         {
    374314            "name": "symfony/polyfill-ctype",
    375315            "version": "v1.29.0",
  • woocommerce-pos/trunk/vendor/composer/installed.php

    r3096869 r3102003  
    22    'root' => array(
    33        'name' => 'wcpos/woocommerce-pos',
    4         'pretty_version' => 'v1.5.1',
    5         'version' => '1.5.1.0',
    6         'reference' => '9eea9f85c69bc5a569f86994f6d03582ed87177e',
     4        'pretty_version' => 'v1.6.0',
     5        'version' => '1.6.0.0',
     6        'reference' => '561cf10f1312c6951c577048394f6f198652652b',
    77        'type' => 'wordpress-plugin',
    88        'install_path' => __DIR__ . '/../../',
     
    5353            ),
    5454        ),
    55         'salesforce/handlebars-php' => array(
    56             'pretty_version' => '3.0.1',
    57             'version' => '3.0.1.0',
    58             'reference' => 'd3a0552d85472249617ef6b56197c844d62d2ac3',
    59             'type' => 'library',
    60             'install_path' => __DIR__ . '/../salesforce/handlebars-php',
    61             'aliases' => array(),
    62             'dev_requirement' => false,
    63         ),
    6455        'symfony/polyfill-ctype' => array(
    6556            'pretty_version' => 'v1.29.0',
     
    9081        ),
    9182        'wcpos/woocommerce-pos' => array(
    92             'pretty_version' => 'v1.5.1',
    93             'version' => '1.5.1.0',
    94             'reference' => '9eea9f85c69bc5a569f86994f6d03582ed87177e',
     83            'pretty_version' => 'v1.6.0',
     84            'version' => '1.6.0.0',
     85            'reference' => '561cf10f1312c6951c577048394f6f198652652b',
    9586            'type' => 'wordpress-plugin',
    9687            'install_path' => __DIR__ . '/../../',
  • woocommerce-pos/trunk/woocommerce-pos.php

    r3096869 r3102003  
    44 * Plugin URI:        https://wordpress.org/plugins/woocommerce-pos/
    55 * Description:       A simple front-end for taking WooCommerce orders at the Point of Sale. Requires <a href="http://wordpress.org/plugins/woocommerce/">WooCommerce</a>.
    6  * Version:           1.5.1
     6 * Version:           1.6.0
    77 * Author:            kilbot
    88 * Author URI:        http://wcpos.com
     
    1818 * WC requires at least: 5.3
    1919 *
    20  * @author    Paul Kilmurray <[email protected]>
    21  *
    2220 * @see      http://wcpos.com
    23  * @package   WCPOS\WooCommercePOS
     21 * @package  WCPOS\WooCommercePOS
    2422 */
    2523
     
    2725
    2826// Define plugin constants.
    29 const VERSION     = '1.5.1';
     27const VERSION     = '1.6.0';
    3028const PLUGIN_NAME = 'woocommerce-pos';
    3129const SHORT_NAME  = 'wcpos';
     
    3432\define( __NAMESPACE__ . '\PLUGIN_URL', trailingslashit( plugins_url( basename( plugin_dir_path( __FILE__ ) ), basename( __FILE__ ) ) ) );
    3533
    36 // minimum requirements.
     34// Minimum requirements.
    3735const WC_MIN_VERSION  = '5.3';
    3836const PHP_MIN_VERSION = '7.4';
    3937const MIN_PRO_VERSION = '1.5.0';
    4038
    41 // load .env flags (for development).
     39// Load .env flags (for development).
    4240function load_env( $file ) {
    4341    if ( ! file_exists( $file ) ) {
    44             return;
     42        return;
    4543    }
    4644
     
    4846    foreach ( $lines as $line ) {
    4947        if ( strpos( trim( $line ), '#' ) === 0 ) {
    50                 continue;
     48            continue;
    5149        }
    5250
     
    5654
    5755        if ( ! array_key_exists( $name, $_SERVER ) && ! array_key_exists( $name, $_ENV ) ) {
    58                 putenv( sprintf( '%s=%s', $name, $value ) );
    59                 $_ENV[ $name ] = $value;
     56            putenv( sprintf( '%s=%s', $name, $value ) );
     57            $_ENV[ $name ] = $value;
    6058        }
    6159    }
    6260}
    6361
    64 // Autoloader.
    65 if ( file_exists( __DIR__ . '/vendor/autoload.php' ) ) {
    66     require_once __DIR__ . '/vendor/autoload.php';
     62// Autoload vendor and prefixed libraries.
     63function wcpos_load_autoloaders() {
     64    $vendor_autoload = __DIR__ . '/vendor/autoload.php';
     65    $vendor_prefixed_autoload = __DIR__ . '/vendor_prefixed/autoload.php';
    6766
    68     // Environment variables.
    69     load_env( __DIR__ . '/.env' );
     67    if ( file_exists( $vendor_autoload ) ) {
     68        require_once $vendor_autoload;
     69    }
     70    if ( file_exists( $vendor_prefixed_autoload ) ) {
     71        require_once $vendor_prefixed_autoload;
     72    }
     73}
    7074
    71     // Activate plugin.
    72     new Activator();
     75wcpos_load_autoloaders();
    7376
    74     // Deactivate plugin.
    75     new Deactivator();
    76 } else {
     77// Environment variables.
     78load_env( __DIR__ . '/.env' );
     79
     80// Error handling for autoload failure.
     81if ( ! class_exists( \WCPOS\WooCommercePOS\Activator::class ) || ! class_exists( \WCPOS\WooCommercePOS\Deactivator::class ) ) {
    7782    add_action(
    7883        'admin_notices',
    7984        function (): void {
    8085            ?>
    81         <div class="notice notice-error">
    82             <p><?php esc_html_e( 'The WooCommerce POS plugin failed to load correctly.', 'woocommerce-pos' ); ?></p>
    83         </div>
     86            <div class="notice notice-error">
     87                <p><?php esc_html_e( 'The WooCommerce POS plugin failed to load correctly.', 'woocommerce-pos' ); ?></p>
     88            </div>
    8489            <?php
    8590        }
    8691    );
     92    return; // Exit early if classes are not found.
    8793}
     94
     95// Activate plugin.
     96new Activator();
     97
     98// Deactivate plugin.
     99new Deactivator();
    88100
    89101// Declare HPOS compatible.
Note: See TracChangeset for help on using the changeset viewer.