PluginProbe
Route ‑ Shipping Protection / 2.4.12
Route ‑ Shipping Protection v2.4.12
2.4.19 2.4.18 2.4.17 2.4.16 2.4.15 2.4.14 2.4.13 2.4.12 2.4.11 2.4.10 2.4.9 2.4.8 2.4.7 2.4.6 2.4.5 2.4.4 2.4.3 2.4.2 2.2.4 2.2.5 2.2.6 2.2.8 2.2.9 2.3.0 2.3.1 All 153 releases
routeapp / admin / class-routeapp-order-recover.php

class-routeapp-order-recover.php in Route ‑ Shipping Protection 2.4.12, at admin/class-routeapp-order-recover.php

257 lines 8.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class Routeapp_Order_Recover file.
4 *
5 * @package Routeapp\Admin
6 */
7
8 class Routeapp_Order_Recover {
9
10 public function __construct() {
11 // Ensure the AJAX actions are registered
12 add_action('wp_ajax_routeapp_save_orders', array($this, 'save'));
13 add_action('wp_ajax_routeapp_process_orders_batch', array($this, 'process_orders_batch'));
14
15 }
16
17 /**
18 * Save function to handle the processing of orders based on specified date range and batch size.
19 * This function processes orders in batches to avoid timeouts and server overload.
20 * It checks if the necessary POST parameters are set, fetches the orders in batches,
21 * processes each batch, and updates the order count accordingly.
22 */
23 public function save() {
24 if ($this->isPostRequestValid()) {
25 $recoverFrom = $_POST['routeapp_order_recover_from'];
26 $recoverTo = $_POST['routeapp_order_recover_to'];
27
28 // Get the total number of orders in the specified date range
29 $orderCount = $this->getOrderCount($recoverFrom, $recoverTo);
30
31 // Determine batch size based on the number of orders
32 $batchSize = $this->determineBatchSize($orderCount);
33
34 // Determine wait time based on batch size
35 $waitTime = $this->determineWaitTimeParameter($batchSize);
36
37 // Send back the initial response with the calculated values
38 wp_send_json_success(array(
39 'orderCount' => $orderCount,
40 'batchSize' => $batchSize,
41 'recoverFrom' => $recoverFrom,
42 'recoverTo' => $recoverTo,
43 'waitTime' => $waitTime,
44 ));
45 }
46 else {
47 wp_send_json_error(array(
48 'message' => __('Error', 'routeapp'),
49 ));
50 }
51 wp_die();
52 }
53
54 // New function to handle batch processing via AJAX
55 public function process_orders_batch() {
56
57 if ($this->isPostRequestValid()) {
58 $recoverFrom = $_POST['routeapp_order_recover_from'];
59 $recoverTo = $_POST['routeapp_order_recover_to'];
60 $batchSize = $_POST['batchSize'];
61 $offset = $_POST['offset'];
62
63 $orders = $this->getOrdersBatch($batchSize, $offset, $recoverTo, $recoverFrom);
64
65 if (!empty($orders)) {
66 $this->processOrders($orders);
67 wp_send_json_success(array(
68 'processed' => count($orders),
69 ));
70 } else {
71 wp_send_json_error(array(
72 'message' => __('No more orders to process.', 'routeapp'),
73 ));
74 }
75 }
76 else {
77 wp_send_json_error(array(
78 'message' => __('Error', 'routeapp'),
79 ));
80 }
81 wp_die();
82 }
83
84 /**
85 * Validates the POST request to ensure required parameters are set.
86 *
87 * @return bool Returns true if the POST request contains 'routeapp_order_recover_from' and 'routeapp_order_recover_to'.
88 */
89 private function isPostRequestValid() {
90 return isset($_POST) && isset($_POST['routeapp_order_recover_from']) && isset($_POST['routeapp_order_recover_to']);
91 }
92
93
94 /**
95 * Fetches a batch of orders based on the specified batch size and offset.
96 *
97 * @param int $batchSize The number of orders to fetch in one batch.
98 * @param int $offset The starting point for fetching orders.
99 * @return array The fetched orders based on the specified arguments.
100 */
101 private function getOrdersBatch($batchSize, $offset, $recoverTo, $recoverFrom) {
102 $args = array(
103 'limit' => (int) $batchSize,
104 'offset' => (int) $offset,
105 'type' => 'shop_order',
106 'date_created' => $recoverFrom . '...' . $recoverTo,
107 );
108
109 return wc_get_orders( $args );
110 }
111
112 /**
113 * Processes the fetched orders by either updating order post meta or performing a massive order save operation.
114 *
115 * @param array $orders The fetched orders to be processed.
116 */
117 private function processOrders($orders) {
118 if (isset($_POST['routeapp_order_recover_reconcile_backend'])) {
119 $this->updateOrderPostMeta($orders);
120 } else {
121 $this->massiveOrderSave($orders);
122 }
123 }
124
125 /**
126 * Trigger save for all the selected orders, which will trigger the webhook for order.update
127 *
128 * @param $orders
129 * @return void
130 */
131 public function massiveOrderSave($orders) {
132 foreach ($orders as $order) {
133 Routeapp_Cron_Schedules::updateOrderStatusMetaIfNeeded( $order, false );
134 $order->save();
135 }
136 }
137
138 /**
139 * Update order post_meta with route order data
140 *
141 * @param $orders
142 * @return void
143 */
144 public function updateOrderPostMeta($orders) {
145 foreach ($orders as $order) {
146 Routeapp_Cron_Schedules::updateOrderStatusMetaIfNeeded( $order );
147
148 $has_route_meta = method_exists( $order, 'get_meta' )
149 ? $order->get_meta( '_routeapp_order_id' )
150 : get_post_meta( $order->get_id(), '_routeapp_order_id', true );
151 if ( ! $has_route_meta ) {
152 //check if order exists on Route side
153 $getOrderResponse = Routeapp_API_Client::getInstance()->get_order($order->get_id());
154 if (is_wp_error($getOrderResponse) || $getOrderResponse['response']['code'] != 200) {
155 continue;
156 }
157 Routeapp_Cron_Schedules::updateOrderPostMeta($order, $getOrderResponse);
158 }
159 }
160 }
161
162 /**
163 * Get the count of orders based on the specified date range.
164 * Supports both High-performance order storage (HPOS) and WordPress posts storage (legacy).
165 *
166 * @param string $from Starting date for the orders (YYYY-MM-DD).
167 * @param string $to Ending date for the orders (YYYY-MM-DD).
168 * @return int The count of orders.
169 */
170 public function getOrderCount($from, $to) {
171 global $wpdb;
172
173 $from_date = $from . ' 00:00:00';
174 $to_date = $to . ' 23:59:59';
175
176 if ( $this->is_hpos_enabled() ) {
177 // High-performance order storage: query wc_orders table
178 $orders_table = $wpdb->prefix . 'wc_orders';
179 $from_gmt = get_gmt_from_date( $from_date );
180 $to_gmt = get_gmt_from_date( $to_date );
181
182 $query = $wpdb->prepare(
183 "SELECT COUNT(1)
184 FROM {$orders_table} AS orders
185 WHERE orders.type = 'shop_order'
186 AND orders.status NOT IN ( 'wc-auto-draft', 'auto-draft', 'trash' )
187 AND orders.date_created_gmt >= %s
188 AND orders.date_created_gmt <= %s",
189 $from_gmt,
190 $to_gmt
191 );
192 } else {
193 // WordPress posts storage (legacy): query wp_posts
194 $query = $wpdb->prepare(
195 "SELECT COUNT(1)
196 FROM {$wpdb->posts} AS posts
197 WHERE posts.post_type = 'shop_order'
198 AND posts.post_status NOT IN ( 'wc-auto-draft', 'auto-draft', 'trash' )
199 AND posts.post_date >= %s
200 AND posts.post_date <= %s",
201 $from_date,
202 $to_date
203 );
204 }
205
206 return (int) $wpdb->get_var( $query );
207 }
208
209 /**
210 * Check if High-performance order storage (HPOS) is enabled.
211 *
212 * @return bool True if HPOS is enabled, false otherwise.
213 */
214 private function is_hpos_enabled() {
215 if ( ! class_exists( 'Automattic\WooCommerce\Utilities\OrderUtil' ) ) {
216 return false;
217 }
218 return \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled();
219 }
220
221 /**
222 * Determine batch size based on the number of orders.
223 *
224 * @param int $orderCount The number of orders.
225 * @return int The batch size.
226 */
227 private function determineBatchSize($orderCount) {
228 switch (true) {
229 case ($orderCount <= 1000):
230 return 100;
231 case ($orderCount <= 5000):
232 return 50;
233 case ($orderCount <= 10000):
234 return 25;
235 default:
236 return 10; // Fallback batch size for more than 100,000 orders
237 }
238 }
239
240 /**
241 * Determine wait time based on the batch size.
242 *
243 * @param int $batchSize The batch size.
244 * @return int The wait time.
245 */
246 private function determineWaitTimeParameter($batchSize) {
247 switch ($batchSize) {
248 case 100:
249 return 10;
250 case 50:
251 return 5;
252 default:
253 return 2; // Fallback wait time
254 }
255 }
256 }
257