This commit introduces a complete announcement management system for HVAC trainers with enterprise-grade security, performance optimization, and email notifications. ## Core Features - Custom post type for trainer announcements with categories and tags - Role-based permissions (master trainers can create/edit, all trainers can read) - AJAX-powered admin interface with real-time updates - Modal popup viewing for announcements on frontend - Automated email notifications when announcements are published - Google Drive integration for training resources ## Security Enhancements - Fixed critical capability mapping bug preventing proper permission checks - Added content disclosure protection for draft/private announcements - Fixed XSS vulnerabilities with proper output escaping and sanitization - Implemented permission checks on all AJAX endpoints - Added rate limiting to prevent abuse (30 requests/minute) - Email validation before sending notifications ## Performance Optimizations - Implemented intelligent caching for user queries (5-minute TTL) - Added cache versioning for announcement lists (2-minute TTL) - Automatic cache invalidation on content changes - Batch email processing to prevent timeouts (50 emails per batch) - Retry mechanism for failed email sends (max 3 attempts) ## Technical Implementation - Singleton pattern for all manager classes - WordPress coding standards compliance - Proper nonce verification on all AJAX requests - Comprehensive error handling and logging - Mobile-responsive UI with smooth animations - WCAG accessibility compliance ## Components Added - 6 PHP classes for modular architecture - 2 page templates (master announcements, trainer resources) - Admin and frontend JavaScript with jQuery integration - Comprehensive CSS for both admin and frontend - Email notification system with HTML templates - Complete documentation and implementation plans This system provides a secure, scalable foundation for trainer communications while following WordPress best practices and maintaining high code quality. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
188 lines
No EOL
8 KiB
PHP
188 lines
No EOL
8 KiB
PHP
<?php
|
|
/**
|
|
* Template Name: Trainer Resources
|
|
* Description: Resources page for HVAC trainers including announcements and Google Drive
|
|
*
|
|
* @package HVAC_Community_Events
|
|
*/
|
|
|
|
// Security check
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
// Define template constant
|
|
if (!defined('HVAC_IN_PAGE_TEMPLATE')) {
|
|
define('HVAC_IN_PAGE_TEMPLATE', true);
|
|
}
|
|
|
|
// Check if user is a trainer
|
|
if (!HVAC_Announcements_Permissions::is_trainer()) {
|
|
wp_redirect(home_url('/'));
|
|
exit;
|
|
}
|
|
|
|
get_header();
|
|
|
|
// Get menu system instance
|
|
$menu_system = HVAC_Menu_System::get_instance();
|
|
?>
|
|
|
|
<div class="hvac-plugin-page hvac-trainer-resources-page">
|
|
<?php
|
|
// Display navigation menu
|
|
echo $menu_system->render_navigation_menu();
|
|
?>
|
|
|
|
<!-- Breadcrumbs -->
|
|
<nav class="hvac-breadcrumbs" aria-label="Breadcrumb">
|
|
<div class="container">
|
|
<ol class="breadcrumb-list">
|
|
<li class="breadcrumb-item"><a href="<?php echo home_url(); ?>">Home</a></li>
|
|
<li class="breadcrumb-item"><a href="<?php echo home_url('/trainer/dashboard/'); ?>">Dashboard</a></li>
|
|
<li class="breadcrumb-item active" aria-current="page">Resources</li>
|
|
</ol>
|
|
</div>
|
|
</nav>
|
|
|
|
<div class="container">
|
|
<div class="hvac-resources-wrapper">
|
|
<header class="page-header">
|
|
<h1><?php _e('Trainer Resources', 'hvac'); ?></h1>
|
|
<p class="page-description">
|
|
<?php _e('Access important announcements, training materials, and shared resources to support your HVAC training programs.', 'hvac'); ?>
|
|
</p>
|
|
</header>
|
|
|
|
<!-- Announcements Section -->
|
|
<section class="resources-section announcements-section">
|
|
<h2 class="section-title">
|
|
<span class="dashicons dashicons-megaphone"></span>
|
|
<?php _e('Latest Announcements', 'hvac'); ?>
|
|
</h2>
|
|
|
|
<div class="announcements-container">
|
|
<?php
|
|
// Use Gutenberg blocks for announcements timeline
|
|
$block_content = '<!-- wp:uagb/post-timeline {
|
|
"postsToShow":10,
|
|
"post_type":"hvac_announcement",
|
|
"categories":"",
|
|
"orderBy":"date",
|
|
"order":"desc",
|
|
"timelinAlignment":"center",
|
|
"timelinAlignmentTablet":"left",
|
|
"timelinAlignmentMobile":"left",
|
|
"dateFontSizeType":"px",
|
|
"dateFontSize":12,
|
|
"headingTag":"h3",
|
|
"block_id":"hvac-announcements-timeline",
|
|
"displayPostDate":true,
|
|
"displayPostExcerpt":true,
|
|
"displayPostAuthor":false,
|
|
"displayPostImage":true,
|
|
"displayPostLink":true,
|
|
"readMoreText":"Read More",
|
|
"excerptLength":30,
|
|
"loadMoreText":"Load More Announcements",
|
|
"offset":0,
|
|
"exclude":"",
|
|
"sectionTitle":"",
|
|
"sectionTitleTag":"h2"
|
|
} /-->';
|
|
|
|
// Check if UAGB is active
|
|
if (class_exists('UAGB_Loader')) {
|
|
echo do_blocks($block_content);
|
|
} else {
|
|
// Fallback to custom shortcode if UAGB is not available
|
|
echo do_shortcode('[hvac_announcements_timeline posts_per_page="10"]');
|
|
}
|
|
?>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Google Drive Resources Section -->
|
|
<section class="resources-section google-drive-section">
|
|
<h2 class="section-title">
|
|
<span class="dashicons dashicons-media-default"></span>
|
|
<?php _e('Training Resources Library', 'hvac'); ?>
|
|
</h2>
|
|
|
|
<div class="google-drive-description">
|
|
<p><?php _e('Access shared training materials, presentations, documentation, and other resources in our Google Drive folder.', 'hvac'); ?></p>
|
|
</div>
|
|
|
|
<div class="google-drive-container">
|
|
<?php
|
|
// Google Drive embed
|
|
$drive_url = 'https://drive.google.com/drive/folders/16uDRkFcaEqKUxfBek9VbfbAIeFV77nZG?usp=drive_link';
|
|
|
|
// Convert to embed URL
|
|
$folder_id = '16uDRkFcaEqKUxfBek9VbfbAIeFV77nZG';
|
|
$embed_url = 'https://drive.google.com/embeddedfolderview?id=' . $folder_id . '#list';
|
|
?>
|
|
|
|
<iframe
|
|
src="<?php echo esc_url($embed_url); ?>"
|
|
width="100%"
|
|
height="600"
|
|
frameborder="0"
|
|
class="google-drive-iframe"
|
|
allowfullscreen="true"
|
|
mozallowfullscreen="true"
|
|
webkitallowfullscreen="true">
|
|
</iframe>
|
|
|
|
<div class="google-drive-footer">
|
|
<p>
|
|
<a href="<?php echo esc_url($drive_url); ?>" target="_blank" class="button">
|
|
<span class="dashicons dashicons-external"></span>
|
|
<?php _e('Open in Google Drive', 'hvac'); ?>
|
|
</a>
|
|
</p>
|
|
<p class="help-text">
|
|
<?php _e('If you have trouble viewing the embedded folder, click the button above to open it directly in Google Drive.', 'hvac'); ?>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Additional Resources Section -->
|
|
<section class="resources-section additional-resources">
|
|
<h2 class="section-title">
|
|
<span class="dashicons dashicons-admin-links"></span>
|
|
<?php _e('Quick Links', 'hvac'); ?>
|
|
</h2>
|
|
|
|
<div class="quick-links-grid">
|
|
<a href="<?php echo home_url('/trainer/dashboard/'); ?>" class="resource-card">
|
|
<span class="dashicons dashicons-dashboard"></span>
|
|
<h3><?php _e('Dashboard', 'hvac'); ?></h3>
|
|
<p><?php _e('Return to your trainer dashboard', 'hvac'); ?></p>
|
|
</a>
|
|
|
|
<a href="<?php echo home_url('/trainer/event/manage/'); ?>" class="resource-card">
|
|
<span class="dashicons dashicons-calendar-alt"></span>
|
|
<h3><?php _e('Manage Events', 'hvac'); ?></h3>
|
|
<p><?php _e('Create and manage your training events', 'hvac'); ?></p>
|
|
</a>
|
|
|
|
<a href="<?php echo home_url('/trainer/certificate-reports/'); ?>" class="resource-card">
|
|
<span class="dashicons dashicons-awards"></span>
|
|
<h3><?php _e('Certificates', 'hvac'); ?></h3>
|
|
<p><?php _e('View and manage certificates', 'hvac'); ?></p>
|
|
</a>
|
|
|
|
<a href="<?php echo home_url('/trainer/profile/'); ?>" class="resource-card">
|
|
<span class="dashicons dashicons-admin-users"></span>
|
|
<h3><?php _e('Profile', 'hvac'); ?></h3>
|
|
<p><?php _e('Update your trainer profile', 'hvac'); ?></p>
|
|
</a>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php get_footer(); ?>
|