ensure_capabilities();
}
/**
* Ensure required capabilities exist
*/
private function ensure_capabilities() {
$master_role = get_role('hvac_master_trainer');
if ($master_role && !$master_role->has_cap('hvac_master_manage_approvals')) {
$master_role->add_cap('hvac_master_manage_approvals');
}
// Also add to admin role
$admin_role = get_role('administrator');
if ($admin_role && !$admin_role->has_cap('hvac_master_manage_approvals')) {
$admin_role->add_cap('hvac_master_manage_approvals');
}
}
/**
* Check if current user can manage approvals
*
* @return bool
*/
public function can_manage_approvals() {
$user = wp_get_current_user();
return in_array('hvac_master_trainer', $user->roles) ||
current_user_can('hvac_master_manage_approvals') ||
current_user_can('manage_options');
}
/**
* Render pending approvals interface
*/
public function render_pending_approvals($atts = array()) {
// Check permissions
if (!$this->can_manage_approvals()) {
return '
You do not have permission to access this page.
';
}
// Get filters from request
$status_filter = sanitize_text_field($_GET['status_filter'] ?? 'pending');
$region_filter = sanitize_text_field($_GET['region_filter'] ?? '');
$date_from = sanitize_text_field($_GET['date_from'] ?? '');
$date_to = sanitize_text_field($_GET['date_to'] ?? '');
$search_term = sanitize_text_field($_GET['search'] ?? '');
$page = max(1, intval($_GET['paged'] ?? 1));
$per_page = 20;
// Get trainers data
$trainers_data = $this->get_trainers_data(array(
'status' => $status_filter,
'region' => $region_filter,
'date_from' => $date_from,
'date_to' => $date_to,
'search' => $search_term,
'page' => $page,
'per_page' => $per_page
));
ob_start();
?>
No trainers found matching your criteria.
$per_page): ?>
render_modals(); ?>
'pending',
'region' => '',
'date_from' => '',
'date_to' => '',
'search' => '',
'page' => 1,
'per_page' => 20
);
$args = wp_parse_args($args, $defaults);
// Base query args
$query_args = array(
'role__in' => array('hvac_trainer', 'hvac_master_trainer'),
'number' => $args['per_page'],
'offset' => ($args['page'] - 1) * $args['per_page'],
'meta_query' => array(),
'date_query' => array()
);
// Status filter
if ($args['status'] !== 'all') {
if ($args['status'] === 'rejected') {
// Handle rejected status - stored as disabled
$query_args['meta_query'][] = array(
'key' => 'account_status',
'value' => 'disabled',
'compare' => '='
);
} else {
$query_args['meta_query'][] = array(
'key' => 'account_status',
'value' => $args['status'],
'compare' => '='
);
}
}
// Date filters
if (!empty($args['date_from']) || !empty($args['date_to'])) {
$date_query = array();
if (!empty($args['date_from'])) {
$date_query['after'] = $args['date_from'];
}
if (!empty($args['date_to'])) {
$date_query['before'] = $args['date_to'] . ' 23:59:59';
}
if (!empty($date_query)) {
$query_args['date_query'] = array($date_query);
}
}
// Search filter
if (!empty($args['search'])) {
$query_args['search'] = '*' . $args['search'] . '*';
$query_args['search_columns'] = array('display_name', 'user_login', 'user_email');
}
// Region filter
if (!empty($args['region'])) {
$query_args['meta_query'][] = array(
'relation' => 'OR',
array(
'key' => 'state',
'value' => $args['region'],
'compare' => '='
),
array(
'key' => 'country',
'value' => $args['region'],
'compare' => '='
)
);
}
// Get total count for pagination
$count_args = $query_args;
unset($count_args['number'], $count_args['offset']);
$total_query = new WP_User_Query($count_args);
$total = $total_query->get_total();
// Get trainers
$user_query = new WP_User_Query($query_args);
$trainers = $user_query->get_results();
return array(
'trainers' => $trainers,
'total' => $total,
'query_args' => $query_args
);
}
/**
* Get available regions from trainer data
*/
private function get_regions() {
global $wpdb;
// Get unique states and countries from trainer meta
$regions = $wpdb->get_col(
"SELECT DISTINCT meta_value
FROM {$wpdb->usermeta} um
INNER JOIN {$wpdb->users} u ON um.user_id = u.ID
INNER JOIN {$wpdb->usermeta} um_role ON u.ID = um_role.user_id
WHERE um.meta_key IN ('state', 'country')
AND um.meta_value != ''
AND um_role.meta_key = 'wp_capabilities'
AND (um_role.meta_value LIKE '%hvac_trainer%' OR um_role.meta_value LIKE '%hvac_master_trainer%')
ORDER BY meta_value"
);
return array_filter($regions);
}
/**
* Get trainer location string
*/
private function get_trainer_location($user_id) {
$city = get_user_meta($user_id, 'city', true);
$state = get_user_meta($user_id, 'state', true);
$country = get_user_meta($user_id, 'country', true);
$location_parts = array_filter(array($city, $state, $country));
return !empty($location_parts) ? implode(', ', $location_parts) : 'Not specified';
}
/**
* Get status badge HTML
*/
private function get_status_badge($status) {
$badges = array(
'pending' => 'Pending',
'approved' => 'Approved',
'active' => 'Active',
'inactive' => 'Inactive',
'disabled' => 'Rejected'
);
return isset($badges[$status]) ? $badges[$status] : '' . esc_html(ucfirst($status)) . '';
}
/**
* Render modal dialogs
*/
private function render_modals() {
?>
can_manage_approvals()) {
wp_send_json_error(array('message' => 'Insufficient permissions.'));
}
$user_id = intval($_POST['user_id'] ?? 0);
$reason = sanitize_textarea_field($_POST['reason'] ?? '');
if (!$user_id) {
wp_send_json_error(array('message' => 'Invalid user ID.'));
}
// Get trainer info
$trainer = get_userdata($user_id);
if (!$trainer) {
wp_send_json_error(array('message' => 'Trainer not found.'));
}
// Update status using existing system
$result = HVAC_Trainer_Status::set_trainer_status($user_id, HVAC_Trainer_Status::STATUS_APPROVED);
if ($result) {
// Log the approval action
$this->log_approval_action($user_id, 'approved', $reason);
wp_send_json_success(array(
'message' => sprintf('Trainer %s has been approved.', $trainer->display_name),
'user_id' => $user_id,
'new_status' => 'approved'
));
} else {
wp_send_json_error(array('message' => 'Failed to approve trainer.'));
}
}
/**
* AJAX: Reject trainer
*/
public function ajax_reject_trainer() {
// Check nonce
check_ajax_referer('hvac_master_approvals', 'nonce');
// Check permissions
if (!$this->can_manage_approvals()) {
wp_send_json_error(array('message' => 'Insufficient permissions.'));
}
$user_id = intval($_POST['user_id'] ?? 0);
$reason = sanitize_textarea_field($_POST['reason'] ?? '');
if (!$user_id) {
wp_send_json_error(array('message' => 'Invalid user ID.'));
}
// Get trainer info
$trainer = get_userdata($user_id);
if (!$trainer) {
wp_send_json_error(array('message' => 'Trainer not found.'));
}
// Update status - use disabled for rejected
$result = HVAC_Trainer_Status::set_trainer_status($user_id, HVAC_Trainer_Status::STATUS_DISABLED);
if ($result) {
// Log the rejection action
$this->log_approval_action($user_id, 'rejected', $reason);
wp_send_json_success(array(
'message' => sprintf('Trainer %s has been rejected.', $trainer->display_name),
'user_id' => $user_id,
'new_status' => 'rejected'
));
} else {
wp_send_json_error(array('message' => 'Failed to reject trainer.'));
}
}
/**
* AJAX: Bulk trainer actions
*/
public function ajax_bulk_trainer_action() {
// Check nonce
check_ajax_referer('hvac_master_approvals', 'nonce');
// Check permissions
if (!$this->can_manage_approvals()) {
wp_send_json_error(array('message' => 'Insufficient permissions.'));
}
$user_ids = array_map('intval', $_POST['user_ids'] ?? array());
$action = sanitize_text_field($_POST['action'] ?? '');
$reason = sanitize_textarea_field($_POST['reason'] ?? '');
if (empty($user_ids) || !in_array($action, array('approve', 'reject'))) {
wp_send_json_error(array('message' => 'Invalid parameters.'));
}
$success_count = 0;
$failed_count = 0;
$results = array();
foreach ($user_ids as $user_id) {
$trainer = get_userdata($user_id);
if (!$trainer) {
$failed_count++;
continue;
}
$new_status = ($action === 'approve') ? HVAC_Trainer_Status::STATUS_APPROVED : HVAC_Trainer_Status::STATUS_DISABLED;
if (HVAC_Trainer_Status::set_trainer_status($user_id, $new_status)) {
$this->log_approval_action($user_id, $action === 'approve' ? 'approved' : 'rejected', $reason);
$success_count++;
$results[$user_id] = 'success';
} else {
$failed_count++;
$results[$user_id] = 'failed';
}
}
$message = sprintf(
'Bulk %s completed: %d successful, %d failed',
$action === 'approve' ? 'approval' : 'rejection',
$success_count,
$failed_count
);
wp_send_json_success(array(
'message' => $message,
'success_count' => $success_count,
'failed_count' => $failed_count,
'results' => $results
));
}
/**
* AJAX: Get trainer details
*/
public function ajax_get_trainer_details() {
// Check nonce
check_ajax_referer('hvac_master_approvals', 'nonce');
// Check permissions
if (!$this->can_manage_approvals()) {
wp_send_json_error(array('message' => 'Insufficient permissions.'));
}
$user_id = intval($_POST['user_id'] ?? 0);
if (!$user_id) {
wp_send_json_error(array('message' => 'Invalid user ID.'));
}
$trainer = get_userdata($user_id);
if (!$trainer) {
wp_send_json_error(array('message' => 'Trainer not found.'));
}
// Get trainer meta data
$trainer_data = array(
'display_name' => $trainer->display_name,
'user_email' => $trainer->user_email,
'user_registered' => date('F j, Y', strtotime($trainer->user_registered)),
'first_name' => get_user_meta($user_id, 'first_name', true),
'last_name' => get_user_meta($user_id, 'last_name', true),
'phone' => get_user_meta($user_id, 'phone', true),
'business_name' => get_user_meta($user_id, 'business_name', true),
'business_email' => get_user_meta($user_id, 'business_email', true),
'business_phone' => get_user_meta($user_id, 'business_phone', true),
'business_website' => get_user_meta($user_id, 'business_website', true),
'city' => get_user_meta($user_id, 'city', true),
'state' => get_user_meta($user_id, 'state', true),
'country' => get_user_meta($user_id, 'country', true),
'application_details' => get_user_meta($user_id, 'application_details', true),
'business_type' => get_user_meta($user_id, 'business_type', true),
'training_audience' => get_user_meta($user_id, 'training_audience', true),
'status' => HVAC_Trainer_Status::get_trainer_status($user_id),
'approval_log' => get_user_meta($user_id, 'hvac_approval_log', true)
);
// Build HTML content
ob_start();
?>
Personal Information
| Name: | |
| Email: | |
| Phone: | |
| Registration Date: | |
Business Information
| Business Name: | |
| Business Email: | |
| Business Phone: | |
| Website: | |
| Business Type: | |
Location
| City: | |
| State/Province: | |
| Country: | |
Current Status
get_status_badge($trainer_data['status']); ?>
ob_get_clean(),
'data' => $trainer_data
));
}
/**
* Log approval action to user meta
*/
private function log_approval_action($user_id, $action, $reason = '') {
$current_user = wp_get_current_user();
$log_entry = array(
'action' => ucfirst($action),
'user' => $current_user->display_name,
'user_id' => $current_user->ID,
'date' => current_time('mysql'),
'reason' => $reason
);
// Get existing log
$approval_log = get_user_meta($user_id, 'hvac_approval_log', true);
if (!is_array($approval_log)) {
$approval_log = array();
}
// Add new entry
$approval_log[] = $log_entry;
// Store updated log
update_user_meta($user_id, 'hvac_approval_log', $approval_log);
}
}
// Initialize the class
HVAC_Master_Pending_Approvals::instance();