PluginProbe
MStore API – Create Native Android & iOS Apps On The Cloud / 4.18.4
MStore API – Create Native Android & iOS Apps On The Cloud v4.18.4
4.21.3 4.21.2 4.21.1 trunk 1.1.5 2.9.4 2.9.5 2.9.6 2.9.7 2.9.8 2.9.9 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 All 192 releases
mstore-api / mstore-api.php

mstore-api.php in MStore API – Create Native Android & iOS Apps On The Cloud 4.18.4, at mstore-api.php

1,483 lines 60.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: MStore API
4 * Plugin URI: https://github.com/inspireui/mstore-api
5 * Description: The MStore API Plugin which is used for the FluxBuilder and FluxStore Mobile App
6 * Version: 4.18.4
7 * Author: FluxBuilder
8 * Author URI: https://fluxbuilder.com
9 *
10 * Text Domain: MStore-Api
11 */
12
13 defined('ABSPATH') or wp_die('No script kiddies please!');
14
15
16 // use MStoreCheckout\Templates\MDetect;
17
18 include plugin_dir_path(__FILE__) . "templates/class-mobile-detect.php";
19 include plugin_dir_path(__FILE__) . "templates/class-rename-generate.php";
20 include_once plugin_dir_path(__FILE__) . "controllers/flutter-app.php";
21 include_once plugin_dir_path(__FILE__) . "controllers/flutter-user.php";
22 include_once plugin_dir_path(__FILE__) . "controllers/flutter-home.php";
23 include_once plugin_dir_path(__FILE__) . "controllers/flutter-booking.php";
24 include_once plugin_dir_path(__FILE__) . "controllers/flutter-vendor-admin.php";
25 include_once plugin_dir_path(__FILE__) . "controllers/flutter-woo.php";
26 include_once plugin_dir_path(__FILE__) . "controllers/flutter-delivery.php";
27 include_once plugin_dir_path(__FILE__) . "functions/index.php";
28 include_once plugin_dir_path(__FILE__) . "functions/utils.php";
29 include_once plugin_dir_path(__FILE__) . "controllers/flutter-tera-wallet.php";
30 include_once plugin_dir_path(__FILE__) . "controllers/flutter-paytm.php";
31 include_once plugin_dir_path(__FILE__) . "controllers/flutter-paystack.php";
32 include_once plugin_dir_path(__FILE__) . "controllers/flutter-flutterwave.php";
33 include_once plugin_dir_path(__FILE__) . "controllers/flutter-myfatoorah.php";
34 include_once plugin_dir_path(__FILE__) . "controllers/flutter-midtrans.php";
35 include_once plugin_dir_path(__FILE__) . "controllers/flutter-modempay.php";
36 include_once plugin_dir_path(__FILE__) . "controllers/flutter-paid-memberships-pro.php";
37 include_once plugin_dir_path(__FILE__) . "controllers/listing-rest-api/class.api.fields.php";
38 include_once plugin_dir_path(__FILE__) . "controllers/flutter-blog.php";
39 include_once plugin_dir_path(__FILE__) . "controllers/flutter-wholesale.php";
40 include_once plugin_dir_path(__FILE__) . "controllers/flutter-stripe.php";
41 include_once plugin_dir_path(__FILE__) . "controllers/flutter-notification.php";
42 include_once plugin_dir_path(__FILE__) . "controllers/flutter-thawani.php";
43 include_once plugin_dir_path(__FILE__) . "controllers/flutter-expresspay.php";
44 include_once plugin_dir_path(__FILE__) . "controllers/flutter-2c2p.php";
45 include_once plugin_dir_path(__FILE__) . "controllers/flutter-cc-avenue.php";
46 include_once plugin_dir_path(__FILE__) . "controllers/flutter-flow-flow.php";
47 include_once plugin_dir_path(__FILE__) . "controllers/flutter-store-locator.php";
48 include_once plugin_dir_path(__FILE__) . "controllers/flutter-composite-products.php";
49 include_once plugin_dir_path(__FILE__) . "controllers/flutter-b2bking.php";
50 include_once plugin_dir_path(__FILE__) . "controllers/flutter-review.php";
51 include_once plugin_dir_path(__FILE__) . "controllers/helpers/firebase-message-helper.php";
52 include_once plugin_dir_path(__FILE__) . "controllers/flutter-fib.php";
53 include_once plugin_dir_path(__FILE__) . "controllers/helpers/firebase-phone-auth-helper.php";
54 include_once plugin_dir_path(__FILE__) . "controllers/helpers/pure-taxonomies-helper.php";
55 include_once plugin_dir_path(__FILE__) . "controllers/flutter-auction.php";
56 include_once plugin_dir_path(__FILE__) . "controllers/flutter-iyzico.php";
57 include_once plugin_dir_path(__FILE__) . "controllers/flutter-phonepe.php";
58 include_once plugin_dir_path(__FILE__) . "controllers/flutter-points-offline-store.php";
59 include_once plugin_dir_path(__FILE__) . "controllers/flutter-smart-cod.php";
60 include_once plugin_dir_path(__FILE__) . "controllers/flutter-discount-rules.php";
61 include_once plugin_dir_path(__FILE__) . "controllers/flutter-checkout.php";
62 include_once plugin_dir_path(__FILE__) . "controllers/flutter-razorpay.php";
63 include_once plugin_dir_path(__FILE__) . "controllers/flutter-fibo-search.php";
64 include_once plugin_dir_path(__FILE__) . "controllers/helpers/fibosearch-woo-rest-integration.php";
65 include_once plugin_dir_path(__FILE__) . "controllers/flutter-paypal.php";
66 include_once plugin_dir_path(__FILE__) . "controllers/flutter-rental.php";
67
68 if ( is_readable( __DIR__ . '/vendor/autoload.php' ) ) {
69 require __DIR__ . '/vendor/autoload.php';
70 }
71
72 class MstoreCheckOut
73 {
74 public $version = '4.18.4';
75
76 public function __construct()
77 {
78 define('MSTORE_CHECKOUT_VERSION', $this->version);
79 define('MSTORE_PLUGIN_FILE', __FILE__);
80
81 /**
82 * Prepare data before checkout by webview
83 */
84 add_action('template_redirect', 'flutter_prepare_checkout');
85
86 add_action( 'pre_get_posts', 'set_author_in_for_vendor_staff' );
87
88 include_once(ABSPATH . 'wp-admin/includes/plugin.php');
89 //include_once(ABSPATH . 'wp-includes/pluggable.php');
90
91 // //migrate old versions to re-verify purchase code automatically
92 // verifyPurchaseCodeAuto();
93
94 add_filter( 'get_avatar_url', array( $this, 'filter_avatar' ), 10, 3 );
95
96 if (is_plugin_active('woocommerce/woocommerce.php') == false) {
97 return 0;
98 }
99 add_action('woocommerce_init', 'woocommerce_mstore_init');
100 function woocommerce_mstore_init()
101 {
102 include_once plugin_dir_path(__FILE__) . "controllers/flutter-order.php";
103 include_once plugin_dir_path(__FILE__) . "controllers/flutter-multi-vendor.php";
104 include_once plugin_dir_path(__FILE__) . "controllers/flutter-vendor.php";
105 include_once plugin_dir_path(__FILE__) . "controllers/helpers/delivery-wcfm-helper.php";
106 include_once plugin_dir_path(__FILE__) . "controllers/helpers/delivery-wcfm-helper.php";
107 include_once plugin_dir_path(__FILE__) . "controllers/helpers/vendor-admin-woo-helper.php";
108 include_once plugin_dir_path(__FILE__) . "controllers/helpers/vendor-admin-wcfm-helper.php";
109 include_once plugin_dir_path(__FILE__) . "controllers/helpers/vendor-admin-dokan-helper.php";
110 include_once plugin_dir_path(__FILE__) . "controllers/flutter-customer.php";
111 include_once plugin_dir_path(__FILE__) . "functions/video-setting-embed.php";
112 }
113
114 add_filter('wp_rest_cache/allowed_endpoints', array($this, 'wprc_add_flutter_api_endpoints'));
115
116 $order = filter_has_var(INPUT_GET, 'code') && strlen(filter_input(INPUT_GET, 'code')) > 0 ? true : false;
117 if ($order) {
118 add_filter('woocommerce_is_checkout', '__return_true');
119 }
120
121 /*
122 add_filter( 'woocommerce_get_item_data', 'display_custom_product_field_data_mstore_api', 10, 2 );
123
124 function display_custom_product_field_data_mstore_api( $cart_data, $cart_item ) {
125
126 if( !empty( $cart_data ) ){
127 $custom_items = $cart_data;
128
129 $code = sanitize_text_field($_GET['code']) ?: get_transient( 'mstore_code' );
130 set_transient( 'mstore_code', $code, 600 );
131
132 global $wpdb;
133 $table_name = $wpdb->prefix . "mstore_checkout";
134 $item = $wpdb->get_row("SELECT * FROM $table_name WHERE code = '$code'");
135 if ($item) {
136 $data = json_decode(urldecode(base64_decode($item->order)), true);
137 $line_items = $data['line_items'];
138 $product_ids = [];
139 foreach($line_items as $line => $item) {
140 $product_ids[$item['product_id']] = $item;
141 }
142
143 if (array_key_exists($cart_item['product_id'], $product_ids)) {
144 if ($varian = $product_ids[$cart_item['product_id']]) {
145 $variations = $varian['meta_data'];
146 foreach($variations as $v => $f) {
147 preg_match('#\((.*?)\)#', $f['key'], $match);
148 $val = $match[1];
149 $custom_items[] = array(
150 'key' => $f['value'],
151 'value' => $val,
152 'display' => $val,
153 );
154 }
155 }
156 }
157 }
158
159 return $custom_items;
160 }
161 return $cart_data;
162 }
163
164
165 add_action( 'woocommerce_before_calculate_totals', 'add_custom_price_mstore_api' );
166
167 function add_custom_price_mstore_api( $cart_object ) {
168 foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
169 $add_price = 0;
170 if ($variations = $cart_item['variation']) {
171 foreach($variations as $v => $f) {
172 preg_match('#\((.*?)\)#', $v, $match);
173 if(is_array($match) && array_key_exists(1,$match)){
174 $val = $match[1];
175 $cents = filter_var($val, FILTER_SANITIZE_NUMBER_INT);
176 if(is_numeric($cents)){
177 $add_price += floatval($cents / 100);
178 }
179 }
180 }
181 }
182 $new_price = $cart_item['data']->get_price() + $add_price;
183 $cart_item['data']->set_price($new_price);
184 }
185 }
186 */
187
188 add_action('wp_print_scripts', array($this, 'handle_received_order_page'));
189
190 //add meta box shipping location in order detail
191 add_action('add_meta_boxes', 'mv_add_meta_boxes');
192 if (!function_exists('mv_add_meta_boxes')) {
193 function mv_add_meta_boxes()
194 {
195 add_meta_box('mv_other_fields', __('Shipping Location', 'woocommerce'), 'mv_add_other_fields_for_packaging', 'shop_order', 'side', 'core');
196 }
197 }
198 // Adding Meta field in the meta container admin shop_order pages
199 if (!function_exists('mv_add_other_fields_for_packaging')) {
200 function mv_add_other_fields_for_packaging()
201 {
202 global $post;
203 $note = $post->post_excerpt;
204 $items = explode("\n", $note);
205 if (strpos($items[0], "URL:") !== false) {
206 $url = str_replace("URL:", "", $items[0]);
207 echo esc_html('<iframe width="600" height="500" src="' . esc_url($url) . '"></iframe>');
208 }
209 }
210 }
211
212 register_activation_hook(__FILE__, array($this, 'create_custom_mstore_table'));
213
214 // Setup Ajax action hook
215 add_action('wp_ajax_mstore_delete_json_file', array($this, 'mstore_delete_json_file'));
216 add_action('wp_ajax_mstore_delete_apple_file', array($this, 'mstore_delete_apple_file'));
217 add_action('wp_ajax_mstore_delete_firebase_file', array($this, 'mstore_delete_firebase_file'));
218 add_action('wp_ajax_mstore_update_limit_product', array($this, 'mstore_update_limit_product'));
219 add_action('wp_ajax_mstore_update_new_order_title', array($this, 'mstore_update_new_order_title'));
220 add_action('wp_ajax_mstore_update_new_order_message', array($this, 'mstore_update_new_order_message'));
221 add_action('wp_ajax_mstore_update_status_order_title', array($this, 'mstore_update_status_order_title'));
222 add_action('wp_ajax_mstore_update_status_order_message', array($this, 'mstore_update_status_order_message'));
223
224 // listen changed order status to notify
225 add_action('woocommerce_order_status_changed', array($this, 'track_order_status_changed'), 9, 4);
226 add_action('woocommerce_checkout_update_order_meta', array($this, 'track_new_order'));
227 add_action('woocommerce_rest_insert_shop_order_object', array($this, 'track_api_new_order'), 10, 4);
228
229 //WCFM - WooCommerce Frontend Manager - Delivery
230 //Handle listen to assign delivery boy on the website
231 add_action( 'wcfmd_after_delivery_boy_assigned', array($this, 'track_delivery_boy_assigned'), 400, 6 );
232
233 $path = get_template_directory() . "/templates";
234 if (!file_exists($path)) {
235 mkdir($path, 0777, true);
236 }
237 if (file_exists($path)) {
238 $templatePath = plugin_dir_path(__FILE__) . "templates/mstore-api-template.php";
239 if (!copy($templatePath, $path . "/mstore-api-template.php")) {
240 return 0;
241 }
242 }
243 }
244
245 public function wprc_add_flutter_api_endpoints($allowed_endpoints){
246 if ( ! isset( $allowed_endpoints[ 'wc/v3' ] ) || ! in_array( 'products', $allowed_endpoints[ 'wc/v3' ] ) ) {
247 $allowed_endpoints[ 'wc/v3' ][] = 'products';
248 $allowed_endpoints[ 'wc/v3' ][] = 'products/categories';
249 $allowed_endpoints[ 'wc/v3' ][] = 'products/attributes';
250 }
251 if ( ! isset( $allowed_endpoints[ 'wc/v2' ] ) || ! in_array( 'products', $allowed_endpoints[ 'wc/v2' ] ) ) {
252 $allowed_endpoints[ 'wc/v2' ][] = 'products';
253 $allowed_endpoints[ 'wc/v2' ][] = 'products/categories';
254 $allowed_endpoints[ 'wc/v2' ][] = 'products/attributes';
255 }
256 return $allowed_endpoints;
257 }
258
259 public function filter_avatar($url, $id_or_email, $args)
260 {
261 $finder = false;
262 $user = false;
263
264 // Early return if id_or_email is empty
265 if (empty($id_or_email)) {
266 return $url;
267 }
268
269 if (is_numeric($id_or_email)) {
270 $user = get_user_by('id', absint($id_or_email));
271 } elseif (is_string($id_or_email) && is_email($id_or_email)) {
272 $user = get_user_by('email', $id_or_email);
273 } elseif ($id_or_email instanceof WP_User) {
274 $user = $id_or_email;
275 } elseif ($id_or_email instanceof WP_Post) {
276 $user = get_user_by('id', (int)$id_or_email->post_author);
277 } elseif ($id_or_email instanceof WP_Comment) {
278 if (!empty($id_or_email->user_id)) {
279 $user = get_user_by('id', (int)$id_or_email->user_id);
280 }
281 }
282
283 if ($user && !is_wp_error($user)) {
284 $avatar = get_user_meta($user->ID, 'user_avatar', true);
285 if (isset($avatar) && $avatar !== "" && !is_bool($avatar) && !empty($avatar[0])) {
286 return $avatar[0];
287 }
288 }
289
290 return $url;
291 }
292
293 function mstore_delete_json_file(){
294 if(checkIsAdmin(get_current_user_id())){
295 $id = sanitize_text_field($_REQUEST['id']);
296 $nonce = sanitize_text_field($_REQUEST['nonce']);
297 FlutterUtils::delete_config_file($id, $nonce);
298 }else{
299 wp_send_json_error('No Permission',401);
300 }
301 }
302
303 function mstore_delete_apple_file(){
304 if(checkIsAdmin(get_current_user_id())){
305 $nonce = sanitize_text_field($_REQUEST['nonce']);
306 FlutterAppleSignInUtils::delete_config_file($nonce);
307 wp_send_json('success',200);
308 }else{
309 wp_send_json_error('No Permission',401);
310 }
311 }
312
313 function mstore_delete_firebase_file(){
314 if(checkIsAdmin(get_current_user_id())){
315 $nonce = sanitize_text_field($_REQUEST['nonce']);
316 FirebaseMessageHelper::delete_config_file($nonce);
317 wp_send_json('success',200);
318 }else{
319 wp_send_json_error('No Permission',401);
320 }
321 }
322
323 function mstore_update_limit_product()
324 {
325 $nonce = sanitize_text_field($_REQUEST['nonce']);
326 if(checkIsAdmin(get_current_user_id()) && wp_verify_nonce($nonce, 'update_limit_product')){
327 $limit = sanitize_text_field($_REQUEST['limit']);
328 if (is_numeric($limit)) {
329 update_option("mstore_limit_product", intval($limit));
330 }
331 }else{
332 wp_send_json_error('No Permission',401);
333 }
334 }
335
336 function mstore_update_new_order_title()
337 {
338 $nonce = sanitize_text_field($_REQUEST['nonce']);
339 if(checkIsAdmin(get_current_user_id()) && wp_verify_nonce($nonce, 'update_new_order_title')){
340 $title = sanitize_text_field($_REQUEST['title']);
341 update_option("mstore_new_order_title", $title);
342 }else{
343 wp_send_json_error('No Permission',401);
344 }
345 }
346
347 function mstore_update_new_order_message()
348 {
349 $nonce = sanitize_text_field($_REQUEST['nonce']);
350 if(checkIsAdmin(get_current_user_id()) && wp_verify_nonce($nonce, 'update_new_order_message')){
351 $message = sanitize_text_field($_REQUEST['message']);
352 update_option("mstore_new_order_message", $message);
353 }else{
354 wp_send_json_error('No Permission',401);
355 }
356 }
357
358 function mstore_update_status_order_title()
359 {
360 $nonce = sanitize_text_field($_REQUEST['nonce']);
361 if(checkIsAdmin(get_current_user_id()) && wp_verify_nonce($nonce, 'update_status_order_title')){
362 $title = sanitize_text_field($_REQUEST['title']);
363 update_option("mstore_status_order_title", $title);
364 }else{
365 wp_send_json_error('No Permission',401);
366 }
367 }
368
369 function mstore_update_status_order_message()
370 {
371 $nonce = sanitize_text_field($_REQUEST['nonce']);
372 if(checkIsAdmin(get_current_user_id()) && wp_verify_nonce($nonce, 'update_status_order_message')){
373 $message = sanitize_text_field($_REQUEST['message']);
374 update_option("mstore_status_order_message", $message);
375 }else{
376 wp_send_json_error('No Permission',401);
377 }
378 }
379
380 // update order via website
381 function track_order_status_changed($id, $previous_status, $next_status)
382 {
383 trackOrderStatusChanged($id, $previous_status, $next_status);
384 }
385
386 // new order via website
387 function track_new_order($order_id)
388 {
389 trackNewOrder($order_id);
390 }
391
392 // New order or update order via API
393 function track_api_new_order($object, $request, $creating)
394 {
395 if ($creating) {
396 trackNewOrder($object->get_id());
397
398 // Update order attributes. Requires WooCommerce 8.5.0 or later.
399 // And make sure you have enabled `Order Attributes` in WooCommerce
400 // Settings > Advanced > Features.
401 // See: https://woocommerce.com/document/order-attribution-tracking/
402 do_action('woocommerce_store_api_checkout_update_order_from_request', $object, $request);
403 } else {
404 $body = $request->get_body_params();
405 if (isset($body['status'])) {
406 sendNotificationForOrderStatusUpdated($object->id, $body['status']);
407 }
408 }
409 }
410
411 function track_delivery_boy_assigned( $order_id, $order_item_id, $wcfm_tracking_data, $product_id, $wcfm_delivery_boy, $wcfm_messages ) {
412 $notification_message = strip_tags($wcfm_messages);
413 $title = "You have new notification";
414 pushNotificationForDeliveryBoy($wcfm_delivery_boy, $title, $notification_message);
415 }
416
417 public function handle_received_order_page()
418 {
419 // default return true for getting checkout library working
420 if (is_order_received_page()) {
421 $detect = new MDetect;
422 if ($detect->isMobile()) {
423 wp_register_style('mstore-order-custom-style', plugins_url('assets/css/mstore-order-style.css', MSTORE_PLUGIN_FILE));
424 wp_enqueue_style('mstore-order-custom-style');
425 }
426 }
427
428 }
429
430 function create_custom_mstore_table()
431 {
432 global $wpdb;
433 // include upgrade-functions for maybe_create_table;
434 if (!function_exists('maybe_create_table')) {
435 require_once ABSPATH . 'wp-admin/includes/upgrade.php';
436 }
437 $charset_collate = $wpdb->get_charset_collate();
438 $table_name = $wpdb->prefix . 'mstore_checkout';
439 $sql = "CREATE TABLE $table_name (
440 id mediumint(9) NOT NULL AUTO_INCREMENT,
441 `code` tinytext NOT NULL,
442 `order` text NOT NULL,
443 PRIMARY KEY (id)
444 ) $charset_collate;";
445 $success = maybe_create_table($table_name, $sql);
446 }
447 }
448
449 $mstoreCheckOut = new MstoreCheckOut();
450
451 // use JO\Module\Templater\Templater;
452 include plugin_dir_path(__FILE__) . "templates/class-templater.php";
453
454 add_action('plugins_loaded', 'load_mstore_templater');
455 function load_mstore_templater()
456 {
457
458 // add our new custom templates
459 $my_templater = new Templater(
460 array(
461 // YOUR_PLUGIN_DIR or plugin_dir_path(__FILE__)
462 'plugin_directory' => plugin_dir_path(__FILE__),
463 // should end with _ > prefix_
464 'plugin_prefix' => 'plugin_prefix_',
465 // templates directory inside your plugin
466 'plugin_template_directory' => 'templates',
467 )
468 );
469 $my_templater->add(
470 array(
471 'page' => array(
472 'mstore-api-template.php' => 'Page Custom Template',
473 ),
474 )
475 )->register();
476 }
477
478 //custom rest api
479 function flutter_users_routes()
480 {
481 $controller = new FlutterUserController();
482 $controller->register_routes();
483 }
484
485 add_action('rest_api_init', 'flutter_users_routes');
486
487 /// FluxBuilder Troubleshooting only 🤔
488 add_action('rest_api_init', 'mstore_check_payment_routes');
489 function mstore_check_payment_routes()
490 {
491 register_rest_route('order', '/verify', array(
492 'methods' => 'GET',
493 'callback' => 'mstore_check_payment',
494 'permission_callback' => function () {
495 return true;
496 },
497 )
498 );
499 }
500
501 function mstore_check_payment()
502 {
503 return true;
504 }
505
506
507 // Add menu Setting
508 add_action('admin_menu', 'mstore_plugin_setup_menu');
509
510 function mstore_plugin_setup_menu()
511 {
512 add_menu_page('MStore Api', 'MStore Api', 'manage_options', 'mstore-plugin', 'mstore_init');
513 }
514
515 function mstore_init()
516 {
517 load_template(dirname(__FILE__) . '/templates/mstore-api-admin-page.php');
518 }
519
520 add_filter('woocommerce_rest_prepare_product_variation_object', 'custom_woocommerce_rest_prepare_product_variation_object', 20, 3);
521 add_filter('woocommerce_rest_prepare_product_object', 'flutter_custom_change_product_response', 20, 3);
522 add_filter('woocommerce_rest_prepare_product_review', 'custom_product_review', 20, 3);
523 add_filter('woocommerce_rest_prepare_product_cat', 'custom_product_category', 20, 3);
524 add_filter('woocommerce_rest_prepare_shop_order_object', 'flutter_custom_change_order_response', 20, 3);
525 // Add image support for WordPress blog categories
526 add_filter('rest_prepare_category', 'flutter_add_image_to_category', 20, 3);
527 add_filter('woocommerce_rest_prepare_product_attribute', 'flutter_custom_change_product_attribute', 20, 3);
528 add_filter('woocommerce_rest_prepare_product_tag', 'flutter_custom_change_product_taxonomy', 20, 3);
529 add_filter('woocommerce_rest_prepare_product_brand', 'flutter_custom_change_product_taxonomy', 20, 3);
530 add_filter('woocommerce_rest_product_object_query', 'flutter_custom_rest_product_object_query', 10, 2);
531 add_filter('woocommerce_rest_product_tag_query', 'flutter_custom_rest_product_tag_query', 10, 2);
532 add_filter('woocommerce_rest_product_brand_query', 'flutter_custom_rest_product_brand_query', 10, 2);
533 add_filter('rest_product_collection_params', 'flutter_custom_rest_product_collection_params', 10, 1);
534 add_filter('posts_pre_query', 'flutter_custom_posts_pre_query', 10, 2);
535 add_filter('found_posts', 'flutter_custom_found_posts', 20, 2);
536
537 /**
538 * WooCommerce REST API: Random sorting for products.
539 *
540 * rest_{post_type}_collection_params
541 *
542 * @param array $params
543 * @return array
544 */
545 function flutter_custom_rest_product_collection_params($params)
546 {
547 $params['orderby']['enum'][] = 'rand';
548 return $params;
549 }
550
551 function flutter_custom_rest_product_tag_query($args, $request)
552 {
553 return flutter_custom_rest_product_taxomomy_query($args, $request, 'product_tag');
554 }
555
556 function flutter_custom_rest_product_brand_query($args, $request)
557 {
558 return flutter_custom_rest_product_taxomomy_query($args, $request, 'product_brand');
559 }
560
561 function flutter_custom_rest_product_taxomomy_query($args, $request, $taxonomy)
562 {
563 // If include or exclude parameters are explicitly set in the request, don't override them
564 if (!empty($request['include']) || !empty($request['exclude'])) {
565 return $args;
566 }
567
568 $hide_empty = isset($args['hide_empty']) && $args['hide_empty'] == true;
569
570 // `include` parameter can be an array or comma separated string
571 $include = wp_parse_id_list($args['include']);
572
573 // Get product count for all tags, brands related to the requested params (based on category, brand, etc.)
574 $terms = get_filtered_term_product_counts($request, $taxonomy, [], $hide_empty);
575
576 // Trick: Use the `include` parameter to fix the API problem below
577 // The page = 1 has no visible items (count = 0), the app does not show
578 // anything (include loadmore button). If the page = 2 has visible items,
579 // cannot do anything in app because it do not show load more button
580 foreach ($terms as $key => $term) {
581 if ($hide_empty) {
582 if ($term['term_count'] > 0) {
583 $include[] = $term['term_count_id'];
584 }
585 } else {
586 $include[] = $term['term_count_id'];
587 }
588 }
589
590 $args['include'] = implode(',', wp_parse_id_list($include));
591 return $args;
592 }
593
594 function flutter_custom_rest_product_object_query($args, $request)
595 {
596 $attrs = $request['attributes'];
597
598 if (is_string($attrs) && !empty($attrs)) {
599 $attrs = json_decode($attrs, true);
600 }
601
602 // Attributes filter.
603 if (!empty($attrs)) {
604 foreach ($attrs as $attr_key => $attr_value) {
605 $args['tax_query'][] = [
606 'taxonomy' => $attr_key,
607 'field' => 'term_id',
608 'terms' => explode(',', $attr_value),
609 ];
610 }
611 }
612
613 return $args;
614 }
615
616 function custom_product_category($response, $object, $request)
617 {
618 $id = $response->data['id'];
619 $children = get_term_children($id, 'product_cat');
620
621 if (empty($children)) {
622 $response->data['has_children'] = false;
623 } else {
624 $response->data['has_children'] = true;
625 }
626 return $response;
627 }
628
629 /**
630 * Add image field to WordPress blog category REST API response
631 */
632 function flutter_add_image_to_category($response, $category, $request)
633 {
634 $image_id = get_term_meta($category->term_id, 'category_image_id', true);
635 $image_url = $image_id ? wp_get_attachment_image_url($image_id, 'full') : '';
636 $response->data['image'] = $image_url;
637
638 return $response;
639 }
640
641 /**
642 * Add image field to category form (Add new category)
643 */
644 add_action('category_add_form_fields', 'flutter_add_category_image_field', 10, 2);
645 function flutter_add_category_image_field($taxonomy)
646 {
647 ?>
648 <div class="form-field term-group">
649 <label for="category-image-id"><?php esc_html_e('Image', 'mstore-api'); ?></label>
650 <input type="hidden" id="category-image-id" name="category-image-id" value="">
651 <div id="category-image-wrapper"></div>
652 <p>
653 <button type="button" class="button button-secondary flutter_category_media_button">
654 <?php esc_html_e('Add Image', 'mstore-api'); ?>
655 </button>
656 <button type="button" class="button button-secondary flutter_category_media_remove">
657 <?php esc_html_e('Remove Image', 'mstore-api'); ?>
658 </button>
659 </p>
660 </div>
661 <?php
662 }
663
664 /**
665 * Add image field to category form (Edit category)
666 */
667 add_action('category_edit_form_fields', 'flutter_edit_category_image_field', 10, 2);
668 function flutter_edit_category_image_field($term, $taxonomy)
669 {
670 $image_id = get_term_meta($term->term_id, 'category_image_id', true);
671 ?>
672 <tr class="form-field term-group-wrap">
673 <th scope="row">
674 <label for="category-image-id"><?php esc_html_e('Image', 'mstore-api'); ?></label>
675 </th>
676 <td>
677 <input type="hidden" id="category-image-id" name="category-image-id" value="<?php echo esc_attr($image_id); ?>">
678 <div id="category-image-wrapper">
679 <?php
680 if ($image_id) {
681 echo wp_get_attachment_image($image_id, 'thumbnail');
682 }
683 ?>
684 </div>
685 <p>
686 <button type="button" class="button button-secondary flutter_category_media_button">
687 <?php esc_html_e('Add Image', 'mstore-api'); ?>
688 </button>
689 <button type="button" class="button button-secondary flutter_category_media_remove">
690 <?php esc_html_e('Remove Image', 'mstore-api'); ?>
691 </button>
692 </p>
693 </td>
694 </tr>
695 <?php
696 }
697
698 /**
699 * Save category image
700 */
701 add_action('created_category', 'flutter_save_category_image', 10, 2);
702 add_action('edited_category', 'flutter_save_category_image', 10, 2);
703 function flutter_save_category_image($term_id, $tt_id)
704 {
705 if (!isset($_POST['category-image-id'])) {
706 return;
707 }
708
709 $image_id = absint($_POST['category-image-id']);
710 update_term_meta($term_id, 'category_image_id', $image_id);
711 }
712
713 /**
714 * Enqueue media uploader scripts for category image
715 */
716 add_action('admin_enqueue_scripts', 'flutter_category_image_admin_scripts');
717 function flutter_category_image_admin_scripts($hook)
718 {
719 if (!in_array($hook, ['edit-tags.php', 'term.php'], true)) {
720 return;
721 }
722
723 wp_enqueue_media();
724 wp_enqueue_script(
725 'flutter-category-image',
726 plugin_dir_url(__FILE__) . 'assets/js/mstore-inspireui.js',
727 array('jquery'),
728 '1.0.0',
729 true
730 );
731 }
732
733 /**
734 * Add image column to category list table
735 */
736 add_filter('manage_edit-category_columns', 'flutter_add_category_image_column');
737 function flutter_add_category_image_column($columns)
738 {
739 $new_columns = array();
740 foreach ($columns as $key => $value) {
741 if ($key === 'description') {
742 $new_columns['image'] = __('Image', 'mstore-api');
743 }
744 $new_columns[$key] = $value;
745 }
746 return $new_columns;
747 }
748
749 /**
750 * Display image in category list table column
751 */
752 add_filter('manage_category_custom_column', 'flutter_display_category_image_column', 10, 3);
753 function flutter_display_category_image_column($content, $column_name, $term_id)
754 {
755 if ($column_name !== 'image') {
756 return $content;
757 }
758
759 $image_id = get_term_meta($term_id, 'category_image_id', true);
760
761 if (!$image_id) {
762 return '';
763 }
764
765 return wp_get_attachment_image(
766 $image_id,
767 'thumbnail',
768 false,
769 array('style' => 'width:50px;height:50px;object-fit:cover;')
770 );
771 }
772
773 function custom_product_review($response, $object, $request)
774 {
775 if(is_plugin_active('woo-photo-reviews/woo-photo-reviews.php') || is_plugin_active('woocommerce-photo-reviews/woocommerce-photo-reviews.php')){
776 $id = $response->data['id'];
777 $image_post_ids = get_comment_meta( $id, 'reviews-images', true );
778 $image_arr = array();
779 if(!is_string($image_post_ids)){
780 foreach( $image_post_ids as $image_post_id ) {
781 $image_arr[] = wp_get_original_image_url( $image_post_id );
782 }
783 }
784 $response->data['images'] = $image_arr;
785 }
786 return $response;
787 }
788
789 function flutter_custom_change_order_response($response, $object, $request)
790 {
791 return customOrderResponse($response, $object, $request);
792 }
793
794 function flutter_custom_change_product_response($response, $object, $request)
795 {
796 return customProductResponse($response, $object, $request);
797 }
798
799 function flutter_custom_change_product_attribute($response, $item, $request)
800 {
801 $taxonomy = wc_attribute_taxonomy_name($item->attribute_name);
802
803 // Combine all attribute terms into the return result when getting
804 // attributes. Reduce api calls to get sub-attributes from the app
805 $options = get_terms([
806 'taxonomy' => $taxonomy,
807 'hide_empty' => false,
808 ]);
809
810 // Get list count of attribute terms based on attribute.
811 $terms = get_filtered_term_product_counts($request, $taxonomy);
812
813 $is_visible = false;
814 // Show this attribute if any attribute terms have product quantity > 0
815 foreach ($terms as $key => $term) {
816 $count = (int)$term['term_count'];
817 if ($is_visible == false && $count > 0) {
818 $is_visible = true;
819 }
820 // Update term count for options
821 foreach ($options as $option) {
822 if ($option->term_id == $term['term_count_id']) {
823 $option->count = $count;
824 break;
825 }
826 }
827 }
828
829 $response->data['terms'] = $options;
830
831 $response->data['is_visible'] = $is_visible;
832
833 return $response;
834 }
835
836 /// Custom response for a product tag or brand
837 function flutter_custom_change_product_taxonomy($response, $item, $request)
838 {
839 // There is only a maximum of 1 entry because term_ids is an array of a
840 // unique id
841 $terms = get_filtered_term_product_counts($request, $item->taxonomy, $item->term_id);
842
843 if (!empty($terms)) {
844 $term = $terms[0];
845 $count = (int)$term['term_count'];
846 $response->data['count'] = $count;
847 $response->data['is_visible'] = $count > 0;
848 } else {
849 $response->data['count'] = 0;
850 $response->data['is_visible'] = false;
851 }
852
853 return $response;
854 }
855
856 function custom_get_attribute_taxonomy_name( $slug, $product ) {
857 // Format slug so it matches attributes of the product.
858 $slug = wc_attribute_taxonomy_slug( $slug );
859 $attributes = $product->get_attributes();
860 $attribute = false;
861
862 // pa_ attributes.
863 if ( isset( $attributes[ wc_attribute_taxonomy_name( $slug ) ] ) ) {
864 $attribute = $attributes[ wc_attribute_taxonomy_name( $slug ) ];
865 } elseif ( isset( $attributes[ $slug ] ) ) {
866 $attribute = $attributes[ $slug ];
867 }
868
869 if ( ! $attribute ) {
870 return $slug;
871 }
872
873 // Taxonomy attribute name.
874 if ( $attribute->is_taxonomy() ) {
875 $taxonomy = $attribute->get_taxonomy_object();
876 return $taxonomy->attribute_label;
877 }
878
879 // Custom product attribute name.
880 return $attribute->get_name();
881 }
882
883 function custom_woocommerce_rest_prepare_product_variation_object($response, $object, $request)
884 {
885
886 global $woocommerce_wpml;
887
888 //update correct product price with tax setting
889 $response->data['price'] = wc_get_price_to_display( $object );
890 $response->data['regular_price'] = wc_get_price_to_display( $object, array( 'price' => $object->get_regular_price() ) );
891 $response->data['sale_price'] = wc_get_price_to_display( $object, array( 'price' => $object->get_sale_price() ) );
892
893 $is_purchased = false;
894 if (isset($request['user_id'])) {
895 $user_id = $request['user_id'];
896 $user_data = get_userdata($user_id);
897 $user_email = $user_data->user_email;
898 $is_purchased = wc_customer_bought_product($user_email, $user_id, $response->data['id']);
899 }
900 $response->data['is_purchased'] = $is_purchased;
901 if (!empty($woocommerce_wpml->multi_currency) && !empty($woocommerce_wpml->settings['currencies_order'])) {
902
903 $price = $response->data['price'];
904
905 foreach ($woocommerce_wpml->settings['currency_options'] as $key => $currency) {
906 $rate = (float)$currency["rate"];
907 $response->data['multi-currency-prices'][$key]['price'] = $rate == 0 ? $price : sprintf("%.2f", $price * $rate);
908 }
909 }
910
911 /*Update product price for subscription product*/
912 if($object->get_type() == 'subscription_variation'){
913 $meta_data = $response->data['meta_data'];
914 $sign_up_fee = null;
915 foreach ($meta_data as $meta_data_item) {
916 if ($meta_data_item->get_data()["key"] == "_subscription_sign_up_fee") {
917 $sign_up_fee = $meta_data_item->get_data()["value"];
918 }
919 }
920 if($sign_up_fee != null){
921 $response->data['regular_price']= $sign_up_fee;
922 $response->data['price']= $sign_up_fee;
923 }
924 }
925
926 if (class_exists('WooCommerceWholeSalePrices')) {
927 $meta_data = $response->data['meta_data'];
928 foreach ($meta_data as $v) {
929 $key = is_array($v) ? $v['key'] : $v->__get('key');
930 if ((strpos($key, '_wholesale_price') !== false && strpos($key, '_have_wholesale_price') === false) || (strpos($key, '_wholesale_sale_price') !== false && strpos($key, '_have_wholesale_sale_price') === false)) {
931 if($v->__get('value')){
932 $wholesale_price = wc_get_price_to_display( $object, array( 'price' => $v->__get('value') ) );
933 $v->__set("value", number_format($wholesale_price, 2, '.', ''));
934 $v->apply_changes();
935 }
936 }
937 }
938 }
939
940 $variation_product = wc_get_product( $response->data['id'] );
941 if($variation_product) {
942 $_product = wc_get_product( $variation_product->get_parent_id() );
943 $attributes = array();
944
945 foreach ( $variation_product->get_variation_attributes() as $attribute_name => $attribute ) {
946 $name = str_replace( 'attribute_', '', $attribute_name );
947
948 if ( empty( $attribute ) && '0' !== $attribute ) {
949 continue;
950 }
951
952 // Taxonomy-based attributes are prefixed with `pa_`, otherwise simply `attribute_`.
953 if ( 0 === strpos( $attribute_name, 'attribute_pa_' ) ) {
954 $option_term = get_term_by( 'slug', $attribute, $name );
955 $attributes[] = array(
956 'id' => wc_attribute_taxonomy_id_by_name( $name ),
957 'name' => custom_get_attribute_taxonomy_name( $name, $_product ),
958 'option' => $option_term && ! is_wp_error( $option_term ) ? $option_term->name : $attribute,
959 );
960 } else {
961 $attributes[] = array(
962 'id' => 0,
963 'name' => custom_get_attribute_taxonomy_name( $name, $_product ),
964 'option' => $attribute,
965 );
966 }
967 }
968 $response->data['attributes'] = $attributes;
969 }
970 return $response;
971 }
972
973 /**
974 * Wordpress REST API: Support Rest API with Relevanssi.
975 *
976 * Attaches to 'the_posts' filter hook, checks to see if there's a place for a
977 * search and runs relevanssi_do_query() if there is.
978 *
979 * https://www.relevanssi.com/user-manual/using-relevanssi-outside-search-pages/
980 *
981 * @param array $posts An array of post objects.
982 * @param WP_Query $query The WP_Query object, default false.
983 */
984 function flutter_custom_posts_pre_query($posts, $query)
985 {
986 if ($query->is_search() && defined('REST_REQUEST') && REST_REQUEST) {
987 if (function_exists('relevanssi_do_query')) {
988 $posts = relevanssi_do_query($query);
989 $query->relevanssi_found_posts = $query->found_posts;
990 return $posts;
991 }
992 }
993 return $posts;
994 }
995
996 /**
997 * Wordpress REST API: Customize `found_posts` in Rest API with Relevanssi.
998 *
999 * @param int $found_posts The number of posts found.
1000 * @param WP_Query $query The WP_Query object.
1001 */
1002 function flutter_custom_found_posts($found_posts, $query)
1003 {
1004 if ($query->is_search() && defined('REST_REQUEST') && REST_REQUEST) {
1005 if (function_exists('relevanssi_do_query')) {
1006 return $query->relevanssi_found_posts;
1007 }
1008 }
1009 return $found_posts;
1010 }
1011
1012
1013 // Prepare data before checkout by webview
1014 function flutter_prepare_checkout()
1015 {
1016
1017 if(empty($_GET) && isset($_SERVER['HTTP_REFERER'])){
1018 $url_components = parse_url($_SERVER['HTTP_REFERER']);
1019 if (isset($url_components['query'])) {
1020 parse_str($url_components['query'], $params);
1021 if(!empty($params)){
1022 $_GET = $params;
1023 }
1024 }
1025 }
1026
1027 if (isset($_GET['mobile']) && isset($_GET['code'])) {
1028
1029 $code = sanitize_text_field($_GET['code']);
1030 global $wpdb;
1031 $table_name = $wpdb->prefix . "mstore_checkout";
1032 $sql = $wpdb->prepare("SELECT * FROM $table_name WHERE code = %s", $code);
1033 $item = $wpdb->get_row($sql);
1034 if ($item) {
1035 $data = json_decode(urldecode(base64_decode($item->order)), true);
1036 } else {
1037 return var_dump("Can't not get the order");
1038 }
1039
1040 $shipping = isset($data['shipping']) ? $data['shipping'] : NULL;
1041 $billing = isset($data['billing']) ? $data['billing'] : $shipping;
1042
1043 if (isset($data['token'])) {
1044 // Validate the cookie token
1045 $userId = validateCookieLogin($data['token']);
1046 if(!is_wp_error($userId)){
1047 if (isset($billing)) {
1048 if(isset($billing["first_name"]) && !empty($billing["first_name"])){
1049 update_user_meta($userId, 'billing_first_name', $billing["first_name"]);
1050 update_user_meta($userId, 'shipping_first_name', $billing["first_name"]);
1051 }
1052 if(isset($billing["last_name"]) && !empty($billing["last_name"])){
1053 update_user_meta($userId, 'billing_last_name', $billing["last_name"]);
1054 update_user_meta($userId, 'shipping_last_name', $billing["last_name"]);
1055 }
1056 if(isset($billing["company"]) && !empty($billing["company"])){
1057 update_user_meta($userId, 'billing_company', $billing["company"]);
1058 update_user_meta($userId, 'shipping_company', $billing["company"]);
1059 }
1060 if(isset($billing["address_1"]) && !empty($billing["address_1"])){
1061 update_user_meta($userId, 'billing_address_1', $billing["address_1"]);
1062 update_user_meta($userId, 'shipping_address_1', $billing["address_1"]);
1063 }
1064 if(isset($billing["address_2"]) && !empty($billing["address_2"])){
1065 update_user_meta($userId, 'billing_address_2', $billing["address_2"]);
1066 update_user_meta($userId, 'shipping_address_2', $billing["address_2"]);
1067 }
1068 if(isset($billing["city"]) && !empty($billing["city"])){
1069 update_user_meta($userId, 'billing_city', $billing["city"]);
1070 update_user_meta($userId, 'shipping_city', $billing["city"]);
1071 }
1072 if(isset($billing["state"]) && !empty($billing["state"])){
1073 update_user_meta($userId, 'billing_state', $billing["state"]);
1074 update_user_meta($userId, 'shipping_state', $billing["state"]);
1075 }
1076 if(isset($billing["postcode"]) && !empty($billing["postcode"])){
1077 update_user_meta($userId, 'billing_postcode', $billing["postcode"]);
1078 update_user_meta($userId, 'shipping_postcode', $billing["postcode"]);
1079 }
1080 if(isset($billing["country"]) && !empty($billing["country"])){
1081 update_user_meta($userId, 'billing_country', $billing["country"]);
1082 update_user_meta($userId, 'shipping_country', $billing["country"]);
1083 }
1084 if(isset($billing["email"]) && !empty($billing["email"])){
1085 update_user_meta($userId, 'billing_email', $billing["email"]);
1086 update_user_meta($userId, 'shipping_email', $billing["email"]);
1087 }
1088 if(isset($billing["phone"]) && !empty($billing["phone"])){
1089 update_user_meta($userId, 'billing_phone', $billing["phone"]);
1090 update_user_meta($userId, 'shipping_phone', $billing["phone"]);
1091 }
1092 } else {
1093 $billing = [];
1094 $shipping = [];
1095
1096 $billing["first_name"] = get_user_meta($userId, 'billing_first_name', true);
1097 $billing["last_name"] = get_user_meta($userId, 'billing_last_name', true);
1098 $billing["company"] = get_user_meta($userId, 'billing_company', true);
1099 $billing["address_1"] = get_user_meta($userId, 'billing_address_1', true);
1100 $billing["address_2"] = get_user_meta($userId, 'billing_address_2', true);
1101 $billing["city"] = get_user_meta($userId, 'billing_city', true);
1102 $billing["state"] = get_user_meta($userId, 'billing_state', true);
1103 $billing["postcode"] = get_user_meta($userId, 'billing_postcode', true);
1104 $billing["country"] = get_user_meta($userId, 'billing_country', true);
1105 $billing["email"] = get_user_meta($userId, 'billing_email', true);
1106 $billing["phone"] = get_user_meta($userId, 'billing_phone', true);
1107
1108 $shipping["first_name"] = get_user_meta($userId, 'shipping_first_name', true);
1109 $shipping["last_name"] = get_user_meta($userId, 'shipping_last_name', true);
1110 $shipping["company"] = get_user_meta($userId, 'shipping_company', true);
1111 $shipping["address_1"] = get_user_meta($userId, 'shipping_address_1', true);
1112 $shipping["address_2"] = get_user_meta($userId, 'shipping_address_2', true);
1113 $shipping["city"] = get_user_meta($userId, 'shipping_city', true);
1114 $shipping["state"] = get_user_meta($userId, 'shipping_state', true);
1115 $shipping["postcode"] = get_user_meta($userId, 'shipping_postcode', true);
1116 $shipping["country"] = get_user_meta($userId, 'shipping_country', true);
1117 $shipping["email"] = get_user_meta($userId, 'shipping_email', true);
1118 $shipping["phone"] = get_user_meta($userId, 'shipping_phone', true);
1119
1120 if (isset($billing["first_name"]) && !isset($shipping["first_name"])) {
1121 $shipping = $billing;
1122 }
1123 if (!isset($billing["first_name"]) && isset($shipping["first_name"])) {
1124 $billing = $shipping;
1125 }
1126 }
1127
1128 // Check user and authentication
1129 $user = get_userdata($userId);
1130 if ($user && (!is_user_logged_in() || get_current_user_id() !== $userId)) {
1131 wp_set_current_user($userId, $user->user_login);
1132 wp_set_auth_cookie($userId);
1133
1134 header("Refresh:0");
1135 }
1136 cleanupAppointmentCartData($userId);
1137 }
1138 } else {
1139 if (is_user_logged_in()) {
1140 wp_logout();
1141 wp_set_current_user(0);
1142 header("Refresh:0");
1143 }
1144 }
1145
1146 if (is_plugin_active('woocommerce/woocommerce.php') == true) {
1147 //header("Content-Security-Policy: frame-ancestors 'self' *.yourdomain.com");
1148 global $woocommerce;
1149 WC()->session->set('refresh_totals', true);
1150 WC()->cart->empty_cart();
1151
1152 if(class_exists('WC_Points_Rewards_Discount') && !empty($data['fee_lines'])){
1153 foreach ($data['fee_lines'] as $fee) {
1154 if($fee['name'] == 'Cart Discount'){
1155 list($points, $monetary_value) = explode(':', get_option('wc_points_rewards_redeem_points_ratio', ''));
1156 $cart_price_rate = floatval($monetary_value);
1157 $cart_points_rate = intval($points);
1158
1159 WC()->session->set( 'wc_points_rewards_discount_amount', intval($fee['total']) * $cart_points_rate / $cart_price_rate * (-1) );
1160 // generate and set unique discount code
1161 $discount_code = WC_Points_Rewards_Discount::generate_discount_code();
1162 // apply the discount
1163 WC()->cart->add_discount( $discount_code );
1164 }
1165 }
1166 }
1167
1168 $products = $data['line_items'];
1169
1170 buildCartItemData($products, function($productId, $quantity, $variationId, $attributes, $cart_item_data){
1171 global $woocommerce;
1172 $woocommerce->cart->add_to_cart($productId, $quantity, $variationId, $attributes, $cart_item_data);
1173 });
1174
1175 if (isset($shipping)) {
1176 $woocommerce->customer->set_shipping_first_name($shipping["first_name"]);
1177 $woocommerce->customer->set_shipping_last_name($shipping["last_name"]);
1178 $woocommerce->customer->set_shipping_company($shipping["company"]);
1179 $woocommerce->customer->set_shipping_address_1($shipping["address_1"]);
1180 $woocommerce->customer->set_shipping_address_2($shipping["address_2"]);
1181 $woocommerce->customer->set_shipping_city($shipping["city"]);
1182 $woocommerce->customer->set_shipping_state($shipping["state"]);
1183 $woocommerce->customer->set_shipping_postcode($shipping["postcode"]);
1184 $woocommerce->customer->set_shipping_country($shipping["country"]);
1185 }
1186
1187 if (isset($billing)) {
1188 $woocommerce->customer->set_billing_first_name($billing["first_name"]);
1189 $woocommerce->customer->set_billing_last_name($billing["last_name"]);
1190 $woocommerce->customer->set_billing_company($billing["company"]);
1191 $woocommerce->customer->set_billing_address_1($billing["address_1"]);
1192 $woocommerce->customer->set_billing_address_2($billing["address_2"]);
1193 $woocommerce->customer->set_billing_city($billing["city"]);
1194 $woocommerce->customer->set_billing_state($billing["state"]);
1195 $woocommerce->customer->set_billing_postcode($billing["postcode"]);
1196 $woocommerce->customer->set_billing_country($billing["country"]);
1197 $woocommerce->customer->set_billing_email($billing["email"]);
1198 $woocommerce->customer->set_billing_phone($billing["phone"]);
1199 }
1200
1201 if (!empty($data['coupon_lines'])) {
1202 $coupons = $data['coupon_lines'];
1203 foreach ($coupons as $coupon) {
1204 $woocommerce->cart->add_discount($coupon['code']);
1205 }
1206 }
1207
1208 if (!empty($data['shipping_lines'])) {
1209 $shippingLines = $data['shipping_lines'];
1210 $shippingMethods = [];
1211 foreach ($shippingLines as $key => $shippingLine) {
1212 if (is_plugin_active('wc-multivendor-marketplace/wc-multivendor-marketplace.php') && !empty($shippingLine['meta_data'])) {
1213 $seller_meta = array_filter($shippingLine['meta_data'],function($item){
1214 return $item['key'] == 'seller_id';
1215 });
1216 if(!empty($seller_meta)){
1217 $shippingMethods[$seller_meta[0]['value']] = $shippingLine['method_id'];
1218 }else{
1219 $shippingMethods[] = $shippingLine['method_id'];
1220 }
1221 } else{
1222 $shippingMethods[] = $shippingLine['method_id'];
1223 }
1224 }
1225 WC()->session->set('chosen_shipping_methods', $shippingMethods);
1226 }
1227 if (!empty($data['payment_method'])) {
1228 WC()->session->set('chosen_payment_method', $data['payment_method']);
1229 }
1230
1231 if (isset($data['customer_note']) && !empty($data['customer_note'])) {
1232 $_POST["order_comments"] = sanitize_text_field($data['customer_note']);
1233 $checkout_fields = WC()->checkout->__get("checkout_fields");
1234 $checkout_fields["order"] = ["order_comments" => ["type" => "textarea", "class" => [], "label" => "Order notes", "placeholder" => "Notes about your order, e.g. special notes for delivery."]];
1235 WC()->checkout->__set("checkout_fields", $checkout_fields);
1236 }
1237 }
1238 }
1239
1240 if (isset($_GET['cookie'])) {
1241 $cookie = urldecode(base64_decode(sanitize_text_field($_GET['cookie'])));
1242 $userId = validateCookieLogin($cookie);
1243 if (!is_wp_error($userId)) {
1244 $user = get_userdata($userId);
1245 if ($user !== false) {
1246 $cookie_elements = explode('|', $cookie);
1247 if (count($cookie_elements) == 4) {
1248 list($username, $expiration, $token, $hmac) = $cookie_elements;
1249 $_COOKIE[LOGGED_IN_COOKIE] = $cookie;
1250 wp_set_current_user($userId, $user->user_login);
1251 wp_set_auth_cookie($userId, true, '', $token);
1252 }
1253
1254 if (isset($_GET['order_detail']) && isset($_GET['order_id']) && is_plugin_active('dokan-lite/dokan.php')) {
1255 $url = add_query_arg(
1256 [
1257 'order_id' => $_GET['order_id'],
1258 '_wpnonce' => wp_create_nonce('dokan_view_order'),
1259 ],
1260 dokan_get_navigation_url('orders')
1261 );
1262 wp_safe_redirect($url);
1263 die;
1264 }
1265
1266 if (isset($_GET['vendor_admin'])) {
1267 global $wp;
1268 $request = $wp->request;
1269 wp_redirect(esc_url_raw(home_url("/" . $request)));
1270 die;
1271 }
1272 }
1273 }
1274 }
1275 }
1276
1277 function set_author_in_for_vendor_staff( $query ) {
1278 global $post;
1279 if ( class_exists('WeDevs_Dokan') && dokan()->is_pro_exists() && isset( $query->query['post_type'] ) && $query->query['post_type'] === 'global_product_addon' && $post != null ) {
1280 $vendor = dokan_get_vendor_by_product( $post->ID );
1281
1282 // Check if $vendor is valid before proceeding
1283 if (!$vendor) {
1284 return;
1285 }
1286
1287 if ( function_exists( 'dokan_get_vendor_staff' ) ) {
1288 $vendor_staffs = dokan_get_vendor_staff( $vendor->get_id() );
1289 if ( ! in_array( $vendor->get_id(), $vendor_staffs, true ) ) {
1290 return;
1291 }
1292 $query->set( 'author__in', $vendor_staffs );
1293 }
1294 }
1295 }
1296
1297 // Add product image to order
1298 add_filter('woocommerce_rest_prepare_shop_order_object', 'custom_woocommerce_rest_prepare_shop_order_object', 10, 1);
1299 function custom_woocommerce_rest_prepare_shop_order_object($response)
1300 {
1301 if (empty($response->data) || empty($response->data['line_items'])) {
1302 return $response;
1303 }
1304 $api = new WC_REST_Products_Controller();
1305 $req = new WP_REST_Request('GET');
1306 $line_items = [];
1307 foreach ($response->data['line_items'] as $item) {
1308 $product_id = $item['product_id'];
1309 $req->set_query_params(["id" => $product_id]);
1310 $res = $api->get_item($req);
1311 if (is_wp_error($res)) {
1312 $item["product_data"] = null;
1313 } else {
1314 $item["product_data"] = $res->get_data();
1315 }
1316 $line_items[] = $item;
1317
1318 }
1319 $response->data['line_items'] = $line_items;
1320
1321 // Get payment method
1322 $payment_method = $response->data['payment_method'];
1323 $payment_method_title = $response->data['payment_method_title'];
1324 $order_id = $response->data['id'];
1325
1326 // Get default Bank transfer info
1327 if ($payment_method == 'bacs' && class_exists('WC_Gateway_BACS')) {
1328 $bacs = new WC_Gateway_BACS();
1329 $bacs_accounts = apply_filters('woocommerce_bacs_accounts', $bacs->account_details, $order_id);
1330 $response->data['bacs_info'] = $bacs_accounts;
1331 }
1332
1333 // Get other Bank transfer info
1334 if (strpos($payment_method, 'bank_transfer') !== false && is_plugin_active('fr-multi-bank-transfer-payment-gateways-for-woocommerce/fr-multi-bank-transfer-gateways-for-woocommerce.php')) {
1335 require_once ABSPATH . 'wp-content/plugins/fr-multi-bank-transfer-payment-gateways-for-woocommerce/includes/gateways/class-fr-multi-bank-transfer-gateways-for-woocommerce-bank-transfer.php';
1336
1337 $bacs = new Fr_Multi_Bank_Transfer_Gateways_For_Woocommerce_Bank_Transfer([
1338 'id' => $payment_method,
1339 'method_title' => $payment_method_title,
1340 ]);
1341 $bacs_accounts = apply_filters('woocommerce_bacs_accounts', $bacs->account_details, $order_id);
1342 $response->data['bacs_info'] = $bacs_accounts;
1343 }
1344
1345 return $response;
1346 }
1347
1348
1349 function mstore_register_order_refund_requested_order_status()
1350 {
1351 register_post_status('wc-refund-req', array(
1352 'label' => esc_attr__('Refund Requested'),
1353 'public' => true,
1354 'show_in_admin_status_list' => true,
1355 'show_in_admin_all_list' => true,
1356 'exclude_from_search' => false,
1357 'label_count' => _n_noop('Refund requested <span class="count">(%s)</span>', 'Refund requested <span class="count">(%s)</span>')
1358 ));
1359 }
1360
1361 add_action('init', 'mstore_register_order_refund_requested_order_status');
1362
1363
1364 function mstore_add_custom_order_statuses($order_statuses)
1365 {
1366 // Create new status array.
1367 $new_order_statuses = array();
1368 // Loop though statuses.
1369 foreach ($order_statuses as $key => $status) {
1370 // Add status to our new statuses.
1371 $new_order_statuses[$key] = $status;
1372 // Add our custom statuses.
1373 if ('wc-processing' === $key) {
1374 $new_order_statuses['wc-refund-req'] = esc_attr__('Refund Requested');
1375 }
1376 }
1377
1378 return $new_order_statuses;
1379 }
1380
1381 add_filter('wc_order_statuses', 'mstore_add_custom_order_statuses');
1382
1383
1384 function custom_status_bulk_edit($actions)
1385 {
1386 // Add order status changes.
1387 $actions['mark_refund-req'] = __('Change status to refund requested');
1388
1389 return $actions;
1390 }
1391
1392 add_filter('bulk_actions-edit-shop_order', 'custom_status_bulk_edit', 20, 1);
1393
1394 add_action('rest_api_init', 'get_promptpay_qrcode_routes');
1395 function get_promptpay_qrcode_routes()
1396 {
1397 register_rest_route('promptpay', '/detail' . '/(?P<id>[\d]+)', array(
1398 'methods' => 'GET',
1399 'callback' => function($request){
1400 $available_payment_methods = WC()->payment_gateways()->payment_gateways();
1401 $paymentMethod = $available_payment_methods['thai-promptpay-easy'];
1402 $order = wc_get_order($request['id'] );
1403 $thank_msg = $paymentMethod->thank_msg;
1404 $promptpay_id = $paymentMethod->promptpay_id;
1405 $promptpay_type = $paymentMethod->promptpay_type;
1406 $promptpay_name = $paymentMethod->promptpay_name;
1407 $include_price = $paymentMethod->include_price;
1408 $image_url = get_site_url() . "/wp-content/plugins/thai-promptpay-payment-easy-gateway-plugin/images/promptpay_qrcode/promptpay-qr-l.php?type=$promptpay_type&promptpay_id=$promptpay_id";
1409
1410 if($include_price=='yes'){
1411 $price = $order->get_total();
1412 $image_url .= "&price=$price&p=1";
1413 }
1414
1415
1416 return ['thank_msg' => $thank_msg, 'qrcode_url' => $image_url, 'promptpay_id' => $promptpay_id, 'promptpay_name' => $promptpay_name, 'promptpay_type' => $paymentMethod->promptpay_type_name[$promptpay_type]];
1417 },
1418 'permission_callback' => function () {
1419 return true;
1420 },
1421 )
1422 );
1423 }
1424
1425 // Check if Woo Variation Swatches is active before adding the filter
1426 if (!function_exists('add_variation_swatches_attribute_images_to_api')) {
1427 function add_variation_swatches_attribute_images_to_api($response, $product, $request) {
1428 // First check if the plugin is active
1429 if (!function_exists('woo_variation_swatches') || !class_exists('Woo_Variation_Swatches')) {
1430 return $response;
1431 }
1432
1433 $data = $response->get_data();
1434
1435 // Only proceed if product has attributes
1436 if (empty($data['attributes'])) {
1437 return $response;
1438 }
1439
1440 $product_attributes = $product->get_attributes();
1441
1442 foreach ($data['attributes'] as $key => $attribute) {
1443 $attribute_name = $attribute['name'];
1444 $attribute_obj = isset($product_attributes[$attribute_name]) ? $product_attributes[$attribute_name] : null;
1445
1446 if ($attribute_obj && $attribute_obj->is_taxonomy()) {
1447 $terms = wp_get_post_terms($product->get_id(), $attribute_name, ['fields' => 'all']);
1448
1449 foreach ($terms as $term_key => $term) {
1450 // Get image ID from term meta set by Woo Variation Swatches
1451 $image_id = get_term_meta($term->term_id, 'product_attribute_image', true);
1452
1453 if ($image_id) {
1454 $image_size = woo_variation_swatches()->get_option('attribute_image_size', 'variation_swatches_image_size');
1455 $image_src = wp_get_attachment_image_src($image_id, $image_size);
1456
1457 if ($image_src) {
1458 // Add image data to the term in the API response
1459 $data['attributes'][$key]['options'][$term_key] = [
1460 'term_id' => $term->term_id,
1461 'name' => $term->name,
1462 'slug' => $term->slug,
1463 'image' => [
1464 'src' => $image_src[0],
1465 'width' => $image_src[1],
1466 'height' => $image_src[2]
1467 ]
1468 ];
1469 }
1470 }
1471 }
1472 }
1473 }
1474
1475 $response->set_data($data);
1476 return $response;
1477 }
1478 }
1479
1480 // Only add the filter if the function exists (as an extra check)
1481 if (function_exists('add_variation_swatches_attribute_images_to_api')) {
1482 add_filter('woocommerce_rest_prepare_product_object', 'add_variation_swatches_attribute_images_to_api', 10, 3);
1483 }