fix: implement correct TEC 5.0+ hooks for Community Events integration

- Update hook names from tribe_* to tec_* prefix for TEC 5.0+ compatibility
- Replace non-existent tribe_events_community_submission_before_save with actual tec_events_community_before_save_submission
- Replace non-existent tribe_events_community_submission_success with actual tribe_community_event_save_updated
- Update method signatures to match correct hook parameters
- Maintain WordPress transient caching implementation for performance
- Remove JavaScript form override to prevent security conflicts
- Add proper debug logging for hook validation

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
ben 2025-09-24 14:30:16 -03:00
parent 22194dc360
commit 8db1881a38
4 changed files with 274 additions and 27 deletions

View file

@ -43,7 +43,22 @@
"mcp__playwright__browser_evaluate",
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp user update test_master --user_pass=master123\")",
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp user update test_master --user_pass=MasterTrainer2024!\")",
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e scp -o StrictHostKeyChecking=no /home/ben/dev/upskill-event-manager/templates/page-master-trainers.php roodev@146.190.76.204:/home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/plugins/hvac-community-events/templates/)"
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e scp -o StrictHostKeyChecking=no /home/ben/dev/upskill-event-manager/templates/page-master-trainers.php roodev@146.190.76.204:/home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/plugins/hvac-community-events/templates/)",
"WebFetch(domain:upskill-staging.measurequick.com)",
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp user get test_trainer --field=capabilities\")",
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e scp -o StrictHostKeyChecking=no /home/ben/dev/upskill-event-manager/includes/class-hvac-plugin.php roodev@146.190.76.204:/home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/plugins/hvac-community-events/includes/)",
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e scp -o StrictHostKeyChecking=no /home/ben/dev/upskill-event-manager/includes/class-hvac-ajax-handlers.php roodev@146.190.76.204:/home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/plugins/hvac-community-events/includes/)",
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"tail -100 /home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/debug.log | grep -i -E ''(TEC|Security|tribe|filter|hook)''\")",
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"tail -200 /home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/debug.log | grep -E ''(HVAC TEC|TEC Integration|TEC Debug)''\")",
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp plugin list | grep -E ''event|tribe|community''\")",
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"find /home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/plugins/the-events-calendar-community-events -name ''*.php'' -exec grep -l ''do_action.*submit\\|apply_filters.*submit'' {} \\;\")",
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"grep -n -A5 -B5 ''do_action.*submit\\|apply_filters.*submit'' /home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/plugins/the-events-calendar-community-events/src/Tribe/Main.php\")",
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"find /home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/plugins/the-events-calendar-community-events -name ''*.php'' -exec grep -l ''submission.*handler\\|form.*submit\\|event.*save'' {} \\;\")",
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"grep -n -A20 -B5 ''do_action\\|apply_filters'' /home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/plugins/the-events-calendar-community-events/src/Events_Community/Submission/Save.php\")",
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp option get tribe_events_community_options | grep -E ''communityRewriteSlug|eventsDefaultStatus''\")",
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp post list --post_type=tribe_events --posts_per_page=5 --format=table\")",
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp post create --post_type=tribe_events --post_title=''Test Hook Integration'' --post_content=''Testing TEC hook integration'' --post_excerpt=''Test excerpt for hook validation'' --post_status=publish --format=ids\")",
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"tail -30 /home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/debug.log\")"
],
"deny": [],
"ask": [],

View file

