## 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>
243 lines
No EOL
7.4 KiB
PHP
243 lines
No EOL
7.4 KiB
PHP
<?php
|
|
/**
|
|
* Master Content Injector - Ensures Master Trainer pages always have content
|
|
*
|
|
* This class provides a failsafe system that injects shortcodes into Master Trainer
|
|
* pages if they're missing content, ensuring the pages always display properly.
|
|
*
|
|
* @package HVAC_Community_Events
|
|
* @since 2.1.0
|
|
*/
|
|
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* HVAC_Master_Content_Injector class
|
|
*/
|
|
class HVAC_Master_Content_Injector {
|
|
|
|
/**
|
|
* Instance of this class
|
|
* @var HVAC_Master_Content_Injector
|
|
*/
|
|
private static $instance = null;
|
|
|
|
/**
|
|
* Master pages mapping
|
|
* @var array
|
|
*/
|
|
private $master_pages = array(
|
|
'all-trainers' => array(
|
|
'shortcode' => '[hvac_master_trainers]',
|
|
'class' => 'HVAC_Master_Trainers_Overview',
|
|
'method' => 'render_trainers_overview'
|
|
),
|
|
'events-overview' => array(
|
|
'shortcode' => '[hvac_master_events]',
|
|
'class' => 'HVAC_Master_Events_Overview',
|
|
'method' => 'render_events_overview'
|
|
),
|
|
'pending-approvals' => array(
|
|
'shortcode' => '[hvac_pending_approvals]',
|
|
'class' => 'HVAC_Master_Pending_Approvals',
|
|
'method' => 'render_pending_approvals'
|
|
),
|
|
'announcements' => array(
|
|
'shortcode' => '[hvac_announcements_timeline]',
|
|
'class' => 'HVAC_Announcements_Display',
|
|
'method' => 'render_timeline_shortcode'
|
|
)
|
|
);
|
|
|
|
/**
|
|
* Get instance
|
|
*/
|
|
public static function instance() {
|
|
if (null === self::$instance) {
|
|
self::$instance = new self();
|
|
}
|
|
return self::$instance;
|
|
}
|
|
|
|
/**
|
|
* Constructor
|
|
*/
|
|
private function __construct() {
|
|
add_filter('the_content', array($this, 'inject_master_content'), 10);
|
|
add_action('wp_head', array($this, 'inject_inline_content'), 1);
|
|
}
|
|
|
|
/**
|
|
* Inject content into master trainer pages via the_content filter
|
|
*
|
|
* @param string $content The existing content
|
|
* @return string Modified content
|
|
*/
|
|
public function inject_master_content($content) {
|
|
// Only run on master trainer pages
|
|
if (!$this->is_master_trainer_page()) {
|
|
return $content;
|
|
}
|
|
|
|
// If content is already present and not just a shortcode, return it
|
|
if (!empty(trim(strip_tags($content))) && !$this->contains_only_shortcode($content)) {
|
|
return $content;
|
|
}
|
|
|
|
// Get the appropriate shortcode for this page
|
|
$shortcode_content = $this->get_page_shortcode_content();
|
|
if (!empty($shortcode_content)) {
|
|
return $shortcode_content;
|
|
}
|
|
|
|
return $content;
|
|
}
|
|
|
|
/**
|
|
* Inject content via inline JavaScript as last resort
|
|
*/
|
|
public function inject_inline_content() {
|
|
if (!$this->is_master_trainer_page()) {
|
|
return;
|
|
}
|
|
|
|
?>
|
|
<script type="text/javascript">
|
|
jQuery(document).ready(function($) {
|
|
// Check if main content areas are empty
|
|
var contentAreas = [
|
|
'.hvac-master-trainers-content',
|
|
'.hvac-master-events-content',
|
|
'.hvac-pending-approvals-content',
|
|
'.announcements-content'
|
|
];
|
|
|
|
$.each(contentAreas, function(index, selector) {
|
|
var $area = $(selector);
|
|
if ($area.length) {
|
|
var content = $area.text().trim();
|
|
// If area exists but is empty or only has loading messages
|
|
if (!content || content.indexOf('not available') > -1 || content.indexOf('Loading') > -1) {
|
|
// Try to trigger content loading via AJAX
|
|
var pageSlug = $('body').attr('class').match(/page-[\w-]+/);
|
|
if (pageSlug) {
|
|
hvacLoadMasterContent(pageSlug[0], selector);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
function hvacLoadMasterContent(pageClass, selector) {
|
|
// Map page classes to AJAX actions
|
|
var actionMap = {
|
|
'page-master-trainers': 'hvac_master_trainers_stats',
|
|
'page-master-events': 'hvac_master_events_kpis',
|
|
'page-pending-approvals': 'hvac_refresh_pending_approvals',
|
|
'page-master-announcements': 'hvac_get_announcements_timeline'
|
|
};
|
|
|
|
var action = actionMap[pageClass];
|
|
if (!action) return;
|
|
|
|
jQuery.post(ajaxurl || '/wp-admin/admin-ajax.php', {
|
|
action: action,
|
|
nonce: <?php echo wp_json_encode(wp_create_nonce('hvac_master_content_nonce')); ?>
|
|
}, function(response) {
|
|
if (response.success && response.data) {
|
|
jQuery(selector).html(response.data);
|
|
}
|
|
}).fail(function() {
|
|
console.log('HVAC: Failed to load content for ' + selector);
|
|
});
|
|
}
|
|
</script>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Check if current page is a master trainer page
|
|
*
|
|
* @return bool
|
|
*/
|
|
private function is_master_trainer_page() {
|
|
global $post;
|
|
|
|
if (!$post) {
|
|
return false;
|
|
}
|
|
|
|
// Check page template
|
|
$template = get_page_template_slug($post->ID);
|
|
if (strpos($template, 'page-master-') === 0) {
|
|
return true;
|
|
}
|
|
|
|
// Check page slug
|
|
$slug = $post->post_name;
|
|
$master_slugs = array('all-trainers', 'events-overview', 'pending-approvals', 'announcements');
|
|
|
|
return in_array($slug, $master_slugs);
|
|
}
|
|
|
|
/**
|
|
* Check if content contains only a shortcode
|
|
*
|
|
* @param string $content
|
|
* @return bool
|
|
*/
|
|
private function contains_only_shortcode($content) {
|
|
$content = trim($content);
|
|
return preg_match('/^\[[\w_-]+[^\]]*\]$/', $content);
|
|
}
|
|
|
|
/**
|
|
* Get appropriate shortcode content for current page
|
|
*
|
|
* @return string
|
|
*/
|
|
private function get_page_shortcode_content() {
|
|
global $post;
|
|
|
|
if (!$post) {
|
|
return '';
|
|
}
|
|
|
|
// Map page slug to shortcode data
|
|
$page_slug = $post->post_name;
|
|
$shortcode_data = null;
|
|
|
|
foreach ($this->master_pages as $key => $data) {
|
|
if (strpos($page_slug, str_replace('-', '-', $key)) !== false) {
|
|
$shortcode_data = $data;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!$shortcode_data) {
|
|
return '';
|
|
}
|
|
|
|
// Try direct method call first
|
|
if (class_exists($shortcode_data['class'])) {
|
|
$instance = call_user_func(array($shortcode_data['class'], 'instance'));
|
|
if (!$instance && method_exists($shortcode_data['class'], 'get_instance')) {
|
|
$instance = call_user_func(array($shortcode_data['class'], 'get_instance'));
|
|
}
|
|
|
|
if ($instance && method_exists($instance, $shortcode_data['method'])) {
|
|
ob_start();
|
|
echo $instance->{$shortcode_data['method']}();
|
|
return ob_get_clean();
|
|
}
|
|
}
|
|
|
|
// Fall back to shortcode
|
|
return do_shortcode($shortcode_data['shortcode']);
|
|
}
|
|
}
|
|
|
|
// Initialize the content injector
|
|
HVAC_Master_Content_Injector::instance();
|