diff --git a/assets/js/hvac-modal-forms.js b/assets/js/hvac-modal-forms.js
index 99b1ec77..abba4310 100644
--- a/assets/js/hvac-modal-forms.js
+++ b/assets/js/hvac-modal-forms.js
@@ -47,6 +47,17 @@
this.closeModal();
}
});
+
+ // Media upload handlers
+ $(document).on('click', '.hvac-modal .select-image-btn', (e) => {
+ e.preventDefault();
+ this.openMediaUploader(e.target);
+ });
+
+ $(document).on('click', '.hvac-modal .remove-image', (e) => {
+ e.preventDefault();
+ this.removeImage(e.target);
+ });
}
createModalContainer() {
@@ -104,7 +115,8 @@
{ name: 'organizer_name', label: 'Organizer Name', type: 'text', required: true },
{ name: 'organizer_email', label: 'Email', type: 'email', required: false },
{ name: 'organizer_website', label: 'Website', type: 'url', required: false },
- { name: 'organizer_phone', label: 'Phone', type: 'tel', required: false }
+ { name: 'organizer_phone', label: 'Phone', type: 'tel', required: false },
+ { name: 'organizer_featured_image', label: 'Featured Image', type: 'media', required: false }
],
action: 'hvac_create_organizer'
},
@@ -127,7 +139,8 @@
{ name: 'venue_zip', label: 'Zip/Postal Code', type: 'text', required: false },
{ name: 'venue_country', label: 'Country', type: 'text', required: false },
{ name: 'venue_website', label: 'Website', type: 'url', required: false },
- { name: 'venue_phone', label: 'Phone', type: 'tel', required: false }
+ { name: 'venue_phone', label: 'Phone', type: 'tel', required: false },
+ { name: 'venue_featured_image', label: 'Featured Image', type: 'media', required: false }
],
action: 'hvac_create_venue'
}
@@ -184,6 +197,33 @@
`;
}
+ if (field.type === 'media') {
+ return `
+
@@ -284,6 +324,68 @@
}, 5000);
}
+ openMediaUploader(button) {
+ const $button = $(button);
+ const $fieldContainer = $button.closest('.hvac-media-field');
+ const $imagePreview = $fieldContainer.find('.image-preview');
+ const $previewImg = $fieldContainer.find('.image-preview img');
+ const $imageIdInput = $fieldContainer.find('.image-id-input');
+ const $imageUrlInput = $fieldContainer.find('.image-url-input');
+
+ // Create WordPress media frame
+ const mediaUploader = wp.media({
+ title: 'Select Image',
+ button: {
+ text: 'Select Image'
+ },
+ multiple: false,
+ library: {
+ type: 'image'
+ }
+ });
+
+ // When an image is selected
+ mediaUploader.on('select', () => {
+ const attachment = mediaUploader.state().get('selection').first().toJSON();
+
+ // Update hidden inputs
+ $imageIdInput.val(attachment.id);
+ $imageUrlInput.val(attachment.url);
+
+ // Update preview
+ $previewImg.attr('src', attachment.url);
+ $previewImg.attr('alt', attachment.alt || attachment.title || 'Selected image');
+ $imagePreview.show();
+
+ // Update button text
+ $button.html('
Change Image');
+ });
+
+ // Open the media modal
+ mediaUploader.open();
+ }
+
+ removeImage(button) {
+ const $button = $(button);
+ const $fieldContainer = $button.closest('.hvac-media-field');
+ const $imagePreview = $fieldContainer.find('.image-preview');
+ const $previewImg = $fieldContainer.find('.image-preview img');
+ const $imageIdInput = $fieldContainer.find('.image-id-input');
+ const $imageUrlInput = $fieldContainer.find('.image-url-input');
+ const $selectBtn = $fieldContainer.find('.select-image-btn');
+
+ // Clear inputs
+ $imageIdInput.val('');
+ $imageUrlInput.val('');
+
+ // Hide preview
+ $imagePreview.hide();
+ $previewImg.attr('src', '');
+
+ // Reset button text
+ $selectBtn.html('
Select Image');
+ }
+
capitalizeFirst(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
diff --git a/docs/EVENT-CREATION-PAGE-DOCUMENTATION.md b/docs/EVENT-CREATION-PAGE-DOCUMENTATION.md
new file mode 100644
index 00000000..8446fa71
--- /dev/null
+++ b/docs/EVENT-CREATION-PAGE-DOCUMENTATION.md
@@ -0,0 +1,739 @@
+# HVAC Community Events - Event Creation Page Documentation
+
+**Version:** 3.2.0
+**Last Updated:** January 2025
+**Status:** Production Ready
+
+## Overview
+
+The HVAC Community Events plugin provides a comprehensive event creation system designed specifically for HVAC training organizations. This document serves as the authoritative reference for the event creation page functionality, architecture, and implementation details.
+
+## Table of Contents
+
+1. [System Architecture](#system-architecture)
+2. [User Interface Components](#user-interface-components)
+3. [Form Fields Reference](#form-fields-reference)
+4. [Dynamic Features](#dynamic-features)
+5. [Role-Based Access Control](#role-based-access-control)
+6. [API Endpoints](#api-endpoints)
+7. [Security Implementation](#security-implementation)
+8. [Template System](#template-system)
+9. [Integration Points](#integration-points)
+10. [Performance Considerations](#performance-considerations)
+11. [Troubleshooting Guide](#troubleshooting-guide)
+
+---
+
+## System Architecture
+
+### Core Components
+
+The event creation system is built on a modular architecture with the following primary components:
+
+#### 1. **HVAC_Event_Form_Builder**
+- **File:** `includes/class-hvac-event-form-builder.php`
+- **Purpose:** Central form generation and validation engine
+- **Pattern:** Singleton with fluent interface
+- **Responsibilities:**
+ - Form field rendering and validation
+ - Progressive disclosure management
+ - Template integration
+ - Media upload handling
+ - Security implementation
+
+#### 2. **HVAC_Ajax_Handlers**
+- **File:** `includes/class-hvac-ajax-handlers.php`
+- **Purpose:** Server-side AJAX request processing
+- **Pattern:** Singleton with dependency injection
+- **Responsibilities:**
+ - AI-powered event population
+ - Dynamic search functionality
+ - Entity creation (venues, organizers, categories)
+ - Security validation and nonce verification
+
+#### 3. **Frontend JavaScript Components**
+- **AI Assistant:** `assets/js/hvac-ai-assist.js`
+- **Searchable Selectors:** `assets/js/hvac-searchable-selectors.js`
+- **Modal Forms:** `assets/js/hvac-modal-forms.js`
+- **Purpose:** Rich user interface interactions
+- **Pattern:** ES6 classes with event delegation
+
+#### 4. **Template System**
+- **File:** `templates/page-tec-create-event.php`
+- **Purpose:** WordPress-native page template
+- **Integration:** The Events Calendar compatibility
+- **Features:** Responsive design, accessibility compliance
+
+---
+
+## User Interface Components
+
+### Layout Structure
+
+```
+Event Creation Page
+├── Header Section
+│ ├── Page Title
+│ ├── Breadcrumb Navigation
+│ └── User Context Information
+├── Main Form Container
+│ ├── Basic Event Fields
+│ ├── Featured Image Upload
+│ ├── DateTime Management
+│ ├── Venue Selection
+│ ├── Organizer Management
+│ ├── Category Assignment
+│ └── Advanced Options (Collapsible)
+├── AI Assistant Panel
+│ ├── Input Methods (URL, Text, Manual)
+│ ├── Processing Indicators
+│ └── Confidence Metrics
+└── Footer Actions
+ ├── Save Draft
+ ├── Preview
+ └── Publish Event
+```
+
+### Progressive Disclosure
+
+The interface implements progressive disclosure to reduce cognitive load:
+
+- **Basic Fields:** Always visible, essential information
+- **Advanced Options:** Collapsible section for power users
+- **Modal Forms:** Overlay interfaces for entity creation
+- **AI Assistant:** Contextual panel that appears when needed
+
+---
+
+## Form Fields Reference
+
+### Basic Event Information
+
+#### Event Title
+- **Type:** Text input
+- **Validation:** 3-200 characters, required
+- **Sanitization:** `sanitize_text_field()`
+- **Purpose:** Primary event identifier
+
+#### Event Description
+- **Type:** WordPress TinyMCE rich text editor
+- **Features:**
+ - Custom toolbar: Format, Bold, Italic, Lists, Links, Alignment
+ - Markdown-to-HTML conversion support
+ - Paste cleanup for external content
+- **Validation:** HTML content filtering with `wp_kses`
+- **Purpose:** Detailed event information
+
+#### Featured Image
+- **Type:** WordPress Media Uploader
+- **Constraints:** Image files only
+- **Recommended:** 1200x630 pixels
+- **Storage:** WordPress attachment with post thumbnail relationship
+- **Purpose:** Visual representation for event listings
+
+### Date and Time Management
+
+#### Start Date & Time
+- **Type:** HTML5 `datetime-local` input
+- **Validation:** Must be future date
+- **Format:** WordPress-compatible datetime
+- **Integration:** The Events Calendar meta fields
+
+#### End Date & Time
+- **Type:** HTML5 `datetime-local` input
+- **Validation:** Must be after start date
+- **Default:** 2 hours after start time
+- **Integration:** TEC `_EventEndDate` meta field
+
+#### Timezone
+- **Type:** Dropdown select
+- **Options:** WordPress timezone list
+- **Default:** Site timezone setting
+- **Storage:** `_EventTimezone` meta field
+- **Advanced:** Hidden by default, revealed in advanced options
+
+### Venue Management
+
+#### Venue Selection
+- **Type:** Searchable single-select
+- **Search:** Real-time AJAX with 2+ character minimum
+- **Features:**
+ - Autocomplete with venue address display
+ - "Add New" modal for inline venue creation
+ - Address validation and formatting
+- **Integration:** TEC `_EventVenueID` relationship
+
+#### Venue Creation Modal
+- **Fields:**
+ - Venue Name (required)
+ - Address, City, State, Zip, Country
+ - Website, Phone
+ - Featured Image
+- **Permissions:** Trainers, Master Trainers, Administrators
+- **Validation:** Address normalization, phone formatting
+
+### Organizer Management
+
+#### Organizer Selection
+- **Type:** Searchable multi-select
+- **Limit:** Maximum 3 organizers per event
+- **Search:** Real-time AJAX with contact information display
+- **Features:**
+ - Selected item display with removal
+ - "Add New" modal for inline organizer creation
+ - Email and phone display in search results
+- **Integration:** TEC `_EventOrganizerID` array
+
+#### Organizer Creation Modal
+- **Fields:**
+ - Organizer Name (required)
+ - Email, Website, Phone
+ - Featured Image
+- **Permissions:** Trainers, Master Trainers, Administrators
+- **Validation:** Email format, URL validation
+
+### Category Assignment
+
+#### Category Selection
+- **Type:** Searchable multi-select
+- **Limit:** Maximum 3 categories per event
+- **Source:** WordPress `tribe_events_cat` taxonomy
+- **Features:**
+ - Hierarchical category display
+ - Description tooltips
+ - Role-based creation permissions
+- **Integration:** WordPress taxonomy relationship
+
+#### Category Creation Modal
+- **Fields:**
+ - Category Name (required)
+ - Description
+- **Permissions:** Master Trainers only
+- **Validation:** Taxonomy name sanitization
+
+### Advanced Fields
+
+#### Event Capacity
+- **Type:** Number input
+- **Range:** 1-10,000 attendees
+- **Purpose:** Registration limit setting
+- **Integration:** TEC capacity management
+- **Advanced:** Hidden by default
+
+#### Event Cost
+- **Type:** Number input with decimal support
+- **Format:** Currency display
+- **Purpose:** Event pricing information
+- **Integration:** TEC cost meta fields
+- **Advanced:** Hidden by default
+
+---
+
+## Dynamic Features
+
+### AI Assistant System
+
+#### Input Methods
+
+**1. URL Processing**
+- **Supported Platforms:** EventBrite, Facebook Events, Meetup, General URLs
+- **Process:**
+ 1. URL validation and platform detection
+ 2. Content extraction with timeout handling (60 seconds)
+ 3. Data parsing and confidence scoring
+ 4. Form field population with validation
+- **Rate Limiting:** 10 requests per hour per user
+
+**2. Text Extraction**
+- **Purpose:** Process existing event descriptions or marketing copy
+- **Features:**
+ - Smart field detection (title, date, location extraction)
+ - Markdown processing with list formatting
+ - Content cleanup and normalization
+- **Validation:** 10+ character minimum
+
+**3. Manual Description**
+- **Purpose:** AI-generated content from user prompts
+- **Features:**
+ - Context-aware content generation
+ - Professional formatting
+ - Industry-specific terminology
+- **Output:** Structured markdown converted to HTML
+
+#### Processing Flow
+
+```mermaid
+graph TD
+ A[User Input] --> B[Input Validation]
+ B --> C[AI Processing Request]
+ C --> D[Progress Indication]
+ D --> E[Response Processing]
+ E --> F[Confidence Analysis]
+ F --> G[Form Population]
+ G --> H[User Validation]
+```
+
+#### Confidence Scoring
+
+The AI system provides confidence levels for each populated field:
+
+- **High (90-100%):** Green indicator, auto-accept
+- **Medium (70-89%):** Yellow indicator, user review recommended
+- **Low (50-69%):** Orange indicator, manual verification required
+- **Very Low (<50%):** Red indicator, suggests manual entry
+
+### Searchable Selectors
+
+#### Real-time Search Implementation
+
+**Debounced AJAX Requests:**
+- **Trigger:** 2+ characters entered
+- **Delay:** 300ms debounce
+- **Caching:** Client-side result caching for 5 minutes
+- **Error Handling:** Graceful degradation with fallback options
+
+**Search Results Display:**
+- **Venue Results:** Name, full address, phone
+- **Organizer Results:** Name, email, organization
+- **Category Results:** Name, description, event count
+
+#### Selection Management
+
+**Multi-select Behavior (Organizers, Categories):**
+- Visual selected item display with removal buttons
+- Duplicate prevention
+- Maximum selection enforcement
+- Keyboard navigation support
+
+**Single-select Behavior (Venues):**
+- Replacement selection model
+- Clear selection option
+- Visual state management
+
+### Modal Creation Forms
+
+#### WordPress Media Integration
+
+**Featured Image Upload:**
+- **Interface:** Native WordPress Media Library
+- **Features:**
+ - Image preview with removal option
+ - File type validation
+ - Size recommendations
+ - Alt text management
+- **Storage:** WordPress attachment system
+
+#### Form Validation
+
+**Client-side Validation:**
+- Real-time field validation
+- Visual error indicators
+- Progressive enhancement
+
+**Server-side Validation:**
+- Comprehensive input sanitization
+- Business rule enforcement
+- Security validation
+
+---
+
+## Role-Based Access Control
+
+### Permission Levels
+
+#### Unauthenticated Users
+- **Access:** Redirected to login page
+- **Message:** Clear authentication requirement
+
+#### Standard WordPress Users
+- **Access:** Denied with capability check
+- **Requirement:** Must have HVAC-specific roles
+
+#### HVAC Trainers
+- **Permissions:**
+ - Create and edit events
+ - Create organizers and venues
+ - Use AI assistant features
+ - Access basic template system
+- **Restrictions:**
+ - Cannot create categories
+ - Limited template management
+
+#### HVAC Master Trainers
+- **Permissions:**
+ - All trainer permissions
+ - Create and manage categories
+ - Full template system access
+ - Advanced configuration options
+ - User management capabilities
+
+#### Administrators
+- **Permissions:**
+ - Complete system access
+ - Plugin configuration
+ - Role management
+ - System maintenance
+
+### Security Implementation
+
+#### Nonce Verification
+```php
+// Example nonce verification
+$security_check = HVAC_Ajax_Security::verify_ajax_request(
+ 'create_event',
+ HVAC_Ajax_Security::NONCE_GENERAL,
+ array('hvac_trainer', 'hvac_master_trainer'),
+ false
+);
+```
+
+#### Input Sanitization
+- **Text Fields:** `sanitize_text_field()`
+- **Email Fields:** `sanitize_email()`
+- **URL Fields:** `esc_url_raw()`
+- **HTML Content:** `wp_kses()` with allowed tags
+- **Number Fields:** `absint()` or `floatval()`
+
+---
+
+## API Endpoints
+
+### Core AJAX Handlers
+
+#### Event Population
+- **Endpoint:** `hvac_ai_populate_event`
+- **Method:** POST
+- **Purpose:** AI-powered event data extraction
+- **Parameters:**
+ - `input_text` (string): URL or text content
+ - `input_type` (enum): 'url', 'text', 'description'
+ - `nonce` (string): Security token
+- **Response:** JSON with populated field data and confidence scores
+
+#### Search Endpoints
+
+**Organizer Search:**
+- **Endpoint:** `hvac_search_organizers`
+- **Parameters:** `search` (string, 2+ chars)
+- **Response:** Array of organizer objects with contact info
+
+**Venue Search:**
+- **Endpoint:** `hvac_search_venues`
+- **Parameters:** `search` (string, 2+ chars)
+- **Response:** Array of venue objects with address info
+
+**Category Search:**
+- **Endpoint:** `hvac_search_categories`
+- **Parameters:** `search` (string, 2+ chars)
+- **Response:** Array of category objects with descriptions
+
+#### Entity Creation
+
+**Create Organizer:**
+- **Endpoint:** `hvac_create_organizer`
+- **Required:** `organizer_name`
+- **Optional:** `organizer_email`, `organizer_website`, `organizer_phone`, `organizer_featured_image`
+- **Response:** Created organizer object
+
+**Create Venue:**
+- **Endpoint:** `hvac_create_venue`
+- **Required:** `venue_name`
+- **Optional:** Address fields, contact info, featured image
+- **Response:** Created venue object
+
+**Create Category:**
+- **Endpoint:** `hvac_create_category`
+- **Required:** `category_name`
+- **Optional:** `category_description`
+- **Permissions:** Master Trainers only
+- **Response:** Created category object
+
+### Response Format
+
+#### Success Response
+```json
+{
+ "success": true,
+ "data": {
+ "id": 123,
+ "title": "Created Item Name",
+ "subtitle": "Additional information",
+ "confidence": 85
+ }
+}
+```
+
+#### Error Response
+```json
+{
+ "success": false,
+ "data": {
+ "message": "Error description",
+ "code": "error_type",
+ "field_errors": {
+ "field_name": "Specific field error"
+ }
+ }
+}
+```
+
+---
+
+## Security Implementation
+
+### Authentication & Authorization
+
+#### WordPress Integration
+- **User Authentication:** WordPress session management
+- **Capability Checking:** Custom capabilities with role mapping
+- **Nonce System:** Action-specific tokens with expiration
+
+#### HVAC_Ajax_Security Class
+```php
+class HVAC_Ajax_Security {
+ const NONCE_GENERAL = 'hvac_general';
+ const NONCE_AI = 'hvac_ai';
+
+ public static function verify_ajax_request($action, $nonce_action, $required_roles, $check_capabilities) {
+ // Comprehensive security validation
+ }
+}
+```
+
+### Input Validation
+
+#### Validation Rules
+```php
+$input_rules = array(
+ 'event_title' => array(
+ 'type' => 'text',
+ 'required' => true,
+ 'min_length' => 3,
+ 'max_length' => 200
+ ),
+ 'event_description' => array(
+ 'type' => 'html',
+ 'required' => false,
+ 'allowed_tags' => 'p,br,strong,em,ul,ol,li,h2,h3,h4,h5,h6'
+ )
+);
+```
+
+#### XSS Prevention
+- **Output Escaping:** All user content escaped with appropriate functions
+- **HTML Filtering:** Allowed tag whitelist with attribute sanitization
+- **JavaScript Safety:** JSON data properly escaped for client consumption
+
+### Rate Limiting
+
+#### AI Endpoint Protection
+- **Rate:** 10 requests per hour per user
+- **Storage:** WordPress transients
+- **Reset:** Hourly cleanup with WP Cron
+- **Error Handling:** Clear rate limit messages
+
+---
+
+## Template System
+
+### Template Architecture
+
+#### Template Storage
+- **Format:** JSON with metadata
+- **Location:** WordPress options table
+- **Versioning:** Timestamp-based versioning
+- **Backup:** Automatic backup on modification
+
+#### Template Categories
+- **General:** Basic event templates
+- **Training:** Technical training sessions
+- **Workshop:** Hands-on workshops
+- **Certification:** Certification programs
+- **Conference:** Large-scale events
+
+### Template Management
+
+#### Template Creation
+```javascript
+// Save current form as template
+const templateData = {
+ name: 'Template Name',
+ category: 'training',
+ fields: {
+ event_title: 'Template Title',
+ event_description: 'Template Description',
+ // ... other fields
+ },
+ metadata: {
+ created_by: userId,
+ created_date: timestamp,
+ usage_count: 0
+ }
+};
+```
+
+#### Template Application
+- **Field Mapping:** Intelligent field matching
+- **Conflict Resolution:** User confirmation for overrides
+- **Partial Application:** Selective field application
+- **Confidence Scoring:** Template fit analysis
+
+---
+
+## Integration Points
+
+### The Events Calendar (TEC)
+
+#### Post Type Integration
+- **Events:** `tribe_events` post type
+- **Venues:** `tribe_venue` post type
+- **Organizers:** `tribe_organizer` post type
+- **Categories:** `tribe_events_cat` taxonomy
+
+#### Meta Field Mapping
+```php
+// TEC meta field integration
+$tec_meta = array(
+ '_EventStartDate' => $start_datetime,
+ '_EventEndDate' => $end_datetime,
+ '_EventTimezone' => $timezone,
+ '_EventVenueID' => $venue_id,
+ '_EventOrganizerID' => $organizer_ids,
+ '_EventCost' => $event_cost,
+ '_EventCapacity' => $event_capacity
+);
+```
+
+### WordPress Core
+
+#### Media Library
+- **Featured Images:** Post thumbnail system
+- **File Handling:** WordPress upload system
+- **Security:** File type validation
+
+#### User Management
+- **Roles:** Custom HVAC roles
+- **Capabilities:** Fine-grained permissions
+- **Session Handling:** WordPress authentication
+
+#### Taxonomy System
+- **Categories:** Native WordPress taxonomy
+- **Hierarchical:** Support for nested categories
+- **Meta:** Additional category metadata
+
+---
+
+## Performance Considerations
+
+### Frontend Optimization
+
+#### JavaScript Loading
+- **Conditional Loading:** Scripts only on event creation page
+- **Dependency Management:** Proper WordPress enqueueing
+- **Minification:** Production asset minification
+- **Caching:** Browser caching headers
+
+#### AJAX Optimization
+- **Request Debouncing:** Reduced server requests
+- **Response Caching:** Client-side result caching
+- **Pagination:** Large result set pagination
+- **Compression:** Gzip response compression
+
+### Backend Optimization
+
+#### Database Queries
+- **Prepared Statements:** SQL injection prevention
+- **Query Optimization:** Efficient database queries
+- **Indexing:** Proper database indexing
+- **Caching:** WordPress object caching
+
+#### Memory Management
+- **Object Lifecycle:** Proper object destruction
+- **Image Processing:** Optimized image handling
+- **Garbage Collection:** PHP memory management
+
+---
+
+## Troubleshooting Guide
+
+### Common Issues
+
+#### AI Assistant Not Working
+**Symptoms:** AI requests fail or timeout
+**Causes:**
+- API rate limiting exceeded
+- Network connectivity issues
+- Invalid input format
+**Solutions:**
+1. Check rate limit status
+2. Verify network connectivity
+3. Validate input format
+4. Check error logs
+
+#### Search Not Returning Results
+**Symptoms:** Empty search results despite existing data
+**Causes:**
+- Insufficient search term length
+- Database connectivity issues
+- Permission problems
+**Solutions:**
+1. Ensure 2+ character search terms
+2. Verify database connection
+3. Check user permissions
+4. Clear search cache
+
+#### Modal Forms Not Opening
+**Symptoms:** "Add New" buttons not working
+**Causes:**
+- JavaScript errors
+- Permission restrictions
+- Missing dependencies
+**Solutions:**
+1. Check browser console for errors
+2. Verify user role permissions
+3. Ensure WordPress media scripts loaded
+4. Clear browser cache
+
+### Error Logging
+
+#### WordPress Debug Integration
+```php
+// Enable debug logging
+define('WP_DEBUG', true);
+define('WP_DEBUG_LOG', true);
+
+// Log custom events
+error_log('HVAC Event Creation: ' . $message);
+```
+
+#### Custom Error Tracking
+- **Error Categorization:** System, user, validation errors
+- **Context Capture:** User, action, environment data
+- **Notification System:** Admin notifications for critical errors
+
+### Performance Monitoring
+
+#### Key Metrics
+- **Page Load Time:** Target < 2 seconds
+- **AJAX Response Time:** Target < 500ms
+- **Database Queries:** Monitor N+1 queries
+- **Memory Usage:** Monitor PHP memory consumption
+
+#### Monitoring Tools
+- **WordPress Debug Bar:** Development debugging
+- **Query Monitor:** Database query analysis
+- **Server Monitoring:** Application performance monitoring
+
+---
+
+## Conclusion
+
+The HVAC Community Events plugin provides a comprehensive, secure, and user-friendly event creation system. This documentation serves as the authoritative reference for developers, administrators, and users working with the system.
+
+For additional support or feature requests, please refer to the project repository or contact the development team.
+
+---
+
+**Document Version:** 1.0
+**Next Review:** July 2025
+**Maintained By:** HVAC Development Team
\ No newline at end of file
diff --git a/includes/class-hvac-ajax-handlers.php b/includes/class-hvac-ajax-handlers.php
index fa3caa2d..2e4f76e9 100644
--- a/includes/class-hvac-ajax-handlers.php
+++ b/includes/class-hvac-ajax-handlers.php
@@ -1287,7 +1287,7 @@ class HVAC_Ajax_Handlers {
$security_check = HVAC_Ajax_Security::verify_ajax_request(
'create_organizer',
HVAC_Ajax_Security::NONCE_GENERAL,
- array('hvac_trainer', 'hvac_master_trainer'),
+ array('administrator', 'hvac_trainer', 'hvac_master_trainer'),
false
);
@@ -1319,6 +1319,10 @@ class HVAC_Ajax_Handlers {
'type' => 'text',
'required' => false,
'max_length' => 20
+ ),
+ 'organizer_featured_image' => array(
+ 'type' => 'text',
+ 'required' => false
)
);
@@ -1361,6 +1365,14 @@ class HVAC_Ajax_Handlers {
update_post_meta($organizer_id, '_OrganizerPhone', $params['organizer_phone']);
}
+ // Set featured image if provided
+ if (!empty($params['organizer_featured_image'])) {
+ $image_id = absint($params['organizer_featured_image']);
+ if ($image_id && wp_attachment_is_image($image_id)) {
+ set_post_thumbnail($organizer_id, $image_id);
+ }
+ }
+
// Return created organizer data
wp_send_json_success(array(
'id' => $organizer_id,
@@ -1456,7 +1468,7 @@ class HVAC_Ajax_Handlers {
$security_check = HVAC_Ajax_Security::verify_ajax_request(
'create_venue',
HVAC_Ajax_Security::NONCE_GENERAL,
- array('hvac_trainer', 'hvac_master_trainer'),
+ array('administrator', 'hvac_trainer', 'hvac_master_trainer'),
false
);
@@ -1509,6 +1521,10 @@ class HVAC_Ajax_Handlers {
'type' => 'text',
'required' => false,
'max_length' => 20
+ ),
+ 'venue_featured_image' => array(
+ 'type' => 'text',
+ 'required' => false
)
);
@@ -1557,6 +1573,14 @@ class HVAC_Ajax_Handlers {
}
}
+ // Set featured image if provided
+ if (!empty($params['venue_featured_image'])) {
+ $image_id = absint($params['venue_featured_image']);
+ if ($image_id && wp_attachment_is_image($image_id)) {
+ set_post_thumbnail($venue_id, $image_id);
+ }
+ }
+
// Build subtitle for display
$subtitle_parts = array_filter(array(
$params['venue_address'],
diff --git a/includes/class-hvac-event-form-builder.php b/includes/class-hvac-event-form-builder.php
index 2ce851cb..a6ad93ba 100644
--- a/includes/class-hvac-event-form-builder.php
+++ b/includes/class-hvac-event-form-builder.php
@@ -172,6 +172,9 @@ class HVAC_Event_Form_Builder extends HVAC_Form_Builder {
// Basic event fields
$this->add_basic_event_fields();
+ // Featured image field
+ $this->add_featured_image_field();
+
/**
* Action hook for TEC ticketing integration
*
@@ -323,6 +326,23 @@ class HVAC_Event_Form_Builder extends HVAC_Form_Builder {
return $this;
}
+ /**
+ * Add featured image field for event
+ */
+ public function add_featured_image_field(): self {
+ $featured_image_field = [
+ 'type' => 'custom',
+ 'name' => 'event_featured_image',
+ 'label' => 'Featured Image',
+ 'custom_html' => $this->render_media_upload_field('event_featured_image', 'Select Event Image'),
+ 'wrapper_class' => 'form-row featured-image-field'
+ ];
+
+ $this->add_field($featured_image_field);
+
+ return $this;
+ }
+
/**
* Add datetime fields for event scheduling
*/
@@ -1475,7 +1495,9 @@ class HVAC_Event_Form_Builder extends HVAC_Form_Builder {
*/
private function render_searchable_organizer_selector(): string {
$current_user = wp_get_current_user();
- $can_create = in_array('hvac_trainer', $current_user->roles) || in_array('hvac_master_trainer', $current_user->roles);
+ $can_create = in_array('administrator', $current_user->roles) ||
+ in_array('hvac_trainer', $current_user->roles) ||
+ in_array('hvac_master_trainer', $current_user->roles);
return <<
@@ -1569,7 +1591,9 @@ HTML;
*/
private function render_searchable_venue_selector(): string {
$current_user = wp_get_current_user();
- $can_create = in_array('hvac_trainer', $current_user->roles) || in_array('hvac_master_trainer', $current_user->roles);
+ $can_create = in_array('administrator', $current_user->roles) ||
+ in_array('hvac_trainer', $current_user->roles) ||
+ in_array('hvac_master_trainer', $current_user->roles);
return <<
@@ -1710,4 +1734,111 @@ HTML;
+
+
+
+