PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / 1.10.18
WCPOS – Point of Sale (POS) plugin for WooCommerce v1.10.18
1.10.18 1.10.17 1.10.16 1.10.15 1.10.13 1.10.14 1.10.12 1.10.11 1.10.10 1.10.9 1.10.8 untagged-3d9b7ccddc54df87c672 1.10.7 1.10.6 1.10.5 1.10.3 1.10.4 1.10.2 1.10.1 1.10.0 1.9.17 1.9.15 1.9.16 1.9.14 1.9.13 All 162 releases
woocommerce-pos / includes / API / V2 / Proxy / Taxes_Proxy_Behavior.php

Taxes_Proxy_Behavior.php in WCPOS – Point of Sale (POS) plugin for WooCommerce 1.10.18, at includes/API/V2/Proxy/Taxes_Proxy_Behavior.php

123 lines 3.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Tax catalog proxy behavior.
4 *
5 * @package WCPOS\WooCommercePOS\API\V2\Proxy
6 */
7
8 namespace WCPOS\WooCommercePOS\API\V2\Proxy;
9
10 use WP_REST_Request;
11
12 /**
13 * Applies tax ID narrowing and POS read permission without a v1 controller.
14 */
15 final class Taxes_Proxy_Behavior extends Scoped_Proxy_Behavior {
16 /** POS read grant for this collection only.
17 *
18 * @var string
19 */
20 protected $permission_collection = 'tax_rates';
21
22 /**
23 * The Collection Rules plan for the request in flight.
24 *
25 * @var int[]
26 */
27 private $include = array();
28
29 /**
30 * The Collection Rules plan for the request in flight.
31 *
32 * @var int[]
33 */
34 private $exclude = array();
35
36 /**
37 * Adjust the params forwarded to wc/v3 for this resource.
38 *
39 * @param array $params Query parameters to forward.
40 * @param WP_REST_Request $request Original proxy request.
41 *
42 * @return array
43 */
44 public function forwarded_params( array $params, WP_REST_Request $request ): array {
45 foreach ( array( 'include', 'exclude' ) as $param ) {
46 if ( isset( $params[ $param ] ) ) {
47 $this->{$param} = wp_parse_id_list( $params[ $param ] );
48 $params[ 'wcpos_' . $param ] = $this->{$param};
49 unset( $params[ $param ] );
50 }
51 }
52
53 return $params;
54 }
55
56 /**
57 * Install this resource's hooks and return their removal tuples.
58 *
59 * @return array<int, array{0: string, 1: callable, 2: int}>
60 */
61 protected function install(): array {
62 $bindings = array();
63
64 if ( array() === $this->include && array() === $this->exclude ) {
65 return $bindings;
66 }
67
68 /*
69 * Stays installed for the whole forward, and is unwound by around()'s
70 * finally rather than by removing itself on first match.
71 *
72 * v1's method self-removes, but it removes the array callback
73 * `array( $this, 'wcpos_tax_add_include_exclude_to_sql' )` — while the
74 * proxy lane registered a CLOSURE wrapping that method, so the removal
75 * never matched and the filter went on to narrow the pagination COUNT
76 * query too. Self-removing here really does unhook, which left the
77 * count unfiltered and the reported total too high.
78 * `test_cashier_include_filter_limits_pagination_totals` pins this.
79 *
80 * Re-application is safe: each invocation receives a fresh query string,
81 * and the strpos guard scopes it to tax-rate queries.
82 */
83 $query_filter = function ( string $query ): string {
84 global $wpdb;
85
86 if ( false === strpos( $query, "{$wpdb->prefix}woocommerce_tax_rates" ) ) {
87 return $query;
88 }
89 if ( array() !== $this->include ) {
90 $query = self::insert_where( $query, "{$wpdb->prefix}woocommerce_tax_rates.tax_rate_id IN (" . implode( ',', $this->include ) . ')' );
91 }
92 if ( array() !== $this->exclude ) {
93 $query = self::insert_where( $query, "{$wpdb->prefix}woocommerce_tax_rates.tax_rate_id NOT IN (" . implode( ',', $this->exclude ) . ')' );
94 }
95
96 return $query;
97 };
98 add_filter( 'query', $query_filter, 10, 1 );
99 $bindings[] = array( 'query', $query_filter, 10 );
100
101 return $bindings;
102 }
103
104 /**
105 * Insert one condition into the WooCommerce tax-rate SQL.
106 *
107 * @param string $query SQL query.
108 * @param string $condition WHERE condition.
109 *
110 * @return string
111 */
112 private static function insert_where( string $query, string $condition ): string {
113 if ( false !== strpos( $query, 'WHERE' ) ) {
114 return str_replace( 'WHERE', "WHERE $condition AND", $query );
115 }
116
117 $position = strpos( $query, 'ORDER BY' );
118 return false !== $position
119 ? substr_replace( $query, " WHERE $condition ", $position, 0 )
120 : $query . " WHERE $condition";
121 }
122 }
123