__('Coupons', 'formipay'), 'singular_name' => __('Coupon', 'formipay'), // 'menu_name' => 'Formipay', 'add_new' => __('Add New', 'formipay'), 'add_new_item' => __('Add New Coupon', 'formipay'), 'edit' => __('Edit', 'formipay'), 'edit_item' => __('Edit Coupon', 'formipay'), 'new_item' => __('New Coupon', 'formipay'), 'view' => __('View', 'formipay'), 'view_item' => __('View Coupon', 'formipay'), 'search_items' => __('Search Coupon', 'formipay'), 'not_found' => __('No coupons found', 'formipay'), 'not_found_in_trash' => __('No coupons found in trash', 'formipay'), 'parent' => __('Coupon Parent', 'formipay') ); $args = array( 'label' => 'Coupons', 'description' => __('Coupon for marketing campaign', 'formipay'), 'labels' => $labels, 'public' => false, 'supports' => array( 'title' ), 'hierarchical' => false, 'has_archive' => false, 'show_ui' => true, 'show_in_menu' => false, 'show_in_rest' => false, 'query_var' => true ); register_post_type( 'formipay-coupon', $args ); } public function add_submenu() { add_submenu_page( 'formipay', __( 'Coupons', 'formipay' ), __( 'Coupons', 'formipay' ), 'manage_options', 'formipay-coupons', [$this, 'formipay_coupon'], ); } public function formipay_coupon() { // React admin \Formipay\Admin\ReactAdmin::render_mount_point('coupons'); } public function enqueue_admin() { $screen = get_current_screen(); // Enqueue SweetAlert2 for coupon post edit screen if ($screen && $screen->post_type === 'formipay-coupon' && $screen->base === 'post') { wp_enqueue_style('sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.css', [], '11.14.4', 'all'); wp_enqueue_script('sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.js', ['jquery'], '11.14.4', true); } } public function cpt_post_fields_box($boxes) { // Disabled - using React metabox instead // $boxes['formipay_coupon_settings'] = array( // 'post_type' => array('formipay-coupon'), // 'label' => __('Details', 'formipay'), // ); return $boxes; } public function cpt_post_fields_content($fields) { $fields['formipay_coupon_settings'] = array(); $fields = apply_filters( 'formipay/coupon-config', $fields ); return $fields; } public function rule_config($fields) { $multicurrency = formipay_is_multi_currency_active(); $all_currencies = formipay_currency_as_options(); $global_selected_currencies = formipay_global_currency_options(); $global_currencies = formipay_global_currency_options('raw'); $default_currency = formipay_default_currency(); // Group : Rules $rules_group_1 = array( 'rules_general_group' => array( 'type' => 'group_title', 'label' => __( 'General', 'formipay' ), 'group' => 'started' ), 'active' => array( 'type' => 'checkbox', 'label' => __( 'Active this coupon', 'formipay' ), 'value' => true, ), 'type' => array( 'type' => 'radio', 'label' => __( 'Type', 'formipay' ), 'required' => true, 'options' => array( 'fixed' => __( 'Fixed', 'formipay' ), 'percentage' => __( 'Percentage', 'formipay' ) ), 'value' => 'fixed' ), 'amount_percentage' => array( 'type' => 'number', 'label' => __( 'Amount', 'formipay' ), 'required' => true, 'dependency' => array( 'key' => 'type', 'value' => 'percentage' ), 'group' => 'ended' ) ); $rules_group_2 = []; $global_currencies = get_global_currency_array(); $default_currency = formipay_default_currency(); $rules_group_2['discount_amount_wrapper'] = array( 'type' => 'group_title', 'label' => __( 'Discount Amount', 'formipay' ), 'dependency' => array( 'key' => 'type', 'value' => 'fixed' ), 'group' => 'started', ); $rules_group_max['discount_max_amount_wrapper'] = array( 'type' => 'group_title', 'label' => __( 'Max Discount Amount', 'formipay' ), 'description' => __( 'Leave empty to not limit the max discount amount.', 'formipay' ), 'group' => 'started', ); foreach($global_currencies as $currency){ $default_currency_symbol = formipay_get_currency_data_by_value($default_currency, 'symbol'); $currency_symbol = formipay_get_currency_data_by_value($currency['currency'], 'symbol'); $currency_title = ucwords(formipay_get_currency_data_by_value($currency['currency'], 'title')); $decimal_digits = intval($currency['decimal_digits']); $step = $decimal_digits > 0 ? pow(10, -$decimal_digits) : 1; $rules_group_2['amount_fixed_'.$currency_symbol] = array( 'type' => 'number', 'label' => sprintf( __( ' Amount in %s', 'formipay' ), formipay_get_flag_by_currency($currency['currency']), $currency_symbol ), 'step' => $step, 'min' => 0, 'required' => true, 'placeholder' => __( 'Enter Amount...', 'formipay' ), 'dependency' => array( 'key' => 'type', 'value' => 'fixed' ) ); $rules_group_max['max_amount_'.$currency_symbol] = array( 'type' => 'number', 'label' => sprintf( __( ' Max Amount in %s', 'formipay' ), formipay_get_flag_by_currency($currency['currency']), $currency_symbol ), 'step' => $step, 'min' => 0, 'placeholder' => __( 'Enter Max Amount...', 'formipay' ), 'dependency' => array( 'key' => 'type', 'value' => 'percentage' ) ); } $last_rules_group_2 = array_key_last($rules_group_2); $rules_group_2[$last_rules_group_2]['group'] = 'ended'; $last_rules_group_max = array_key_last($rules_group_max); $rules_group_max[$last_rules_group_max]['group'] = 'ended'; $rules_group_3 = array( 'rules_group' => array( 'type' => 'group_title', 'label' => __( 'Rules', 'formipay' ), 'description' => __( 'Define the rules of this coupon.', 'formipay' ), 'group' => 'started' ), 'case_sensitive' => array( 'type' => 'checkbox', 'label' => __( 'Case Sensitive', 'formipay' ), 'description' => __( 'If this activated, coupon codes must be entered with the exact capitalization as specified.
For example code SAVE10:
- SAVE10 is valid
- save10 is invalid
- Save10 is invalid.', 'formipay' ) ), 'free_shipping' => array( 'type' => 'checkbox', 'label' => __( 'Free Shipping', 'formipay' ), 'description' => __( 'Shipping cost will be free when this coupon applied.', 'formipay' ) ), 'quantity_active' => array( 'type' => 'checkbox', 'label' => __( 'Influenced by Quantity', 'formipay' ), 'description' => __( 'Example: when buyer buy 4 pcs of item, 4 × discount amount will be implemented.', 'formipay' ), 'dependency' => array( 'key' => 'type', 'value' => 'fixed' ) ), // 'max_discount' => array( // 'type' => 'number', // 'label' => __( 'Max Discount Amount', 'formipay' ), // 'description' => __( 'Leave it empty to not limit the max discount amount.', 'formipay' ) // ), ); $rules_group = $rules_group_1 + $rules_group_2 + $rules_group_max + $rules_group_3; $rules_group = apply_filters( 'formipay/coupon-settings/tab:rules/group:rules', $rules_group ); $last_rules_group = array_key_last($rules_group); $rules_group[$last_rules_group]['group'] = 'ended'; $all_group_merged = $rules_group; $settings_all_fields = apply_filters( 'formipay/coupon-settings/tab:rules', $all_group_merged ); $settings_fields = []; if(!empty($settings_all_fields)){ foreach($settings_all_fields as $key => $value){ $settings_fields[$key] = $value; } } $fields['formipay_coupon_settings']['rules'] = array( 'name' => __('Rules', 'formipay'), 'fields' => $settings_fields ); return $fields; } public function restriction_config($fields) { // Group : Restrictions $restriction_group = array( 'restriction_group' => array( 'type' => 'group_title', 'label' => __( 'Restrictions', 'formipay' ), 'group' => 'started' ), 'use_limit' => array( 'type' => 'number', 'label' => __( 'Usage Limit', 'formipay' ), 'description' => __( 'Leave it empty or 0 (zero) to set it as unlimited usage.', 'formipay' ), 'placeholder' => __( 'Set limit...', 'formipay' ) ), 'date_limit' => array( 'type' => 'date', 'label' => __( 'Date Limit', 'formipay' ), 'description' => __( 'Chosen date is the last day the coupon can be used. Leave it empty tio set it as no-limit date.', 'formipay' ) ), 'forms' => array( 'type' => 'autocomplete', 'post_type' => array('formipay-form'), 'label' => __( 'Forms', 'formipay' ), 'description' => __( 'Only selected form(s) can use the coupon. Leave empty to apply to all forms.', 'formipay' ) ), 'products' => array( 'type' => 'autocomplete', 'post_type' => array('formipay-product'), 'label' => __( 'Products', 'formipay' ), 'description' => __( 'Only selected product(s) can use the coupon. Leave empty to apply to all products.', 'formipay' ) ), 'users' => array( 'type' => 'autocomplete', 'object_type' => 'user', 'label' => __( 'Customers', 'formipay' ), 'description' => __( 'Only selected registered customer(s) can use this coupon. Leave empty to apply to all customers.', 'formipay' ) ) ); $restriction_group = apply_filters( 'formipay/coupon-settings/tab:restriction/group:restrictions', $restriction_group ); $last_restriction_group = array_key_last($restriction_group); $restriction_group[$last_restriction_group]['group'] = 'ended'; $details_all_fields = apply_filters( 'formipay/coupon-settings/tab:restriction', $restriction_group ); $details_fields = []; if(!empty($details_all_fields)){ foreach($details_all_fields as $key => $value){ $details_fields[$key] = $value; } } $fields['formipay_coupon_settings']['restriction'] = array( 'name' => __('Restrictions', 'formipay'), 'fields' => $details_fields ); return $fields; } public function add_static_element($elements) { $elements[] = [ 'id' => 'coupon_field', 'label' => __( 'Coupon Field', 'formipay' ) ]; return $elements; } public function render_static_element($element_id) { if($element_id == 'coupon_field'){ ?>
'Unauthorized' ] ); } $code = isset($_REQUEST['code']) ? sanitize_text_field( wp_unslash($_REQUEST['code']) ) : ''; $form_id = isset($_REQUEST['form']) ? intval( $_REQUEST['form'] ) : 0; $check_code = formipay_get_coupon_id_by_code($code, $form_id); if(false == $check_code){ wp_send_json_error( [ 'message' => __( 'Coupon code is not valid', 'formipay' ) ] ); } wp_send_json_success(); } public function order_details($details, $form_id, $order_data) { if( isset($order_data['coupon_code']) && !empty($order_data['coupon_code']) ) { $coupon_id = formipay_get_coupon_id_by_code( sanitize_text_field( $order_data['coupon_code'] ), $form_id ); if(false !== $coupon_id) { $amount = floatval( formipay_get_post_meta( $coupon_id, 'amount' ) ); $discount = $amount; $coupon_type = formipay_get_post_meta( $coupon_id, 'type' ); $qty = 1; if( formipay_get_post_meta( $form_id, 'product_quantity_toggle' ) == 'on' ){ $qty = intval($order_data['qty']); } if( $coupon_type == 'percentage' ){ $product_price = floatval( formipay_get_post_meta( $form_id, 'product_price' ) ); $amount = $amount / 100; $discount = $product_price * $amount; } $amount = $discount * $qty; $amount = $amount * -1; $details[] = [ 'item' => esc_html( $order_data['coupon_code'] ), 'amount' => floatval($amount), 'subtotal' => floatval($amount), 'context' => 'sub' ]; } } return $details; } public function count_order_by_coupon_code($coupon_code) { global $wpdb; $table = $wpdb->prefix .'formipay_orders'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $data = $wpdb->get_results( $wpdb->prepare( "SELECT COUNT(id) as count FROM %i WHERE `items` LIKE %s", $table, '%' . $wpdb->esc_like($coupon_code) . '%' ) ); return $data[0]->count; } public function add_discount_item($breakdown, $currency, $order_data) { if( isset($order_data['form_data']['coupon_code']) && !empty($order_data['form_data']['coupon_code']) ) { $form_id = $order_data['form_id']; $coupon_id = formipay_get_coupon_id_by_code( sanitize_text_field( $order_data['form_data']['coupon_code'] ), $form_id ); if(false !== $coupon_id) { $amount = floatval( formipay_get_post_meta( $coupon_id, 'amount' ) ); $discount = $amount; $coupon_type = formipay_get_post_meta( $coupon_id, 'type' ); $qty = 1; if( formipay_get_post_meta( $form_id, 'product_quantity_toggle' ) == 'on' ){ $qty = intval($order_data['form_data']['qty']); } if( $coupon_type == 'percentage' ){ $product_price = floatval( formipay_get_post_meta( $form_id, 'product_price' ) ); $amount = $amount / 100; $discount = $product_price * $amount; } $breakdown['item_total']['value'] += $discount; $breakdown['discount'] = array( "currency_code" => $currency, "value" => $discount ); } } return $breakdown; } public function formipay_tabledata_coupons() { check_ajax_referer( 'formipay-admin', '_wpnonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( [ 'message' => 'Unauthorized' ] ); } $args = [ 'post_type' => 'formipay-coupon', 'posts_per_page' => -1, 'post_status' => array( 'pending', 'draft', 'publish' ) ]; $get_total_coupons = get_posts($args); $coupon_status = [ 'all' => 0, 'active' => 0, 'inactive' => 0 ]; if(!empty($get_total_coupons)){ foreach($get_total_coupons as $coupon){ $status = (formipay_get_post_meta($coupon->ID, 'active') == 'on') ? 'active' : 'inactive'; $coupon_status['all'] = intval($coupon_status['all']) + 1; if($status == 'active'){ $coupon_status['active'] = intval($coupon_status['active']) + 1; }elseif($status == 'inactive'){ $coupon_status['inactive'] = intval($coupon_status['inactive']) + 1; } } } if(isset($_REQUEST['limit'])){ $args['posts_per_page'] = intval($_REQUEST['limit']); } if(isset($_REQUEST['offset'])){ $args['offset'] = intval($_REQUEST['offset']); } if(!empty($_REQUEST['search'])){ $args['s'] = sanitize_text_field( wp_unslash($_REQUEST['search']) ); } // Handle status filtering (active/inactive) $status_filter = isset($_REQUEST['status']) ? sanitize_text_field($_REQUEST['status']) : 'all'; $get_coupons = get_posts($args); $global_currencies = get_global_currency_array(); $coupons = []; if(!empty($get_coupons)){ foreach($get_coupons as $key => $coupon){ $is_active = formipay_get_post_meta($coupon->ID, 'active') == 'on'; // Apply status filter if ($status_filter !== 'all') { if ($status_filter === 'active' && !$is_active) continue; if ($status_filter === 'inactive' && $is_active) continue; } $date_limit = formipay_get_post_meta($coupon->ID, 'date_limit'); $date_limit_display = 'none'; if ($date_limit && $date_limit !== '') { if (preg_match('/^\d{4}-\d{2}-\d{2}/', $date_limit)) { $date_limit_display = $date_limit; } elseif (is_numeric($date_limit)) { $date_limit_display = formipay_date('Y-m-d', intval($date_limit) / 1000); } } $type = formipay_get_post_meta($coupon->ID, 'type'); $amount_meta_key = "amount_$type"; if($type == 'fixed'){ $amount_value = []; foreach($global_currencies as $currency){ $raw = $currency['currency']; $decimal_digits = $currency['decimal_digits']; $decimal_symbol = $currency['decimal_symbol']; $thousand_separator = $currency['thousand_separator']; $parse_currency = explode(':::', $raw); $currency_code = $parse_currency[0]; $amount_in_currency = formipay_get_post_meta($coupon->ID, 'amount_fixed_'.$currency_code); $amount_value[] = [ 'raw' => $raw, 'amount' => number_format($amount_in_currency, $decimal_digits, $decimal_symbol, $thousand_separator), 'flag' => formipay_get_flag_by_currency($raw) ]; } }else{ $amount_value = floatval(formipay_get_post_meta($coupon->ID, $amount_meta_key)); } $coupons[] = [ 'ID' => $coupon->ID, 'code' => get_the_title($coupon->ID), 'amount' => $amount_value, 'type' => ucfirst(formipay_get_post_meta($coupon->ID, 'type')), 'case_sensitive' => formipay_get_post_meta($coupon->ID, 'case_sensitive'), 'usage_count' => $this->count_order_by_coupon_code(get_the_title($coupon->ID)), 'usages' => $this->count_order_by_coupon_code(get_the_title($coupon->ID)), 'date_limit' => $date_limit_display, 'active' => $is_active ? 'on' : 'off', 'post_status' => $is_active ? 'active' : 'inactive', 'status' => $is_active ? 'active' : 'inactive' ]; } } $response = [ 'results' => $coupons, 'total' => count($get_total_coupons), // Total number of forms 'posts_report' => array_map('intval', (array)$coupon_status) ]; wp_send_json($response); } public function formipay_coupon_get_products() { check_ajax_referer( 'formipay-admin', '_wpnonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( [ 'message' => 'Unauthorized' ] ); } if (!isset($_POST['search']) || empty($_POST['search'])) { wp_send_json_error( __('No search term provided.', 'formipay') ); } $search_term = sanitize_text_field( wp_unslash($_POST['search']) ); $query = get_posts([ 'post_type' => 'formipay-form', 's' => $search_term, 'posts_per_page' => -1, ]); $results = []; if(!empty($query)){ foreach($query as $post){ $results[] = [ 'value' => $post->ID, 'label' => $post->post_title, ]; } } wp_send_json($results); } public function formipay_create_coupon_post() { check_ajax_referer( 'formipay-admin', '_wpnonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( [ 'message' => 'Unauthorized' ] ); } $code = isset($_REQUEST['title']) ? sanitize_text_field( wp_unslash($_REQUEST['title']) ) : ''; if( !empty($code) && '' !== $code ){ $post_id = wp_insert_post( [ 'post_title' => $code, 'post_type' => 'formipay-coupon', ], true ); if(is_wp_error($post_id)){ wp_send_json_error( [ 'message' => $post_id->get_error_message() ] ); } update_post_meta($post_id, 'type', 'percentage'); update_post_meta($post_id, 'amount', 0); wp_send_json_success( [ 'edit_post_url' => admin_url('post.php?post='.$post_id.'&action=edit') ] ); } wp_send_json_error( [ 'message' => esc_html__( 'Coupon code is empty.', 'formipay' ) ] ); } public function formipay_delete_coupon() { check_ajax_referer( 'formipay-admin', '_wpnonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( [ 'message' => 'Unauthorized' ] ); } $post_id = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : 0; $delete = wp_delete_post($post_id, true); if(is_wp_error( $delete )){ wp_send_json_error( [ 'title' => esc_html__( 'Failed', 'formipay' ), 'message' => esc_html__( 'Failed to delete coupon. Please try again.', 'formipay' ), 'icon' => 'error' ] ); } wp_send_json_success( [ 'title' => esc_html__( 'Deleted', 'formipay' ), 'message' => esc_html__( 'Coupon is deleted permanently.', 'formipay' ), 'icon' => 'success' ] ); } public function formipay_bulk_delete_coupon() { check_ajax_referer( 'formipay-admin', '_wpnonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( [ 'message' => 'Unauthorized' ] ); } if( empty($_REQUEST['ids']) ){ wp_send_json_error( [ 'title' => esc_html__( 'Failed', 'formipay' ), 'message' => esc_html__( 'There is no coupon selected. Please try again.', 'formipay' ), 'icon' => 'error' ] ); } $ids = isset($_REQUEST['ids']) ? $_REQUEST['ids'] : []; $success = 0; $failed = 0; $report = __( 'Done.', 'formipay' ); if(!empty($ids)){ foreach($ids as $id){ $delete = wp_delete_post($id, true); if(is_wp_error( $delete )){ $failed++; }else{ $success++; } } } if($success > 0){ $report .= sprintf( __( ' Deleted %d coupon(s).', 'formipay' ), $success); } if($failed > 0){ $report .= sprintf( __( ' Failed %d coupon(s).', 'formipay' ), $failed); } wp_send_json_success( [ 'title' => esc_html__( 'Done!', 'formipay' ), 'message' => $report, 'icon' => 'info' ] ); } public function formipay_duplicate_coupon() { check_ajax_referer( 'formipay-admin', '_wpnonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( [ 'message' => 'Unauthorized' ] ); } $post_id = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : 0; $post = get_post($post_id); if (!$post) { wp_send_json_error( [ 'title' => esc_html__('Failed', 'formipay'), 'message' => esc_html__( 'Coupon is not defined.', 'formipay' ), 'icon' => 'error' ] ); } if (!in_array($post->post_type, ['formipay-coupon'])) { wp_send_json_error( [ 'title' => esc_html__('Failed', 'formipay'), 'message' => esc_html__( 'Wrong Post Type.', 'formipay' ), 'icon' => 'error' ] ); } $duplicate_post = [ 'post_title' => $post->post_title . ' ' . __('Copy', 'formipay'), 'post_content' => $post->post_content, 'post_status' => 'draft', // Set sebagai draft 'post_type' => $post->post_type, 'post_author' => $post->post_author, ]; // Masukkan duplikat ke database $new_post_id = wp_insert_post($duplicate_post); if (is_wp_error($new_post_id)) { wp_send_json_error( [ 'title' => esc_html__('Failed', 'formipay'), 'message' => esc_html__( 'Something happened. Please try again.', 'formipay' ), 'icon' => 'error' ] ); } // Salin semua meta data $meta_data = get_post_meta($post_id); foreach ($meta_data as $key => $values) { if($key !== 'forms'){ foreach ($values as $value) { add_post_meta($new_post_id, $key, maybe_unserialize($value)); } } } wp_send_json_success( [ 'title' => esc_html__('Duplicated!', 'formipay'), 'message' => esc_html__( 'Coupon is successfully duplicated.', 'formipay' ), 'icon' => 'success' ] ); } /** * Get coupon data for React editor */ public function formipay_get_coupon() { check_ajax_referer( 'formipay-admin', '_wpnonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( [ 'message' => 'Unauthorized' ] ); } $post_id = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : 0; if ( empty($post_id) ) { wp_send_json_error( [ 'message' => esc_html__( 'Coupon ID is required.', 'formipay' ) ] ); } $post = get_post($post_id); if ( ! $post || $post->post_type !== 'formipay-coupon' ) { wp_send_json_error( [ 'message' => esc_html__( 'Coupon not found.', 'formipay' ) ] ); } $global_currencies = get_global_currency_array(); // Build coupon data $coupon_data = [ 'ID' => $post_id, 'post_title' => $post->post_title, 'active' => formipay_get_post_meta($post_id, 'active'), 'type' => formipay_get_post_meta($post_id, 'type'), 'amount_percentage' => formipay_get_post_meta($post_id, 'amount_percentage'), 'case_sensitive' => formipay_get_post_meta($post_id, 'case_sensitive'), 'free_shipping' => formipay_get_post_meta($post_id, 'free_shipping'), 'quantity_active' => formipay_get_post_meta($post_id, 'quantity_active'), 'use_limit' => formipay_get_post_meta($post_id, 'use_limit'), 'date_limit' => formipay_get_post_meta($post_id, 'date_limit'), 'amounts_fixed' => [], 'max_amounts' => [], 'forms' => formipay_get_post_meta($post_id, 'forms') ?: [], 'products' => formipay_get_post_meta($post_id, 'products') ?: [], 'users' => formipay_get_post_meta($post_id, 'users') ?: [], ]; // Get fixed amounts for each currency foreach ($global_currencies as $currency) { $currency_raw = $currency['currency']; $currency_parts = explode(':::', $currency_raw); $currency_code = $currency_parts[0] ?? ''; $symbol = formipay_get_currency_data_by_value($currency_raw, 'symbol'); $amount_fixed = formipay_get_post_meta($post_id, 'amount_fixed_' . $symbol); if ( $amount_fixed ) { $coupon_data['amounts_fixed'][] = [ 'currency' => $currency_code, 'symbol' => $symbol, 'amount' => $amount_fixed, ]; } $max_amount = formipay_get_post_meta($post_id, 'max_amount_' . $symbol); if ( $max_amount ) { $coupon_data['max_amounts'][] = [ 'currency' => $currency_code, 'symbol' => $symbol, 'amount' => $max_amount, ]; } } wp_send_json_success( $coupon_data ); } /** * Save coupon data from React editor */ public function formipay_save_coupon() { check_ajax_referer( 'formipay-admin', '_wpnonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( [ 'message' => 'Unauthorized' ] ); } $post_id = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : 0; $title = isset($_REQUEST['title']) ? sanitize_text_field(wp_unslash($_REQUEST['title'])) : ''; if ( empty($title) ) { wp_send_json_error( [ 'message' => esc_html__( 'Coupon code is required.', 'formipay' ) ] ); } $global_currencies = get_global_currency_array(); // Prepare post data $post_data = [ 'post_title' => $title, 'post_type' => 'formipay-coupon', 'post_status' => 'publish', ]; if ( $post_id > 0 ) { $post_data['ID'] = $post_id; $post_data['post_status'] = get_post_status($post_id); $new_post_id = wp_update_post($post_data); } else { $new_post_id = wp_insert_post($post_data); } if ( is_wp_error($new_post_id) ) { wp_send_json_error( [ 'message' => $new_post_id->get_error_message() ] ); } // Save meta fields $meta_fields = [ 'active', 'type', 'amount_percentage', 'case_sensitive', 'free_shipping', 'quantity_active', 'use_limit', 'date_limit', ]; foreach ($meta_fields as $field) { $value = isset($_REQUEST[$field]) ? wp_unslash($_REQUEST[$field]) : ''; update_post_meta($new_post_id, $field, $value); } // Save fixed amounts foreach ($global_currencies as $currency) { $symbol = formipay_get_currency_data_by_value($currency['currency'], 'symbol'); if ( isset($_REQUEST['amount_fixed_' . $symbol]) ) { update_post_meta($new_post_id, 'amount_fixed_' . $symbol, wp_unslash($_REQUEST['amount_fixed_' . $symbol])); } if ( isset($_REQUEST['max_amount_' . $symbol]) ) { update_post_meta($new_post_id, 'max_amount_' . $symbol, wp_unslash($_REQUEST['max_amount_' . $symbol])); } } // Save relation fields $relation_fields = ['forms', 'products', 'users']; foreach ($relation_fields as $field) { if ( isset($_REQUEST[$field]) ) { $values = is_array($_REQUEST[$field]) ? array_map('intval', $_REQUEST[$field]) : []; update_post_meta($new_post_id, $field, $values); } } wp_send_json_success( [ 'message' => esc_html__( 'Coupon saved successfully.', 'formipay' ), 'id' => $new_post_id, ] ); } /** * Add React metabox for coupon editor */ public function add_react_metabox() { add_meta_box( 'formipay_coupon_settings', __( 'Coupon Settings', 'formipay' ), [$this, 'render_react_metabox'], 'formipay-coupon', 'normal', 'high' ); } /** * Render React metabox container */ public function render_react_metabox($post) { ?>
post_type !== 'formipay-coupon') { return; } // Add Toaster container for toast notifications echo '
'; // Get field configuration for this post $config = \Formipay\Admin\FieldConfigBridge::get_config_for_post($post->ID, $post->post_type); // Pass config to JavaScript ?> $default_currency_raw, 'decimal_digits' => isset($formipay_settings['default_currency_decimal_digits']) ? intval($formipay_settings['default_currency_decimal_digits']) : 2, 'decimal_symbol' => isset($formipay_settings['default_currency_decimal_symbol']) ? $formipay_settings['default_currency_decimal_symbol'] : '.', 'thousand_separator' => isset($formipay_settings['default_currency_thousand_separator']) ? $formipay_settings['default_currency_thousand_separator'] : ',', ] ]; } } ?> 'Unauthorized' ] ); } $post_type = isset($_REQUEST['post_type']) ? sanitize_text_field(wp_unslash($_REQUEST['post_type'])) : ''; $object_type = isset($_REQUEST['object_type']) ? sanitize_text_field(wp_unslash($_REQUEST['object_type'])) : ''; $search = isset($_REQUEST['search']) ? sanitize_text_field(wp_unslash($_REQUEST['search'])) : ''; $include = isset($_REQUEST['include']) ? array_map('intval', (array) $_REQUEST['include']) : []; // Handle WP Users if ($object_type === 'user') { // Resolve labels for specific IDs (pre-selected items) if (!empty($include)) { $users = get_users(['include' => $include, 'fields' => ['ID', 'display_name', 'user_email']]); $results = []; if (!empty($users)) { foreach ($users as $user) { $results[] = [ 'value' => $user->ID, 'label' => $user->display_name . ' (' . $user->user_email . ')', ]; } } wp_send_json_success($results); return; } // Search by keyword if (strlen($search) < 2) { wp_send_json_error( [ 'message' => 'Invalid request' ] ); } $users = get_users([ 'search' => '*' . $search . '*', 'search_columns' => ['display_name', 'user_email', 'user_login'], 'number' => 20, 'fields' => ['ID', 'display_name', 'user_email'], ]); $results = []; if (!empty($users)) { foreach ($users as $user) { $results[] = [ 'value' => $user->ID, 'label' => $user->display_name . ' (' . $user->user_email . ')', ]; } } wp_send_json_success($results); return; } // Handle CPTs (posts) if (empty($post_type)) { wp_send_json_error( [ 'message' => 'Invalid request' ] ); } // Resolve labels for specific IDs (pre-selected items) if (!empty($include)) { $query = get_posts([ 'post_type' => $post_type, 'post__in' => $include, 'posts_per_page' => -1, 'post_status' => 'any', ]); $results = []; if (!empty($query)) { foreach ($query as $post) { $results[] = [ 'value' => $post->ID, 'label' => $post->post_title, ]; } } wp_send_json_success($results); return; } // Search by keyword if (strlen($search) < 2) { wp_send_json_error( [ 'message' => 'Invalid request' ] ); } $query = get_posts([ 'post_type' => $post_type, 's' => $search, 'posts_per_page' => 20, 'post_status' => ['publish', 'draft'], ]); $results = []; if (!empty($query)) { foreach ($query as $post) { $results[] = [ 'value' => $post->ID, 'label' => $post->post_title, ]; } } wp_send_json_success($results); } /** * Save coupon data via WordPress save_post hook * Called when user clicks WordPress Update button */ public function save_coupon_on_post_update($post_id, $post) { // Check if this is an autosave if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return $post_id; } // Check permissions if (!current_user_can('manage_options')) { return $post_id; } // Verify nonce if (!isset($_POST['_wpnonce']) || !wp_verify_nonce($_POST['_wpnonce'], 'update-post_' . $post_id)) { return $post_id; } // Only save for our coupon post type if ($post->post_type !== 'formipay-coupon') { return $post_id; } // Get global currencies for currency field processing $global_currencies = get_global_currency_array(); // Save basic meta fields $meta_fields = [ 'active', 'type', 'amount_percentage', 'case_sensitive', 'free_shipping', 'quantity_active', 'use_limit', 'date_limit', ]; foreach ($meta_fields as $field) { if (isset($_POST[$field])) { $value = wp_unslash($_POST[$field]); update_post_meta($post_id, $field, $value); } } // Save fixed amounts for each currency foreach ($global_currencies as $currency) { $symbol = formipay_get_currency_data_by_value($currency['currency'], 'symbol'); if (isset($_POST['amount_fixed_' . $symbol])) { update_post_meta($post_id, 'amount_fixed_' . $symbol, wp_unslash($_POST['amount_fixed_' . $symbol])); } if (isset($_POST['max_amount_' . $symbol])) { update_post_meta($post_id, 'max_amount_' . $symbol, wp_unslash($_POST['max_amount_' . $symbol])); } } // Save relation fields $relation_fields = ['forms', 'products', 'users']; foreach ($relation_fields as $field) { if (isset($_POST[$field])) { $values = is_array($_POST[$field]) ? array_map('intval', $_POST[$field]) : []; update_post_meta($post_id, $field, $values); } else { delete_post_meta($post_id, $field); } } return $post_id; } }