PluginProbe ʕ •ᴥ•ʔ
CommerceBird – AI Command Center, ERP Integrations & B2B for WooCommerce (Zoho, Exact Online). / 2.3.7
CommerceBird – AI Command Center, ERP Integrations & B2B for WooCommerce (Zoho, Exact Online). v2.3.7
3.0.3 3.0.2 3.0.1 trunk 2.2.14 2.2.15 2.2.16 2.2.17 2.2.18 2.2.19 2.3.0 2.3.1 2.3.10 2.3.11 2.3.12 2.3.13 2.3.14 2.3.2 2.3.3 2.3.4 2.3.5 2.3.6 2.3.7 2.3.8 2.3.9 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.5.0 2.5.1 2.5.2 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.6.5 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 2.7.9 2.7.91 2.7.92 2.7.93 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.8.5 2.9.0 2.9.1 2.9.2 2.9.3 3.0.0
commercebird / includes / woo-functions.php
commercebird / includes Last commit date
classes 1 year ago sync 1 year ago index.php 1 year ago woo-functions.php 1 year ago
woo-functions.php
638 lines
1 <?php
2
3 /**
4 * All WooCommerce related functions.
5 *
6 * @category WooCommerce
7 * @package CommerceBird
8 * @author Fawad Tiemoerie <info@roadmapstudios.com>
9 * @license GNU General Public License v3.0
10 * @link https://commercebird.com
11 */
12
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit;
15 }
16
17 /**
18 * Helper functions to ensure correct handling of Data being transferred via rest api
19 */
20
21 function cmbird_clear_product_cache( $object, $request, $is_creating ) {
22 if ( ! $is_creating ) {
23 $product_id = $object->get_id();
24 $zoho_inventory_access_token = get_option( 'cmbird_zoho_inventory_access_token' );
25 $cmbird_zi_product_sync = get_option( 'cmbird_zoho_disable_product_sync_status' );
26 if ( ! empty( $zoho_inventory_access_token ) && ! $cmbird_zi_product_sync ) {
27 $product_handler = new CMBIRD_Products_ZI_Export();
28 $product_handler->cmbird_zi_product_sync( $product_id );
29 }
30 wc_delete_product_transients( $product_id );
31 }
32 }
33 add_action( 'woocommerce_rest_insert_product_object', 'cmbird_clear_product_cache', 10, 3 );
34
35
36
37 /**
38 * Function to update the Contact in Zoho when customer updates address on frontend
39 * @param $user_id
40 */
41 function cmbird_update_contact_via_accountpage( $user_id ) {
42 $zoho_inventory_access_token = get_option( 'cmbird_zoho_inventory_access_token' );
43 if ( ! empty( $zoho_inventory_access_token ) ) {
44 $contact_class_handle = new CMBIRD_Contact_ZI();
45 $contact_class_handle->cmbird_contact_update_function( $user_id );
46
47 global $wpdb;
48 $meta_key_search = 'zi_contact_person_id%';
49 $query = $wpdb->get_results(
50 $wpdb->prepare(
51 "SELECT meta_key, meta_value
52 FROM {$wpdb->usermeta}
53 WHERE user_id = %d
54 AND meta_key LIKE %s",
55 $user_id,
56 $meta_key_search
57 )
58 );
59 if ( ! empty( $query ) ) {
60 // Usermeta keys containing 'zi_contact_person_id' exist.
61 foreach ( $query as $row ) {
62 $contact_class_handle->cmbird_update_contact_person( $user_id, $row->meta_value );
63 }
64 } else {
65 return;
66 }
67 } else {
68 return;
69 }
70 }
71 add_action( 'profile_update', 'cmbird_update_contact_via_accountpage' );
72
73 /**
74 * Function to be called by hook when new product is added in WooCommerce.
75 *
76 * @param $product_id
77 * @return void
78 */
79 add_action( 'woocommerce_update_product', 'cmbird_zi_product_sync_class', 10, 1 );
80 add_action( 'wp_ajax_zoho_admin_product_sync', 'cmbird_zi_product_sync_class' );
81 function cmbird_zi_product_sync_class( $product_id ) {
82 if ( ! is_admin() ) {
83 return;
84 }
85 if ( ! $product_id ) {
86 // Check nonce for security
87 if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'zoho_admin_product_sync' ) ) {
88 wp_send_json_error( 'Nonce verification failed' );
89 } else {
90 $product_id = isset( $_POST['post_id'] ) ? intval( $_POST['post_id'] ) : 0;
91 if ( ! $product_id ) {
92 wp_send_json_error( 'Invalid Product ID' );
93 }
94 }
95 }
96 $zoho_inventory_access_token = get_option( 'cmbird_zoho_inventory_access_token' );
97 // return if zoho inventory access token is empty
98 if ( empty( $zoho_inventory_access_token ) ) {
99 return;
100 }
101 $cmbird_zi_product_sync = get_option( 'cmbird_zoho_disable_product_sync_status' );
102 if ( ! $cmbird_zi_product_sync ) {
103 $product_handler = new CMBIRD_Products_ZI_Export();
104 $product_handler->cmbird_zi_product_sync( $product_id );
105 }
106 // if its variable product but without variations, then sync it.
107 $product = wc_get_product( $product_id );
108 if ( $product->is_type( 'variable' ) ) {
109 $variations = $product->get_available_variations();
110 if ( isset( $variations ) && count( $variations ) === 0 ) {
111 $zi_product_id = get_post_meta( $product_id, 'zi_item_id', true );
112 if ( ! empty( $zi_product_id ) ) {
113 $product_handler = new CMBIRD_Products_ZI();
114 $product_handler->import_variable_product_variations( $zi_product_id, $product_id );
115 }
116 }
117 }
118 }
119
120 /**
121 * Bulk-action to sync products from WooCommerce to Zoho
122 *
123 * @param: $bulk_array
124 * @return: $bulk_array
125 */
126 add_filter( 'bulk_actions-edit-product', 'cmbird_zi_sync_all_items_to_zoho' );
127 function cmbird_zi_sync_all_items_to_zoho( $bulk_array ) {
128 $bulk_array['sync_item_to_zoho'] = 'Sync to Zoho';
129 // add option to unmap items from zoho
130 $bulk_array['unmap_item_to_zoho'] = 'Unmap from Zoho';
131 return $bulk_array;
132 }
133
134 add_filter( 'handle_bulk_actions-edit-product', 'cmbird_zi_sync_all_items_to_zoho_handler', 10, 3 );
135 function cmbird_zi_sync_all_items_to_zoho_handler( $redirect, $action, $object_ids ) {
136 // let's remove query args first
137 $redirect = remove_query_arg( 'sync_item_to_zoho_done', $redirect );
138 $redirect = remove_query_arg( 'unmap_item_to_zoho_done', $redirect );
139
140 // do something for "Make Draft" bulk action
141 if ( 'sync_item_to_zoho' === $action ) {
142
143 foreach ( $object_ids as $post_id ) {
144 $product_handler = new CMBIRD_Products_ZI_Export();
145 $product_handler->cmbird_zi_product_sync( $post_id );
146 }
147
148 // do not forget to add query args to URL because we will show notices later
149 $redirect = add_query_arg( 'sync_item_to_zoho_done', count( $object_ids ), $redirect );
150
151 } elseif ( 'unmap_item_to_zoho' === $action ) {
152 foreach ( $object_ids as $post_id ) {
153 $nonce = wp_create_nonce( 'zi_product_unmap_hook' );
154 cmbird_zi_product_unmap_hook( $post_id, $nonce );
155 }
156 // do not forget to add query args to URL because we will show notices later
157 $redirect = add_query_arg('unmap_item_to_zoho_done', count( $object_ids ), $redirect );
158 }
159
160 return $redirect;
161 }
162
163 // output the message of bulk action
164 add_action( 'admin_notices', 'cmbird_sync_item_to_zoho_notices' );
165 function cmbird_sync_item_to_zoho_notices() {
166 // verify nonce
167 if ( ! isset( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ), 'bulk-edit-products' ) ) {
168 return;
169 }
170 if ( ! empty( $_REQUEST['sync_item_to_zoho_done'] ) ) {
171 echo '<div id="message" class="updated notice is-dismissible">
172 <p>Products Synced. If product is not synced, please click on Edit Product to see the API response.</p>
173 </div>';
174 }
175 if ( !empty( $_REQUEST['unmap_item_to_zoho_done'] ) ) {
176 echo '<div id="message" class="updated notice is-dismissible">
177 <p>Products Unmapped from Zoho.</p>
178 </div>';
179 }
180 }
181
182 /**
183 * Function to be called by ajax hook when unmap button called.
184 * This function remove zoho mapped id.
185 */
186 add_action( 'wp_ajax_zi_product_unmap_hook', 'cmbird_zi_product_unmap_hook' );
187 function cmbird_zi_product_unmap_hook( $product_id, $nonce ='' ) {
188 // if nonce is not there in the request, then check if it is passed as parameter
189 if ( ! $nonce ) {
190 $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
191 }
192 // verify nonce
193 if ( ! $nonce || ! wp_verify_nonce( $nonce, 'zi_product_unmap_hook' ) ) {
194 wp_send_json_error( 'Nonce verification failed' );
195 }
196 if ( ! $product_id && isset( $_POST['product_id'] ) ) {
197 $product_id = sanitize_text_field( wp_unslash( $_POST['product_id'] ) );
198 }
199
200 if ( $product_id ) {
201 $product = wc_get_product( $product_id );
202 // If this is variable items then unmap all of it's variations.
203 if ( $product->is_type( 'variable' ) ) {
204 $variations = $product->get_available_variations();
205 if ( isset( $variations ) && count( $variations ) > 0 ) {
206 foreach ( $variations as $child ) {
207 delete_post_meta( $child['variation_id'], 'zi_item_id' );
208 delete_post_meta( $child['variation_id'], 'zi_account_id' );
209 delete_post_meta( $child['variation_id'], 'zi_account_name' );
210 delete_post_meta( $child['variation_id'], 'zi_category_id' );
211 delete_post_meta( $child['variation_id'], 'zi_inventory_account_id' );
212 delete_post_meta( $child['variation_id'], 'zi_purchase_account_id' );
213 }
214 }
215 }
216 delete_post_meta( $product_id, 'zi_item_id' );
217 delete_post_meta( $product_id, 'zi_account_id' );
218 delete_post_meta( $product_id, 'zi_account_name' );
219 delete_post_meta( $product_id, 'zi_category_id' );
220 delete_post_meta( $product_id, 'zi_inventory_account_id' );
221 delete_post_meta( $product_id, 'zi_purchase_account_id' );
222 // update message
223 update_post_meta( $product_id, 'zi_product_errmsg', 'Product is Unmapped' );
224 }
225 }
226
227 /**
228 * Function to be called by ajax hook when unmap button called.
229 * This function remove zoho mapped id.
230 */
231 add_action( 'wp_ajax_zi_customer_unmap_hook', 'cmbird_zi_customer_unmap_hook' );
232 function cmbird_zi_customer_unmap_hook( $order_id ) {
233 // verify Nonce
234 if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'zi_customer_unmap_hook' ) ) {
235 wp_send_json_error( 'Nonce verification failed' );
236 }
237 if ( ! $order_id && isset( $_POST['order_id'] ) ) {
238 $order_id = sanitize_text_field( wp_unslash( $_POST['order_id'] ) );
239 }
240
241 $order = wc_get_order( $order_id );
242 $customer_id = $order->get_user_id();
243
244 if ( $customer_id ) {
245 delete_user_meta( $customer_id, 'zi_contact_id' );
246 delete_user_meta( $customer_id, 'zi_contact_persons_id' );
247 delete_user_meta( $customer_id, 'zi_contactperson_id_0' );
248 delete_user_meta( $customer_id, 'zi_contactperson_id_1' );
249 delete_user_meta( $customer_id, 'zi_currency_code' );
250 delete_user_meta( $customer_id, 'zi_currency_id' );
251 delete_user_meta( $customer_id, 'zi_created_time' );
252 delete_user_meta( $customer_id, 'zi_last_modified_time' );
253 delete_user_meta( $customer_id, 'zi_primary_contact_id' );
254 delete_user_meta( $customer_id, 'zi_billing_address_id' );
255 delete_user_meta( $customer_id, 'zi_shipping_address_id' );
256
257 $order->add_order_note( 'Zoho Sync: Customer is now unmapped. Please try syncing the order again' );
258 $order->save();
259 }
260 }
261
262 /**
263 * Add WordPress Meta box to show sync response
264 */
265 function cmbird_product_metabox() {
266 $zoho_inventory_access_token = get_option( 'cmbird_zoho_inventory_access_token' );
267 if ( ! $zoho_inventory_access_token ) {
268 return;
269 }
270 add_meta_box(
271 'zoho-product-sync',
272 __( 'Zoho Inventory', 'commercebird' ),
273 'cmbird_product_metabox_callback',
274 'product',
275 'side',
276 'high'
277 );
278 }
279 function cmbird_product_metabox_callback( $post ) {
280 $response = get_post_meta( $post->ID, 'zi_product_errmsg' );
281 echo 'API Response: ' . esc_html( implode( $response ) ) . '<br>';
282 // Generate nonce
283 $nonce = wp_create_nonce( 'zoho_admin_product_sync' );
284 $nonce_unmap = wp_create_nonce( 'zi_product_unmap_hook' );
285 $post_id = $post->ID;
286 echo '<br><a href="javascript:void(0)" style="width:100%; text-align: center;" class="button button-primary" onclick="zoho_admin_product_ajax(' . esc_attr( $post_id ) . ', \'' . esc_attr( $nonce ) . '\')">Sync Product</a>';
287 echo '<br><a href="javascript:void(0)" style="margin-top:10px; background:#b32d2e; border-color: #b32d2e; width:100%; text-align: center;" class="button button-primary" onclick="zoho_admin_unmap_product_ajax(' . esc_attr( $post_id ) . ', \'' . esc_attr( $nonce_unmap ) . '\')">Unmap this Product</a>';
288 $product = wc_get_product( $post->ID );
289 $product_type = $product->get_type();
290 if ( 'variable' === $product_type || 'variable-subscription' === $product_type ) {
291 echo '<p class="howto" style="color:#b32d2e;"><strong>Important : </strong> Please ensure all variations have price and SKU</p>';
292 }
293 // echo the zi_category_id
294 $zi_category_id = get_post_meta( $post->ID, 'zi_category_id', true );
295 if ( $zi_category_id ) {
296 echo '<p class="howto"><strong>Zoho Category: </strong>' . esc_html( $zi_category_id ) . '</p>';
297 }
298 // make api call to get the zoho item details
299 $zi_item_id = get_post_meta( $post->ID, 'zi_item_id', true );
300 if ( $zi_item_id && is_admin() ) {
301 $zoho_inventory_oid = get_option( 'cmbird_zoho_inventory_organization_id' );
302 $zoho_inventory_url = get_option( 'cmbird_zoho_inventory_url' );
303 $urlitem = "{$zoho_inventory_url}inventory/v1/items/{$zi_item_id}?organization_id=$zoho_inventory_oid";
304 // fwrite( $fd, PHP_EOL . 'URL : ' . $urlitem );
305
306 $execute_curl_call = new CMBIRD_API_Handler_Zoho();
307 $json = $execute_curl_call->execute_curl_call_get( $urlitem );
308 $code = (int) property_exists( $json, 'code' ) ? $json->code : '0';
309 if ( '0' === $code || 0 === $code ) {
310 // echo the item details here that are in array called "item"
311 $item = $json->item;
312 $actual_available_stock = (int) property_exists( $item, 'actual_available_stock' ) ? $item->actual_available_stock : '0';
313 $rate = (int) property_exists( $item, 'rate' ) ? $item->rate : '0';
314 echo '<p class="howto"><strong>Rate: </strong>' . esc_html( $rate ) . '</p>';
315 // echo the actual_available_stock
316 echo '<p class="howto"><strong>Available Stock: </strong>' . esc_html( $actual_available_stock ) . '</p>';
317 }
318 }
319 }
320 add_action( 'add_meta_boxes', 'cmbird_product_metabox' );
321
322
323 /**
324 * Add Zoho and Exact Item IDs to Product and Variations
325 * @return void
326 */
327 add_action( 'woocommerce_product_options_pricing', 'cmbird_item_id_field' );
328 add_action( 'woocommerce_variation_options_pricing', 'cmbird_item_id_variation_field', 10, 3 );
329 function cmbird_item_id_field() {
330 woocommerce_wp_text_input(
331 array(
332 'id' => '_cost_price',
333 'class' => 'readonly',
334 'wrapper_class' => 'form-row',
335 'label' => esc_html__( 'Cost Price', 'commercebird' ),
336 'data_type' => 'price',
337 'description' => esc_html__( 'You can edit this via the CommerceBird App', 'commercebird' ),
338 )
339 );
340 woocommerce_wp_text_input(
341 array(
342 'id' => 'eo_item_id',
343 'label' => esc_html__( 'Exact Item ID', 'commercebird' ),
344 'class' => 'readonly',
345 'desc_tip' => true,
346 'description' => esc_html__( 'This is the Exact Item ID of this product. You cannot change this', 'commercebird' ),
347 )
348 );
349 woocommerce_wp_text_input(
350 array(
351 'id' => 'zi_item_id',
352 'label' => esc_html__( 'Zoho Item ID', 'commercebird' ),
353 'class' => 'readonly',
354 'desc_tip' => true,
355 'description' => esc_html__( 'This is the Zoho Item ID of this product. You cannot change this', 'commercebird' ),
356 )
357 );
358 }
359 function cmbird_item_id_variation_field( $loop, $variation_data, $variation ) {
360 woocommerce_wp_text_input(
361 array(
362 'id' => 'cost_price[' . $loop . ']',
363 'class' => 'readonly',
364 'wrapper_class' => 'form-row',
365 'data_type' => 'price',
366 'label' => esc_html__( 'Cost Price', 'commercebird' ),
367 'value' => get_post_meta( $variation->ID, '_cost_price', true ),
368 'description' => esc_html__( 'You can edit this via the CommerceBird App', 'commercebird' ),
369 )
370 );
371 woocommerce_wp_text_input(
372 array(
373 'id' => 'eo_item_id[' . $loop . ']',
374 'class' => 'readonly',
375 'label' => esc_html__( 'Exact Item ID', 'commercebird' ),
376 'value' => get_post_meta( $variation->ID, 'eo_item_id', true ),
377 'desc_tip' => true,
378 'description' => esc_html__( 'This is the Exact Item ID of this product. You cannot change this', 'commercebird' ),
379 )
380 );
381 woocommerce_wp_text_input(
382 array(
383 'id' => 'zi_item_id[' . $loop . ']',
384 'class' => 'readonly',
385 'label' => esc_html__( 'Zoho Item ID', 'commercebird' ),
386 'value' => get_post_meta( $variation->ID, 'zi_item_id', true ),
387 'desc_tip' => true,
388 'description' => esc_html__( 'This is the Zoho Item ID of this product. You cannot change this', 'commercebird' ),
389 )
390 );
391 }
392
393 /**
394 * Adds 'Zoho Sync' column header to 'Orders' page immediately after 'Total' column.
395 *
396 * @param string[] $columns
397 * @return string[] $new_columns
398 */
399 function cmbird_zi_sync_column_orders_overview( $columns ) {
400 $zoho_inventory_access_token = get_option( 'cmbird_zoho_inventory_access_token' );
401 if ( empty( $zoho_inventory_access_token ) ) {
402 return $columns;
403 }
404 $new_columns = array();
405 foreach ( $columns as $column_name => $column_info ) {
406
407 $new_columns[ $column_name ] = $column_info;
408
409 if ( 'order_total' === $column_name ) {
410 $new_columns['zoho_sync'] = __( 'Zoho Sync', 'commercebird' );
411 }
412 }
413 return $new_columns;
414 }
415 add_filter( 'manage_woocommerce_page_wc-orders_columns', 'cmbird_zi_sync_column_orders_overview', 20 );
416
417 /**
418 * Adding Sync Status for Orders Column
419 *
420 * @param string $column Column name.
421 * @param int $order_id $order id.
422 * @return void
423 */
424 function cmbird_zi_add_zoho_orders_content( $column, $order_id ) {
425 $zi_url = get_option( 'cmbird_zoho_inventory_url' );
426 $zi_visit_url = str_replace( 'www.zohoapis', 'inventory.zoho', $zi_url );
427 switch ( $column ) {
428 case 'zoho_sync':
429 // Get custom order meta data.
430 $order = wc_get_order( $order_id );
431 $zi_order_id = $order->get_meta( 'zi_salesorder_id', true, 'edit' );
432 $url = $zi_visit_url . 'app#/salesorders/' . $zi_order_id;
433 if ( $zi_order_id ) {
434 echo '<span class="dashicons dashicons-yes-alt" style="color:green;"></span><a href="' . esc_url( $url ) . '" target="_blank"> <span class="dashicons dashicons-external" style="color:green;"></span> </a>';
435 } else {
436 echo '<span class="dashicons dashicons-dismiss" style="color:red;"></span>';
437 }
438 unset( $order );
439 break;
440 }
441 }
442 add_action( 'manage_woocommerce_page_wc-orders_custom_column', 'cmbird_zi_add_zoho_orders_content', 20, 2 );
443
444 /**
445 * Adds 'Zoho Sync' column content.
446 *
447 * @param string[] $column name of column being displayed
448 */
449 function cmbird_zi_add_zoho_column_content( $column ) {
450 global $post;
451 $post_type = get_post_type( $post );
452
453 if ( 'zoho_sync' === $column && 'product' === $post_type ) {
454 $product_id = $post->ID;
455 $zi_product_id = get_post_meta( $product_id, 'zi_item_id' );
456 if ( $zi_product_id ) {
457 echo '<span class="dashicons dashicons-yes-alt" style="color:green;"></span>';
458 } else {
459 echo '<span class="dashicons dashicons-dismiss" style="color:red;"></span>';
460 }
461 }
462 }
463 add_action( 'manage_product_posts_custom_column', 'cmbird_zi_add_zoho_column_content' );
464
465 /**
466 * Adds 'Zoho Sync' column header to 'Products' page.
467 *
468 * @param string[] $columns
469 * @return string[] $new_columns
470 */
471 function cmbird_zi_sync_column_products_overview( $columns ) {
472 $zoho_inventory_access_token = get_option( 'cmbird_zoho_inventory_access_token' );
473 if ( empty( $zoho_inventory_access_token ) ) {
474 return $columns;
475 }
476 $new_columns = array();
477
478 foreach ( $columns as $column_name => $column_info ) {
479
480 $new_columns[ $column_name ] = $column_info;
481
482 if ( 'product_cat' === $column_name ) {
483 $new_columns['zoho_sync'] = __( 'Zoho Sync', 'commercebird' );
484 }
485 }
486
487 return $new_columns;
488 }
489 add_filter( 'manage_edit-product_columns', 'cmbird_zi_sync_column_products_overview', 20 );
490
491 /**
492 * Make 'Zoho Sync' column filterable.
493 */
494 function cmbird_zi_sync_column_filterable() {
495 global $typenow;
496
497 if ( 'product' === $typenow ) {
498 // code here
499 $value = isset( $_GET['zoho_sync_filter'] ) ? sanitize_text_field( wp_unslash( $_GET['zoho_sync_filter'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
500
501 echo '<select name="zoho_sync_filter">';
502 echo '<option value="">Zoho Sync Filter</option>';
503
504 // Count synced products
505 $synced_count = new WP_Query(
506 array(
507 'post_type' => 'product',
508 'meta_query' => array(
509 array(
510 'key' => 'zi_item_id',
511 'compare' => 'EXISTS',
512 ),
513 ),
514 'fields' => 'ids',
515 )
516 );
517 $synced_count = $synced_count->found_posts;
518 $synced_label = 'Synced';
519 if ( $synced_count > 0 ) {
520 $synced_label .= ' (' . $synced_count . ')';
521 }
522 echo '<option value="synced" ' . selected( $value, 'synced', false ) . '>' . esc_html( $synced_label ) . '</option>';
523
524 // Count not synced products
525 $not_synced_count = new WP_Query(
526 array(
527 'post_type' => 'product',
528 'meta_query' => array(
529 array(
530 'key' => 'zi_item_id',
531 'compare' => 'NOT EXISTS',
532 ),
533 ),
534 'fields' => 'ids',
535 )
536 );
537 $not_synced_count = $not_synced_count->found_posts;
538 $not_synced_label = 'Not Synced';
539 if ( $not_synced_count > 0 ) {
540 $not_synced_label .= ' (' . $not_synced_count . ')';
541 }
542 echo '<option value="not_synced" ' . selected( $value, 'not_synced', false ) . '>' . esc_html( $not_synced_label ) . '</option>';
543
544 echo '</select>';
545 }
546 }
547 add_action( 'restrict_manage_posts', 'cmbird_zi_sync_column_filterable' );
548
549 /**
550 * Modify the product query based on the filter.
551 *
552 * @param WP_Query $query The query object.
553 */
554 function cmbird_zi_sync_column_filter_query( $query ) {
555 global $typenow, $pagenow;
556
557 if ( $typenow === 'product' && $pagenow === 'edit.php' && isset( $_GET['zoho_sync_filter'] ) && $_GET['zoho_sync_filter'] !== '' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
558 $value = sanitize_text_field( wp_unslash( $_GET['zoho_sync_filter'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
559
560 $meta_query = array();
561
562 if ( $value === 'synced' ) {
563 $meta_query[] = array(
564 'key' => 'zi_item_id',
565 'compare' => 'EXISTS',
566 );
567 } elseif ( $value === 'not_synced' ) {
568 $meta_query[] = array(
569 'relation' => 'OR',
570 array(
571 'key' => 'zi_item_id',
572 'compare' => 'NOT EXISTS',
573 ),
574 array(
575 'key' => 'zi_item_id',
576 'value' => '',
577 'compare' => '=',
578 ),
579 );
580 }
581
582 $query->set( 'meta_query', $meta_query );
583 }
584 }
585 add_action( 'pre_get_posts', 'cmbird_zi_sync_column_filter_query' );
586
587 /**
588 * Change Action Scheduler default purge to 1 week
589 * @return int
590 */
591 function cmbird_action_scheduler_purge() {
592 return WEEK_IN_SECONDS;
593 }
594 add_filter( 'action_scheduler_retention_period', 'cmbird_action_scheduler_purge' );
595
596 add_filter(
597 'action_scheduler_default_cleaner_statuses',
598 function ($statuses) {
599 $statuses[] = ActionScheduler_Store::STATUS_FAILED;
600 return $statuses;
601 }
602 );
603
604 /**
605 * Modify the Products API to include brands.
606 *
607 * TODO: This is a temporary solution. We need to find a better way to include brands in the API response.
608 *
609 * @param $response The response object.
610 * @param $post The post object.
611 * @param $request The request object.
612 * @return mixed
613 */
614 add_filter( 'woocommerce_rest_prepare_product_object', 'cmbird_rest_api_prepare_brands_tax', 10, 3 );
615 function cmbird_rest_api_prepare_brands_tax( $response, $object, $request ) {
616 $product_id = $object->get_id();
617 if ( empty( $response->data['product_brands'] ) ) {
618 $terms = [];
619 foreach ( wp_get_post_terms( $product_id, 'product_brands' ) as $term ) {
620 $terms[] = [
621 'id' => $term->term_id,
622 'name' => $term->name,
623 'slug' => $term->slug,
624 ];
625 }
626 $response->data['product_brands'] = $terms;
627 }
628 return $response;
629 }
630
631
632 function cmbird_prepare_insert_product( $product, $request ) {
633 if ( isset( $request['product_brands'] ) ) {
634 wp_set_post_terms( $request['id'], $request['product_brands'], 'product_brands', false );
635 }
636 return $product;
637 }
638 add_filter( 'woocommerce_rest_pre_insert_product_object', 'cmbird_prepare_insert_product', 10, 2 );