- Implement singleton pattern for HVAC_Enhanced_Settings to prevent duplicate initialization - Fix jQuery selector error by checking for valid hash selectors before using $(href) - Add default email templates with professional copy for trainer notifications - Update plugin version to 1.0.1 for cache busting - Remove duplicate Enhanced Settings initialization from HVAC_Community_Events - Add force cache refresh suffix to admin scripts This resolves the duplicate content issue on email templates page and fixes JavaScript errors in the admin interface. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
423 lines
No EOL
17 KiB
PHP
423 lines
No EOL
17 KiB
PHP
<?php
|
|
/**
|
|
* HVAC Community Events - Approval Workflow
|
|
*
|
|
* Handles trainer approval workflow and email notifications
|
|
*
|
|
* @package HVAC_Community_Events
|
|
* @since 1.0.0
|
|
*/
|
|
|
|
// Exit if accessed directly
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Class HVAC_Approval_Workflow
|
|
*
|
|
* Manages the trainer approval process including email notifications
|
|
*/
|
|
class HVAC_Approval_Workflow {
|
|
|
|
/**
|
|
* Constructor
|
|
*/
|
|
public function __construct() {
|
|
// Hook into trainer status changes
|
|
add_action( 'hvac_trainer_status_changed', array( $this, 'handle_status_change' ), 10, 3 );
|
|
|
|
// Add query variable for approval token
|
|
add_filter( 'query_vars', array( $this, 'add_query_vars' ) );
|
|
|
|
// Handle approval URL visits
|
|
add_action( 'template_redirect', array( $this, 'handle_approval_request' ), 5 );
|
|
|
|
// Add AJAX handlers for bulk updates
|
|
add_action( 'wp_ajax_hvac_bulk_update_trainer_status', array( $this, 'ajax_bulk_update_status' ) );
|
|
}
|
|
|
|
/**
|
|
* Add query variables for approval
|
|
*/
|
|
public function add_query_vars( $vars ) {
|
|
$vars[] = 'hvac_approve_trainer';
|
|
$vars[] = 'hvac_approval_token';
|
|
return $vars;
|
|
}
|
|
|
|
/**
|
|
* Handle trainer status changes
|
|
*
|
|
* @param int $user_id User ID
|
|
* @param string $new_status New status
|
|
* @param string $old_status Old status
|
|
*/
|
|
public function handle_status_change( $user_id, $new_status, $old_status ) {
|
|
// Send appropriate notifications based on status change
|
|
if ( $new_status === HVAC_Trainer_Status::STATUS_APPROVED && $old_status === HVAC_Trainer_Status::STATUS_PENDING ) {
|
|
$this->send_approval_notification( $user_id );
|
|
} elseif ( $new_status === HVAC_Trainer_Status::STATUS_DISABLED ) {
|
|
$this->send_disabled_notification( $user_id );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Send new registration notification to admins
|
|
*
|
|
* @param int $user_id User ID
|
|
* @param array $registration_data Registration form data
|
|
*/
|
|
public function send_new_registration_notification( $user_id, $registration_data ) {
|
|
$user = get_userdata( $user_id );
|
|
if ( ! $user ) {
|
|
return false;
|
|
}
|
|
|
|
// Get notification emails
|
|
$options = get_option( 'hvac_ce_options', array() );
|
|
$notification_emails = isset( $options['notification_emails'] ) ? $options['notification_emails'] : get_option( 'admin_email' );
|
|
|
|
// Convert comma-separated list to array
|
|
if ( is_string( $notification_emails ) ) {
|
|
$notification_emails = array_map( 'trim', explode( ',', $notification_emails ) );
|
|
}
|
|
|
|
// Generate approval token
|
|
$approval_token = $this->generate_approval_token( $user_id );
|
|
update_user_meta( $user_id, 'hvac_approval_token', $approval_token );
|
|
|
|
// Build approval URL
|
|
$approval_url = add_query_arg( array(
|
|
'hvac_approve_trainer' => $user_id,
|
|
'hvac_approval_token' => $approval_token,
|
|
), home_url( '/master-trainer/dashboard/' ) );
|
|
|
|
// Get email template
|
|
$template = $this->get_email_template( 'new_registration' );
|
|
|
|
// Replace placeholders
|
|
$replacements = array(
|
|
'{trainer_name}' => $user->display_name,
|
|
'{trainer_email}' => $user->user_email,
|
|
'{business_name}' => get_user_meta( $user_id, 'business_name', true ),
|
|
'{business_phone}' => get_user_meta( $user_id, 'business_phone', true ),
|
|
'{business_email}' => get_user_meta( $user_id, 'business_email', true ),
|
|
'{registration_date}' => date( 'F j, Y', strtotime( $user->user_registered ) ),
|
|
'{application_details}' => get_user_meta( $user_id, 'application_details', true ),
|
|
'{approval_url}' => $approval_url,
|
|
'{website_name}' => get_bloginfo( 'name' ),
|
|
'{website_url}' => home_url(),
|
|
);
|
|
|
|
$subject = str_replace( array_keys( $replacements ), array_values( $replacements ), $template['subject'] );
|
|
$message = str_replace( array_keys( $replacements ), array_values( $replacements ), $template['body'] );
|
|
|
|
// Send emails
|
|
$headers = array( 'Content-Type: text/html; charset=UTF-8' );
|
|
|
|
foreach ( $notification_emails as $email ) {
|
|
wp_mail( $email, $subject, $message, $headers );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Send approval notification to trainer
|
|
*
|
|
* @param int $user_id User ID
|
|
*/
|
|
public function send_approval_notification( $user_id ) {
|
|
$user = get_userdata( $user_id );
|
|
if ( ! $user ) {
|
|
return false;
|
|
}
|
|
|
|
// Get email template
|
|
$template = $this->get_email_template( 'account_approved' );
|
|
|
|
// Replace placeholders
|
|
$replacements = array(
|
|
'{trainer_name}' => $user->display_name,
|
|
'{trainer_email}' => $user->user_email,
|
|
'{business_name}' => get_user_meta( $user_id, 'business_name', true ),
|
|
'{dashboard_url}' => home_url( '/trainer/dashboard/' ),
|
|
'{login_url}' => home_url( '/community-login/' ),
|
|
'{website_name}' => get_bloginfo( 'name' ),
|
|
'{website_url}' => home_url(),
|
|
'{current_date}' => date( 'F j, Y' ),
|
|
);
|
|
|
|
$subject = str_replace( array_keys( $replacements ), array_values( $replacements ), $template['subject'] );
|
|
$message = str_replace( array_keys( $replacements ), array_values( $replacements ), $template['body'] );
|
|
|
|
// Send email
|
|
$headers = array( 'Content-Type: text/html; charset=UTF-8' );
|
|
|
|
return wp_mail( $user->user_email, $subject, $message, $headers );
|
|
}
|
|
|
|
/**
|
|
* Send disabled notification to trainer
|
|
*
|
|
* @param int $user_id User ID
|
|
*/
|
|
public function send_disabled_notification( $user_id ) {
|
|
$user = get_userdata( $user_id );
|
|
if ( ! $user ) {
|
|
return false;
|
|
}
|
|
|
|
// Get email template
|
|
$template = $this->get_email_template( 'account_disabled' );
|
|
|
|
// Replace placeholders
|
|
$replacements = array(
|
|
'{trainer_name}' => $user->display_name,
|
|
'{trainer_email}' => $user->user_email,
|
|
'{business_name}' => get_user_meta( $user_id, 'business_name', true ),
|
|
'{support_email}' => get_option( 'admin_email' ),
|
|
'{website_name}' => get_bloginfo( 'name' ),
|
|
'{website_url}' => home_url(),
|
|
'{current_date}' => date( 'F j, Y' ),
|
|
);
|
|
|
|
$subject = str_replace( array_keys( $replacements ), array_values( $replacements ), $template['subject'] );
|
|
$message = str_replace( array_keys( $replacements ), array_values( $replacements ), $template['body'] );
|
|
|
|
// Send email
|
|
$headers = array( 'Content-Type: text/html; charset=UTF-8' );
|
|
|
|
return wp_mail( $user->user_email, $subject, $message, $headers );
|
|
}
|
|
|
|
/**
|
|
* Get email template
|
|
*
|
|
* @param string $template_key Template key
|
|
* @return array Template data with subject and body
|
|
*/
|
|
private function get_email_template( $template_key ) {
|
|
$options = get_option( 'hvac_ce_email_templates', array() );
|
|
|
|
// Default templates
|
|
$defaults = array(
|
|
'new_registration' => array(
|
|
'subject' => 'New HVAC Trainer Registration - {trainer_name}',
|
|
'body' => '
|
|
<h2>New Trainer Registration Pending Approval</h2>
|
|
<p>A new HVAC trainer has registered and is awaiting approval.</p>
|
|
|
|
<h3>Trainer Details:</h3>
|
|
<ul>
|
|
<li><strong>Name:</strong> {trainer_name}</li>
|
|
<li><strong>Email:</strong> {trainer_email}</li>
|
|
<li><strong>Business:</strong> {business_name}</li>
|
|
<li><strong>Phone:</strong> {business_phone}</li>
|
|
<li><strong>Business Email:</strong> {business_email}</li>
|
|
<li><strong>Registration Date:</strong> {registration_date}</li>
|
|
</ul>
|
|
|
|
<h3>Application Details:</h3>
|
|
<p>{application_details}</p>
|
|
|
|
<p><a href="{approval_url}" style="display: inline-block; padding: 10px 20px; background: #0073aa; color: white; text-decoration: none; border-radius: 4px;">Approve This Trainer</a></p>
|
|
|
|
<p>Or copy this link: {approval_url}</p>
|
|
',
|
|
),
|
|
'account_approved' => array(
|
|
'subject' => 'Your HVAC Trainer Account Has Been Approved!',
|
|
'body' => '
|
|
<h2>Welcome to {website_name}!</h2>
|
|
|
|
<p>Dear {trainer_name},</p>
|
|
|
|
<p>Great news! Your HVAC trainer account has been approved and you now have full access to create and manage training events.</p>
|
|
|
|
<h3>What You Can Do Now:</h3>
|
|
<ul>
|
|
<li>Create and manage training events</li>
|
|
<li>Access your trainer dashboard</li>
|
|
<li>Generate certificates for attendees</li>
|
|
<li>Communicate with your attendees</li>
|
|
<li>View analytics and reports</li>
|
|
</ul>
|
|
|
|
<h3>Getting Started:</h3>
|
|
<ol>
|
|
<li><a href="{login_url}">Log in to your account</a></li>
|
|
<li>Visit your <a href="{dashboard_url}">Trainer Dashboard</a></li>
|
|
<li>Click "Create New Event" to post your first training event</li>
|
|
<li>Share your event with your network to maximize attendance</li>
|
|
</ol>
|
|
|
|
<p>If you have any questions or need assistance, please don\'t hesitate to reach out to our support team.</p>
|
|
|
|
<p>We\'re excited to have you as part of our training community!</p>
|
|
|
|
<p>Best regards,<br>
|
|
The {website_name} Team</p>
|
|
',
|
|
),
|
|
'account_disabled' => array(
|
|
'subject' => 'Your HVAC Trainer Account Has Been Disabled',
|
|
'body' => '
|
|
<h2>Account Status Update</h2>
|
|
|
|
<p>Dear {trainer_name},</p>
|
|
|
|
<p>We regret to inform you that your HVAC trainer account on {website_name} has been disabled.</p>
|
|
|
|
<p>Your account may have been disabled for one of the following reasons:</p>
|
|
<ul>
|
|
<li>Violation of our terms of service or community guidelines</li>
|
|
<li>Extended period of inactivity</li>
|
|
<li>Incomplete or inaccurate information</li>
|
|
<li>Quality concerns or complaints</li>
|
|
</ul>
|
|
|
|
<p>If you believe this action was taken in error or would like to discuss reactivating your account, please contact our support team at <a href="mailto:{support_email}">{support_email}</a>.</p>
|
|
|
|
<p>We appreciate your understanding.</p>
|
|
|
|
<p>Sincerely,<br>
|
|
The {website_name} Team</p>
|
|
',
|
|
),
|
|
);
|
|
|
|
// Return custom template if exists, otherwise default
|
|
if ( isset( $options[$template_key] ) ) {
|
|
return $options[$template_key];
|
|
}
|
|
|
|
return isset( $defaults[$template_key] ) ? $defaults[$template_key] : array( 'subject' => '', 'body' => '' );
|
|
}
|
|
|
|
/**
|
|
* Generate approval token
|
|
*
|
|
* @param int $user_id User ID
|
|
* @return string Token
|
|
*/
|
|
private function generate_approval_token( $user_id ) {
|
|
return wp_hash( $user_id . time() . wp_rand() );
|
|
}
|
|
|
|
/**
|
|
* Handle approval request from email link
|
|
*/
|
|
public function handle_approval_request() {
|
|
$user_id = get_query_var( 'hvac_approve_trainer' );
|
|
$token = get_query_var( 'hvac_approval_token' );
|
|
|
|
if ( ! $user_id || ! $token ) {
|
|
return;
|
|
}
|
|
|
|
// Verify token
|
|
$stored_token = get_user_meta( $user_id, 'hvac_approval_token', true );
|
|
|
|
if ( $token !== $stored_token ) {
|
|
wp_die( __( 'Invalid approval token.', 'hvac-community-events' ) );
|
|
}
|
|
|
|
// Check if user is logged in
|
|
if ( ! is_user_logged_in() ) {
|
|
// Store approval request in session/transient
|
|
set_transient( 'hvac_pending_approval_' . $token, $user_id, HOUR_IN_SECONDS );
|
|
|
|
// Redirect to login with return URL
|
|
$login_url = add_query_arg( array(
|
|
'redirect_to' => urlencode( add_query_arg( array(
|
|
'hvac_approve_trainer' => $user_id,
|
|
'hvac_approval_token' => $token,
|
|
), home_url( '/master-trainer/dashboard/' ) ) ),
|
|
), home_url( '/community-login/' ) );
|
|
|
|
wp_redirect( $login_url );
|
|
exit;
|
|
}
|
|
|
|
// Check if current user can approve trainers
|
|
if ( ! current_user_can( 'view_master_dashboard' ) && ! current_user_can( 'manage_options' ) ) {
|
|
wp_die( __( 'You do not have permission to approve trainers.', 'hvac-community-events' ) );
|
|
}
|
|
|
|
// Approve the trainer
|
|
if ( ! class_exists( 'HVAC_Trainer_Status' ) ) {
|
|
require_once HVAC_PLUGIN_DIR . 'includes/class-hvac-trainer-status.php';
|
|
}
|
|
|
|
$result = HVAC_Trainer_Status::set_trainer_status( $user_id, HVAC_Trainer_Status::STATUS_APPROVED );
|
|
|
|
if ( $result ) {
|
|
// Delete the token
|
|
delete_user_meta( $user_id, 'hvac_approval_token' );
|
|
|
|
// Get trainer info for message
|
|
$trainer = get_userdata( $user_id );
|
|
$message = sprintf(
|
|
__( 'Trainer %s with email %s has been approved!', 'hvac-community-events' ),
|
|
$trainer->display_name,
|
|
$trainer->user_email
|
|
);
|
|
|
|
// Store success message in transient
|
|
set_transient( 'hvac_approval_message', $message, 30 );
|
|
}
|
|
|
|
// Redirect to master dashboard
|
|
wp_redirect( home_url( '/master-trainer/dashboard/' ) );
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* AJAX handler for bulk status updates
|
|
*/
|
|
public function ajax_bulk_update_status() {
|
|
// Check nonce
|
|
if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'hvac_master_dashboard_nonce' ) ) {
|
|
wp_die( 'Security check failed' );
|
|
}
|
|
|
|
// Check permissions
|
|
if ( ! current_user_can( 'view_master_dashboard' ) && ! current_user_can( 'manage_options' ) ) {
|
|
wp_send_json_error( array( 'message' => 'Insufficient permissions' ) );
|
|
}
|
|
|
|
// Get parameters
|
|
$user_ids = isset( $_POST['user_ids'] ) ? array_map( 'intval', $_POST['user_ids'] ) : array();
|
|
$new_status = isset( $_POST['status'] ) ? sanitize_text_field( $_POST['status'] ) : '';
|
|
|
|
if ( empty( $user_ids ) || empty( $new_status ) ) {
|
|
wp_send_json_error( array( 'message' => 'Missing required parameters' ) );
|
|
}
|
|
|
|
// Load status class
|
|
if ( ! class_exists( 'HVAC_Trainer_Status' ) ) {
|
|
require_once HVAC_PLUGIN_DIR . 'includes/class-hvac-trainer-status.php';
|
|
}
|
|
|
|
// Perform bulk update
|
|
$results = HVAC_Trainer_Status::bulk_update_status( $user_ids, $new_status );
|
|
|
|
if ( $results['success'] > 0 ) {
|
|
wp_send_json_success( array(
|
|
'message' => sprintf(
|
|
__( 'Successfully updated %d trainer(s). %d failed.', 'hvac-community-events' ),
|
|
$results['success'],
|
|
$results['failed']
|
|
),
|
|
'results' => $results,
|
|
) );
|
|
} else {
|
|
wp_send_json_error( array(
|
|
'message' => __( 'Failed to update trainer statuses.', 'hvac-community-events' ),
|
|
'results' => $results,
|
|
) );
|
|
}
|
|
}
|
|
} |