## Major Enhancements ### 🏗️ Architecture & Infrastructure - Implement comprehensive Docker testing infrastructure with hermetic environment - Add Forgejo Actions CI/CD pipeline for automated deployments - Create Page Object Model (POM) testing architecture reducing test duplication by 90% - Establish security-first development patterns with input validation and output escaping ### 🧪 Testing Framework Modernization - Migrate 146+ tests from 80 duplicate files to centralized architecture - Add comprehensive E2E test suites for all user roles and workflows - Implement WordPress error detection with automatic site health monitoring - Create robust browser lifecycle management with proper cleanup ### 📚 Documentation & Guides - Add comprehensive development best practices guide - Create detailed administrator setup documentation - Establish user guides for trainers and master trainers - Document security incident reports and migration guides ### 🔧 Core Plugin Features - Enhance trainer profile management with certification system - Improve find trainer functionality with advanced filtering - Strengthen master trainer area with content management - Add comprehensive venue and organizer management ### 🛡️ Security & Reliability - Implement security-first patterns throughout codebase - Add comprehensive input validation and output escaping - Create secure credential management system - Establish proper WordPress role-based access control ### 🎯 WordPress Integration - Strengthen singleton pattern implementation across all classes - Enhance template hierarchy with proper WordPress integration - Improve page manager with hierarchical URL structure - Add comprehensive shortcode and menu system ### 🔍 Developer Experience - Add extensive debugging and troubleshooting tools - Create comprehensive test data seeding scripts - Implement proper error handling and logging - Establish consistent code patterns and standards ### 📊 Performance & Optimization - Optimize database queries and caching strategies - Improve asset loading and script management - Enhance template rendering performance - Streamline user experience across all interfaces 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			318 lines
		
	
	
		
			No EOL
		
	
	
		
			9.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			318 lines
		
	
	
		
			No EOL
		
	
	
		
			9.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * Master Layout Standardizer - Ensures consistent single-column layout for Master Trainer pages
 | |
|  * 
 | |
|  * This class provides standardized styling and layout for all Master Trainer pages,
 | |
|  * enforcing single-column layouts and consistent design patterns.
 | |
|  *
 | |
|  * @package HVAC_Community_Events
 | |
|  * @since 2.1.0
 | |
|  */
 | |
| 
 | |
