get_charset_collate(); $create[] = "CREATE TABLE `{$wpdb->base_prefix}formipay_orders` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `created_date` datetime DEFAULT CURRENT_TIMESTAMP, `updated_date` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `form_id` int, `user_id` int, `customer_id` int, `items` text, `total` float(10, 2) DEFAULT 0, `status` varchar(20) DEFAULT 'on-hold', `form_data` text, `payment_gateway` text, `meta_data` text, PRIMARY KEY (`id`) ) $charset_collate;"; require_once ABSPATH . 'wp-admin/includes/upgrade.php'; dbDelta($create); } public function retrieve_form_data() { // Verify nonce if ( empty($_POST['nonce']) || ! wp_verify_nonce( sanitize_text_field(wp_unslash($_POST['nonce'])), 'formipay_order_submit' ) ) { wp_send_json_error([ 'message' => 'Nonce verification failed' ]); } // Sanitize and unslash inputs explicitly $form_id = isset($_REQUEST['form_id']) ? intval(wp_unslash($_REQUEST['form_id'])) : 0; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized $raw_data = isset($_REQUEST['data']) ? wp_unslash($_REQUEST['data']) : []; $form_data = is_array($raw_data) ? formipay_sanitize_array($raw_data) : sanitize_text_field($raw_data); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized $order_meta_data = isset($_REQUEST['meta_data']) ? wp_unslash($_REQUEST['meta_data']) : []; $purpose = isset($_REQUEST['purpose']) ? sanitize_text_field(wp_unslash($_REQUEST['purpose'])) : ''; $this->currency = isset($_REQUEST['currency']) ? wp_unslash($_REQUEST['currency']) : formipay_default_currency('symbol'); $this->form_id = $form_id; // Let everyone modify this data (sanitize inside filters if needed) $order_data = apply_filters('formipay/order/process-data', $form_data, $form_id); $this->order_data = $order_data; $order_details = $this->process_order_details(); $this->order_details = $order_details; $total = $this->process_order_total(); if ($purpose === 'calculate') { $order_data['total'] = $total; $order_data['items'] = $order_details; $order_data['form_data'] = formipay_get_post_meta($form_id); wp_send_json($order_data); } $status = ($total == 0) ? 'completed' : 'on-hold'; $submit_args = [ 'form_id' => $form_id, 'items' => $order_details, 'total' => $total, 'status' => $status, 'form_data' => $order_data, 'payment_gateway' => isset($order_data['payment_gateway']) ? sanitize_text_field($order_data['payment_gateway']) : '', 'meta_data' => $order_meta_data, ]; $submit = $this->submit($submit_args); $order_date = formipay_date('Y-m-d H:i:s'); $form_settings = formipay_get_post_meta($form_id, 'formipay_settings'); $global_settings = get_option('formipay_settings'); $thankyou_link = (!empty($global_settings['thankyou_link'])) ? $global_settings['thankyou_link'] : 'thankyou'; if ($submit !== false) { $order_data = formipay_get_order($submit); $this->order_data = apply_filters('formipay/order/result', $order_data); do_action('formipay/order/new', $this->order_data); do_action('formipay/order/on-hold', $this->order_data); do_action('formipay/notification/order', $this->order_data); $submit_action_type = formipay_get_post_meta($form_id, 'submit_action_type'); $success_message = formipay_get_post_meta($form_id, 'success_response_content'); $success_message = $this->process_response_content($success_message, 'thankyou'); $unique_id = isset($order_meta_data['session_id']) ? sanitize_text_field($order_meta_data['session_id']) : ''; $thankyou_url = site_url('/' . $thankyou_link . '/' . base64_encode($form_id . ':::' . $order_data['id'] . ':::' . $unique_id)); setcookie('fp_access', maybe_serialize([$order_data['id'] => $unique_id]), time() + 86400, '/'); if ( !empty($this->order_data['redirect_url']) && $submit_action_type !== 'whatsapp' ) { $redirect_url = esc_url_raw($this->order_data['redirect_url']); } else { switch ($submit_action_type) { case 'redirect': $redirect_url = esc_url_raw(formipay_get_post_meta($form_id, 'redirect_url')); break; case 'whatsapp': $admin_number = sanitize_text_field(formipay_get_post_meta($form_id, 'whatsapp_admin')); $whatsapp_message_format = formipay_get_post_meta($form_id, 'whatsapp_message'); $redirect_url = 'https://wa.me/' . $admin_number . '?text=' . rawurlencode($this->process_response_content($whatsapp_message_format, $submit_action_type)); break; default: $redirect_url = esc_url_raw($thankyou_url); break; } } wp_send_json_success([ 'message' => wp_kses_post($success_message), 'response_type' => formipay_get_post_meta($form_id, 'response_type'), 'action_type' => $submit_action_type, 'url' => $redirect_url, ]); } $message = formipay_get_post_meta($form_id, 'failed_response_content'); $message = str_replace('{{error_message}}', $submit->error_message(), $message); wp_send_json_error(['message' => wp_kses_post($message)]); } public function process_order_shortcodes($submit_action_type) { $buyer_name = ''; if(!empty(formipay_get_post_meta($this->form_id, 'buyer_name'))){ $buyer_name_field = formipay_get_post_meta($this->form_id, 'buyer_name'); $buyer_name = $this->order_data['form_data'][$buyer_name_field]; } $shortcodes = [ 'buyer_name' => $buyer_name, 'product_name' => html_entity_decode(get_the_title($this->form_id)), 'order_id' => $this->order_data['id'], 'order_date' => $this->order_data['created_date'], 'order_total' => formipay_price_format($this->order_data['total'], $this->form_id), 'order_status' => $this->order_data['status'], 'order_details' => $this->render_order_details($submit_action_type), 'form_submission' => $this->render_form_submit($submit_action_type) ]; $shortcodes = apply_filters( 'formipay/order/shortcodes', $shortcodes, $this->form_id, $this->order_data, $submit_action_type ); return $shortcodes; } public function process_order_details() { $currency_codes = []; $allowed_currencies = formipay_get_post_meta($this->form_id, 'allowed_currencies'); if(!empty($allowed_currencies)){ $parse_currencies = json_decode($allowed_currencies, true); foreach($parse_currencies as $currency_data){ $parse_currency = explode(':::', $currency_data); $currency_codes[] = $parse_currency[0]; } } $details = []; // $product_price = floatval(formipay_get_post_meta($this->form_id, 'product_price')); // $details[] = [ // 'item' => html_entity_decode(get_the_title($this->form_id)), // 'amount' => $product_price, // 'qty' => (int) $this->order_data['qty'], // 'subtotal' => floatval($product_price) * intval($this->order_data['qty']), // 'context' => 'main' // ]; // $check_fields = formipay_get_post_meta($this->form_id, 'formipay_settings'); // if(!empty($check_fields['fields'])){ // foreach($check_fields['fields'] as $field){ // // if($field['field_type'] == 'select'){ // if(in_array($field['field_type'], ['select','checkbox', 'radio'])) { // $options = $field['field_options']; // if(!empty($options)){ // foreach($options as $option){ // $option_value = ($field['show_toggle']['value'] && '' !== $option['value']) ? $option['value'] : $option['label']; // if(!empty($this->order_data[$field['field_id']])) { // $field_value = $this->order_data[$field['field_id']]; // if($field['field_type'] == 'select'){ // $field_value = ($field['show_toggle']['value']) ? // $this->order_data[$field['field_id']]['value'] : // $this->order_data[$field['field_id']]['label']; // } // $field_value = explode(',', $field_value); // $context = 'no-context'; // if(floatval($option['amount']) < 0){ // $context = 'sub'; // }elseif(floatval($option['amount']) > 0){ // $context = 'add'; // } // if(!empty($field_value) && $field['show_toggle']['amount'] == 'yes'){ // foreach($field_value as $f_value){ // if($option_value == $f_value){ // $qty = ($option['qty'] == 'yes') ? $this->order_data['qty'] : 1; // $details[] = [ // 'item' => $field['label'] .' - '. $option['label'], // 'amount' => floatval($option['amount']), // 'qty' => (int) $qty, // 'subtotal' => floatval($option['amount']) * intval($qty), // 'context' => $context // ]; // } // } // } // } // } // } // } // } // } /** * Cart items (not implemented yet) */ /** * Attached Product */ $products = formipay_get_post_meta($this->form_id, 'static_products'); if(!empty($products)){ $products = explode(',', $products); foreach($products as $product_id){ $product_data = formipay_get_post_meta($product_id); $regular_price = formipay_get_post_meta($product_id, 'setting_product_price_regular_'.$this->currency); $sale_price = formipay_get_post_meta($product_id, 'setting_product_price_sale_'.$this->currency); $this_item = [ 'item' => html_entity_decode(get_the_title($product_id)), 'amount' => (float) $sale_price ?: $regular_price, 'qty' => 1, 'subtotal' => (float) $sale_price ?: $regular_price, ]; } } $details = apply_filters('formipay/order/order-details', $details, $this->form_id, $this->order_data ); return $details; } public function process_order_total() { $detail_total = 0.00; if(!empty($this->order_details)){ foreach ($this->order_details as $detail) { $detail_total += $detail['subtotal']; } } $order_total = apply_filters('formipay/order/set-total', $detail_total, $this->form_id, $this->order_data); if($order_total <= 0){ $order_total = 0; } return $order_total; } public function process_response_content($content, $submit_action_type){ $shortcodes = $this->process_order_shortcodes($submit_action_type); // $target = []; // $replace_to_be = []; $replacements = []; if(!empty($shortcodes)){ foreach($shortcodes as $key => $value){ // $target[] = '{{'.$key.'}}'; // $replace_to_be[] = $value; $replacements['{{'.$key.'}}'] = $value; } } // $content = str_replace($target, $replace_to_be, $content); $content = strtr($content, $replacements); if($submit_action_type == 'whatsapp'){ $content = str_replace( [ PHP_EOL, "\n", ' ' ], [ '%0A', '%0A', '%20' ], $content ); } return $content; } public function render_order_details($submit_action_type) { if($submit_action_type == 'thankyou'){ ob_start(); if(!empty($this->order_details)){ ?> order_details as $detail){ $qty = ''; if(isset($detail['qty'])){ $qty = ' '.$detail['qty']; } ?>
form_id)); ?>
order_data['total'], $this->form_id)); ?>
form_id, 'whatsapp_message'); $order_details_message = ''; if(!empty($this->order_details)){ foreach($this->order_details as $detail){ $qty = ''; if(isset($detail['qty']) && !empty($detail['qty'])){ $qty = $detail['qty'].'×'; } $subtotal = formipay_price_format($detail['subtotal'], $this->form_id); $qty_length = strlen($qty); $subtotal_length = strlen($subtotal); if(floatval($detail['subtotal']) < 0){ $subtotal_length = $subtotal_length + 1; } $dot_length = $target_length - ($qty_length + $subtotal_length); $dots = str_repeat('.', intval($dot_length)); $order_details_message .= "%0A".$detail['item']; $order_details_message .= "%0A".$qty.$dots.$subtotal; } $total = formipay_price_format($this->order_data['total'], $this->form_id); $total_length = strlen($total); $dot_length = $target_length - ($total_length + 6); $dots = str_repeat('.', intval($dot_length)); $divider = str_repeat('_', intval($target_length)); $order_details_message .= "%0A".$divider."%0A%0A".'Total'.$dots.$total; } $order_details_message .= ''; $content = '%60%60%60'.$order_details_message.'%60%60%60'; }else{ $content = apply_filters( 'formipay/order/order-details/shortcode-render', '', $this->form_id, $this->order_details, $submit_action_type ); } return $content; } public function render_form_submit($submit_action_type) { ob_start(); if(!empty($this->order_data)){ $field_config = formipay_get_post_meta($this->order_data['form_id'], 'formipay_settings'); $skip_row = array( 'form_id', 'payment', 'id', 'status', 'total', 'created_date', 'redirect_url', 'items', 'form_data', 'meta_data' ); $rows = []; foreach($this->order_data['form_data'] as $field_name => $field_value){ $field_value = $field_value['value']; // $field_label = $field_config['fields'][$field_name.'_config']['label']; if(in_array($field_name, $skip_row)){ continue; } switch ($field_name) { case 'form_id': $field_label = __( 'Form ID', 'formipay' ); break; case 'qty': $field_label = __( 'Quantity', 'formipay' ); break; case 'coupon_code': $field_label = __( 'Coupon Code', 'formipay' ); break; case 'payment': $field_label = __( 'Payment', 'formipay' ); break; case 'payment_gateway': $field_label = __( 'Payment Gateway', 'formipay' ); $field_value = ucwords(str_replace('_', ' ', $field_value)); break; case 'id': $field_label = __( 'Order ID', 'formipay' ); break; case 'total': $field_label = __( 'Grand Total', 'formipay' ); $field_value = formipay_price_format($field_value, $this->form_id); break; case 'status': $field_label = __( 'Order Status', 'formipay' ); break; case 'created_date': $field_label = __( 'Order Date', 'formipay' ); break; default: $field_label = $field_config['fields'][$field_name.'_config']['label']; if(is_array($field_value)){ $field_value = $field_value['value']; } if(filter_var($field_value, FILTER_VALIDATE_EMAIL)){ $field_value = $field_value; }elseif(strpos($field_value, ',') !== false){ $values = explode(',', $field_value); $field_value = ''; foreach($values as $value){ $field_value .= ''.$value.' '; } }else{ $field_value = ucwords(str_replace(['-','_'], ' ', $field_value)); } break; } $rows[] = [ 'label' => $field_label, 'value' => $field_value ]; } if($submit_action_type == 'thankyou') { ?>
form_id)); ?>
0, 'items' => [], 'total' => 0, 'status' => 'on-hold', 'form_data' => [], 'payment_gateway' => '', 'meta_data' => [] ] ); global $wpdb; $table = $wpdb->prefix . 'formipay_orders'; $insert_data = [ 'created_date' => formipay_date('Y-m-d H:i:s'), 'form_id' => intval($args['form_id']), 'items' => maybe_serialize($args['items']), 'total' => floatval($args['total']), 'status' => sanitize_text_field( $args['status'] ), 'form_data' => maybe_serialize($args['form_data']), 'payment_gateway' => sanitize_text_field($args['payment_gateway']), 'meta_data' => maybe_serialize($args['meta_data']) ]; if($args['form_id'] > 0){ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery $wpdb->insert($table, $insert_data); return $wpdb->insert_id; } return false; } public function get($order_id = 0) { global $wpdb; $table = $wpdb->prefix .'formipay_orders'; if($order_id == 0){ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $get = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM %i", $table ) ); }else{ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $get = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM %i WHERE `id` = %d", $table, $order_id ) ); } return $get; } public function get_order_by_id($data, $order_id){ global $wpdb; $table = $wpdb->prefix .'formipay_orders'; if($order_id == 0){ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $data = $wpdb->get_results( $wpdb->prepare("SELECT * FROM %i", $table), ARRAY_A ); }else{ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $data = $wpdb->get_row( $wpdb->prepare("SELECT * FROM %i WHERE `id` = %d", $table, $order_id), ARRAY_A); } return $data; } public function get_by_form_id($form_id, $search='', $limit=false, $offset=false) { global $wpdb; $table = $wpdb->prefix .'formipay_orders'; if(false == $limit && false == $offset){ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $get = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM %i WHERE `form_id` = %d", $table, $form_id ) ); }else{ if('' == $search){ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $get = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM %i WHERE `form_id` = %d ORDER BY `id` DESC LIMIT %d, %d", $table, $form_id, $offset, $limit ) ); }else{ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $get = $wpdb->get_results( $wpdb->prepare("SELECT * FROM %i WHERE `form_id` = %d AND `form_data` LIKE %s ORDER BY `id` DESC LIMIT %d, %d", $table, $form_id, '%'.$search.'%',$offset, $limit) ); } } return $get; } public function add_menu() { add_submenu_page( 'formipay', __( 'Orders', 'formipay' ), __( 'Orders', 'formipay' ), 'manage_options', 'formipay-orders', [$this, 'orders_page'] ); } public function orders_page() { // phpcs:ignore WordPress.Security.NonceVerification.Recommended $order_id = isset($_GET['order_id']) ? intval($_GET['order_id']) : 0; if(empty($order_id)){ include FORMIPAY_PATH . 'admin/page-orders.php'; }else{ $order = formipay_get_order( $order_id ); include FORMIPAY_PATH . 'admin/page-order-details.php'; } } public function enqueue() { global $current_screen; if($current_screen->id == 'formipay_page_formipay-orders') { // phpcs:ignore WordPress.Security.NonceVerification.Recommended $order_id = isset($_GET['order_id']) ? intval($_GET['order_id']) : 0; if(empty($order_id)){ wp_enqueue_style( 'page-orders', FORMIPAY_URL . 'admin/assets/css/admin-orders.css', [], FORMIPAY_VERSION, 'all' ); wp_enqueue_script( 'page-orders', FORMIPAY_URL . 'admin/assets/js/admin-orders.js', ['jquery', 'gridjs'], FORMIPAY_VERSION, true ); wp_localize_script( 'page-orders', 'formipay_orders_page', [ 'ajax_url' => admin_url('admin-ajax.php'), 'site_url' => site_url(), 'columns' => [ 'id' => esc_html__( 'ID', 'formipay' ), 'form' => esc_html__( 'Form', 'formipay' ), 'total' => esc_html__( 'Total', 'formipay' ), 'date' => esc_html__( 'Date', 'formipay' ), 'payment_gateway' => esc_html__( 'Payment Gateway', 'formipay' ), 'status' => esc_html__( 'Status', 'formipay' ), ], 'filter_form' => [ 'products' => [ 'placeholder' => esc_html__( 'Filter by Product', 'formipay' ), 'noresult_text' => esc_html__( 'No results found', 'formipay' ) ], 'currencies' => [ 'placeholder' => esc_html__( 'Filter by Currency', 'formipay' ), 'noresult_text' => esc_html__( 'No results found', 'formipay' ) ] ], 'nonce' => wp_create_nonce( 'formipay-order-details' ) ] ); }else{ wp_enqueue_style( 'bootstrap-icon', FORMIPAY_URL . 'vendor/Bootstrap/bootstrap-icons.css', [], '1.11.1', 'all'); wp_enqueue_style( 'bootstrap', FORMIPAY_URL . 'vendor/Bootstrap/bootstrap.min.css', [], '5.3.2' ); wp_enqueue_style( 'page-orders', FORMIPAY_URL . 'admin/assets/css/admin-order-details.css', [], FORMIPAY_VERSION, 'all' ); wp_enqueue_script( 'handlebars', FORMIPAY_URL . 'vendor/HandleBars/handlebars.min.js', [], '4.7.7', true); wp_enqueue_script( 'bootstrap', FORMIPAY_URL . 'vendor/Bootstrap/bootstrap.bundle.min.js', ['jquery'], '5.3.2', true ); wp_enqueue_script( 'page-orders', FORMIPAY_URL . 'admin/assets/js/admin-order-details.js', ['jquery'], FORMIPAY_VERSION, true ); wp_localize_script( 'page-orders', 'formipay_order_details_page', [ 'ajax_url' => admin_url('admin-ajax.php'), 'site_url' => site_url(), 'order_id' => $order_id, 'order_detail' => [ 'change_order_status_confirmation' => esc_html__( 'Are you sure to change status?', 'formipay' ), 'change_order_status_button_confirm' => esc_html__( 'Change', 'formipay' ), 'change_order_status_button_cancel' => esc_html__( 'Cancel', 'formipay' ), 'edit_button_loading_text' => esc_html__( 'Preparing...', 'formipay' ), 'update_button_loading_text' => esc_html__( 'Updating...', 'formipay' ), 'pass_method' => [ 'magic_link' => esc_html__( 'Magic Link', 'formipay' ), 'static_password' => esc_html__( 'Static Password', 'formipay' ) ] ], 'modal' => [ 'delete' => [ 'question' => esc_html__( 'Do you want to delete the order?', 'formipay' ), 'cancelButton' => esc_html__( 'Cancel', 'formipay' ), 'confirmButton' => esc_html__( 'Delete Permanently', 'formipay' ) ], 'bulk_delete' => [ 'question' => esc_html__( 'Do you want to delete the selected the order(s)?', 'formipay' ), 'cancelButton' => esc_html__( 'Cancel', 'formipay' ), 'confirmButton' => esc_html__( 'Confirm', 'formipay' ) ], ], 'nonce' => wp_create_nonce( 'formipay-order-details' ) ] ); } } } public function formipay_get_all_forms() { $all_forms = get_posts([ 'post_type' => 'formipay-form', 'posts_per_page' => -1 ]); $forms = []; if(!empty($all_forms)){ foreach($all_forms as $form){ $forms[$form->ID] = get_the_title($form->ID); } } wp_send_json( $forms ); } public function get_all_field_name($formid) { $meta = get_post_meta($formid, 'formipay_settings', true); $headers = $meta['fields']; $table_header = []; if(!empty($headers)){ foreach($headers as $config => $header){ $header_id = $header['field_id']; $table_header[$header_id] = $header['label']; } } return $table_header; } public function formipay_orders_get_choices() { check_ajax_referer( 'formipay-order-details', '_wpnonce' ); $type = isset($_REQUEST['type']) ? sanitize_text_field( wp_unslash($_REQUEST['type']) ) : ''; $search = isset($_REQUEST['search']) ? sanitize_text_field( wp_unslash($_REQUEST['search']) ) : ''; $results = []; if($type == 'form'){ $args = [ 'post_type' => 'formipay-form', 'posts_per_page' => -1, ]; if('' !== $search) { $args['s'] = $search; } $get = get_posts($args); if(!empty($get)){ foreach($get as $post){ $results[] = [ 'value' => $post->ID, 'label' => $post->post_title ]; } } }elseif($type == 'currency'){ $countries = formipay_currency_array(); foreach($countries as $country){ $country_name = strtolower($country['name']); $country_search = strtolower($search); if(strpos($country_name, $country_search) !== false || $country_search == strtolower($country['code'])){ $results[] = [ 'value' => $country['code'], // phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage 'label' => ' '.$country['name'] ]; } } } wp_send_json($results); } public function update($order_id, $args) { global $wpdb; $table_name = $wpdb->prefix . 'formipay_orders'; // Get current data safely $recent_data = $this->get($order_id); if (!$recent_data) { return new WP_Error('invalid_order', __('Order not found', 'formipay')); } // Parse args with type safety $args = wp_parse_args($args, [ 'form_id' => (int)$recent_data->form_id, 'items' => maybe_unserialize($recent_data->items) ?: [], 'total' => (float)$recent_data->total, 'status' => sanitize_text_field($recent_data->status), 'form_data' => maybe_unserialize($recent_data->form_data) ?: [], 'payment_gateway' => sanitize_text_field($recent_data->payment_gateway), 'meta_data' => maybe_unserialize($recent_data->meta_data) ?: [] ]); // Prepare update log $update_time = current_time('mysql'); $user_id = get_current_user_id(); $changes = []; $status_changed = false; // Compare values properly (unserialized) $compare_fields = [ 'items' => ['before' => maybe_unserialize($recent_data->items), 'after' => $args['items']], 'total' => ['before' => (float)$recent_data->total, 'after' => (float)$args['total']], 'status' => ['before' => $recent_data->status, 'after' => $args['status']], 'form_data' => ['before' => maybe_unserialize($recent_data->form_data), 'after' => $args['form_data']], 'payment_gateway' => ['before' => $recent_data->payment_gateway, 'after' => $args['payment_gateway']] ]; foreach ($compare_fields as $field => $values) { if ($values['before'] !== $values['after']) { $changes[$field] = [ 'before' => $this->sanitize_log_value($values['before']), 'after' => $this->sanitize_log_value($values['after']) ]; if ($field === 'status') { $status_changed = true; } } } // Update meta_data with log if (!empty($changes)) { $args['meta_data']['update_log'][] = [ 'timestamp' => $update_time, 'user_id' => $user_id, 'changes' => $changes ]; } // Prepare database update $new_args = [ 'form_id' => (int)$args['form_id'], 'items' => maybe_serialize($args['items']), 'total' => (float)$args['total'], 'status' => sanitize_text_field($args['status']), 'form_data' => maybe_serialize($args['form_data']), 'payment_gateway' => sanitize_text_field($args['payment_gateway']), 'meta_data' => maybe_serialize($args['meta_data']) ]; $formats = [ '%d', // form_id '%s', // items '%f', // total '%s', // status '%s', // form_data '%s', // payment_gateway '%s' // meta_data ]; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery $updated = $wpdb->update( $table_name, $new_args, ['id' => (int)$order_id], $formats, ['%d'] ); // Trigger actions if status changed if ($status_changed && $updated) { $order_data = $this->get($order_id); do_action("formipay/order/{$args['status']}", $order_data); do_action('formipay/notification/order', $order_data); } return $updated; } public function delete($order_id) { global $wpdb; return $wpdb->delete( $wpdb->prefix . 'formipay_orders', ['id' => $id], ['%d'], ); } private function sanitize_log_value($value) { if (is_array($value)) { return array_map([$this, 'sanitize_log_value'], $value); } return sanitize_text_field(wp_unslash($value)); } public function formipay_tabledata_orders() { check_ajax_referer( 'formipay-order-details', '_wpnonce' ); $all_orders = $this->get(); $order_status = [ 'all' => 0, 'completed' => 0, 'on-hold' => 0, 'payment-confirm' => 0 ]; // Count order statuses if (!empty($all_orders)) { foreach ($all_orders as $order) { $order_status['all']++; $order_status[$order->status]++; } } global $wpdb; $table = $wpdb->prefix . 'formipay_orders'; $where = []; $params = []; // ID filter if (!empty(intval($_REQUEST['order_id']))) { $where[] = "`id` = %d"; $params[] = intval($_REQUEST['order_id']); } else { $where[] = "`id` > %d"; $params[] = 0; } // Status filter if (isset($_REQUEST['order_status']) && 'all' !== $_REQUEST['order_status']) { $where[] = "`status` = %s"; $params[] = sanitize_text_field(wp_unslash($_REQUEST['order_status'])); } // Product filter if (isset($_REQUEST['product']) && 0 < intval($_REQUEST['product'])) { $where[] = "`form_id` = %d"; $params[] = intval($_REQUEST['product']); } // Combine WHERE clause $where_sql = implode(' AND ', $where); $sql = "SELECT * FROM {$table} WHERE $where_sql ORDER BY `id` DESC"; // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $get_all_orders = $wpdb->get_results($wpdb->prepare($sql, ...$params)); // For paginated query: $limit = intval($_REQUEST['limit'] ?? 10); $offset = intval($_REQUEST['offset'] ?? 0); $sql_paginated = $sql . " LIMIT %d OFFSET %d"; $params_paginated = array_merge($params, [$limit, $offset]); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $get_filtered_orders = $wpdb->get_results($wpdb->prepare($sql_paginated, ...$params_paginated)); $orders = []; // Process filtered orders if (!empty($get_filtered_orders)) { foreach ($get_filtered_orders as $key => $order) { $currency = explode(':::', formipay_get_post_meta($order->form_id, 'product_currency')); $code = !empty($currency[0]) ? $currency[0] : ''; // Prepare order data $orders[] = [ 'ID' => $order->id, 'form' => get_the_title($order->form_id), 'date' => $order->created_date, 'payment_gateway' => ucwords(str_replace('_', ' ', $order->payment_gateway)), 'status' => ucwords(str_replace('-', ' ', $order->status)), 'total' => [ 'flag' => formipay_get_flag_by_currency($code), 'name' => $code, 'value' => formipay_price_format($order->total, $order->form_id), ] ]; } } // Prepare response data $response = [ 'results' => $orders, 'total' => count($get_all_orders), 'posts_report' => $order_status ]; wp_send_json($response); } public function formipay_delete_order() { check_ajax_referer( 'formipay-order-details', '_wpnonce' ); $order_id = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : 0; $delete = $this->delete($order_id); if(is_wp_error( $delete )){ wp_send_json_error( [ 'title' => esc_html__( 'Failed', 'formipay' ), 'message' => esc_html__( 'Failed to delete ortder. Please try again.', 'formipay' ), 'icon' => 'error' ] ); } wp_send_json_success( [ 'title' => esc_html__( 'Deleted', 'formipay' ), 'message' => esc_html__( 'Order is deleted permanently.', 'formipay' ), 'icon' => 'success' ] ); } public function formipay_bulk_delete_order() { check_ajax_referer( 'formipay-order-details', '_wpnonce' ); 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 = $this->delete($order_id); 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_load_order_data() { check_ajax_referer( 'formipay-order-details', '_wpnonce' ); $order_id = isset($_REQUEST['order']) ? intval($_REQUEST['order']) : 0; wp_send_json(formipay_get_order($order_id)); } public function formipay_change_order_status() { check_ajax_referer( 'formipay-order-details', '_wpnonce' ); $order_id = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : 0; $status = isset($_REQUEST['status']) ? sanitize_text_field( wp_unslash($_REQUEST['status']) ) : ''; if ($order_id > 0 && $status !== '') { $update = $this->update($order_id, ['status' => $status]); if (is_wp_error($update)) { wp_send_json_error([ 'message' => $update->get_error_message(), 'code' => $update->get_error_code(), ]); } wp_send_json_success([ 'message' => sprintf( esc_html__('Change status order of #%d is success', 'formipay'), $order_id ), ]); } wp_send_json_error([ 'message' => sprintf( esc_html__('Change status order of #%d is failed', 'formipay'), $order_id ), ]); } public function formipay_check_editable_field() { check_ajax_referer( 'formipay-order-details', '_wpnonce' ); $editable_field = []; $order_id = isset($_REQUEST['order_id']) ? intval($_REQUEST['order_id']) : 0; $get_order_data = formipay_get_order($order_id); $form_id = $get_order_data['form_id']; $field_types = formipay_field_type_collection(); $form_field = formipay_get_post_meta($form_id, 'formipay_settings'); $form_field = $form_field['fields']; unset($field_types['divider']); unset($field_types['page_break']); unset($field_types['country_list']); foreach($form_field as $key => $field){ if(array_key_exists($field['field_type'], $field_types)){ $skip = false; if(in_array($field['field_type'], ['select', 'checkbox', 'radio'])){ $options = $field['field_options']; if(!empty($options)){ foreach($options as $option){ if('' !== $option['amount']){ if(isset($get_order_data['status']) && $get_order_data['status'] == 'completed'){ $skip = true; } } } } } if(false == $skip){ $editable_field[$key] = $field; } } } wp_send_json($editable_field); } public function formipay_update_editable_field_data() { check_ajax_referer( 'formipay-order-details', '_wpnonce' ); $order_id = isset($_REQUEST['order_id']) ? intval($_REQUEST['order_id']) : 0; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized $raw_data = isset($_REQUEST['new_values']) ? wp_unslash( $_REQUEST['new_values'] ) : []; $data = is_array($raw_data) ? formipay_sanitize_array($raw_data) : sanitize_text_field($raw_data); $new_values = []; if(!empty($data)){ foreach($data as $_data){ $name = $_data['name']; $new_values[$name] = $_data['value']; } } $get_order_data = formipay_get_order($order_id); if(!empty($get_order_data)){ $current_form_data = $get_order_data['form_data']; $new_form_data = []; foreach($current_form_data as $current_data){ $field_name = $current_data['name']; $field_value = $current_data['value']; if(isset($new_values[$field_name])) { $field_value = $new_values[$field_name]; } $new_form_data[$field_name] = $field_value; } $update_form_data = $this->update($order_id, ['form_data' => $new_form_data]); if (is_wp_error($update_form_data)) { wp_send_json_error([ 'message' => $update_form_data->get_error_message(), 'code' => $update_form_data->get_error_code(), ]); } wp_send_json_success( [ 'message' => esc_html__( 'Succesfully change transaction data', 'formipay' ) ] ); } wp_send_json_error( [ 'message' => esc_html__( 'Error. Data is not available or not able to be changed. Try again.', 'formipay' ) ] ); } public function formipay_update_digital_access() { check_ajax_referer( 'formipay-order-details', '_wpnonce' ); $order_id = isset($_REQUEST['order_id']) ? intval($_REQUEST['order_id']) : 0; $method = isset($_REQUEST['method']) ? sanitize_text_field( wp_unslash($_REQUEST['method']) ) : ''; $password = isset($_REQUEST['password']) ? sanitize_text_field( wp_unslash($_REQUEST['password']) ) : ''; $get_order_data = $this->get($order_id); $meta_data = maybe_unserialize($get_order_data->meta_data); $meta_data['access_method'] = $method; if($method == 'static_password'){ $meta_data['access_password'] = $password; } $update_meta_data = $this->update($order_id, ['meta_data' => $meta_data]); if(is_wp_error($update_meta_data)){ wp_send_json_error([ 'message' => $update_meta_data->get_error_message(), 'code' => $update_meta_data->get_error_code(), ]); } wp_send_json_success( [ 'message' => esc_html__( 'Succesfully set access data', 'formipay' ) ] ); } }