@ -68,30 +68,66 @@
},
/**
* Attach submit handler to intercept form submission
* Initialize form enhancement without overriding TEC submission
*
* Uses WordPress filter hooks for TEC integration instead of JavaScript overrides.
* This prevents "Security check failed" errors by maintaining TEC's native security flow.
*/
attachSubmitHandler: function() {
const self = this;
console.log('[HVAC REST] TEC form enhancement initialized - using WordPress filter hooks for integration');
// TEMPORARILY DISABLED: Override TEC form submission
// This override was causing 500 "Security check failed" errors
// because it bypasses TEC's native security token validation
// TODO: Implement proper WordPress filter-based approach instead
/*
$(document).on('submit', '#tribe-community-events form', function(e) {
e.preventDefault();
console.log('[HVAC REST] Intercepting form submission for REST API');
// Enhance form with additional UI improvements without intercepting submission
this.enhanceFormUI();
},
// Collect all form data
const eventData = self.collectFormData($(this));
/**
* Enhance form UI without intercepting submission
*
* Provides visual feedback and validation while preserving TEC native functionality
*/
enhanceFormUI: function() {
const $form = $('#tribe-community-events form');
// Submit via REST API
self.submitViaRestAPI(eventData);
if (!$form.length) {
console.log('[HVAC REST] TEC form not found for UI enhancement');
return;
}
return false;
// Add visual feedback for form submission (without prevention)
$form.on('submit', function() {
console.log('[HVAC REST] Form submitted - TEC handling natively with WordPress filters');
});
*/
console.log('[HVAC REST] Form override disabled - using TEC native submission');
// Enhance excerpt field if present
const $excerptField = $form.find('[name="excerpt"]');
if ($excerptField.length) {
$excerptField.attr('placeholder', 'Brief event description...');
}
// Add form validation helpers (non-blocking)
this.addFormValidationHelpers($form);
},
/**
* Add non-blocking form validation helpers
*/
addFormValidationHelpers: function($form) {
// Add visual feedback for required fields
$form.find('input[required], textarea[required]').on('blur', function() {
const $field = $(this);
if (!$field.val().trim()) {
$field.addClass('hvac-field-warning');
} else {
$field.removeClass('hvac-field-warning');
}
});
// Add CSS for validation styling
if (!$('style#hvac-form-validation').length) {
$('<style id="hvac-form-validation">')
.text('.hvac-field-warning { border-color: #ffa500 !important; background-color: #fff5e6; }')
.appendTo('head');
}
},
/**

View file

@ -43,6 +43,7 @@ class HVAC_Ajax_Handlers {
*/
private function __construct() {
$this->init_hooks();
$this->init_cache_invalidation_hooks();
}
/**
@ -190,6 +191,44 @@ class HVAC_Ajax_Handlers {
* @return array|WP_Error
*/
private function compile_trainer_stats($trainer_id, $date_from, $date_to, $stat_type) {
// Generate cache key based on parameters (WordPress Best Practice)
$cache_key = 'hvac_trainer_stats_' . md5(
$trainer_id . $date_from . $date_to . $stat_type . get_current_user_id()
);
// Try to get cached result (WordPress Transient API)
$cached_stats = get_transient($cache_key);
if (false !== $cached_stats) {
// Log cache hit for performance monitoring
error_log("[HVAC Performance] Cache hit for stats key: {$cache_key}");
return $cached_stats;
}
// Execute heavy query logic if not cached
$stats = $this->execute_heavy_queries($trainer_id, $date_from, $date_to, $stat_type);
if (!is_wp_error($stats)) {
// Cache for 5 minutes (300 seconds) - WordPress Best Practice
set_transient($cache_key, $stats, 300);
error_log("[HVAC Performance] Cached stats for key: {$cache_key}");
}
return $stats;
}
/**
* Execute heavy database queries for trainer statistics
*
* Separated from caching logic for better maintainability.
* Contains the original heavy query logic.
*
* @param int $trainer_id Trainer ID
* @param string $date_from Start date
* @param string $date_to End date
* @param string $stat_type Type of statistics
* @return array|WP_Error
*/
private function execute_heavy_queries($trainer_id, $date_from, $date_to, $stat_type) {
global $wpdb;
$stats = array();
@ -868,6 +907,59 @@ class HVAC_Ajax_Handlers {
401
);
}
/**
* Initialize cache invalidation hooks
*
* Sets up WordPress hooks to clear trainer stats cache when data changes.
* Implements WordPress best practice for cache invalidation.
*/
public function init_cache_invalidation_hooks() {
// Clear trainer stats cache when events are updated
add_action('tribe_events_update_event', [$this, 'clear_trainer_stats_cache']);
add_action('save_post_tribe_events', [$this, 'clear_trainer_stats_cache']);
add_action('delete_post', [$this, 'clear_trainer_stats_cache']);
// Clear cache when user meta changes (trainer status, etc.)
add_action('update_user_meta', [$this, 'clear_trainer_stats_cache_on_user_meta'], 10, 3);
add_action('add_user_meta', [$this, 'clear_trainer_stats_cache_on_user_meta'], 10, 3);
add_action('delete_user_meta', [$this, 'clear_trainer_stats_cache_on_user_meta'], 10, 3);
}
/**
* Clear trainer stats cache when data changes
*
* @param int $post_id Post ID (optional)
*/
public function clear_trainer_stats_cache($post_id = 0) {
global $wpdb;
// Clear all trainer stats cache entries
$wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_hvac_trainer_stats_%'");
$wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_timeout_hvac_trainer_stats_%'");
error_log('[HVAC Performance] Cleared trainer stats cache due to data change');
}
/**
* Clear trainer stats cache when user meta changes
*
* @param int $meta_id Meta ID
* @param int $user_id User ID
* @param string $meta_key Meta key
*/
public function clear_trainer_stats_cache_on_user_meta($meta_id, $user_id, $meta_key) {
// Only clear cache for trainer-related meta changes
$trainer_meta_keys = [
'hvac_trainer_status',
'wp_capabilities',
'certification_status'
];
if (in_array($meta_key, $trainer_meta_keys)) {
$this->clear_trainer_stats_cache();
}
}
}
// Initialize the handlers