| if (!defined('ABSPATH')) {
 | |
|     exit;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * HVAC_Master_Layout_Standardizer class
 | |
|  */
 | |
| class HVAC_Master_Layout_Standardizer {
 | |
| 
 | |
|     /**
 | |
|      * Instance of this class
 | |
|      * @var HVAC_Master_Layout_Standardizer
 | |
|      */
 | |
|     private static $instance = null;
 | |
| 
 | |
|     /**
 | |
|      * Get instance
 | |
|      */
 | |
|     public static function instance() {
 | |
|         if (null === self::$instance) {
 | |
|             self::$instance = new self();
 | |
|         }
 | |
|         return self::$instance;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Constructor
 | |
|      */
 | |
|     private function __construct() {
 | |
|         add_action('wp_enqueue_scripts', array($this, 'inject_standardized_styles'), 20);
 | |
|         add_filter('body_class', array($this, 'add_layout_body_class'));
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Add body class for master trainer pages
 | |
|      */
 | |
|     public function add_layout_body_class($classes) {
 | |
|         if ($this->is_master_trainer_page()) {
 | |
|             $classes[] = 'hvac-master-single-column';
 | |
|         }
 | |
|         return $classes;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Check if current page is a master trainer page
 | |
|      */
 | |
|     private function is_master_trainer_page() {
 | |
|         // Check URL path first (most reliable)
 | |
|         $request_uri = $_SERVER['REQUEST_URI'] ?? '';
 | |
|         if (strpos($request_uri, '/master-trainer/') !== false) {
 | |
|             return true;
 | |
|         }
 | |
|         
 | |
|         // Check page template if we have a post
 | |
|         global $post;
 | |
|         if ($post) {
 | |
|             $template = get_page_template_slug($post->ID);
 | |
|             if (strpos($template, 'page-master-') === 0) {
 | |
|                 return true;
 | |
|             }
 | |
|         }
 | |
|         
 | |
|         // Check query vars for custom pages
 | |
|         if (get_query_var('pagename')) {
 | |
|             $pagename = get_query_var('pagename');
 | |
|             if (strpos($pagename, 'master-trainer') !== false) {
 | |
|                 return true;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Inject standardized styles for master trainer pages
 | |
|      */
 | |
|     public function inject_standardized_styles() {
 | |
|         if (!$this->is_master_trainer_page()) {
 | |
|             return;
 | |
|         }
 | |
|         ?>
 | |
|         <style type="text/css">
 | |
|         /* Master Trainer Single Column Layout Standardization */
 | |
|         .hvac-master-single-column .hvac-page-wrapper {
 | |
|             max-width: 1200px;
 | |
|             margin: 0 auto;
 | |
|             padding: 20px;
 | |
|         }
 | |
| 
 | |
|         /* Force single column layout for all content sections */
 | |
|         .hvac-master-single-column .hvac-stats-tiles,
 | |
|         .hvac-master-single-column .hvac-announcements-timeline,
 | |
|         .hvac-master-single-column .hvac-pending-approvals-content,
 | |
|         .hvac-master-single-column .hvac-master-trainers-content,
 | |
|         .hvac-master-single-column .hvac-master-events-content {
 | |
|             display: block !important;
 | |
|             width: 100% !important;
 | |
|             max-width: 100% !important;
 | |
|             margin: 0 auto !important;
 | |
|         }
 | |
| 
 | |
|         /* Remove multi-column layouts */
 | |
|         .hvac-master-single-column .hvac-stats-tiles {
 | |
|             display: grid !important;
 | |
|             grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)) !important;
 | |
|             gap: 20px !important;
 | |
|             margin-bottom: 30px !important;
 | |
|         }
 | |
| 
 | |
|         /* Announcements single column */
 | |
|         .hvac-master-single-column .hvac-announcements-timeline {
 | |
|             column-count: 1 !important;
 | |
|             -webkit-column-count: 1 !important;
 | |
|             -moz-column-count: 1 !important;
 | |
|         }
 | |
| 
 | |
|         .hvac-master-single-column .announcement-item {
 | |
|             width: 100% !important;
 | |
|             max-width: 100% !important;
 | |
|             margin-bottom: 20px !important;
 | |
|             break-inside: avoid !important;
 | |
|             page-break-inside: avoid !important;
 | |
|         }
 | |
| 
 | |
|         /* Pending approvals single column */
 | |
|         .hvac-master-single-column .hvac-pending-approvals-list {
 | |
|             display: block !important;
 | |
|             width: 100% !important;
 | |
|         }
 | |
| 
 | |
|         .hvac-master-single-column .approval-item {
 | |
|             width: 100% !important;
 | |
|             max-width: 100% !important;
 | |
|             margin-bottom: 15px !important;
 | |
|             display: block !important;
 | |
|         }
 | |
| 
 | |
|         /* Trainers overview single column */
 | |
|         .hvac-master-single-column .hvac-trainers-table-container {
 | |
|             width: 100% !important;
 | |
|             overflow-x: auto !important;
 | |
|         }
 | |
| 
 | |
|         .hvac-master-single-column .hvac-trainers-table {
 | |
|             width: 100% !important;
 | |
|             table-layout: auto !important;
 | |
|         }
 | |
| 
 | |
|         /* Events overview single column */
 | |
|         .hvac-master-single-column .hvac-events-table-container {
 | |
|             width: 100% !important;
 | |
|             overflow-x: auto !important;
 | |
|         }
 | |
| 
 | |
|         /* Consistent button styling */
 | |
|         .hvac-master-single-column .hvac-btn,
 | |
|         .hvac-master-single-column .hvac-button,
 | |
|         .hvac-master-single-column .button {
 | |
|             font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
 | |
|             font-size: 14px;
 | |
|             line-height: 1.5;
 | |
|             padding: 8px 16px;
 | |
|             border-radius: 4px;
 | |
|             border: 1px solid #ddd;
 | |
|             background: #f7f7f7;
 | |
|             color: #333;
 | |
|             cursor: pointer;
 | |
|             text-decoration: none;
 | |
|             display: inline-block;
 | |
|             transition: all 0.2s ease;
 | |
|         }
 | |
| 
 | |
|         .hvac-master-single-column .hvac-btn-primary,
 | |
|         .hvac-master-single-column .hvac-button-primary,
 | |
|         .hvac-master-single-column .button-primary {
 | |
|             background: #0073aa;
 | |
|             border-color: #0073aa;
 | |
|             color: white;
 | |
|         }
 | |
| 
 | |
|         .hvac-master-single-column .hvac-btn:hover,
 | |
|         .hvac-master-single-column .hvac-button:hover,
 | |
|         .hvac-master-single-column .button:hover {
 | |
|             background: #fafafa;
 | |
|             border-color: #999;
 | |
|         }
 | |
| 
 | |
|         .hvac-master-single-column .hvac-btn-primary:hover,
 | |
|         .hvac-master-single-column .hvac-button-primary:hover,
 | |
|         .hvac-master-single-column .button-primary:hover {
 | |
|             background: #005a87;
 | |
|             border-color: #005a87;
 | |
|         }
 | |
| 
 | |
|         /* Consistent font styling */
 | |
|         .hvac-master-single-column {
 | |
|             font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
 | |
|             font-size: 14px;
 | |
|             line-height: 1.6;
 | |
|             color: #333;
 | |
|         }
 | |
| 
 | |
|         .hvac-master-single-column h1 {
 | |
|             font-size: 28px;
 | |
|             font-weight: 600;
 | |
|             margin: 0 0 20px 0;
 | |
|             color: #23282d;
 | |
|         }
 | |
| 
 | |
|         .hvac-master-single-column h2 {
 | |
|             font-size: 22px;
 | |
|             font-weight: 600;
 | |
|             margin: 20px 0 15px 0;
 | |
|             color: #23282d;
 | |
|         }
 | |
| 
 | |
|         .hvac-master-single-column h3 {
 | |
|             font-size: 18px;
 | |
|             font-weight: 600;
 | |
|             margin: 15px 0 10px 0;
 | |
|             color: #23282d;
 | |
|         }
 | |
| 
 | |
|         /* Consistent table styling */
 | |
|         .hvac-master-single-column table {
 | |
|             width: 100%;
 | |
|             border-collapse: collapse;
 | |
|             margin: 20px 0;
 | |
|             background: white;
 | |
|             box-shadow: 0 1px 3px rgba(0,0,0,0.1);
 | |
|         }
 | |
| 
 | |
|         .hvac-master-single-column table th {
 | |
|             background: #f1f1f1;
 | |
|             text-align: left;
 | |
|             padding: 12px;
 | |
|             font-weight: 600;
 | |
|             border-bottom: 1px solid #ddd;
 | |
|         }
 | |
| 
 | |
|         .hvac-master-single-column table td {
 | |
|             padding: 12px;
 | |
|             border-bottom: 1px solid #eee;
 | |
|         }
 | |
| 
 | |
|         .hvac-master-single-column table tr:hover {
 | |
|             background: #f7f7f7;
 | |
|         }
 | |
| 
 | |
|         /* Consistent card/box styling */
 | |
|         .hvac-master-single-column .hvac-card,
 | |
|         .hvac-master-single-column .hvac-box,
 | |
|         .hvac-master-single-column .sync-card,
 | |
|         .hvac-master-single-column .announcement-item,
 | |
|         .hvac-master-single-column .approval-item {
 | |
|             background: white;
 | |
|             border: 1px solid #ddd;
 | |
|             border-radius: 4px;
 | |
|             padding: 20px;
 | |
|             margin-bottom: 20px;
 | |
|             box-shadow: 0 1px 3px rgba(0,0,0,0.05);
 | |
|         }
 | |
| 
 | |
|         /* Responsive adjustments */
 | |
|         @media (max-width: 768px) {
 | |
|             .hvac-master-single-column .hvac-stats-tiles {
 | |
|                 grid-template-columns: 1fr !important;
 | |
|             }
 | |
|             
 | |
|             .hvac-master-single-column .hvac-page-wrapper {
 | |
|                 padding: 10px;
 | |
|             }
 | |
|             
 | |
|             .hvac-master-single-column table {
 | |
|                 font-size: 12px;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /* Remove any conflicting multi-column CSS */
 | |
|         .hvac-master-single-column [class*="col-md-"],
 | |
|         .hvac-master-single-column [class*="col-sm-"],
 | |
|         .hvac-master-single-column [class*="col-lg-"] {
 | |
|             width: 100% !important;
 | |
|             float: none !important;
 | |
|             padding-left: 0 !important;
 | |
|             padding-right: 0 !important;
 | |
|         }
 | |
| 
 | |
|         /* Ensure proper navigation spacing */
 | |
|         .hvac-master-single-column .hvac-master-menu {
 | |
|             margin-bottom: 20px;
 | |
|         }
 | |
| 
 | |
|         .hvac-master-single-column .hvac-breadcrumbs {
 | |
|             margin-bottom: 20px;
 | |
|         }
 | |
|         </style>
 | |
|         <?php
 | |
|     }
 | |
| }
 | |
| 
 | |
| // Initialize the standardizer
 | |
| add_action('init', function() {
 | |
|     if (class_exists('HVAC_Master_Layout_Standardizer')) {
 | |
|         HVAC_Master_Layout_Standardizer::instance();
 | |
|     }
 | |
| });
 |