| 1 |
<?php |
| 2 |
/** |
| 3 |
* Order catalog proxy behavior. |
| 4 |
* |
| 5 |
* @package WCPOS\WooCommercePOS\API\V2\Proxy |
| 6 |
*/ |
| 7 |
|
| 8 |
namespace WCPOS\WooCommercePOS\API\V2\Proxy; |
| 9 |
|
| 10 |
use Automattic\WooCommerce\Utilities\OrderUtil; |
| 11 |
use WCPOS\WooCommercePOS\API\Order_Search; |
| 12 |
use WCPOS\WooCommercePOS\Sync\Collection_Rules; |
| 13 |
use WCPOS\WooCommercePOS\Sync\Order_Serializer; |
| 14 |
use WP_REST_Request; |
| 15 |
|
| 16 |
/** |
| 17 |
* Applies the order Collection Rules plan and v2 order wire shape. |
| 18 |
*/ |
| 19 |
final class Orders_Proxy_Behavior extends Scoped_Proxy_Behavior { |
| 20 |
/** |
| 21 |
* Search text removed from the forwarded request. |
| 22 |
* |
| 23 |
* @var string |
| 24 |
*/ |
| 25 |
private $search = ''; |
| 26 |
|
| 27 |
/** |
| 28 |
* Proxy request keys claimed by the order Collection Rules plan. |
| 29 |
*/ |
| 30 |
private const PARAM_MAP = array( |
| 31 |
'orderby' => 'orderby', |
| 32 |
'order' => 'order', |
| 33 |
'pos_cashier' => 'pos_cashier', |
| 34 |
'pos_store' => 'pos_store', |
| 35 |
'created_via' => 'created_via', |
| 36 |
'include' => array( |
| 37 |
'key' => 'include', |
| 38 |
'when' => 'search', |
| 39 |
'parse' => 'id_list', |
| 40 |
), |
| 41 |
'exclude' => array( |
| 42 |
'key' => 'exclude', |
| 43 |
'when' => 'search', |
| 44 |
'parse' => 'id_list', |
| 45 |
), |
| 46 |
); |
| 47 |
|
| 48 |
/** |
| 49 |
* The Collection Rules plan for the request in flight. |
| 50 |
* |
| 51 |
* @var null|\WCPOS\WooCommercePOS\Sync\Collection_Rules_Plan |
| 52 |
*/ |
| 53 |
private $plan; |
| 54 |
|
| 55 |
/** |
| 56 |
* Claim the orders params the rules table owns, then ask wc/v3 for full precision. |
| 57 |
* |
| 58 |
* @param array $params Query parameters to forward. |
| 59 |
* @param WP_REST_Request $request Original proxy request. |
| 60 |
* |
| 61 |
* @return array |
| 62 |
*/ |
| 63 |
public function forwarded_params( array $params, WP_REST_Request $request ): array { |
| 64 |
$this->plan = Collection_Rules::for_request( 'orders', $request, self::PARAM_MAP ); |
| 65 |
$params = $this->plan->forwarded_params( $params ); |
| 66 |
// Claim only a string with at least one term. Anything else (an array from |
| 67 |
// `search[]=`, whitespace only) stays on the forward so wc/v3's own schema |
| 68 |
// validation answers it, as it did before. |
| 69 |
$search = $params['search'] ?? null; |
| 70 |
if ( is_string( $search ) && array() !== Order_Search::terms( $search ) ) { |
| 71 |
$this->search = $search; |
| 72 |
unset( $params['search'] ); |
| 73 |
} |
| 74 |
$params['dp'] = '6'; |
| 75 |
|
| 76 |
return $params; |
| 77 |
} |
| 78 |
|
| 79 |
/** |
| 80 |
* Install the storage-specific POS order search filter. |
| 81 |
* |
| 82 |
* @return array<int, array{0: string, 1: callable, 2: int}> |
| 83 |
*/ |
| 84 |
protected function install(): array { |
| 85 |
if ( '' === $this->search ) { |
| 86 |
return array(); |
| 87 |
} |
| 88 |
|
| 89 |
$search = $this->search; |
| 90 |
// The class arrived after the declared WooCommerce minimum (5.3); without it the |
| 91 |
// store is on post storage. Same guard as Collection_Rules::detect_storage(). |
| 92 |
if ( class_exists( OrderUtil::class ) && OrderUtil::custom_orders_table_usage_is_enabled() ) { |
| 93 |
$filter = static function ( $clauses, $query ) use ( $search ) { |
| 94 |
$clauses['where'] .= ' AND ' . Order_Search::hpos_where( $search, $query ); |
| 95 |
return $clauses; |
| 96 |
}; |
| 97 |
add_filter( 'woocommerce_orders_table_query_clauses', $filter, 10, 2 ); |
| 98 |
return array( array( 'woocommerce_orders_table_query_clauses', $filter, 10 ) ); |
| 99 |
} |
| 100 |
|
| 101 |
$filter = static function ( $where, $query ) use ( $search ) { |
| 102 |
$post_type = is_object( $query ) ? ( $query->query_vars['post_type'] ?? null ) : null; |
| 103 |
if ( 'shop_order' !== $post_type && ( ! is_array( $post_type ) || ! in_array( 'shop_order', $post_type, true ) ) ) { |
| 104 |
return $where; |
| 105 |
} |
| 106 |
return $where . ' AND ' . Order_Search::posts_where( $search ); |
| 107 |
}; |
| 108 |
add_filter( 'posts_where', $filter, 10, 2 ); |
| 109 |
return array( array( 'posts_where', $filter, 10 ) ); |
| 110 |
} |
| 111 |
|
| 112 |
/** |
| 113 |
* Run the forward inside the Collection Rules plan for this request. |
| 114 |
* |
| 115 |
* @param callable $forward Forward operation. |
| 116 |
* |
| 117 |
* @return mixed |
| 118 |
*/ |
| 119 |
protected function run( callable $forward ) { |
| 120 |
return null === $this->plan ? $forward() : $this->plan->around( $forward ); |
| 121 |
} |
| 122 |
|
| 123 |
/** |
| 124 |
* Apply the shared v2 order augmentations to every row. |
| 125 |
* |
| 126 |
* @param mixed $data Response data. |
| 127 |
* |
| 128 |
* @return mixed |
| 129 |
*/ |
| 130 |
public function post_process( $data ) { |
| 131 |
$serializer = new Order_Serializer(); |
| 132 |
foreach ( (array) $data as $index => $payload ) { |
| 133 |
if ( is_array( $payload ) ) { |
| 134 |
$data[ $index ] = $serializer->document( $payload, Order_Serializer::V2_AUGMENTATIONS ); |
| 135 |
} |
| 136 |
} |
| 137 |
|
| 138 |
return $data; |
| 139 |
} |
| 140 |
} |
| 141 |
|