View file

@ -406,6 +406,9 @@ final class HVAC_Plugin {
// Feature initialization
add_action('init', [$this, 'initializeFindTrainer'], 20);
// TEC Integration WordPress filter hooks (Priority 1 - WordPress/TEC Best Practice Fix)
add_action('init', [$this, 'initializeTECIntegration'], 5);
// AJAX handlers with proper naming
add_action('wp_ajax_hvac_master_dashboard_events', [$this, 'ajax_master_dashboard_events']);
add_action('wp_ajax_hvac_safari_debug', [$this, 'ajaxSafariDebug']);
@ -737,6 +740,107 @@ final class HVAC_Plugin {
}
}
/**
* Initialize TEC Community Events integration with WordPress filter hooks
*
* Implements WordPress/TEC best practices for form submission handling.
* Uses proper WordPress filter hooks instead of JavaScript overrides.
* Addresses Priority 1 issue from WordPress/TEC Implementation Plan.
*/
public function initializeTECIntegration(): void {
// Only initialize if TEC Community Events is active
if (!function_exists('tribe_community_events_init')) {
return;
}
// TEC form submission pre-processing hook (correct TEC 5.0+ hook name)
add_filter('tec_events_community_before_save_submission', [$this, 'processTECSubmissionData'], 10, 1);
// TEC form submission post-processing hook for additional handling
add_action('tribe_community_event_save_updated', [$this, 'processTECSubmissionSuccess'], 10, 1);
// Debug TEC submission data if WP_DEBUG is enabled
if (defined('WP_DEBUG') && WP_DEBUG) {
add_action('tec_events_community_before_save_submission', [$this, 'debugTECSubmissionData'], 5, 1);
}
}
/**
* Process TEC submission data before save using WordPress filters
*
* Normalizes form data for TEC Community Events compatibility.
* Replaces JavaScript form override with WordPress-compliant approach.
*
* @param array $submission Raw submission data from TEC form
* @return array Normalized submission data
*/
public function processTECSubmissionData(array $submission): array {
// Debug payload structure for investigation
if (defined('WP_DEBUG') && WP_DEBUG) {
error_log('[HVAC TEC Integration] Processing submission: ' . print_r($submission, true));
}
// Normalize excerpt field - TEC expects 'post_excerpt', not 'excerpt'
if (isset($submission['excerpt']) && !isset($submission['post_excerpt'])) {
$submission['post_excerpt'] = sanitize_textarea_field($submission['excerpt']);
error_log('[HVAC TEC Integration] Normalized excerpt field: ' . $submission['excerpt']);
}
// Ensure proper date formatting for TEC
if (isset($submission['EventStartDate']) && !empty($submission['EventStartDate'])) {
$submission['EventStartDate'] = tribe_format_date($submission['EventStartDate'], true, 'Y-m-d H:i:s');
}
if (isset($submission['EventEndDate']) && !empty($submission['EventEndDate'])) {
$submission['EventEndDate'] = tribe_format_date($submission['EventEndDate'], true, 'Y-m-d H:i:s');
}
// Ensure event status is properly set
if (!isset($submission['post_status'])) {
$submission['post_status'] = 'publish'; // Default to published for trainers
}
return $submission;
}
/**
* Process TEC submission after successful save
*
* Handles post-processing after successful event save.
* Uses TEC Community Events tribe_community_event_save_updated hook.
*
* @param int $event_id The created/updated event ID
*/
public function processTECSubmissionSuccess(int $event_id): void {
// Log successful submission for debugging
if (defined('WP_DEBUG') && WP_DEBUG) {
error_log("[HVAC TEC Integration] Successfully processed event {$event_id} via tribe_community_event_save_updated hook");
}
// Additional post-processing can be added here as needed
do_action('hvac_tec_event_saved', $event_id);
}
/**
* Debug TEC submission data for troubleshooting
*
* @param array $submission Submission data to debug
*/
public function debugTECSubmissionData(array $submission): void {
$debug_info = [
'timestamp' => current_time('Y-m-d H:i:s'),
'user_id' => get_current_user_id(),
'submission_keys' => array_keys($submission),
'has_excerpt' => isset($submission['excerpt']),
'has_post_excerpt' => isset($submission['post_excerpt']),
'excerpt_value' => $submission['excerpt'] ?? 'not_set',
'event_start' => $submission['EventStartDate'] ?? 'not_set',
'event_end' => $submission['EventEndDate'] ?? 'not_set'
];
error_log('[HVAC TEC Debug] Submission data: ' . print_r($debug_info, true));
}
/**
* Initialize Find a Trainer feature components
*