'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '' ]); register_setting('hvac_trainer_profile_settings', 'hvac_geocoding_enabled', [ 'type' => 'boolean', 'default' => true ]); register_setting('hvac_trainer_profile_settings', 'hvac_geocoding_rate_limit', [ 'type' => 'integer', 'default' => 50 ]); register_setting('hvac_trainer_profile_settings', 'hvac_geocoding_cache_duration', [ 'type' => 'integer', 'default' => DAY_IN_SECONDS ]); // Profile visibility settings register_setting('hvac_trainer_profile_settings', 'hvac_default_profile_visibility', [ 'type' => 'string', 'default' => 'public' ]); register_setting('hvac_trainer_profile_settings', 'hvac_require_profile_approval', [ 'type' => 'boolean', 'default' => false ]); // Sync settings register_setting('hvac_trainer_profile_settings', 'hvac_sync_verification_enabled', [ 'type' => 'boolean', 'default' => true ]); } public function enqueue_admin_scripts($hook) { if ($hook !== 'hvac-settings_page_hvac-trainer-profiles') { return; } wp_enqueue_script( 'hvac-trainer-profile-admin', HVAC_PLUGIN_URL . 'assets/js/hvac-trainer-profile-admin.js', ['jquery'], HVAC_PLUGIN_VERSION, true ); wp_localize_script('hvac-trainer-profile-admin', 'hvacProfileAdmin', [ 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('hvac_profile_admin_nonce') ]); } public function render_settings_page() { if (isset($_POST['submit'])) { $this->handle_settings_save(); } $google_maps_key = get_option('hvac_google_maps_api_key', ''); $geocoding_enabled = get_option('hvac_geocoding_enabled', true); $rate_limit = get_option('hvac_geocoding_rate_limit', 50); $cache_duration = get_option('hvac_geocoding_cache_duration', DAY_IN_SECONDS); $default_visibility = get_option('hvac_default_profile_visibility', 'public'); $require_approval = get_option('hvac_require_profile_approval', false); $sync_enabled = get_option('hvac_sync_verification_enabled', true); // Get statistics $stats = $this->get_profile_statistics(); ?>

Trainer Profile Settings

Geocoding Configuration

Configure Google Maps API for address geocoding and proximity search.

Google Maps API Key

Get your API key from the Google Cloud Console

Enable Geocoding
Rate Limit requests per minute
Cache Duration

Profile Configuration

Default Visibility

Default visibility for new trainer profiles

Require Approval

Data Synchronization

Sync Verification

Profile Statistics

Total Profiles
Public Profiles
Geocoded
Sync Issues

Recent Activity

get_recent_activity(); ?>

Settings saved successfully!

'; } public function ajax_test_geocoding() { check_ajax_referer('hvac_profile_admin_nonce', 'nonce'); if (!current_user_can('manage_options')) { wp_send_json_error('Insufficient permissions'); } $test_address = sanitize_text_field($_POST['address'] ?? 'New York, NY, USA'); $geocoding_service = HVAC_Geocoding_Service::get_instance(); $result = $geocoding_service->make_geocoding_request($test_address); if (isset($result['error'])) { wp_send_json_error($result['error']); } wp_send_json_success([ 'address' => $test_address, 'coordinates' => [ 'lat' => $result['lat'], 'lng' => $result['lng'] ], 'formatted_address' => $result['formatted_address'], 'confidence' => $result['confidence'] ]); } public function ajax_bulk_geocode() { check_ajax_referer('hvac_profile_admin_nonce', 'nonce'); if (!current_user_can('manage_options')) { wp_send_json_error('Insufficient permissions'); } $geocoding_service = HVAC_Geocoding_Service::get_instance(); $processed = $geocoding_service->bulk_geocode_profiles(5); // Process 5 at a time wp_send_json_success([ 'processed' => $processed, 'message' => "Processed {$processed} profiles for geocoding" ]); } public function ajax_sync_profiles() { check_ajax_referer('hvac_profile_admin_nonce', 'nonce'); if (!current_user_can('manage_options')) { wp_send_json_error('Insufficient permissions'); } $sync_handler = HVAC_Profile_Sync_Handler::get_instance(); $sync_handler->verify_sync_integrity(); wp_send_json_success([ 'message' => 'Profile synchronization completed' ]); } private function get_profile_statistics() { global $wpdb; $total_profiles = wp_count_posts('trainer_profile')->publish; $public_profiles = $wpdb->get_var(" SELECT COUNT(*) FROM {$wpdb->posts} p LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id AND pm.meta_key = 'is_public_profile' WHERE p.post_type = 'trainer_profile' AND p.post_status = 'publish' AND pm.meta_value = '1' "); $geocoded_profiles = $wpdb->get_var(" SELECT COUNT(*) FROM {$wpdb->posts} p LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id AND pm.meta_key = 'latitude' WHERE p.post_type = 'trainer_profile' AND p.post_status = 'publish' AND pm.meta_value IS NOT NULL AND pm.meta_value != '' "); // Check for sync issues $sync_issues = 0; $profiles = get_posts([ 'post_type' => 'trainer_profile', 'posts_per_page' => -1, 'fields' => 'ids' ]); foreach ($profiles as $profile_id) { $user_id = get_post_meta($profile_id, 'user_id', true); if ($user_id) { $sync_handler = HVAC_Profile_Sync_Handler::get_instance(); $status = $sync_handler->get_sync_status($user_id); if ($status['status'] === 'out_of_sync') { $sync_issues++; } } } return [ 'total_profiles' => $total_profiles, 'public_profiles' => $public_profiles, 'geocoded_profiles' => $geocoded_profiles, 'sync_issues' => $sync_issues ]; } /** * Public method to get profile statistics (secure alternative to reflection) * * @return array Profile statistics */ public function get_profile_statistics_public() { // Check permissions if (!current_user_can('hvac_trainer') && !current_user_can('hvac_master_trainer') && !current_user_can('administrator')) { return ['error' => 'Insufficient permissions']; } return $this->get_profile_statistics(); } private function get_recent_activity() { $recent_profiles = get_posts([ 'post_type' => 'trainer_profile', 'posts_per_page' => 5, 'orderby' => 'modified', 'order' => 'DESC' ]); $activity = []; foreach ($recent_profiles as $profile) { $user_id = get_post_meta($profile->ID, 'user_id', true); $user = get_userdata($user_id); $activity[] = [ 'type' => 'profile_updated', 'message' => "Profile updated: " . ($user ? $user->display_name : 'Unknown User'), 'time' => $profile->post_modified ]; } $output = ''; foreach ($activity as $item) { $time_diff = human_time_diff(strtotime($item['time']), current_time('timestamp')); $output .= "
"; $output .= "{$item['message']}"; $output .= "{$time_diff} ago"; $output .= "
"; } return $output ?: '

No recent activity

'; } } // Initialize the settings HVAC_Trainer_Profile_Settings::get_instance();