Files
formipay/includes/Customer.php
2025-08-21 20:39:34 +07:00

451 lines
17 KiB
PHP

<?php
namespace Formipay;
use Formipay\Traits\SingletonTrait;
if ( ! defined( 'ABSPATH' ) ) exit;
class Customer {
use SingletonTrait;
private $order_data;
/**
* Initializes the plugin by setting filters and administration functions.
*/
protected function __construct() {
add_action( 'init', [$this, 'create_db'] );
add_action( 'admin_menu', [$this, 'add_menu'] );
add_action( 'admin_enqueue_scripts', [$this, 'enqueue'] );
add_action( 'wp_ajax_formipay-tabledata-customers', [$this, 'formipay_tabledata_customers'] );
add_action( 'wp_ajax_formipay_check_for_data_mapping_saved_value', [$this, 'check_data_mapping'] );
// Add Global & Form Settings
// add_filter( 'formipay/global-settings', [$this, 'global_settings'] );
add_filter( 'formipay/global-settings/tab:general', [$this, 'global_settings'], 20 );
add_filter( 'formipay/form-config', [$this, 'add_menu_on_product_setting'], 100 );
// Register new customer by order submitted
add_action( 'formipay/order/new', [$this, 'add_customer'] );
}
public function create_db() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$create[] = "CREATE TABLE `{$wpdb->base_prefix}formipay_customers` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) DEFAULT 0,
`registered_date` datetime DEFAULT '00-00-00 00:00:00',
`name` text,
`phone` text,
`email` text,
`purchase_value` float(10, 4) DEFAULT 0,
`purchase_count` int,
`meta_data` text,
PRIMARY KEY (`id`)
) $charset_collate;";
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
dbDelta($create);
}
public function submit($args) {
$args = wp_parse_args( $args, [
'user_id' => 0,
'registered_date' => '',
'name' => NULL,
'phone' => NULL,
'email' => NULL,
'purchase_value' => 0,
'purchase_count' => 0,
'meta_data' => []
] );
global $wpdb;
$table = $wpdb->prefix . 'formipay_customers';
$insert_data = [
'user_id' => intval($args['user_id']),
'registered_date' => formipay_date('Y-m-d H:i:s'),
'name' => sanitize_text_field( $args['name'] ),
'phone' => sanitize_text_field( $args['phone'] ),
'email' => sanitize_email( $args['email'] ),
'purchase_value' => floatval($args['purchase_value']),
'purchase_count' => intval($args['purchase_count']),
'meta_data' => maybe_serialize($args['meta_data'])
];
if($args['name'] !== ''){
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
$wpdb->insert($table, $insert_data);
return $wpdb->insert_id;
}
return false;
}
public function get($customer_id = 0) {
global $wpdb;
$table = $wpdb->prefix .'formipay_customers';
if($customer_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, $customer_id
)
);
}
return $get;
}
public function get_by_email($email) {
global $wpdb;
$table = $wpdb->prefix .'formipay_customers';
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
$get = $wpdb->get_row(
$wpdb->prepare(
"SELECT * FROM %i WHERE `email` = %s", $table, $email
), ARRAY_A
);
return $get;
}
public function update($customer_id, $args) {
$recent_data = $this->get($customer_id);
$args = wp_parse_args( $args, [
'user_id' => $recent_data->user_id,
'name' => $recent_data->name,
'phone' => $recent_data->phone,
'email' => $recent_data->email,
'purchase_value' => $recent_data->purchase_value,
'purchase_count' => $recent_data->purchase_count,
'meta_data' => maybe_unserialize( $recent_data->meta_data )
] );
global $wpdb;
$table = $wpdb->prefix . 'formipay_customers';
$insert_data = [
'user_id' => intval($args['user_id']),
'name' => sanitize_text_field( $args['name'] ),
'phone' => sanitize_text_field( $args['phone'] ),
'email' => sanitize_email( $args['email'] ),
'purchase_value' => floatval($args['purchase_value']),
'purchase_count' => intval($args['purchase_count']),
'meta_data' => maybe_serialize($args['meta_data'])
];
$where = [ 'id' => $customer_id ];
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
$update = $wpdb->update( $table_name, $new_args, $where );
return $update;
}
public function add_menu() {
add_submenu_page(
'formipay',
__( 'Customers', 'formipay' ),
__( 'Customers', 'formipay' ),
'manage_options',
'formipay-customers',
[$this, 'customers_page']
);
}
public function enqueue() {
global $current_screen;
if($current_screen->id == 'formipay_page_formipay-customers') {
$customer_id = intval(filter_input(INPUT_GET, 'customer_id', FILTER_SANITIZE_STRING));
if(empty($customer_id)){
wp_enqueue_style( 'page-customers', FORMIPAY_URL . 'admin/assets/css/admin-customers.css', [], FORMIPAY_VERSION, 'all' );
wp_enqueue_script( 'page-customers', FORMIPAY_URL . 'admin/assets/js/admin-customers.js', ['jquery', 'gridjs'], FORMIPAY_VERSION, true );
}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-customers', FORMIPAY_URL . 'admin/assets/css/admin-customer-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-customers', FORMIPAY_URL . 'admin/assets/js/admin-customer-details.js', ['jquery'], FORMIPAY_VERSION, true );
}
wp_localize_script( 'page-customers', 'formipay_customers_page', [
'ajax_url' => admin_url('admin-ajax.php'),
'site_url' => site_url(),
'customer_id' => $customer_id,
'columns' => [
'id' => esc_html__( 'ID', 'formipay' ),
'name' => esc_html__( 'Name', 'formipay' ),
'email' => esc_html__( 'Email', 'formipay' ),
'phone' => esc_html__( 'Phone', 'formipay' ),
'total_order' => esc_html__( 'Total Order', 'formipay' ),
]
] );
}
}
public function customers_page() {
$customer_id = intval(filter_input(INPUT_GET, 'customer_id', FILTER_SANITIZE_STRING));
if(empty($customer_id)){
include FORMIPAY_PATH . 'admin/page-customers.php';
}else{
include FORMIPAY_PATH . 'admin/page-customer-details.php';
}
}
public function formipay_tabledata_customers() {
$get_all_customers = $this->get();
$customers = [];
if(!empty($get_all_customers)){
foreach($get_all_customers as $customer){
$customers[] = [
'ID' => $customer->id,
'name' => $customer->name,
'email' => $customer->email,
'phone' => $customer->phone,
'total_order' => $customer->purchase_count
];
}
}
// Prepare response data
$response = [
'results' => $customers,
'total' => count($get_all_customers),
'posts_report' => $customers
];
wp_send_json($response);
}
public function check_data_mapping() {
check_ajax_referer( 'formipay-form-editor', '_wpnonce' );
$form_id = isset($_REQUEST['post']) ? intval($_REQUEST['post']) : 0;
$saved = [
'buyer_name' => formipay_get_post_meta($form_id, 'buyer_name'),
'buyer_country' => formipay_get_post_meta($form_id, 'buyer_country')
];
$medias = apply_filters('formipay/notification/media', ['email', 'phone'] );
if(!empty($medias)){
foreach($medias as $media) {
$saved['buyer_'.$media] = formipay_get_post_meta($form_id, 'buyer_'.$media);
}
}
wp_send_json($saved);
}
public function global_settings($fields) {
$config = array(
'customer_field_group' => array(
'type' => 'group_title',
'label' => __( 'Customer Data', 'formipay' ),
'group' => 'started'
),
'customer_mandatory_data' => array(
'type' => 'sorter',
'label' => __( 'Identities', 'formipay' ),
'options' => array(
array(
'id' => 'optional',
'name' => esc_html__( 'Optional', 'formipay' ),
'options' => array(
array(
'id' => 'phone',
'label' => esc_html__( 'Phone', 'formipay' ),
),
)
),
array(
'id' => 'mandatory',
'name' => esc_html__( 'Mandatory', 'formipay' ),
'options' => array(
array(
'id' => 'name',
'label' => esc_html__( 'Name', 'formipay' ),
'icon' => 'fa fa-exclamation',
'class' => 'disable'
),
array(
'id' => 'email',
'label' => esc_html__( 'Email', 'formipay' ),
),
)
)
),
'group' => 'ended'
)
);
$fields = array_merge($fields, $config);
// $customer_settings = apply_filters( 'formipay/global-settings/tab:customer', $config );
// if(!empty($customer_settings)){
// $fields['customer'] = array(
// 'name' => __('Customer', 'formipay'),
// 'fields' => $customer_settings
// );
// }
return $fields;
}
public function add_menu_on_product_setting($fields) {
$medias = apply_filters('formipay/notification/media', ['email', 'phone'] );
$customer_mandatory_data = formipay_customer_mandatory_data();
$customer_fields = [
'notification_buyer_identify' => [
'type' => 'group_title',
'label' => __( 'Data Mapping', 'formipay' ),
'group' => 'started',
'description' => __( 'Match the required data for store the customer data, render shortcode and sending notification (if any)', 'formipay' ),
],
'buyer_name' => [
'type' => 'select',
'label' => __( 'Buyer\'s Name Field ID', 'formipay' ),
'description' => __( 'Fill in the field ID that represents the buyer\'s name.', 'formipay' ),
'required' => true
]
];
foreach($medias as $media){
$customer_fields['buyer_'.$media] = [
'type' => 'select',
// translators: %s is the media type name.
'label' => sprintf( __('Buyer\'s %s Field ID', 'formipay' ), ucfirst($media) ),
// translators: %s is the media type name.
'description' => sprintf( __( 'Fill in the field ID that represents the buyer\'s %s.', 'formipay' ), ucfirst($media) ),
'required' => in_array($media, $customer_mandatory_data) ? true : false
];
}
if(in_array('phone', $medias)){
$customer_fields['buyer_allow_choose_country_code'] = [
'type' => 'checkbox',
'label' => __('Buyer\'s can choose their own country code', 'formipay' ),
'value' => true,
'required' => in_array('phone', $customer_mandatory_data) ? true : false
];
$customer_fields['buyer_country'] = [
'type' => 'select',
'label' => __('Buyer\'s Country Field', 'formipay' ),
'description' => __( 'Fill in the field ID that represents the buyer\'s country. This will define the country phone code.', 'formipay' ),
'required' => in_array('phone', $customer_mandatory_data) ? true : false,
'dependency' => array(
'key' => 'buyer_allow_choose_country_code',
'value' => 'not_empty'
)
];
$customer_fields['buyer_phone_country_code'] = [
'type' => 'select',
'label' => __('Buyer\'s Default Country Code', 'formipay' ),
'options' => formipay_phone_country_code_options(),
'required' => true,
'searchable' => true,
'required' => in_array('phone', $customer_mandatory_data) ? true : false,
'dependency' => array(
'key' => 'buyer_allow_choose_country_code',
'value' => 'empty'
)
];
}
$last_data_mapping_fields = array_key_last($customer_fields);
$customer_fields[$last_data_mapping_fields]['group'] = 'ended';
$fields['formipay_form_settings']['customer_data'] = [
'name' => __('Customer Data', 'formipay'),
'fields' => $customer_fields
];
return $fields;
}
public function add_customer($order_data) {
$this->order_data = $order_data;
$buyer_name_field = formipay_get_post_meta($this->order_data['form_id'], 'buyer_name');
$buyer_email_field = formipay_get_post_meta($this->order_data['form_id'], 'buyer_email');
$buyer_phone_field = formipay_get_post_meta($this->order_data['form_id'], 'buyer_phone');
// Fallback Array
$customer_data = [
'name' => '',
'email' => '',
'phone' => ''
];
if(!empty($buyer_name_field) && !empty($this->order_data['form_data'][$buyer_name_field])) {
$customer_data['name'] = $this->order_data['form_data'][$buyer_name_field]['value'];
}
if(!empty($buyer_email_field) && !empty($this->order_data['form_data'][$buyer_email_field])) {
$customer_data['email'] = $this->order_data['form_data'][$buyer_email_field]['value'];
}
if(!empty($buyer_phone_field) && !empty($this->order_data['form_data'][$buyer_phone_field])) {
$customer_data['phone'] = $this->order_data['form_data'][$buyer_phone_field]['value'];
}
$email_is_exist = false;
if(!empty($customer_data['email'])){
$check = $this->get_by_email($customer_data['email']);
if(!empty($check)){
$email_is_exist = true;
}
}
if(false == $email_is_exist && !empty($customer_data['name'])){
$add_customer = $this->submit($customer_data);
}
}
}