class AttendanceTracker { public function __construct() { // ... (existing code) ... add_action('wp_ajax_submit_course_hold_request', array($this, 'submit_course_hold_request')); add_action('wp_ajax_update_course_hold_status', array($this, 'update_course_hold_status')); add_action('wp_ajax_admin_apply_course_hold', array($this, 'admin_apply_course_hold')); add_action('admin_init', array($this, 'export_course_hold_report')); } public function create_db_tables() { // ... (existing code) ... $course_hold_table = $wpdb->prefix . 'attendance_tracker_course_holds'; $course_hold_sql = "CREATE TABLE $course_hold_table ( id mediumint(9) NOT NULL AUTO_INCREMENT, user_id bigint(20) NOT NULL, start_date date NOT NULL, end_date date NOT NULL, reason text NOT NULL, status enum('pending', 'approved', 'rejected') DEFAULT 'pending', created_at datetime DEFAULT CURRENT_TIMESTAMP, updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id) ) $charset_collate;"; dbDelta($course_hold_sql); } public function add_admin_menu() { // ... (existing code) ... add_submenu_page('attendance-tracker', 'Course Hold Requests', 'Course Hold Requests', 'edit_pages', 'course-hold-requests', array($this, 'course_hold_requests_page')); add_submenu_page('attendance-tracker', 'Course Hold Reports', 'Hold Reports', 'edit_pages', 'course-hold-reports', array($this, 'course_hold_reports_page')); } public function mark_attendance() { // ... (existing code) ... $current_hold = $this->get_current_course_hold($user_id); if ($current_hold && $current_hold->status == 'approved') { $today = current_time('Y-m-d'); if ($today >= $current_hold->start_date && $today <= $current_hold->end_date) { wp_send_json_error('Your course is currently on hold'); } } // ... (rest of the existing code) } public function submit_course_hold_request() { check_ajax_referer('attendance_tracker_nonce', 'nonce'); $user_id = get_current_user_id(); $start_date = sanitize_text_field($_POST['start_date']); $end_date = sanitize_text_field($_POST['end_date']); $reason = sanitize_textarea_field($_POST['reason']); $result = $this->insert_course_hold_request($user_id, $start_date, $end_date, $reason); if ($result) { wp_send_json_success('Course hold request submitted successfully'); } else { wp_send_json_error('Failed to submit course hold request'); } } public function update_course_hold_status() { check_ajax_referer('update_course_hold_status', 'nonce'); if (!current_user_can('edit_pages')) { wp_send_json_error('Permission denied'); } $request_id = intval($_POST['request_id']); $status = sanitize_text_field($_POST['status']); global $wpdb; $table_name = $wpdb->prefix . 'attendance_tracker_course_holds'; $result = $wpdb->update( $table_name, array('status' => $status), array('id' => $request_id), array('%s'), array('%d') ); if ($result !== false) { wp_send_json_success('Course hold status updated successfully'); } else { wp_send_json_error('Failed to update course hold status'); } } public function admin_apply_course_hold() { check_ajax_referer('admin_apply_course_hold', 'nonce'); if (!current_user_can('edit_users')) { wp_send_json_error('Permission denied'); } $user_id = intval($_POST['user_id']); $start_date = sanitize_text_field($_POST['start_date']); $end_date = sanitize_text_field($_POST['end_date']); $reason = sanitize_textarea_field($_POST['reason']); $result = $this->insert_course_hold_request($user_id, $start_date, $end_date, $reason, 'approved'); if ($result) { wp_send_json_success('Course hold applied successfully'); } else { wp_send_json_error('Failed to apply course hold'); } } private function insert_course_hold_request($user_id, $start_date, $end_date, $reason, $status = 'pending') { global $wpdb; $table_name = $wpdb->prefix . 'attendance_tracker_course_holds'; return $wpdb->insert( $table_name, array( 'user_id' => $user_id, 'start_date' => date('Y-m-d', strtotime($start_date)), 'end_date' => date('Y-m-d', strtotime($end_date)), 'reason' => $reason, 'status' => $status ), array('%d', '%s', '%s', '%s', '%s') ); } private function get_current_course_hold($user_id) { global $wpdb; $table_name = $wpdb->prefix . 'attendance_tracker_course_holds'; return $wpdb->get_row($wpdb->prepare( "SELECT * FROM $table_name WHERE user_id = %d AND (status = 'pending' OR (status = 'approved' AND end_date >= CURDATE())) ORDER BY created_at DESC LIMIT 1", $user_id )); } private function is_course_on_hold($user_id) { $current_hold = $this->get_current_course_hold($user_id); if ($current_hold && $current_hold->status == 'approved') { $today = current_time('Y-m-d'); return ($today >= $current_hold->start_date && $today <= $current_hold->end_date); } return false; } public function course_hold_requests_page() { global $wpdb; $table_name = $wpdb->prefix . 'attendance_tracker_course_holds'; $hold_requests = $wpdb->get_results("SELECT * FROM $table_name ORDER BY created_at DESC"); include plugin_dir_path(__FILE__) . 'admin-course-hold-requests.php'; } public function course_hold_reports_page() { $start_date = isset($_GET['start_date']) ? sanitize_text_field($_GET['start_date']) : ''; $end_date = isset($_GET['end_date']) ? sanitize_text_field($_GET['end_date']) : ''; $status = isset($_GET['status']) ? sanitize_text_field($_GET['status']) : ''; global $wpdb; $table_name = $wpdb->prefix . 'attendance_tracker_course_holds'; $query = "SELECT * FROM $table_name WHERE 1=1"; $args = array(); if (!empty($start_date)) { $query .= " AND start_date >= %s"; $args[] = date('Y-m-d', strtotime($start_date)); } if (!empty($end_date)) { $query .= " AND end_date <= %s"; $args[] = date('Y-m-d', strtotime($end_date)); } if (!empty($status)) { $query .= " AND status = %s"; $args[] = $status; } $query .= " ORDER BY created_at DESC"; if (!empty($args)) { $hold_requests = $wpdb->get_results($wpdb->prepare($query, $args)); } else { $hold_requests = $wpdb->get_results($query); } include plugin_dir_path(__FILE__) . 'admin-course-hold-reports.php'; } private function get_course_hold_statistics() { global $wpdb; $table_name = $wpdb->prefix . 'attendance_tracker_course_holds'; $stats = $wpdb->get_results(" SELECT status, COUNT(*) as count, AVG(DATEDIFF(end_date, start_date)) as avg_duration FROM $table_name GROUP BY status "); return $stats; } public function export_course_hold_report() { if (isset($_POST['action']) && $_POST['action'] == 'export_course_hold_report') { check_admin_referer('export_course_hold_report', 'export_nonce'); $start_date = isset($_POST['start_date']) ? sanitize_text_field($_POST['start_date']) : ''; $end_date = isset($_POST['end_date']) ? sanitize_text_field($_POST['end_date']) : ''; $status = isset($_POST['status']) ? sanitize_text_field($_POST['status']) : ''; global $wpdb; $table_name = $wpdb->prefix . 'attendance_tracker_course_holds'; $query = "SELECT ch.*, u.display_name FROM $table_name ch JOIN {$wpdb->users} u ON ch.user_id = u.ID WHERE 1=1"; $args = array(); if (!empty($start_date)) { $query .= " AND start_date >= %s"; $args[] = date('Y-m-d', strtotime($start_date)); } if (!empty($end_date)) { $query .= " AND end_date <= %s"; $args[] = date('Y-m-d', strtotime($end_date)); } if (!empty($status)) { $query .= " AND status = %s"; $args[] = $status; } $query .= " ORDER BY created_at DESC"; if (!empty($args)) { $hold_requests = $wpdb->get_results($wpdb->prepare($query, $args)); } else { $hold_requests = $wpdb->get_results($query); } header('Content-Type: text/csv'); header('Content-Disposition: attachment; filename="course_hold_report.csv"'); $output = fopen('php://output', 'w'); fputcsv($output, array('User', 'Start Date', 'End Date', 'Reason', 'Status', 'Requested On')); foreach ($hold_requests as $request) { fputcsv($output, array( $request->display_name, date('j-M-Y', strtotime($request->start_date)), date('j-M-Y', strtotime($request->end_date)), $request->reason, ucfirst($request->status), date('j-M-Y', strtotime($request->created_at)) )); } fclose($output); exit; } } }