🚨 CRITICAL: Fixed deployment blockers by adding missing core directories: **Community System (CRITICAL)** - includes/community/ - Login_Handler and all community classes - templates/community/ - Community login forms **Certificate System (CRITICAL)** - includes/certificates/ - 8+ certificate classes and handlers - templates/certificates/ - Certificate reports and generation templates **Core Individual Classes (CRITICAL)** - includes/class-hvac-event-summary.php - includes/class-hvac-trainer-profile-manager.php - includes/class-hvac-master-dashboard-data.php - Plus 40+ other individual HVAC classes **Major Feature Systems (HIGH)** - includes/database/ - Training leads database tables - includes/find-trainer/ - Find trainer directory and MapGeo integration - includes/google-sheets/ - Google Sheets integration system - includes/zoho/ - Complete Zoho CRM integration - includes/communication/ - Communication templates system **Template Infrastructure** - templates/attendee/, templates/email-attendees/ - templates/event-summary/, templates/status/ - templates/template-parts/ - Shared template components **Impact:** - 70+ files added covering 10+ missing directories - Resolves ALL deployment blockers and feature breakdowns - Plugin activation should now work correctly - Multi-machine deployment fully supported 🔧 Generated with Claude Code Co-Authored-By: Ben Reed <ben@tealmaker.com>
213 lines
No EOL
6.6 KiB
PHP
213 lines
No EOL
6.6 KiB
PHP
<?php
|
|
/**
|
|
* Certificate URL Handler Class
|
|
*
|
|
* Handles certificate URL routing without relying on rewrite rules
|
|
*
|
|
* @package HVAC_Community_Events
|
|
* @subpackage Certificates
|
|
*/
|
|
|
|
// Exit if accessed directly
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Certificate URL Handler class.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
class HVAC_Certificate_URL_Handler {
|
|
|
|
/**
|
|
* The single instance of the class.
|
|
*
|
|
* @var HVAC_Certificate_URL_Handler
|
|
*/
|
|
protected static $_instance = null;
|
|
|
|
/**
|
|
* Main HVAC_Certificate_URL_Handler Instance.
|
|
*/
|
|
public static function instance() {
|
|
if (is_null(self::$_instance)) {
|
|
self::$_instance = new self();
|
|
}
|
|
return self::$_instance;
|
|
}
|
|
|
|
/**
|
|
* Constructor.
|
|
*/
|
|
public function __construct() {
|
|
// Hook very early to catch certificate URLs - before WordPress parses the request
|
|
add_action('plugins_loaded', array($this, 'catch_certificate_urls'), 1);
|
|
add_action('init', array($this, 'catch_certificate_urls'), 1);
|
|
|
|
// Also try parse_request as a fallback
|
|
add_action('parse_request', array($this, 'parse_certificate_request'), 1);
|
|
|
|
// Log initialization
|
|
if (class_exists('HVAC_Logger')) {
|
|
HVAC_Logger::info('Certificate URL Handler initialized', 'Certificates');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Catch certificate URLs and handle them directly
|
|
*/
|
|
public function catch_certificate_urls() {
|
|
// Only process on frontend
|
|
if (is_admin()) {
|
|
return;
|
|
}
|
|
|
|
// Get the request URI
|
|
$request_uri = $_SERVER['REQUEST_URI'];
|
|
$parsed_url = parse_url($request_uri);
|
|
$path = $parsed_url['path'] ?? '';
|
|
|
|
// Remove any trailing slash for consistency
|
|
$path = rtrim($path, '/');
|
|
|
|
// Check if this is a certificate URL
|
|
if (preg_match('#^/hvac-certificate/([a-zA-Z0-9]{32})$#', $path, $matches)) {
|
|
$token = $matches[1];
|
|
|
|
// Log the request
|
|
if (class_exists('HVAC_Logger')) {
|
|
HVAC_Logger::info("Certificate URL detected - Token: $token", 'Certificates');
|
|
}
|
|
|
|
// Handle the certificate download
|
|
$this->handle_certificate_download($token);
|
|
exit; // Stop WordPress from processing further
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handle certificate download
|
|
*/
|
|
protected function handle_certificate_download($token) {
|
|
// Validate the token
|
|
$certificate_data = $this->validate_download_token($token);
|
|
|
|
if (!$certificate_data) {
|
|
if (class_exists('HVAC_Logger')) {
|
|
HVAC_Logger::error("Invalid or expired certificate token: $token", 'Certificates');
|
|
}
|
|
wp_die(__('Invalid or expired certificate download link.', 'hvac-community-events'), 'Certificate Error', array('response' => 404));
|
|
}
|
|
|
|
// Get file path
|
|
$file_path = $this->get_certificate_file_path($certificate_data);
|
|
|
|
if (!$file_path || !file_exists($file_path)) {
|
|
if (class_exists('HVAC_Logger')) {
|
|
HVAC_Logger::error("Certificate file not found for token: $token", 'Certificates');
|
|
}
|
|
wp_die(__('Certificate file not found.', 'hvac-community-events'), 'Certificate Error', array('response' => 404));
|
|
}
|
|
|
|
// Log successful access
|
|
if (class_exists('HVAC_Logger')) {
|
|
HVAC_Logger::info("Serving certificate file: $file_path", 'Certificates');
|
|
}
|
|
|
|
// Serve the file
|
|
$this->serve_certificate_file($file_path, $certificate_data);
|
|
}
|
|
|
|
/**
|
|
* Validate a certificate download token.
|
|
*/
|
|
protected function validate_download_token($token) {
|
|
// Check if token exists in transients
|
|
$certificate_data = get_transient('hvac_certificate_token_' . $token);
|
|
|
|
if (!$certificate_data) {
|
|
return false;
|
|
}
|
|
|
|
// Delete the transient to prevent reuse
|
|
delete_transient('hvac_certificate_token_' . $token);
|
|
|
|
return $certificate_data;
|
|
}
|
|
|
|
/**
|
|
* Get the full file path for a certificate.
|
|
*/
|
|
protected function get_certificate_file_path($certificate_data) {
|
|
if (empty($certificate_data['file_path'])) {
|
|
return false;
|
|
}
|
|
|
|
$upload_dir = wp_upload_dir();
|
|
$file_path = $upload_dir['basedir'] . '/' . $certificate_data['file_path'];
|
|
|
|
if (file_exists($file_path)) {
|
|
return $file_path;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Serve a certificate file for download.
|
|
*/
|
|
protected function serve_certificate_file($file_path, $certificate_data) {
|
|
// Get file information
|
|
$file_name = basename($file_path);
|
|
$file_size = filesize($file_path);
|
|
$file_ext = pathinfo($file_path, PATHINFO_EXTENSION);
|
|
|
|
// Set download filename
|
|
$event_name = sanitize_title($certificate_data['event_name'] ?? 'event');
|
|
$attendee_name = sanitize_title($certificate_data['attendee_name'] ?? 'attendee');
|
|
$download_filename = "certificate-{$event_name}-{$attendee_name}.{$file_ext}";
|
|
|
|
// Send headers
|
|
nocache_headers();
|
|
header('Content-Type: application/pdf');
|
|
header('Content-Disposition: attachment; filename="' . $download_filename . '"');
|
|
header('Content-Transfer-Encoding: binary');
|
|
header('Content-Length: ' . $file_size);
|
|
|
|
// Disable output buffering
|
|
if (ob_get_level()) {
|
|
ob_end_clean();
|
|
}
|
|
|
|
// Output the file
|
|
readfile($file_path);
|
|
}
|
|
|
|
/**
|
|
* Parse request fallback method
|
|
*/
|
|
public function parse_certificate_request($wp) {
|
|
// Get the request URI
|
|
$request_uri = $_SERVER['REQUEST_URI'];
|
|
$parsed_url = parse_url($request_uri);
|
|
$path = $parsed_url['path'] ?? '';
|
|
|
|
// Remove any trailing slash for consistency
|
|
$path = rtrim($path, '/');
|
|
|
|
// Check if this is a certificate URL
|
|
if (preg_match('#^/hvac-certificate/([a-zA-Z0-9]{32})$#', $path, $matches)) {
|
|
$token = $matches[1];
|
|
|
|
// Log the request
|
|
if (class_exists('HVAC_Logger')) {
|
|
HVAC_Logger::info("Certificate URL detected via parse_request - Token: $token", 'Certificates');
|
|
}
|
|
|
|
// Handle the certificate download
|
|
$this->handle_certificate_download($token);
|
|
exit; // Stop WordPress from processing further
|
|
}
|
|
}
|
|
} |