PluginProbe ʕ •ᴥ•ʔ
CommerceBird – AI Command Center, ERP Integrations & B2B for WooCommerce (Zoho, Exact Online). / 2.3.14
CommerceBird – AI Command Center, ERP Integrations & B2B for WooCommerce (Zoho, Exact Online). v2.3.14
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 11 months ago sync 11 months ago index.php 1 year ago woo-functions.php 1 year ago
woo-functions.php
643 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 // echo the zoho category name from the item
318 $category_name = (string) property_exists( $item, 'category_name' ) ? $item->category_name : '';
319 if ( ! empty( $category_name ) || 'variable' === $product_type || 'variable-subscription' === $product_type ) {
320 echo '<p class="howto"><strong>Category Name: </strong>' . esc_html( $category_name ) . '</p>';
321 }
322 }
323 }
324 }
325 add_action( 'add_meta_boxes', 'cmbird_product_metabox' );
326
327
328 /**
329 * Add Zoho and Exact Item IDs to Product and Variations
330 * @return void
331 */
332 add_action( 'woocommerce_product_options_pricing', 'cmbird_item_id_field' );
333 add_action( 'woocommerce_variation_options_pricing', 'cmbird_item_id_variation_field', 10, 3 );
334 function cmbird_item_id_field() {
335 woocommerce_wp_text_input(
336 array(
337 'id' => '_cost_price',
338 'class' => 'readonly',
339 'wrapper_class' => 'form-row',
340 'label' => esc_html__( 'Cost Price', 'commercebird' ),
341 'data_type' => 'price',
342 'description' => esc_html__( 'You can edit this via the CommerceBird App', 'commercebird' ),
343 )
344 );
345 woocommerce_wp_text_input(
346 array(
347 'id' => 'eo_item_id',
348 'label' => esc_html__( 'Exact Item ID', 'commercebird' ),
349 'class' => 'readonly',
350 'desc_tip' => true,
351 'description' => esc_html__( 'This is the Exact Item ID of this product. You cannot change this', 'commercebird' ),
352 )
353 );
354 woocommerce_wp_text_input(
355 array(
356 'id' => 'zi_item_id',
357 'label' => esc_html__( 'Zoho Item ID', 'commercebird' ),
358 'class' => 'readonly',
359 'desc_tip' => true,
360 'description' => esc_html__( 'This is the Zoho Item ID of this product. You cannot change this', 'commercebird' ),
361 )
362 );
363 }
364 function cmbird_item_id_variation_field( $loop, $variation_data, $variation ) {
365 woocommerce_wp_text_input(
366 array(
367 'id' => 'cost_price[' . $loop . ']',
368 'class' => 'readonly',
369 'wrapper_class' => 'form-row',
370 'data_type' => 'price',
371 'label' => esc_html__( 'Cost Price', 'commercebird' ),
372 'value' => get_post_meta( $variation->ID, '_cost_price', true ),
373 'description' => esc_html__( 'You can edit this via the CommerceBird App', 'commercebird' ),
374 )
375 );
376 woocommerce_wp_text_input(
377 array(
378 'id' => 'eo_item_id[' . $loop . ']',
379 'class' => 'readonly',
380 'label' => esc_html__( 'Exact Item ID', 'commercebird' ),
381 'value' => get_post_meta( $variation->ID, 'eo_item_id', true ),
382 'desc_tip' => true,
383 'description' => esc_html__( 'This is the Exact Item ID of this product. You cannot change this', 'commercebird' ),
384 )
385 );
386 woocommerce_wp_text_input(
387 array(
388 'id' => 'zi_item_id[' . $loop . ']',
389 'class' => 'readonly',
390 'label' => esc_html__( 'Zoho Item ID', 'commercebird' ),
391 'value' => get_post_meta( $variation->ID, 'zi_item_id', true ),
392 'desc_tip' => true,
393 'description' => esc_html__( 'This is the Zoho Item ID of this product. You cannot change this', 'commercebird' ),
394 )
395 );
396 }
397
398 /**
399 * Adds 'Zoho Sync' column header to 'Orders' page immediately after 'Total' column.
400 *
401 * @param string[] $columns
402 * @return string[] $new_columns
403 */
404 function cmbird_zi_sync_column_orders_overview( $columns ) {
405 $zoho_inventory_access_token = get_option( 'cmbird_zoho_inventory_access_token' );
406 if ( empty( $zoho_inventory_access_token ) ) {
407 return $columns;
408 }
409 $new_columns = array();
410 foreach ( $columns as $column_name => $column_info ) {
411
412 $new_columns[ $column_name ] = $column_info;
413
414 if ( 'order_total' === $column_name ) {
415 $new_columns['zoho_sync'] = __( 'Zoho Sync', 'commercebird' );
416 }
417 }
418 return $new_columns;
419 }
420 add_filter( 'manage_woocommerce_page_wc-orders_columns', 'cmbird_zi_sync_column_orders_overview', 20 );
421
422 /**
423 * Adding Sync Status for Orders Column
424 *
425 * @param string $column Column name.
426 * @param int $order_id $order id.
427 * @return void
428 */
429 function cmbird_zi_add_zoho_orders_content( $column, $order_id ) {
430 $zi_url = get_option( 'cmbird_zoho_inventory_url' );
431 $zi_visit_url = str_replace( 'www.zohoapis', 'inventory.zoho', $zi_url );
432 switch ( $column ) {
433 case 'zoho_sync':
434 // Get custom order meta data.
435 $order = wc_get_order( $order_id );
436 $zi_order_id = $order->get_meta( 'zi_salesorder_id', true, 'edit' );
437 $url = $zi_visit_url . 'app#/salesorders/' . $zi_order_id;
438 if ( $zi_order_id ) {
439 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>';
440 } else {
441 echo '<span class="dashicons dashicons-dismiss" style="color:red;"></span>';
442 }
443 unset( $order );
444 break;
445 }
446 }
447 add_action( 'manage_woocommerce_page_wc-orders_custom_column', 'cmbird_zi_add_zoho_orders_content', 20, 2 );
448
449 /**
450 * Adds 'Zoho Sync' column content.
451 *
452 * @param string[] $column name of column being displayed
453 */
454 function cmbird_zi_add_zoho_column_content( $column ) {
455 global $post;
456 $post_type = get_post_type( $post );
457
458 if ( 'zoho_sync' === $column && 'product' === $post_type ) {
459 $product_id = $post->ID;
460 $zi_product_id = get_post_meta( $product_id, 'zi_item_id' );
461 if ( $zi_product_id ) {
462 echo '<span class="dashicons dashicons-yes-alt" style="color:green;"></span>';
463 } else {
464 echo '<span class="dashicons dashicons-dismiss" style="color:red;"></span>';
465 }
466 }
467 }
468 add_action( 'manage_product_posts_custom_column', 'cmbird_zi_add_zoho_column_content' );
469
470 /**
471 * Adds 'Zoho Sync' column header to 'Products' page.
472 *
473 * @param string[] $columns
474 * @return string[] $new_columns
475 */
476 function cmbird_zi_sync_column_products_overview( $columns ) {
477 $zoho_inventory_access_token = get_option( 'cmbird_zoho_inventory_access_token' );
478 if ( empty( $zoho_inventory_access_token ) ) {
479 return $columns;
480 }
481 $new_columns = array();
482
483 foreach ( $columns as $column_name => $column_info ) {
484
485 $new_columns[ $column_name ] = $column_info;
486
487 if ( 'product_cat' === $column_name ) {
488 $new_columns['zoho_sync'] = __( 'Zoho Sync', 'commercebird' );
489 }
490 }
491
492 return $new_columns;
493 }
494 add_filter( 'manage_edit-product_columns', 'cmbird_zi_sync_column_products_overview', 20 );
495
496 /**
497 * Make 'Zoho Sync' column filterable.
498 */
499 function cmbird_zi_sync_column_filterable() {
500 global $typenow;
501
502 if ( 'product' === $typenow ) {
503 // code here
504 $value = isset( $_GET['zoho_sync_filter'] ) ? sanitize_text_field( wp_unslash( $_GET['zoho_sync_filter'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
505
506 echo '<select name="zoho_sync_filter">';
507 echo '<option value="">Zoho Sync Filter</option>';
508
509 // Count synced products
510 $synced_count = new WP_Query(
511 array(
512 'post_type' => 'product',
513 'meta_query' => array(
514 array(
515 'key' => 'zi_item_id',
516 'compare' => 'EXISTS',
517 ),
518 ),
519 'fields' => 'ids',
520 )
521 );
522 $synced_count = $synced_count->found_posts;
523 $synced_label = 'Synced';
524 if ( $synced_count > 0 ) {
525 $synced_label .= ' (' . $synced_count . ')';
526 }
527 echo '<option value="synced" ' . selected( $value, 'synced', false ) . '>' . esc_html( $synced_label ) . '</option>';
528
529 // Count not synced products
530 $not_synced_count = new WP_Query(
531 array(
532 'post_type' => 'product',
533 'meta_query' => array(
534 array(
535 'key' => 'zi_item_id',
536 'compare' => 'NOT EXISTS',
537 ),
538 ),
539 'fields' => 'ids',
540 )
541 );
542 $not_synced_count = $not_synced_count->found_posts;
543 $not_synced_label = 'Not Synced';
544 if ( $not_synced_count > 0 ) {
545 $not_synced_label .= ' (' . $not_synced_count . ')';
546 }
547 echo '<option value="not_synced" ' . selected( $value, 'not_synced', false ) . '>' . esc_html( $not_synced_label ) . '</option>';
548
549 echo '</select>';
550 }
551 }
552 add_action( 'restrict_manage_posts', 'cmbird_zi_sync_column_filterable' );
553
554 /**
555 * Modify the product query based on the filter.
556 *
557 * @param WP_Query $query The query object.
558 */
559 function cmbird_zi_sync_column_filter_query( $query ) {
560 global $typenow, $pagenow;
561
562 if ( $typenow === 'product' && $pagenow === 'edit.php' && isset( $_GET['zoho_sync_filter'] ) && $_GET['zoho_sync_filter'] !== '' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
563 $value = sanitize_text_field( wp_unslash( $_GET['zoho_sync_filter'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
564
565 $meta_query = array();
566
567 if ( $value === 'synced' ) {
568 $meta_query[] = array(
569 'key' => 'zi_item_id',
570 'compare' => 'EXISTS',
571 );
572 } elseif ( $value === 'not_synced' ) {
573 $meta_query[] = array(
574 'relation' => 'OR',
575 array(
576 'key' => 'zi_item_id',
577 'compare' => 'NOT EXISTS',
578 ),
579 array(
580 'key' => 'zi_item_id',
581 'value' => '',
582 'compare' => '=',
583 ),
584 );
585 }
586
587 $query->set( 'meta_query', $meta_query );
588 }
589 }
590 add_action( 'pre_get_posts', 'cmbird_zi_sync_column_filter_query' );
591
592 /**
593 * Change Action Scheduler default purge to 1 week
594 * @return int
595 */
596 function cmbird_action_scheduler_purge() {
597 return WEEK_IN_SECONDS;
598 }
599 add_filter( 'action_scheduler_retention_period', 'cmbird_action_scheduler_purge' );
600
601 add_filter(
602 'action_scheduler_default_cleaner_statuses',
603 function ($statuses) {
604 $statuses[] = ActionScheduler_Store::STATUS_FAILED;
605 return $statuses;
606 }
607 );
608
609 /**
610 * Modify the Products API to include brands.
611 *
612 * TODO: This is a temporary solution. We need to find a better way to include brands in the API response.
613 *
614 * @param $response The response object.
615 * @param $post The post object.
616 * @param $request The request object.
617 * @return mixed
618 */
619 //add_filter( 'woocommerce_rest_prepare_product_object', 'cmbird_rest_api_prepare_brands_tax', 10, 3 );
620 function cmbird_rest_api_prepare_brands_tax( $response, $object, $request ) {
621 $product_id = $object->get_id();
622 if ( empty( $response->data['product_brands'] ) ) {
623 $terms = [];
624 foreach ( wp_get_post_terms( $product_id, 'product_brands' ) as $term ) {
625 $terms[] = [
626 'id' => $term->term_id,
627 'name' => $term->name,
628 'slug' => $term->slug,
629 ];
630 }
631 $response->data['product_brands'] = $terms;
632 }
633 return $response;
634 }
635
636
637 function cmbird_prepare_insert_product( $product, $request ) {
638 if ( isset( $request['product_brands'] ) ) {
639 wp_set_post_terms( $request['id'], $request['product_brands'], 'product_brands', false );
640 }
641 return $product;
642 }
643 // add_filter( 'woocommerce_rest_pre_insert_product_object', 'cmbird_prepare_insert_product', 10, 2 );