/* ========================================================= AJAX SAVE TRAINING ========================================================= */ add_action('wp_ajax_gmrtc_save_training', 'gmrtc_save_training'); function gmrtc_save_training() { check_ajax_referer('gmrtc_secure_nonce', 'nonce'); if ( ! current_user_can('manage_options') ) { wp_send_json_error(array('message' => 'Unauthorized.')); } global $wpdb; $table = $wpdb->prefix . 'gmrtc_trn_db'; $allowed_status = array( 'Template', 'Listed', 'Private', 'Started', 'Finished', 'Cancelled' ); $trn_status = sanitize_text_field($_POST['trn_status']); if ( ! in_array($trn_status, $allowed_status) ) { wp_send_json_error(array('message' => 'Invalid Training Status.')); } $data = array( 'trn_id' => sanitize_text_field($_POST['trn_id']), 'trn_status' => $trn_status, 'trn_title' => sanitize_text_field($_POST['trn_title']), 'trn_company' => sanitize_text_field($_POST['trn_company']), 'trn_lang' => sanitize_text_field($_POST['trn_lang']), 'trn_class' => sanitize_text_field($_POST['trn_class']), 'trn_expertise' => sanitize_text_field($_POST['trn_expertise']), 'trn_posterlink' => esc_url_raw($_POST['trn_posterlink']), 'trn_venue' => sanitize_text_field($_POST['trn_venue']), 'trn_slogan' => sanitize_text_field($_POST['trn_slogan']), 'trn_outcomes' => wp_kses_post($_POST['trn_outcomes']), 'trn_explanation' => wp_kses_post($_POST['trn_explanation']), 'trn_startdate' => sanitize_text_field($_POST['trn_startdate']), 'trn_enddate' => sanitize_text_field($_POST['trn_enddate']), 'trn_duration' => intval($_POST['trn_duration']), 'trn_listingdate' => sanitize_text_field($_POST['trn_listingdate']), 'trn_discenddate' => sanitize_text_field($_POST['trn_discenddate']), 'trn_discountrat' => floatval($_POST['trn_discountrat']), 'trn_fee_usd' => floatval($_POST['trn_fee_usd']), 'trn_fee_try' => floatval($_POST['trn_fee_try']), 'trn_quota' => intval($_POST['trn_quota']), 'trn_validity' => intval($_POST['trn_validity']), 'trn_inst_id1' => sanitize_text_field($_POST['trn_inst_id1']), 'trn_inst_id2' => sanitize_text_field($_POST['trn_inst_id2']), 'cert_bg_attendance' => esc_url_raw($_POST['cert_bg_attendance']), 'cert_bg_bronze' => esc_url_raw($_POST['cert_bg_bronze']), 'cert_bg_silver' => esc_url_raw($_POST['cert_bg_silver']), 'cert_bg_gold' => esc_url_raw($_POST['cert_bg_gold']), 'cert_text_attendance' => wp_kses_post($_POST['cert_text_attendance']), 'cert_text_bronze' => wp_kses_post($_POST['cert_text_bronze']), 'cert_text_silver' => wp_kses_post($_POST['cert_text_silver']), 'cert_text_gold' => wp_kses_post($_POST['cert_text_gold']), 'trn_canceldate' => sanitize_text_field($_POST['trn_canceldate']), 'trn_cancelreason' => sanitize_text_field($_POST['trn_cancelreason']), 'updated_at' => current_time('mysql') ); $db_id = intval($_POST['db_id']); if ( empty($db_id) ) { $data['created_at'] = current_time('mysql'); $data['ip_address'] = $_SERVER['REMOTE_ADDR']; $exists = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $table WHERE trn_id = %s", $data['trn_id'] ) ); if ( $exists ) { wp_send_json_error(array('message' => 'Training ID already exists.')); } $insert = $wpdb->insert($table, $data); if ( ! $insert ) { wp_send_json_error(array('message' => 'Database insert failed.')); } wp_send_json_success(array( 'message' => 'Training created successfully.' )); } else { $update = $wpdb->update( $table, $data, array('id' => $db_id) ); if ( $update === false ) { wp_send_json_error(array('message' => 'Database update failed.')); } wp_send_json_success(array( 'message' => 'Training updated successfully.' )); } } /* ========================================================= AJAX SAVE PARTICIPANT ========================================================= */ add_action('wp_ajax_gmrtc_save_participant', 'gmrtc_save_participant'); function gmrtc_save_participant() { check_ajax_referer('gmrtc_secure_nonce', 'nonce'); if ( ! current_user_can('manage_options') ) { wp_send_json_error(array('message' => 'Unauthorized.')); } global $wpdb; $allowed = array( 'Awaiting Attendance', 'Participated', 'Certified', 'Removed', 'Cancelled' ); $participant_status = sanitize_text_field($_POST['participant_status']); if ( ! in_array($participant_status, $allowed) ) { wp_send_json_error(array('message' => 'Invalid Participant Status.')); } $updated = $wpdb->update( $wpdb->prefix . 'gmrtc_ptcp_db', array( 'participant_status' => $participant_status, 'updated_at' => current_time('mysql') ), array( 'id' => intval($_POST['db_id']) ) ); if ( $updated === false ) { wp_send_json_error(array('message' => 'Participant update failed.')); } wp_send_json_success(array( 'message' => 'Participant updated successfully.' )); } /* ========================================================= AJAX DELETE RECORD ========================================================= */ add_action('wp_ajax_gmrtc_delete_record', 'gmrtc_delete_record'); function gmrtc_delete_record() { check_ajax_referer('gmrtc_secure_nonce', 'nonce'); if ( ! current_user_can('manage_options') ) { wp_send_json_error(array('message' => 'Unauthorized.')); } global $wpdb; $db_id = intval($_POST['db_id']); $table_type = sanitize_text_field($_POST['table_type']); $allowed = array( 'trn_db', 'preg_db', 'ptcp_db', 'cert_db' ); if ( ! in_array($table_type, $allowed) ) { wp_send_json_error(array('message' => 'Invalid table.')); } $table = $wpdb->prefix . 'gmrtc_' . $table_type; $deleted = $wpdb->delete( $table, array('id' => $db_id) ); if ( ! $deleted ) { wp_send_json_error(array('message' => 'Delete failed.')); } wp_send_json_success(array( 'message' => 'Record archived successfully.' )); } /* ========================================================= AJAX APPROVE PREREGISTRATION ========================================================= */ add_action('wp_ajax_gmrtc_approve_preg', 'gmrtc_approve_preg'); function gmrtc_approve_preg() { check_ajax_referer('gmrtc_secure_nonce', 'nonce'); if ( ! current_user_can('manage_options') ) { wp_send_json_error(array('message' => 'Unauthorized.')); } global $wpdb; $preg_table = $wpdb->prefix . 'gmrtc_preg_db'; $ptcp_table = $wpdb->prefix . 'gmrtc_ptcp_db'; $db_id = intval($_POST['db_id']); $record = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $preg_table WHERE id = %d", $db_id ) ); if ( ! $record ) { wp_send_json_error(array('message' => 'Record not found.')); } $insert = $wpdb->insert( $ptcp_table, array( 'ptcp_id' => $record->ptcp_id, 'participant_status' => 'Awaiting Attendance', 'trn_id' => $record->trn_id, 'trn_title' => $record->trn_title, 'ptcp_name' => $record->ptcp_name, 'ptcp_surname' => $record->ptcp_surname, 'ptcp_email' => $record->ptcp_email, 'ptcp_tel' => $record->ptcp_tel, 'ptcp_address' => $record->ptcp_address, 'ptcp_province' => $record->ptcp_province, 'ptcp_country' => $record->ptcp_country, 'ptcp_bill_type' => $record->ptcp_bill_type, 'ptcp_tax_office' => $record->ptcp_tax_office, 'ptcp_nat_id' => $record->ptcp_nat_id, 'ptcp_organization' => $record->ptcp_organization, 'ptcp_jobtitle' => $record->ptcp_jobtitle, 'accepted_at' => current_time('mysql'), 'created_at' => current_time('mysql'), 'updated_at' => current_time('mysql') ) ); if ( ! $insert ) { wp_send_json_error(array('message' => 'Transfer failed.')); } $wpdb->update( $preg_table, array( 'ptcp_status' => 'Approved', 'updated_at' => current_time('mysql') ), array( 'id' => $db_id ) ); wp_send_json_success(array( 'message' => 'Participant transferred successfully.' )); } /* ========================================================= AJAX REJECT PREREGISTRATION ========================================================= */ add_action('wp_ajax_gmrtc_reject_preg', 'gmrtc_reject_preg'); function gmrtc_reject_preg() { check_ajax_referer('gmrtc_secure_nonce', 'nonce'); if ( ! current_user_can('manage_options') ) { wp_send_json_error(array('message' => 'Unauthorized.')); } global $wpdb; $updated = $wpdb->update( $wpdb->prefix . 'gmrtc_preg_db', array( 'ptcp_status' => 'Rejected', 'updated_at' => current_time('mysql') ), array( 'id' => intval($_POST['db_id']) ) ); if ( $updated === false ) { wp_send_json_error(array('message' => 'Reject failed.')); } wp_send_json_success(array( 'message' => 'Preregistration rejected.' )); } /* ========================================================= CERTIFICATE SAVE SYSTEM ========================================================= */ add_action('wp_ajax_gmrtc_save_certification', 'gmrtc_save_certification'); function gmrtc_save_certification() { check_ajax_referer('gmrtc_secure_nonce', 'nonce'); if ( ! current_user_can('manage_options') ) { wp_send_json_error(array('message' => 'Unauthorized.')); } global $wpdb; $cert_table = $wpdb->prefix . 'gmrtc_cert_db'; $ptcp_table = $wpdb->prefix . 'gmrtc_ptcp_db'; $db_id = intval($_POST['db_id']); $grade = floatval($_POST['certification_grade']); if($grade < 0) $grade = 0; if($grade > 100) $grade = 100; $level = sanitize_text_field($_POST['achieved_level']); $allowed_levels = array( 'Participant', 'Bronze', 'Silver', 'Gold' ); if(!in_array($level, $allowed_levels)){ $level = 'Participant'; } if(empty($db_id)){ do { $cert_no = 'CERT-' . mt_rand(10000000,99999999); $exists = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $cert_table WHERE cert_no = %s", $cert_no ) ); } while($exists); } else { $existing = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $cert_table WHERE id = %d", $db_id ) ); $cert_no = $existing->cert_no; } $verify_token = wp_generate_password(64,false,false); $data = array( 'cert_no' => $cert_no, 'ptcp_id' => sanitize_text_field($_POST['ptcp_id']), 'trn_id' => sanitize_text_field($_POST['trn_id']), 'ptcp_test1weight' => floatval($_POST['ptcp_test1weight']), 'ptcp_test1grade' => floatval($_POST['ptcp_test1grade']), 'ptcp_test2weight' => floatval($_POST['ptcp_test2weight']), 'ptcp_test2grade' => floatval($_POST['ptcp_test2grade']), 'ptcp_test3weight' => floatval($_POST['ptcp_test3weight']), 'ptcp_test3grade' => floatval($_POST['ptcp_test3grade']), 'ptcp_bonus1pts' => floatval($_POST['ptcp_bonus1pts']), 'ptcp_bonus2pts' => floatval($_POST['ptcp_bonus2pts']), 'ptcp_bonus3pts' => floatval($_POST['ptcp_bonus3pts']), 'certification_grade' => $grade, 'achieved_level' => $level, 'issue_date' => sanitize_text_field($_POST['issue_date']), 'valid_until' => sanitize_text_field($_POST['valid_until']), 'cert_status' => sanitize_text_field($_POST['cert_status']), 'verify_token' => $verify_token, 'updated_at' => current_time('mysql') ); if(empty($db_id)){ $data['created_at'] = current_time('mysql'); $insert = $wpdb->insert($cert_table,$data); if(!$insert){ wp_send_json_error(array( 'message' => 'Certificate insert failed.' )); } } else { $update = $wpdb->update( $cert_table, $data, array( 'id' => $db_id ) ); if($update === false){ wp_send_json_error(array( 'message' => 'Certificate update failed.' )); } } $wpdb->update( $ptcp_table, array( 'participant_status' => 'Certified', 'updated_at' => current_time('mysql') ), array( 'ptcp_id' => sanitize_text_field($_POST['ptcp_id']) ) ); wp_send_json_success(array( 'message' => 'Certification saved successfully.', 'cert_no' => $cert_no )); } /* ========================================================= GENERATE PDF + QR ========================================================= */ add_action('wp_ajax_gmrtc_generate_pdf', 'gmrtc_generate_pdf'); function gmrtc_generate_pdf() { check_ajax_referer('gmrtc_secure_nonce', 'nonce'); if ( ! current_user_can('manage_options') ) { wp_send_json_error(array('message' => 'Unauthorized.')); } global $wpdb; require_once get_stylesheet_directory() . '/gmrtc-system/tcpdf/tcpdf.php'; $db_id = intval($_POST['db_id']); $cert = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}gmrtc_cert_db WHERE id = %d", $db_id ) ); if(!$cert){ wp_send_json_error(array( 'message' => 'Certificate record not found.' )); } $participant = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}gmrtc_ptcp_db WHERE ptcp_id = %s", $cert->ptcp_id ) ); $training = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}gmrtc_trn_db WHERE trn_id = %s", $cert->trn_id ) ); if(!$participant || !$training){ wp_send_json_error(array( 'message' => 'Participant or Training missing.' )); } $pdf = new TCPDF('L','mm','A4',true,'UTF-8',false); $pdf->SetCreator('GMRTC'); $pdf->SetAuthor('GMRTC'); $pdf->SetTitle($cert->cert_no); $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); $pdf->SetMargins(0,0,0); $pdf->AddPage(); $bg = ''; if($cert->achieved_level === 'Gold'){ $bg = $training->cert_bg_gold; $text_template = $training->cert_text_gold; } elseif($cert->achieved_level === 'Silver'){ $bg = $training->cert_bg_silver; $text_template = $training->cert_text_silver; } elseif($cert->achieved_level === 'Bronze'){ $bg = $training->cert_bg_bronze; $text_template = $training->cert_text_bronze; } else{ $bg = $training->cert_bg_attendance; $text_template = $training->cert_text_attendance; } if(!empty($bg)){ $pdf->Image($bg,0,0,297,210,'','','',false,300); } $full_name = $participant->ptcp_name . ' ' . $participant->ptcp_surname; $verify_url = add_query_arg(array( 'verify_cert' => $cert->verify_token ), home_url('/')); $text_template = str_replace( array( '{FULLNAME}', '{TRAINING}', '{GRADE}', '{LEVEL}', '{CERTNO}' ), array( $full_name, $training->trn_title, $cert->certification_grade, $cert->achieved_level, $cert->cert_no ), $text_template ); $pdf->SetFont('helvetica','',18); $pdf->SetTextColor(20,20,20); $pdf->SetXY(25,80); $pdf->MultiCell( 245, 10, $text_template, 0, 'C', false, 1 ); $pdf->write2DBarcode( $verify_url, 'QRCODE,H', 240, 150, 35, 35 ); $pdf->SetFont('helvetica','',9); $pdf->SetXY(200,190); $pdf->Cell( 80, 5, $cert->cert_no, 0, 0, 'R' ); $upload_dir = wp_upload_dir(); $cert_dir = $upload_dir['basedir'] . '/gmrtc-certificates'; if(!file_exists($cert_dir)){ wp_mkdir_p($cert_dir); } $filename = sanitize_file_name($cert->cert_no . '.pdf'); $filepath = $cert_dir . '/' . $filename; $fileurl = $upload_dir['baseurl'] . '/gmrtc-certificates/' . $filename; $pdf->Output($filepath,'F'); $wpdb->update( $wpdb->prefix . 'gmrtc_cert_db', array( 'pdf_url' => $fileurl, 'updated_at' => current_time('mysql') ), array( 'id' => $db_id ) ); wp_send_json_success(array( 'message' => 'Certificate generated successfully.', 'pdf_url' => $fileurl )); } /* ========================================================= CERTIFICATE VERIFY PAGE ========================================================= */ add_action('init','gmrtc_certificate_verify_router'); function gmrtc_certificate_verify_router(){ if(!isset($_GET['verify_cert'])){ return; } global $wpdb; $token = sanitize_text_field($_GET['verify_cert']); $cert = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}gmrtc_cert_db WHERE verify_token = %s", $token ) ); if(!$cert){ wp_die('Certificate not found.'); } $month_key = 'gmrtc_cert_views_' . md5($cert->cert_no . date('Ym')); $views = intval(get_transient($month_key)); if($views >= 50){ wp_die('Monthly certificate display limit exceeded.'); } set_transient( $month_key, ($views + 1), MONTH_IN_SECONDS ); if(empty($cert->pdf_url)){ wp_die('Certificate PDF missing.'); } wp_redirect($cert->pdf_url); exit; }