## 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>
403 lines
No EOL
12 KiB
Markdown
403 lines
No EOL
12 KiB
Markdown
# Venue Management System Documentation
|
|
|
|
**Version**: 2.0.0
|
|
**Last Updated**: August 28, 2025
|
|
**Component**: HVAC_Venues
|
|
**Status**: ✅ Production Ready
|
|
|
|
## Table of Contents
|
|
1. [Overview](#overview)
|
|
2. [Features](#features)
|
|
3. [User Interface](#user-interface)
|
|
4. [Technical Architecture](#technical-architecture)
|
|
5. [Database Schema](#database-schema)
|
|
6. [API Reference](#api-reference)
|
|
7. [Integration with The Events Calendar](#integration-with-the-events-calendar)
|
|
8. [Security Considerations](#security-considerations)
|
|
9. [Troubleshooting](#troubleshooting)
|
|
|
|
## Overview
|
|
|
|
The Venue Management System provides trainers with comprehensive tools to create, manage, and organize training venues. This system is fully integrated with The Events Calendar (TEC) plugin, allowing seamless venue selection during event creation.
|
|
|
|
### Key Benefits
|
|
- **Centralized Management**: All venues in one searchable directory
|
|
- **Reusability**: Create once, use for multiple events
|
|
- **Location Services**: Automatic geocoding and map integration
|
|
- **Access Control**: Trainers can only edit their own venues
|
|
- **TEC Integration**: Native support for The Events Calendar
|
|
|
|
## Features
|
|
|
|
### Core Functionality
|
|
|
|
#### 1. Venue Listing (`/trainer/venue/list/`)
|
|
- **Searchable Directory**: Filter venues by name, city, or state
|
|
- **Pagination**: 20 venues per page with navigation
|
|
- **Ownership Indicators**: Visual badges for user's own venues
|
|
- **Quick Actions**: Edit buttons for owned venues
|
|
- **Responsive Table**: Mobile-optimized display
|
|
|
|
#### 2. Venue Management (`/trainer/venue/manage/`)
|
|
- **Create New Venues**: Complete form with validation
|
|
- **Edit Existing Venues**: Update all venue details
|
|
- **Delete Venues**: Safe deletion with event check
|
|
- **Rich Information**: Address, contact, and description fields
|
|
|
|
### Data Fields
|
|
|
|
#### Required Fields
|
|
- **Venue Name**: Unique identifier for the venue
|
|
- **Street Address**: Physical location
|
|
- **City**: Municipality name
|
|
- **State/Province**: Regional identifier
|
|
- **Zip/Postal Code**: Postal information
|
|
- **Country**: Selected from supported countries
|
|
|
|
#### Optional Fields
|
|
- **Description**: Detailed venue information
|
|
- **Phone Number**: Contact telephone
|
|
- **Website URL**: Venue website
|
|
- **Show Map**: Display map on event pages
|
|
- **Show Map Link**: Include directions link
|
|
|
|
### Advanced Features
|
|
|
|
#### Location Services
|
|
- **Geocoding**: Automatic latitude/longitude calculation
|
|
- **Map Display**: Interactive maps on public pages
|
|
- **Directions**: Google Maps integration
|
|
|
|
#### Search and Filter
|
|
- **Text Search**: Find venues by name
|
|
- **State Filter**: Filter by state/province
|
|
- **Pagination**: Navigate large venue lists
|
|
- **Sort Options**: Alphabetical by default
|
|
|
|
## User Interface
|
|
|
|
### Venue List Page
|
|
```
|
|
┌─────────────────────────────────────────────┐
|
|
│ Training Venues [Add New Venue] │
|
|
├─────────────────────────────────────────────┤
|
|
│ [Search: ________] [State: All ▼] [Filter] │
|
|
├─────────────────────────────────────────────┤
|
|
│ Name │ Address │ City │ State │ Actions │
|
|
├──────┼─────────┼──────┼───────┼────────────┤
|
|
│ Main │ 123 St │ NYC │ NY │ [Edit] │
|
|
│ Hall │ │ │ │ Your Venue │
|
|
└─────────────────────────────────────────────┘
|
|
```
|
|
|
|
### Venue Management Form
|
|
```
|
|
┌─────────────────────────────────────────────┐
|
|
│ Create New Venue / Edit Venue │
|
|
├─────────────────────────────────────────────┤
|
|
│ Venue Information │
|
|
│ ├─ Venue Name: [_______________] * │
|
|
│ └─ Description: [_______________] │
|
|
│ │
|
|
│ Location Details │
|
|
│ ├─ Street Address: [___________] * │
|
|
│ ├─ City: [_________] * │
|
|
│ ├─ State: [________] * │
|
|
│ ├─ Zip: [_____] * │
|
|
│ └─ Country: [United States ▼] * │
|
|
│ │
|
|
│ Contact Information │
|
|
│ ├─ Phone: [___________] │
|
|
│ └─ Website: [_________] │
|
|
│ │
|
|
│ [Save Venue] [Cancel] [Delete] │
|
|
└─────────────────────────────────────────────┘
|
|
```
|
|
|
|
## Technical Architecture
|
|
|
|
### Class Structure
|
|
|
|
```php
|
|
class HVAC_Venues {
|
|
// Singleton pattern
|
|
private static $instance = null;
|
|
|
|
public static function instance() {
|
|
if (null === self::$instance) {
|
|
self::$instance = new self();
|
|
}
|
|
return self::$instance;
|
|
}
|
|
|
|
// Core methods
|
|
public function render_venues_list()
|
|
public function render_venue_manage()
|
|
public function ajax_save_venue()
|
|
public function ajax_delete_venue()
|
|
public function ajax_load_venue()
|
|
}
|
|
```
|
|
|
|
### File Structure
|
|
```
|
|
includes/
|
|
├── class-hvac-venues.php # Main venue class
|
|
assets/
|
|
├── css/
|
|
│ └── hvac-venues.css # Venue styles
|
|
└── js/
|
|
└── hvac-venues.js # Venue JavaScript
|
|
templates/
|
|
├── page-trainer-venue-list.php # List template
|
|
└── page-trainer-venue-manage.php # Manage template
|
|
```
|
|
|
|
### AJAX Endpoints
|
|
|
|
#### Save Venue
|
|
- **Action**: `wp_ajax_hvac_save_venue`
|
|
- **Nonce**: `hvac_venues_nonce`
|
|
- **Parameters**: venue data fields
|
|
- **Response**: Success/error with venue ID
|
|
|
|
#### Delete Venue
|
|
- **Action**: `wp_ajax_hvac_delete_venue`
|
|
- **Nonce**: `hvac_venues_nonce`
|
|
- **Parameters**: `venue_id`
|
|
- **Response**: Success/error message
|
|
|
|
#### Load Venue
|
|
- **Action**: `wp_ajax_hvac_load_venue`
|
|
- **Nonce**: `hvac_venues_nonce`
|
|
- **Parameters**: `venue_id`
|
|
- **Response**: Venue data object
|
|
|
|
## Database Schema
|
|
|
|
### Post Type
|
|
- **Type**: `tribe_venue`
|
|
- **Status**: `publish`
|
|
- **Author**: Current user ID
|
|
|
|
### Post Meta Fields
|
|
```sql
|
|
_VenueAddress -- Street address
|
|
_VenueCity -- City name
|
|
_VenueState -- State abbreviation
|
|
_VenueStateProvince -- Full state/province name
|
|
_VenueZip -- Postal code
|
|
_VenueCountry -- Country name
|
|
_VenuePhone -- Phone number
|
|
_VenueURL -- Website URL
|
|
_VenueShowMap -- Boolean (show map)
|
|
_VenueShowMapLink -- Boolean (show directions)
|
|
_VenueLat -- Latitude (geocoded)
|
|
_VenueLng -- Longitude (geocoded)
|
|
```
|
|
|
|
## API Reference
|
|
|
|
### PHP Functions
|
|
|
|
#### Creating a Venue
|
|
```php
|
|
// Using TEC function
|
|
$venue_id = tribe_create_venue([
|
|
'Venue' => 'Conference Center',
|
|
'Address' => '123 Main St',
|
|
'City' => 'New York',
|
|
'StateProvince' => 'NY',
|
|
'Zip' => '10001',
|
|
'Country' => 'United States',
|
|
'Phone' => '555-0123',
|
|
'URL' => 'https://example.com'
|
|
]);
|
|
|
|
// Using HVAC wrapper
|
|
$venues = HVAC_Venues::instance();
|
|
$venue_data = $venues->create_venue($data);
|
|
```
|
|
|
|
#### Retrieving Venues
|
|
```php
|
|
// Get all venues for current user
|
|
$venues = get_posts([
|
|
'post_type' => 'tribe_venue',
|
|
'author' => get_current_user_id(),
|
|
'posts_per_page' => -1
|
|
]);
|
|
|
|
// Get venue by ID
|
|
$venue = get_post($venue_id);
|
|
$address = get_post_meta($venue_id, '_VenueAddress', true);
|
|
```
|
|
|
|
#### Updating a Venue
|
|
```php
|
|
// Using TEC function
|
|
tribe_update_venue($venue_id, [
|
|
'Venue' => 'Updated Name',
|
|
'City' => 'Updated City'
|
|
]);
|
|
|
|
// Direct update
|
|
update_post_meta($venue_id, '_VenueCity', 'New City');
|
|
```
|
|
|
|
### JavaScript Functions
|
|
|
|
#### Save Venue via AJAX
|
|
```javascript
|
|
jQuery.ajax({
|
|
url: hvacVenues.ajax_url,
|
|
type: 'POST',
|
|
data: {
|
|
action: 'hvac_save_venue',
|
|
nonce: hvacVenues.nonce,
|
|
venue_name: 'Conference Center',
|
|
venue_address: '123 Main St',
|
|
// ... other fields
|
|
},
|
|
success: function(response) {
|
|
if (response.success) {
|
|
console.log('Venue saved:', response.data.venue_id);
|
|
}
|
|
}
|
|
});
|
|
```
|
|
|
|
## Integration with The Events Calendar
|
|
|
|
### Event Creation
|
|
When creating an event, venues appear in a dropdown:
|
|
```php
|
|
// Venues are automatically available in TEC
|
|
// No additional integration required
|
|
```
|
|
|
|
### Venue Selection
|
|
```javascript
|
|
// In event creation form
|
|
$('#EventVenueID').val(venue_id);
|
|
```
|
|
|
|
### Public Display
|
|
Venues are displayed on event pages with:
|
|
- Full address
|
|
- Map (if enabled)
|
|
- Directions link (if enabled)
|
|
- Contact information
|
|
|
|
## Security Considerations
|
|
|
|
### Access Control
|
|
- **Creation**: Any logged-in trainer can create venues
|
|
- **Editing**: Only venue owner can edit
|
|
- **Deletion**: Only venue owner can delete
|
|
- **Viewing**: All trainers can view all venues
|
|
|
|
### Data Validation
|
|
```php
|
|
// All inputs are sanitized
|
|
$venue_name = sanitize_text_field($_POST['venue_name']);
|
|
$venue_address = sanitize_text_field($_POST['venue_address']);
|
|
$venue_url = esc_url_raw($_POST['venue_website']);
|
|
$venue_description = wp_kses_post($_POST['venue_description']);
|
|
```
|
|
|
|
### Nonce Verification
|
|
```php
|
|
// All AJAX requests verify nonces
|
|
check_ajax_referer('hvac_venues_nonce', 'nonce');
|
|
```
|
|
|
|
### SQL Injection Prevention
|
|
```php
|
|
// Using WordPress prepared statements
|
|
$wpdb->prepare("SELECT * FROM $wpdb->posts WHERE ID = %d", $venue_id);
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
#### Venue Not Appearing in Event Creation
|
|
**Problem**: Created venue doesn't show in dropdown
|
|
**Solution**: Check venue post_status is 'publish'
|
|
```php
|
|
// Verify venue status
|
|
$venue = get_post($venue_id);
|
|
if ($venue->post_status !== 'publish') {
|
|
wp_update_post(['ID' => $venue_id, 'post_status' => 'publish']);
|
|
}
|
|
```
|
|
|
|
#### Cannot Delete Venue
|
|
**Problem**: Delete button doesn't work
|
|
**Solution**: Venue is being used by events
|
|
```php
|
|
// Check for events using venue
|
|
$events = get_posts([
|
|
'post_type' => 'tribe_events',
|
|
'meta_key' => '_EventVenueID',
|
|
'meta_value' => $venue_id
|
|
]);
|
|
if (!empty($events)) {
|
|
// Cannot delete - venue in use
|
|
}
|
|
```
|
|
|
|
#### Map Not Displaying
|
|
**Problem**: Map doesn't show on event page
|
|
**Solution**: Enable map display
|
|
```php
|
|
update_post_meta($venue_id, '_VenueShowMap', 'true');
|
|
update_post_meta($venue_id, '_VenueShowMapLink', 'true');
|
|
```
|
|
|
|
### Error Messages
|
|
|
|
| Error | Meaning | Solution |
|
|
|-------|---------|----------|
|
|
| "Unauthorized" | User not logged in or not a trainer | Check user role |
|
|
| "Cannot delete venue" | Venue is being used by events | Remove venue from events first |
|
|
| "Invalid venue ID" | Venue doesn't exist | Verify venue ID |
|
|
| "Permission denied" | User doesn't own the venue | Only edit own venues |
|
|
|
|
## Best Practices
|
|
|
|
### Performance
|
|
- **Caching**: Venue queries are cached
|
|
- **Pagination**: Large lists are paginated
|
|
- **Lazy Loading**: Maps load on demand
|
|
|
|
### User Experience
|
|
- **Auto-save**: Form data persists
|
|
- **Validation**: Real-time field validation
|
|
- **Feedback**: Clear success/error messages
|
|
|
|
### Development
|
|
- **Singleton Pattern**: Use `HVAC_Venues::instance()`
|
|
- **Hooks**: Use WordPress actions/filters
|
|
- **Security**: Always validate and sanitize
|
|
|
|
## Future Enhancements
|
|
|
|
### Planned Features
|
|
- **Bulk Import**: CSV venue upload
|
|
- **Venue Categories**: Organize by type
|
|
- **Capacity Tracking**: Maximum attendees
|
|
- **Amenities**: List venue features
|
|
- **Photo Gallery**: Multiple venue images
|
|
- **Availability Calendar**: Booking system
|
|
- **Reviews**: Trainer venue ratings
|
|
|
|
### API Extensions
|
|
- **REST API**: Full CRUD operations
|
|
- **GraphQL**: Query support
|
|
- **Webhooks**: Event notifications
|
|
|
|
---
|
|
|
|
*For additional support, see [TROUBLESHOOTING.md](TROUBLESHOOTING.md) or contact the development team.* |