## 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>
174 lines
No EOL
5.5 KiB
PHP
174 lines
No EOL
5.5 KiB
PHP
<?php
|
|
/**
|
|
* MapGeo Safety Wrapper
|
|
* Prevents MapGeo plugin from crashing the page in any browser
|
|
*
|
|
* @package HVAC_Community_Events
|
|
* @since 2.0.0
|
|
*/
|
|
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Class HVAC_MapGeo_Safety
|
|
* Wraps MapGeo integration with error boundaries and fallbacks
|
|
*/
|
|
class HVAC_MapGeo_Safety {
|
|
|
|
/**
|
|
* Instance of this class
|
|
*/
|
|
private static $instance = null;
|
|
|
|
/**
|
|
* Get instance
|
|
*/
|
|
public static function get_instance() {
|
|
if (null === self::$instance) {
|
|
self::$instance = new self();
|
|
}
|
|
return self::$instance;
|
|
}
|
|
|
|
/**
|
|
* Constructor
|
|
*/
|
|
private function __construct() {
|
|
$this->init_hooks();
|
|
}
|
|
|
|
/**
|
|
* Initialize hooks
|
|
*/
|
|
private function init_hooks() {
|
|
// Add safety wrapper before MapGeo loads
|
|
add_action('wp_enqueue_scripts', array($this, 'add_safety_wrapper'), 4);
|
|
|
|
// Add error boundaries in footer
|
|
add_action('wp_footer', array($this, 'add_error_boundaries'), 1);
|
|
|
|
// Filter MapGeo shortcode output
|
|
add_filter('do_shortcode_tag', array($this, 'wrap_mapgeo_shortcode'), 10, 4);
|
|
}
|
|
|
|
/**
|
|
* Add safety wrapper script
|
|
*/
|
|
public function add_safety_wrapper() {
|
|
// Only on find-a-trainer page
|
|
if (!is_page() || get_post_field('post_name') !== 'find-a-trainer') {
|
|
return;
|
|
}
|
|
|
|
wp_enqueue_script(
|
|
'hvac-mapgeo-safety',
|
|
HVAC_PLUGIN_URL . 'assets/js/mapgeo-safety.js',
|
|
array(),
|
|
HVAC_PLUGIN_VERSION,
|
|
false // Load in head to catch errors early
|
|
);
|
|
|
|
// Add inline configuration
|
|
wp_add_inline_script('hvac-mapgeo-safety', '
|
|
window.HVAC_MapGeo_Config = {
|
|
maxRetries: 3,
|
|
retryDelay: 2000,
|
|
timeout: 10000,
|
|
fallbackEnabled: true,
|
|
debugMode: ' . (defined('WP_DEBUG') && WP_DEBUG ? 'true' : 'false') . '
|
|
};
|
|
', 'before');
|
|
}
|
|
|
|
/**
|
|
* Add error boundaries in footer
|
|
*/
|
|
public function add_error_boundaries() {
|
|
// Only on find-a-trainer page
|
|
if (!is_page() || get_post_field('post_name') !== 'find-a-trainer') {
|
|
return;
|
|
}
|
|
|
|
?>
|
|
<script type="text/javascript">
|
|
(function() {
|
|
'use strict';
|
|
|
|
// Global error handler for MapGeo issues
|
|
window.addEventListener('error', function(event) {
|
|
// Check if error is MapGeo related
|
|
if (event.filename && (
|
|
event.filename.includes('mapgeo') ||
|
|
event.filename.includes('amcharts') ||
|
|
event.filename.includes('interactive-geo-maps')
|
|
)) {
|
|
console.error('[HVAC MapGeo Safety] Caught MapGeo error:', event.message);
|
|
|
|
// Prevent browser error page
|
|
event.preventDefault();
|
|
|
|
// Show fallback content if available
|
|
var fallback = document.getElementById('hvac-map-fallback');
|
|
var mapContainer = document.querySelector('.igm-map-container, [class*="mapgeo"], [id*="map-"]');
|
|
|
|
if (fallback && mapContainer) {
|
|
mapContainer.style.display = 'none';
|
|
fallback.style.display = 'block';
|
|
}
|
|
|
|
// Log to our error tracking
|
|
if (window.HVAC_MapGeo_Config && window.HVAC_MapGeo_Config.debugMode) {
|
|
console.log('[HVAC MapGeo Safety] Activated fallback due to error');
|
|
}
|
|
|
|
return true;
|
|
}
|
|
});
|
|
|
|
// Promise rejection handler for async MapGeo issues
|
|
window.addEventListener('unhandledrejection', function(event) {
|
|
if (event.reason && event.reason.toString().includes('MapGeo')) {
|
|
console.error('[HVAC MapGeo Safety] Caught unhandled MapGeo promise:', event.reason);
|
|
event.preventDefault();
|
|
}
|
|
});
|
|
|
|
})();
|
|
</script>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Wrap MapGeo shortcode output with error handling
|
|
*/
|
|
public function wrap_mapgeo_shortcode($output, $tag, $attr, $m) {
|
|
// Check if this is a MapGeo related shortcode
|
|
$mapgeo_shortcodes = apply_filters('hvac_mapgeo_safety_shortcodes',
|
|
array('mapgeo', 'interactive-geo-maps', 'igm', 'map-widget', 'display-map')
|
|
);
|
|
|
|
if (!in_array($tag, $mapgeo_shortcodes)) {
|
|
return $output;
|
|
}
|
|
|
|
// Wrap output with safety container
|
|
$wrapped = '<div class="hvac-mapgeo-wrapper" data-shortcode="' . esc_attr($tag) . '">';
|
|
$wrapped .= $output;
|
|
$wrapped .= '</div>';
|
|
|
|
// Add fallback content
|
|
$wrapped .= '<div id="hvac-map-fallback" style="display:none;" class="hvac-map-fallback">';
|
|
$wrapped .= '<div class="hvac-fallback-message">';
|
|
$wrapped .= '<p>Interactive map is currently loading...</p>';
|
|
$wrapped .= '<p>If the map doesn\'t appear, you can still browse trainers below:</p>';
|
|
$wrapped .= '</div>';
|
|
$wrapped .= '</div>';
|
|
|
|
return $wrapped;
|
|
}
|
|
}
|
|
|
|
// Initialize
|
|
HVAC_MapGeo_Safety::get_instance();
|