- Updated default email in HVAC_Activator from support@upskillevents.com to joe@upskillhvac.com - Added email obfuscation methods (obfuscate_email, encode_email) to HVAC_Page_Manager - Updated registration pending template to use {support_email_encoded} placeholder - Added JavaScript and HTML entity protection against email harvesting bots 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Ben Reed <ben@tealmaker.com>
630 lines
No EOL
22 KiB
PHP
630 lines
No EOL
22 KiB
PHP
<?php
|
|
/**
|
|
* Page Manager for HVAC Community Events
|
|
*
|
|
* Handles creation and management of plugin pages following WordPress best practices
|
|
*
|
|
* @package HVAC_Community_Events
|
|
* @since 1.0.0
|
|
*/
|
|
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* HVAC_Page_Manager class
|
|
*/
|
|
class HVAC_Page_Manager {
|
|
|
|
/**
|
|
* Page definitions
|
|
*
|
|
* @var array
|
|
*/
|
|
private static $pages = [
|
|
// Public pages
|
|
'training-login' => [
|
|
'title' => 'Trainer Login',
|
|
'template' => 'page-trainer-login.php',
|
|
'public' => true,
|
|
'parent' => null,
|
|
'capability' => null
|
|
],
|
|
'find-a-trainer' => [
|
|
'title' => 'Find a Trainer',
|
|
'template' => 'page-find-trainer.php',
|
|
'public' => true,
|
|
'parent' => null,
|
|
'capability' => null
|
|
],
|
|
|
|
// Trainer pages
|
|
'trainer' => [
|
|
'title' => 'Trainer',
|
|
'template' => null,
|
|
'public' => false,
|
|
'parent' => null,
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
'trainer/dashboard' => [
|
|
'title' => 'Trainer Dashboard',
|
|
'template' => 'page-trainer-dashboard.php',
|
|
'public' => false,
|
|
'parent' => 'trainer',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
'trainer/registration' => [
|
|
'title' => 'Trainer Registration',
|
|
'template' => 'page-trainer-registration.php',
|
|
'public' => true,
|
|
'parent' => 'trainer',
|
|
'capability' => null
|
|
],
|
|
'trainer/my-profile' => [
|
|
'title' => 'Trainer Profile',
|
|
'template' => 'page-trainer-profile.php',
|
|
'public' => false,
|
|
'parent' => 'trainer',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
|
|
// New trainer profile pages
|
|
'trainer/profile' => [
|
|
'title' => 'Personal Profile',
|
|
'template' => 'page-trainer-profile.php',
|
|
'public' => false,
|
|
'parent' => 'trainer',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
'trainer/profile/edit' => [
|
|
'title' => 'Edit Profile',
|
|
'template' => 'page-trainer-profile-edit.php',
|
|
'public' => false,
|
|
'parent' => 'trainer/profile',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
'trainer/training-leads' => [
|
|
'title' => 'Training Leads',
|
|
'template' => 'page-trainer-training-leads.php',
|
|
'public' => false,
|
|
'parent' => 'trainer/profile',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
|
|
// Venue management pages
|
|
'trainer/venue' => [
|
|
'title' => 'Venues',
|
|
'template' => null,
|
|
'public' => false,
|
|
'parent' => 'trainer',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
'trainer/venue/list' => [
|
|
'title' => 'Training Venues',
|
|
'template' => 'page-trainer-venues-list.php',
|
|
'public' => false,
|
|
'parent' => 'trainer/venue',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
'trainer/venue/manage' => [
|
|
'title' => 'Manage Venue',
|
|
'template' => 'page-trainer-venue-manage.php',
|
|
'public' => false,
|
|
'parent' => 'trainer/venue',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
|
|
// Organizer management pages
|
|
'trainer/organizer' => [
|
|
'title' => 'Organizers',
|
|
'template' => null,
|
|
'public' => false,
|
|
'parent' => 'trainer',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
'trainer/organizer/list' => [
|
|
'title' => 'Training Organizers',
|
|
'template' => 'page-trainer-organizers-list.php',
|
|
'public' => false,
|
|
'parent' => 'trainer/organizer',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
'trainer/organizer/manage' => [
|
|
'title' => 'Manage Organizer',
|
|
'template' => 'page-trainer-organizer-manage.php',
|
|
'public' => false,
|
|
'parent' => 'trainer/organizer',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
'trainer/event' => [
|
|
'title' => 'Event',
|
|
'template' => null,
|
|
'public' => false,
|
|
'parent' => 'trainer',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
'trainer/event/manage' => [
|
|
'title' => 'Manage Event',
|
|
'template' => 'page-manage-event.php',
|
|
'public' => false,
|
|
'parent' => 'trainer/event',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
'trainer/event/summary' => [
|
|
'title' => 'Event Summary',
|
|
'template' => 'page-event-summary.php',
|
|
'public' => false,
|
|
'parent' => 'trainer/event',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
|
|
// Status pages
|
|
'trainer-account-pending' => [
|
|
'title' => 'Account Pending Approval',
|
|
'template' => 'status/trainer-account-pending.php',
|
|
'public' => false,
|
|
'parent' => null,
|
|
'capability' => 'read',
|
|
'content_file' => 'content/trainer-account-pending.html'
|
|
],
|
|
'trainer-account-disabled' => [
|
|
'title' => 'Account Access Restricted',
|
|
'template' => 'status/trainer-account-disabled.php',
|
|
'public' => false,
|
|
'parent' => null,
|
|
'capability' => 'read',
|
|
'content_file' => 'content/trainer-account-disabled.html'
|
|
],
|
|
|
|
// Certificate pages
|
|
'trainer/certificate-reports' => [
|
|
'title' => 'Certificate Reports',
|
|
'template' => 'page-certificate-reports.php',
|
|
'public' => false,
|
|
'parent' => 'trainer',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
'trainer/generate-certificates' => [
|
|
'title' => 'Generate Certificates',
|
|
'template' => 'page-generate-certificates.php',
|
|
'public' => false,
|
|
'parent' => 'trainer',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
|
|
// Communication pages
|
|
'trainer/email-attendees' => [
|
|
'title' => 'Email Attendees',
|
|
'template' => 'page-email-attendees.php',
|
|
'public' => false,
|
|
'parent' => 'trainer',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
'trainer/communication-templates' => [
|
|
'title' => 'Communication Templates',
|
|
'template' => 'page-communication-templates.php',
|
|
'public' => false,
|
|
'parent' => 'trainer',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
'trainer/communication-schedules' => [
|
|
'title' => 'Communication Schedules',
|
|
'template' => 'page-communication-schedules.php',
|
|
'public' => false,
|
|
'parent' => 'trainer',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
|
|
// Master trainer pages
|
|
'master-trainer' => [
|
|
'title' => 'Master Trainer',
|
|
'template' => null,
|
|
'public' => false,
|
|
'parent' => null,
|
|
'capability' => 'hvac_master_trainer'
|
|
],
|
|
'master-trainer/dashboard' => [
|
|
'title' => 'Master Dashboard',
|
|
'template' => 'page-master-dashboard.php',
|
|
'public' => false,
|
|
'parent' => 'master-trainer',
|
|
'capability' => 'hvac_master_trainer'
|
|
],
|
|
'master-trainer/master-dashboard' => [
|
|
'title' => 'Master Dashboard',
|
|
'template' => 'page-master-dashboard.php',
|
|
'public' => false,
|
|
'parent' => 'master-trainer',
|
|
'capability' => 'hvac_master_trainer'
|
|
],
|
|
'master-trainer/certificate-fix' => [
|
|
'title' => 'Certificate System Diagnostics',
|
|
'template' => 'page-certificate-fix.php',
|
|
'public' => false,
|
|
'parent' => 'master-trainer',
|
|
'capability' => 'hvac_master_trainer'
|
|
],
|
|
'master-trainer/google-sheets' => [
|
|
'title' => 'Google Sheets Integration',
|
|
'template' => 'page-google-sheets.php',
|
|
'public' => false,
|
|
'parent' => 'master-trainer',
|
|
'capability' => 'hvac_master_trainer'
|
|
],
|
|
'master-trainer/edit-trainer-profile' => [
|
|
'title' => 'Edit Trainer Profile',
|
|
'template' => 'page-master-trainer-profile-edit-simple.php',
|
|
'public' => false,
|
|
'parent' => 'master-trainer',
|
|
'capability' => 'hvac_master_trainer'
|
|
],
|
|
'master-trainer/master-dashboard' => [
|
|
'title' => 'Master Dashboard',
|
|
'template' => 'page-master-dashboard.php',
|
|
'public' => false,
|
|
'parent' => 'master-trainer',
|
|
'capability' => 'hvac_master_trainer'
|
|
],
|
|
|
|
// Trainer Profile pages
|
|
'trainer/profile' => [
|
|
'title' => 'Personal Profile',
|
|
'template' => 'page-trainer-profile.php',
|
|
'public' => false,
|
|
'parent' => 'trainer',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
'trainer/profile/edit' => [
|
|
'title' => 'Edit Profile',
|
|
'template' => 'page-trainer-profile-edit.php',
|
|
'public' => false,
|
|
'parent' => 'trainer/profile',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
|
|
// Venue pages
|
|
'trainer/venue' => [
|
|
'title' => 'Venues',
|
|
'template' => null,
|
|
'public' => false,
|
|
'parent' => 'trainer',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
'trainer/venue/list' => [
|
|
'title' => 'Training Venues',
|
|
'template' => 'page-trainer-venues-list.php',
|
|
'public' => false,
|
|
'parent' => 'trainer/venue',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
'trainer/venue/manage' => [
|
|
'title' => 'Manage Venue',
|
|
'template' => 'page-trainer-venue-manage.php',
|
|
'public' => false,
|
|
'parent' => 'trainer/venue',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
|
|
// Organizer pages
|
|
'trainer/organizer' => [
|
|
'title' => 'Organizers',
|
|
'template' => null,
|
|
'public' => false,
|
|
'parent' => 'trainer',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
'trainer/organizer/list' => [
|
|
'title' => 'Training Organizers',
|
|
'template' => 'page-trainer-organizers-list.php',
|
|
'public' => false,
|
|
'parent' => 'trainer/organizer',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
'trainer/organizer/manage' => [
|
|
'title' => 'Manage Organizer',
|
|
'template' => 'page-trainer-organizer-manage.php',
|
|
'public' => false,
|
|
'parent' => 'trainer/organizer',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
|
|
// Other pages
|
|
'trainer/documentation' => [
|
|
'title' => 'Trainer Documentation',
|
|
'template' => 'page-documentation.php',
|
|
'public' => false,
|
|
'parent' => 'trainer',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
'trainer/attendee-profile' => [
|
|
'title' => 'Attendee Profile',
|
|
'template' => 'page-attendee-profile.php',
|
|
'public' => false,
|
|
'parent' => 'trainer',
|
|
'capability' => 'hvac_trainer'
|
|
],
|
|
'registration-pending' => [
|
|
'title' => 'Registration Pending',
|
|
'template' => 'page-registration-pending.php',
|
|
'public' => false,
|
|
'parent' => null,
|
|
'capability' => null,
|
|
'content_file' => 'content/registration-pending.html'
|
|
]
|
|
];
|
|
|
|
/**
|
|
* Create all required pages
|
|
*
|
|
* @return void
|
|
*/
|
|
public static function create_pages() {
|
|
HVAC_Logger::info('Starting page creation process', 'Page Manager');
|
|
|
|
foreach (self::$pages as $slug => $config) {
|
|
self::create_page($slug, $config);
|
|
}
|
|
|
|
// Flush rewrite rules after creating all pages
|
|
flush_rewrite_rules();
|
|
HVAC_Logger::info('Completed page creation process', 'Page Manager');
|
|
}
|
|
|
|
/**
|
|
* Create a single page
|
|
*
|
|
* @param string $slug Page slug
|
|
* @param array $config Page configuration
|
|
* @return int|false Page ID or false on failure
|
|
*/
|
|
private static function create_page($slug, $config) {
|
|
// Check if page already exists
|
|
$existing_page = get_page_by_path($slug);
|
|
if ($existing_page) {
|
|
HVAC_Logger::info("Page already exists: {$slug}", 'Page Manager');
|
|
return $existing_page->ID;
|
|
}
|
|
|
|
// Prepare page data
|
|
$page_data = [
|
|
'post_title' => $config['title'],
|
|
'post_name' => basename($slug),
|
|
'post_content' => self::get_page_content($slug, $config),
|
|
'post_status' => 'publish',
|
|
'post_type' => 'page',
|
|
'post_author' => 1,
|
|
'comment_status' => 'closed',
|
|
'ping_status' => 'closed'
|
|
];
|
|
|
|
// Set parent page if specified
|
|
if (!empty($config['parent'])) {
|
|
$parent_page = get_page_by_path($config['parent']);
|
|
if ($parent_page) {
|
|
$page_data['post_parent'] = $parent_page->ID;
|
|
}
|
|
}
|
|
|
|
// Create the page
|
|
$page_id = wp_insert_post($page_data);
|
|
|
|
if (is_wp_error($page_id)) {
|
|
HVAC_Logger::error("Failed to create page: {$slug} - " . $page_id->get_error_message(), 'Page Manager');
|
|
return false;
|
|
}
|
|
|
|
// Set page template if specified
|
|
if (!empty($config['template'])) {
|
|
update_post_meta($page_id, '_wp_page_template', $config['template']);
|
|
}
|
|
|
|
// Set Astra theme layout to full-width for all HVAC pages
|
|
update_post_meta($page_id, 'ast-site-content-layout', 'page-builder');
|
|
update_post_meta($page_id, 'site-post-title', 'disabled');
|
|
update_post_meta($page_id, 'site-sidebar-layout', 'no-sidebar');
|
|
update_post_meta($page_id, 'theme-transparent-header-meta', 'disabled');
|
|
|
|
// Set page capabilities if specified
|
|
if (!empty($config['capability'])) {
|
|
update_post_meta($page_id, '_hvac_required_capability', $config['capability']);
|
|
}
|
|
|
|
HVAC_Logger::info("Created page: {$slug} (ID: {$page_id})", 'Page Manager');
|
|
return $page_id;
|
|
}
|
|
|
|
/**
|
|
* Get page content
|
|
*
|
|
* @param string $slug Page slug
|
|
* @param array $config Page configuration
|
|
* @return string Page content
|
|
*/
|
|
private static function get_page_content($slug, $config) {
|
|
// If content file is specified, load it
|
|
if (!empty($config['content_file'])) {
|
|
$content_path = HVAC_PLUGIN_DIR . 'templates/' . $config['content_file'];
|
|
if (file_exists($content_path)) {
|
|
$content = file_get_contents($content_path);
|
|
|
|
// Replace placeholders
|
|
$replacements = [
|
|
'{home_url}' => home_url(),
|
|
'{logout_url}' => wp_logout_url(home_url()),
|
|
'{login_url}' => home_url('/training-login/'),
|
|
'{site_name}' => get_bloginfo('name'),
|
|
'{support_email}' => get_option('hvac_support_email', 'joe@upskillhvac.com'),
|
|
'{support_email_obfuscated}' => self::obfuscate_email(get_option('hvac_support_email', 'joe@upskillhvac.com')),
|
|
'{support_email_encoded}' => self::encode_email(get_option('hvac_support_email', 'joe@upskillhvac.com'))
|
|
];
|
|
|
|
$content = str_replace(array_keys($replacements), array_values($replacements), $content);
|
|
|
|
return $content;
|
|
}
|
|
}
|
|
|
|
// Define shortcode mappings for specific pages
|
|
$shortcode_mappings = [
|
|
'trainer/profile' => '[hvac_trainer_profile_view]',
|
|
'trainer/profile/edit' => '[hvac_trainer_profile_edit]',
|
|
'trainer/training-leads' => '[hvac_trainer_training_leads]',
|
|
'trainer/venue/list' => '[hvac_trainer_venues_list]',
|
|
'trainer/venue/manage' => '[hvac_trainer_venue_manage]',
|
|
'trainer/organizer/list' => '[hvac_trainer_organizers_list]',
|
|
'trainer/organizer/manage' => '[hvac_trainer_organizer_manage]',
|
|
'trainer/certificate-reports' => '[hvac_certificate_reports]',
|
|
'trainer/generate-certificates' => '[hvac_generate_certificates]'
|
|
];
|
|
|
|
// Return shortcode if mapped
|
|
if (isset($shortcode_mappings[$slug])) {
|
|
return $shortcode_mappings[$slug];
|
|
}
|
|
|
|
// For pages with templates, use a placeholder
|
|
if (!empty($config['template'])) {
|
|
return '<!-- This page uses a custom template -->';
|
|
}
|
|
|
|
// Default content for parent pages
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* Get page definition by slug
|
|
*
|
|
* @param string $slug Page slug
|
|
* @return array|null Page configuration or null if not found
|
|
*/
|
|
public static function get_page_config($slug) {
|
|
return isset(self::$pages[$slug]) ? self::$pages[$slug] : null;
|
|
}
|
|
|
|
/**
|
|
* Check if a page requires authentication
|
|
*
|
|
* @param string $slug Page slug
|
|
* @return bool
|
|
*/
|
|
public static function requires_auth($slug) {
|
|
$config = self::get_page_config($slug);
|
|
return $config && !empty($config['capability']);
|
|
}
|
|
|
|
/**
|
|
* Get required capability for a page
|
|
*
|
|
* @param string $slug Page slug
|
|
* @return string|null Required capability or null if none
|
|
*/
|
|
public static function get_required_capability($slug) {
|
|
$config = self::get_page_config($slug);
|
|
return $config ? $config['capability'] : null;
|
|
}
|
|
|
|
/**
|
|
* Delete all plugin pages
|
|
*
|
|
* @return void
|
|
*/
|
|
public static function delete_pages() {
|
|
HVAC_Logger::info('Starting page deletion process', 'Page Manager');
|
|
|
|
foreach (self::$pages as $slug => $config) {
|
|
$page = get_page_by_path($slug);
|
|
if ($page) {
|
|
wp_delete_post($page->ID, true);
|
|
HVAC_Logger::info("Deleted page: {$slug}", 'Page Manager');
|
|
}
|
|
}
|
|
|
|
HVAC_Logger::info('Completed page deletion process', 'Page Manager');
|
|
}
|
|
|
|
/**
|
|
* Update all existing pages with proper layout settings
|
|
*
|
|
* @return void
|
|
*/
|
|
public static function update_existing_page_layouts() {
|
|
HVAC_Logger::info('Updating page layouts and templates', 'Page Manager');
|
|
|
|
foreach (self::$pages as $slug => $config) {
|
|
$page = get_page_by_path($slug);
|
|
if ($page) {
|
|
// Update page template if specified
|
|
if (!empty($config['template'])) {
|
|
$current_template = get_post_meta($page->ID, '_wp_page_template', true);
|
|
if ($current_template !== $config['template']) {
|
|
update_post_meta($page->ID, '_wp_page_template', $config['template']);
|
|
HVAC_Logger::info("Updated template for page {$slug}: {$config['template']}", 'Page Manager');
|
|
}
|
|
}
|
|
|
|
// Set Astra theme layout to full-width
|
|
update_post_meta($page->ID, 'ast-site-content-layout', 'page-builder');
|
|
update_post_meta($page->ID, 'site-post-title', 'disabled');
|
|
update_post_meta($page->ID, 'site-sidebar-layout', 'no-sidebar');
|
|
update_post_meta($page->ID, 'theme-transparent-header-meta', 'disabled');
|
|
|
|
HVAC_Logger::info("Updated layout settings for page: {$slug}", 'Page Manager');
|
|
}
|
|
}
|
|
|
|
HVAC_Logger::info('Completed page layout and template updates', 'Page Manager');
|
|
}
|
|
|
|
/**
|
|
* Obfuscate email address to prevent bot harvesting
|
|
*
|
|
* @param string $email Email address to obfuscate
|
|
* @return string Obfuscated email HTML
|
|
*/
|
|
public static function obfuscate_email($email) {
|
|
$obfuscated = '';
|
|
$len = strlen($email);
|
|
|
|
// Convert each character to HTML entity
|
|
for ($i = 0; $i < $len; $i++) {
|
|
$char = $email[$i];
|
|
// Mix between decimal and hex entities
|
|
if (mt_rand(0, 1)) {
|
|
$obfuscated .= '&#' . ord($char) . ';';
|
|
} else {
|
|
$obfuscated .= '&#x' . dechex(ord($char)) . ';';
|
|
}
|
|
}
|
|
|
|
return $obfuscated;
|
|
}
|
|
|
|
/**
|
|
* Encode email with JavaScript protection
|
|
*
|
|
* @param string $email Email address to encode
|
|
* @return string JavaScript-protected email HTML
|
|
*/
|
|
public static function encode_email($email) {
|
|
$encoded = '';
|
|
$len = strlen($email);
|
|
|
|
// Create reversed and encoded email
|
|
$reversed = strrev($email);
|
|
for ($i = 0; $i < $len; $i++) {
|
|
$encoded .= '&#' . ord($reversed[$i]) . ';';
|
|
}
|
|
|
|
// Return JavaScript that decodes and reverses the email
|
|
return '<script type="text/javascript">
|
|
document.write(\'<a href="mailto:\' + \'' . $encoded . '\'.replace(/&#(\\d+);/g, function(match, dec) {
|
|
return String.fromCharCode(dec);
|
|
}).split("").reverse().join("") + \'">\' + \'' . self::obfuscate_email($email) . '\' + \'</a>\');
|
|
</script>
|
|
<noscript>
|
|
<span style="unicode-bidi: bidi-override; direction: rtl;">' . self::obfuscate_email(strrev($email)) . '</span>
|
|
<br><small>(Enable JavaScript to view email)</small>
|
|
</noscript>';
|
|
}
|
|
} |