docs: Comprehensive documentation update with best practices

- Created WORDPRESS-BEST-PRACTICES.md with complete WP standards guide
- Created TESTING-GUIDE.md with E2E testing procedures and display session setup
- Updated CLAUDE.md with JavaScript simplification and recent fixes
- Enhanced main docs README with new documentation links
- Added guidance on MCP Playwright usage vs standard Playwright
- Documented proper role checking (roles vs capabilities)
- Included display session configuration for headless testing
- Added production testing checklists and debug procedures

Key additions:
- How to use jQuery properly in WordPress (no compatibility layers needed)
- Display session setup (DISPLAY=:0) for Playwright testing
- Security best practices with proper examples
- Common pitfalls and solutions
- Test user accounts for staging/production

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ben 2025-08-18 22:44:43 -03:00
parent b110b49c01
commit 8752905f9e
4 changed files with 950 additions and 6 deletions

View file

@ -1,6 +1,6 @@
# CLAUDE.md # CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. This file provides comprehensive guidance to Claude Code (claude.ai/code) when working with the HVAC Community Events WordPress plugin. Follow these instructions carefully to maintain code quality, security, and WordPress best practices.
## 🏗️ Architecture Overview ## 🏗️ Architecture Overview
@ -54,13 +54,28 @@ wp post meta update [PAGE_ID] _wp_page_template templates/page-*.php
scripts/clear-staging-cache.sh scripts/clear-staging-cache.sh
``` ```
### Testing with Display Session
```bash
# Set display environment for headless testing
export DISPLAY=:0
export XAUTHORITY=/run/user/1000/.mutter-Xwaylandauth.90WDB3
# Run Playwright tests with display
DISPLAY=:0 node test-trainer-features.js
# Use MCP Playwright for browser automation
# The MCP tools provide better integration than standard Playwright
```
## 📚 Documentation ## 📚 Documentation
For comprehensive information, see: For comprehensive information, see:
- **[docs/README.md](docs/README.md)** - Overview and navigation - **[docs/README.md](docs/README.md)** - Overview and navigation
- **[docs/WORDPRESS-BEST-PRACTICES.md](docs/WORDPRESS-BEST-PRACTICES.md)** - WordPress coding standards and patterns
- **[docs/CONFIGURATION.md](docs/CONFIGURATION.md)** - System configuration and architecture - **[docs/CONFIGURATION.md](docs/CONFIGURATION.md)** - System configuration and architecture
- **[docs/DEVELOPMENT-GUIDE.md](docs/DEVELOPMENT-GUIDE.md)** - Development standards and workflow - **[docs/DEVELOPMENT-GUIDE.md](docs/DEVELOPMENT-GUIDE.md)** - Development standards and workflow
- **[docs/TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md)** - Common issues and solutions - **[docs/TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md)** - Common issues and solutions
- **[docs/API-REFERENCE.md](docs/API-REFERENCE.md)** - Complete API documentation - **[docs/API-REFERENCE.md](docs/API-REFERENCE.md)** - Complete API documentation
- **[docs/TESTING-GUIDE.md](docs/TESTING-GUIDE.md)** - Testing procedures and best practices
### 🚀 Deployment Guidelines ### 🚀 Deployment Guidelines
- **ALWAYS** use `scripts/deploy.sh staging` for staging deployments - **ALWAYS** use `scripts/deploy.sh staging` for staging deployments
@ -71,6 +86,20 @@ For comprehensive information, see:
### 🎯 WordPress Best Practices ### 🎯 WordPress Best Practices
#### JavaScript and jQuery
```javascript
// ✅ CORRECT - Use WordPress jQuery patterns
jQuery(document).ready(function($) {
'use strict';
// $ is available within this scope
$('.element').addClass('active');
});
// ❌ WRONG - Don't create compatibility layers
// WordPress handles jQuery in no-conflict mode
// Trust the WordPress implementation
```
#### Security First #### Security First
```php ```php
// Always escape output // Always escape output
@ -85,10 +114,16 @@ $clean_email = sanitize_email($_POST['email']);
// Always verify nonces // Always verify nonces
wp_verify_nonce($_POST['nonce'], 'action_name'); wp_verify_nonce($_POST['nonce'], 'action_name');
// Always check capabilities // Always check capabilities correctly
if (!current_user_can('required_capability')) { if (!current_user_can('edit_posts')) {
wp_die('Insufficient permissions'); wp_die('Insufficient permissions');
} }
// Check custom roles properly (roles aren't capabilities!)
$user = wp_get_current_user();
if (!in_array('hvac_trainer', $user->roles)) {
wp_die('Access denied');
}
``` ```
#### Code Standards #### Code Standards
@ -254,6 +289,5 @@ The following systems are commented out in `/includes/class-hvac-plugin.php` lin
- **Registration Form Production Deployment and Verification (2025-08-08)**: Successfully deployed updated registration form to production environment using `scripts/deploy.sh production`. Comprehensive Playwright E2E tests executed against production site (https://upskillhvac.com/trainer/registration/) with 100% pass rate. Test verification confirmed: all 40+ form fields functional with proper Business Type dropdown (11 options), Training Audience multi-select checkboxes (4 options), dynamic Organization Headquarters country/state dropdowns with automatic US/Canada state loading, file upload functionality for profile images and organization logos, complete form submission workflow, user registration with redirect to /registration-pending/. Database verification completed on production server: user account created (ID: 65), all user meta fields stored correctly (business_name, business_email, training_audience serialized array, first_name, last_name, application_details, business_type), organizer post created (ID: 6020 - "Test HVAC Training Company 1754663473108"), venue post created (ID: 6022 - "Test Training Center Dallas 1754663473108"). Registration system fully operational in production with complete end-to-end functionality verified through automated testing and manual database inspection. Test email: test.registration.1754663473108@example.com used for verification. - **Registration Form Production Deployment and Verification (2025-08-08)**: Successfully deployed updated registration form to production environment using `scripts/deploy.sh production`. Comprehensive Playwright E2E tests executed against production site (https://upskillhvac.com/trainer/registration/) with 100% pass rate. Test verification confirmed: all 40+ form fields functional with proper Business Type dropdown (11 options), Training Audience multi-select checkboxes (4 options), dynamic Organization Headquarters country/state dropdowns with automatic US/Canada state loading, file upload functionality for profile images and organization logos, complete form submission workflow, user registration with redirect to /registration-pending/. Database verification completed on production server: user account created (ID: 65), all user meta fields stored correctly (business_name, business_email, training_audience serialized array, first_name, last_name, application_details, business_type), organizer post created (ID: 6020 - "Test HVAC Training Company 1754663473108"), venue post created (ID: 6022 - "Test Training Center Dallas 1754663473108"). Registration system fully operational in production with complete end-to-end functionality verified through automated testing and manual database inspection. Test email: test.registration.1754663473108@example.com used for verification.
- **Trainer Dashboard Template Refactoring (2025-08-11)**: Fixed critical dashboard and navigation issues. Root cause: hardcoded template override in `class-hvac-community-events.php` lines 804-806 forcing old shortcode-based template. Solution: removed hardcoded override, updated to use refactored `page-trainer-dashboard.php` template with proper WordPress integration. Fixed navigation menu rendering by removing conflicting `HVAC_NAV_RENDERED` constant checks in `class-hvac-menu-system.php` and page templates. Added missing `hvac-menu-system.css` file via git pull. Dashboard now displays correctly with working navigation across all trainer pages. Deployment script updated to automatically assign correct page template during deployment. - **Trainer Dashboard Template Refactoring (2025-08-11)**: Fixed critical dashboard and navigation issues. Root cause: hardcoded template override in `class-hvac-community-events.php` lines 804-806 forcing old shortcode-based template. Solution: removed hardcoded override, updated to use refactored `page-trainer-dashboard.php` template with proper WordPress integration. Fixed navigation menu rendering by removing conflicting `HVAC_NAV_RENDERED` constant checks in `class-hvac-menu-system.php` and page templates. Added missing `hvac-menu-system.css` file via git pull. Dashboard now displays correctly with working navigation across all trainer pages. Deployment script updated to automatically assign correct page template during deployment.
- **Documentation Page Double Navigation Fix (2025-08-11)**: Resolved duplicate navigation bar issue on documentation page. Root cause: HVAC_Help_System class was rendering its own navigation (lines 223-231) via `[hvac_documentation]` shortcode while page template also rendered navigation. Solution: commented out duplicate navigation in `class-hvac-help-system.php`. Documentation page now uses comprehensive template (`page-trainer-documentation.php`) with table of contents sidebar, WordPress/Gutenberg integration, and single navigation instance. Help content provided via `HVAC_Documentation_Content` class with fallback to shortcode for empty pages. - **Documentation Page Double Navigation Fix (2025-08-11)**: Resolved duplicate navigation bar issue on documentation page. Root cause: HVAC_Help_System class was rendering its own navigation (lines 223-231) via `[hvac_documentation]` shortcode while page template also rendered navigation. Solution: commented out duplicate navigation in `class-hvac-help-system.php`. Documentation page now uses comprehensive template (`page-trainer-documentation.php`) with table of contents sidebar, WordPress/Gutenberg integration, and single navigation instance. Help content provided via `HVAC_Documentation_Content` class with fallback to shortcode for empty pages.
- **Custom Event Edit Implementation (2025-08-18)**: Implemented secure custom event editing without JavaScript dependencies. Created HVAC_Custom_Event_Edit class with proper authorization checks using role verification instead of capability checks. Fixed permission bug where `current_user_can('hvac_trainer')` was incorrectly used - custom roles are not capabilities. Solution: use `in_array('hvac_trainer', $user->roles)` for proper role checking. Added professional CSS styling matching registration page design with 1200px container width, card-based layout, and proper z-index layering to prevent navigation overlap. Successfully deployed to production with full functionality verified.
[... rest of the existing content remains unchanged ...] - **JavaScript Simplification (2025-08-18)**: Removed 200+ lines of unnecessary jQuery compatibility code following WordPress best practices. Eliminated hvac-jquery-compatibility-fix.js and class-hvac-jquery-compatibility.php. Updated community-login.js to use standard `jQuery(document).ready()` pattern. WordPress handles jQuery in no-conflict mode automatically - complex compatibility layers violate best practices and add unnecessary complexity. Production deployment successful with all functionality working correctly.
- When testing any pages which require hvac trainer role permissions, always include login steps via the /training-login page.

View file

@ -4,8 +4,37 @@
The HVAC Community Events plugin is a comprehensive event management system designed specifically for HVAC trainers. It integrates seamlessly with WordPress and The Events Calendar to provide trainer profiles, certificate generation, venue management, certification tracking, advanced reporting capabilities, comprehensive CSV import functionality with taxonomy integration, and professional trainer profile sharing with QR code generation. The HVAC Community Events plugin is a comprehensive event management system designed specifically for HVAC trainers. It integrates seamlessly with WordPress and The Events Calendar to provide trainer profiles, certificate generation, venue management, certification tracking, advanced reporting capabilities, comprehensive CSV import functionality with taxonomy integration, and professional trainer profile sharing with QR code generation.
**Latest Updates (August 2025):**
- Custom event editing interface without JavaScript dependencies
- Simplified jQuery implementation following WordPress best practices
- Enhanced security with proper authorization checks
- Professional responsive design matching registration pages
- Production-ready with comprehensive testing
## Documentation Structure ## Documentation Structure
### 🎯 [WordPress Best Practices](./WORDPRESS-BEST-PRACTICES.md)
Comprehensive guide to WordPress development standards:
- JavaScript and jQuery patterns
- Security implementation
- Plugin development standards
- Asset management
- Database operations
- Template development
- Performance optimization
- Common pitfalls to avoid
### 🧪 [Testing Guide](./TESTING-GUIDE.md)
Complete testing procedures and best practices:
- Display session configuration
- E2E testing with Playwright
- MCP Playwright tools usage
- Test user accounts
- Manual testing procedures
- Production verification
- Debugging failed tests
- Performance and security testing
### 📋 [Configuration Guide](./CONFIGURATION.md) ### 📋 [Configuration Guide](./CONFIGURATION.md)
Complete reference for plugin configuration including: Complete reference for plugin configuration including:
- System architecture overview - System architecture overview

414
docs/TESTING-GUIDE.md Normal file
View file

@ -0,0 +1,414 @@
# Testing Guide
## Overview
This guide provides comprehensive testing procedures for the HVAC Community Events plugin, including E2E testing with Playwright, manual testing procedures, and production verification steps.
## Setting Up the Testing Environment
### Display Session Configuration
When running tests on a headless server or in CI/CD environments, you need to configure the display session:
```bash
# Set display environment variables
export DISPLAY=:0
export XAUTHORITY=/run/user/1000/.mutter-Xwaylandauth.90WDB3
# Verify display is working
echo $DISPLAY
# Should output: :0
# Run tests with display
DISPLAY=:0 node test-trainer-features.js
```
### Why Display Session Matters
- Playwright needs a display to render pages for screenshots
- Some JavaScript interactions require a visible browser
- CSS animations and transitions need a display context
- Debugging is easier with visual feedback
## E2E Testing with Playwright
### Test Structure
```javascript
// test-trainer-features.js
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({
headless: true, // Set to false for debugging
args: ['--no-sandbox']
});
const context = await browser.newContext({
viewport: { width: 1920, height: 1080 }
});
const page = await context.newPage();
// Test implementation
await page.goto('https://upskill-staging.measurequick.com');
// Always close browser
await browser.close();
})();
```
### Using MCP Playwright Tools
MCP Playwright provides better integration with Claude Code:
```javascript
// Using MCP tools (preferred in Claude Code)
mcp__playwright__browser_navigate({ url: 'https://upskillhvac.com/training-login/' });
mcp__playwright__browser_type({ element: 'Username field', ref: 'e40', text: 'joe@measurequick.com' });
mcp__playwright__browser_click({ element: 'Log In button', ref: 'e50' });
mcp__playwright__browser_snapshot(); // Get page state
mcp__playwright__browser_take_screenshot({ filename: 'login-success.png' });
```
### Key Test Files
```bash
# Core test suites
test-all-features.js # Comprehensive test suite
test-trainer-features.js # Trainer-specific features
test-master-dashboard.js # Master trainer dashboard
test-custom-event-edit.js # Event editing functionality
test-registration.js # Registration form validation
# Run specific test
DISPLAY=:0 node test-trainer-features.js
# Run on staging
UPSKILL_STAGING_URL="https://upskill-staging.measurequick.com" node test-all-features.js
```
## Test User Accounts
### Staging Environment
```
Regular Trainer:
- Username: test_trainer
- Password: TestTrainer123!
Master Trainer:
- Username: JoeMedosch@gmail.com
- Password: JoeTrainer2025@
Dual Role (Trainer + Master):
- Username: joe@measurequick.com
- Password: JoeTrainer2025@
```
### Production Environment
```
Master Trainer:
- Username: joe@measurequick.com
- Password: JoeTrainer2025@
Note: Always test with real accounts in production
Never create test data in production
```
## Manual Testing Procedures
### Login Flow Testing
1. Navigate to `/training-login/`
2. Enter credentials
3. Verify redirect to appropriate dashboard
4. Check navigation menu displays correctly
5. Verify role-based features are accessible
### Event Management Testing
```
1. Create Event:
- Navigate to /trainer/event/manage/
- Fill all required fields
- Submit and verify creation
- Check event appears in dashboard
2. Edit Event:
- Navigate to /trainer/event/edit/?event_id=XXX
- Verify form populates with existing data
- Make changes and save
- Verify changes persist
3. Event Permissions:
- Test with different user roles
- Verify trainers can only edit own events
- Check master trainers can view all events
```
### CSS and Layout Testing
```
1. Responsive Design:
- Test at 320px (mobile)
- Test at 768px (tablet)
- Test at 1920px (desktop)
2. Browser Compatibility:
- Chrome/Edge (Chromium)
- Firefox
- Safari (critical for production)
- Mobile browsers
3. Theme Integration:
- Verify Astra theme compatibility
- Check sidebar removal on plugin pages
- Verify navigation z-index layering
```
## Automated Test Writing Best Practices
### Structure Your Tests
```javascript
describe('Trainer Dashboard', () => {
beforeEach(async () => {
// Login before each test
await loginAsTrainer(page);
});
test('displays user statistics', async () => {
await page.goto('/trainer/dashboard/');
const stats = await page.locator('.hvac-stats-card');
expect(await stats.count()).toBeGreaterThan(0);
});
test('shows events table', async () => {
await page.goto('/trainer/dashboard/');
const table = await page.locator('.hvac-events-table');
expect(await table.isVisible()).toBeTruthy();
});
});
```
### Common Test Patterns
```javascript
// Wait for navigation
await page.waitForURL('**/dashboard/**');
// Wait for element
await page.waitForSelector('.hvac-dashboard', { timeout: 10000 });
// Check for errors in console
page.on('console', msg => {
if (msg.type() === 'error') {
console.error('Console error:', msg.text());
}
});
// Take screenshot on failure
try {
// Test code
} catch (error) {
await page.screenshot({ path: 'error-screenshot.png' });
throw error;
}
```
## Production Testing Checklist
### Pre-deployment Verification
```bash
✅ Run pre-deployment validation
bin/pre-deployment-check.sh
✅ Test all features on staging
DISPLAY=:0 node test-all-features.js
✅ Verify no JavaScript errors
Check browser console for errors
✅ Validate CSS rendering
Test in Chrome, Firefox, Safari
✅ Check database operations
Verify CRUD operations work
```
### Post-deployment Verification
```bash
✅ Clear all caches
wp cache flush
wp rewrite flush
✅ Test critical paths
- Login flow
- Dashboard access
- Event creation/editing
- Navigation menus
✅ Monitor error logs
tail -f wp-content/debug.log
✅ Verify page load times
Check performance metrics
✅ Test with real user accounts
Use production credentials
```
## Debugging Failed Tests
### Common Issues and Solutions
#### jQuery Errors
```javascript
// Error: $ is not defined
// Solution: Use jQuery(document).ready()
jQuery(document).ready(function($) {
// $ is now available
});
```
#### Permission Errors
```php
// Error: You do not have permission
// Check role properly:
$user = wp_get_current_user();
if (!in_array('hvac_trainer', $user->roles)) {
// No access
}
```
#### CSS Not Loading
```php
// Verify page detection
private function is_plugin_page() {
// Check multiple conditions
return $this->check_page_template() ||
$this->check_url_pattern() ||
$this->check_page_id();
}
```
### Debug Output
```javascript
// Add debug logging
console.log('Current URL:', window.location.href);
console.log('User role:', hvac_ajax.user_role);
console.log('Page ID:', hvac_ajax.page_id);
// Check element state
const element = document.querySelector('.hvac-dashboard');
console.log('Element exists:', !!element);
console.log('Element visible:', element?.offsetParent !== null);
```
## Performance Testing
### Load Time Benchmarks
```javascript
// Measure page load time
const startTime = performance.now();
await page.goto('/trainer/dashboard/');
const loadTime = performance.now() - startTime;
console.log(`Page loaded in ${loadTime}ms`);
// Acceptable thresholds:
// - Homepage: < 2000ms
// - Dashboard: < 3000ms
// - Event forms: < 2500ms
```
### Database Query Monitoring
```php
// Enable query monitoring (development only)
define('SAVEQUERIES', true);
// Log slow queries
add_filter('log_query_custom_data', function($data, $query) {
if ($data['elapsed'] > 0.5) {
error_log('Slow query: ' . $query);
}
return $data;
}, 10, 2);
```
## Security Testing
### Authorization Testing
```javascript
// Test unauthorized access
await page.goto('/trainer/dashboard/');
// Should redirect to login if not authenticated
// Test role-based access
await loginAsRegularUser(page);
await page.goto('/master-trainer/master-dashboard/');
// Should show access denied
```
### Input Validation Testing
```javascript
// Test XSS prevention
await page.fill('#event_title', '<script>alert("XSS")</script>');
await page.click('#submit');
// Should sanitize input, no alert should appear
// Test SQL injection prevention
await page.fill('#user_email', "admin' OR '1'='1");
// Should reject invalid input
```
## Continuous Integration
### GitHub Actions Workflow
```yaml
name: Test Plugin
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Node
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Install dependencies
run: npm install playwright
- name: Run tests
run: |
export DISPLAY=:99
Xvfb :99 -screen 0 1920x1080x24 &
node test-all-features.js
```
## Test Coverage Goals
### Minimum Coverage Requirements
- **Authentication**: 100% - All login/logout paths
- **Authorization**: 100% - Role-based access control
- **CRUD Operations**: 90% - Create, Read, Update, Delete
- **UI Components**: 80% - Forms, buttons, navigation
- **Error Handling**: 85% - Error messages, validation
- **Edge Cases**: 70% - Boundary conditions
### Coverage Reporting
```bash
# Generate coverage report
npm run test:coverage
# View coverage
open coverage/index.html
```
## Best Practices Summary
1. **Always test on staging first**
2. **Use real test accounts, not mocked data**
3. **Verify both functionality and UI**
4. **Check browser console for errors**
5. **Test with different user roles**
6. **Take screenshots for debugging**
7. **Clean up test data after tests**
8. **Monitor performance metrics**
9. **Document test failures**
10. **Keep tests maintainable and readable**
## Resources
- [Playwright Documentation](https://playwright.dev/docs/intro)
- [WordPress Testing Best Practices](https://make.wordpress.org/core/handbook/testing/)
- [PHPUnit for WordPress](https://make.wordpress.org/core/handbook/testing/automated-testing/phpunit/)
- [Browser Testing Guide](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing)

View file

@ -0,0 +1,467 @@
# WordPress Best Practices Guide
## Overview
This guide documents WordPress best practices as implemented in the HVAC Community Events plugin. Following these practices ensures maintainability, security, and compatibility with WordPress core and other plugins.
## JavaScript and jQuery
### ✅ DO: Use WordPress jQuery Patterns
```javascript
// CORRECT - WordPress standard pattern
jQuery(document).ready(function($) {
'use strict';
// $ is now available within this scope
$('.my-element').addClass('active');
});
```
### ❌ DON'T: Create Complex Compatibility Layers
```javascript
// WRONG - Unnecessary complexity
(function($) {
if (typeof $ === 'undefined' && typeof window.jQuery !== 'undefined') {
$ = window.jQuery;
}
// Complex error handling for basic jQuery operations
})(jQuery);
```
### Key Principles
1. WordPress loads jQuery in no-conflict mode by default
2. Use `jQuery` globally, `$` within document ready callbacks
3. Don't create compatibility shims - they add complexity without value
4. Trust WordPress's jQuery implementation
## Security Best Practices
### Always Escape Output
```php
// ✅ CORRECT
echo esc_html($user_input);
echo esc_url($link);
echo esc_attr($attribute);
echo wp_kses_post($content_with_html);
// ❌ WRONG
echo $user_input;
```
### Always Sanitize Input
```php
// ✅ CORRECT
$clean_text = sanitize_text_field($_POST['field']);
$clean_email = sanitize_email($_POST['email']);
$clean_url = esc_url_raw($_POST['url']);
// ❌ WRONG
$data = $_POST['field'];
```
### Always Verify Nonces
```php
// ✅ CORRECT
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'action_name')) {
wp_die('Security check failed');
}
// ❌ WRONG - No nonce verification
if (isset($_POST['submit'])) {
// Process form
}
```
### Always Check Capabilities
```php
// ✅ CORRECT
if (!current_user_can('edit_posts')) {
wp_die('Insufficient permissions');
}
// Check custom roles properly
$user = wp_get_current_user();
if (!in_array('hvac_trainer', $user->roles)) {
wp_die('Access denied');
}
// ❌ WRONG
if (!current_user_can('hvac_trainer')) { // Custom roles aren't capabilities!
wp_die('Access denied');
}
```
## Plugin Development Standards
### File Organization
```
hvac-community-events/
├── hvac-community-events.php # Main plugin file
├── includes/ # PHP classes and functions
│ ├── class-*.php # One class per file
│ └── functions.php # Helper functions
├── assets/ # Frontend resources
│ ├── css/ # Stylesheets
│ ├── js/ # JavaScript files
│ └── images/ # Images
├── templates/ # Page templates
└── docs/ # Documentation
```
### Class Structure
```php
/**
* HVAC Example Class
*
* @package HVAC_Community_Events
* @since 1.0.0
*/
class HVAC_Example {
/**
* Instance
* @var HVAC_Example
*/
private static $instance = null;
/**
* Get instance (Singleton pattern)
*/
public static function 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_action('init', array($this, 'init'));
}
}
```
### Naming Conventions
- **PHP Classes**: `HVAC_Class_Name` (prefix + PascalCase)
- **Functions**: `hvac_function_name` (prefix + snake_case)
- **Hooks**: `hvac_hook_name` (prefix + snake_case)
- **Constants**: `HVAC_CONSTANT_NAME` (prefix + UPPER_SNAKE_CASE)
- **Database**: `hvac_table_name` (prefix + snake_case)
## Asset Management
### Conditional Loading
```php
/**
* Only load assets on plugin pages
*/
public function enqueue_scripts() {
// Check if we're on a plugin page
if (!$this->is_plugin_page()) {
return;
}
wp_enqueue_script(
'hvac-dashboard',
HVAC_PLUGIN_URL . 'assets/js/hvac-dashboard.js',
array('jquery'),
HVAC_PLUGIN_VERSION,
true
);
// Localize script for AJAX
wp_localize_script('hvac-dashboard', 'hvac_ajax', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('hvac_ajax_nonce')
));
}
```
### CSS Organization
```css
/* Use consistent naming and organization */
.hvac-wrapper {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
/* Component-based styling */
.hvac-card {
background: #fff;
border-radius: 8px;
padding: 20px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
/* State modifiers */
.hvac-card--active {
border-color: var(--hvac-primary);
}
```
## Database Operations
### Use WordPress Database API
```php
global $wpdb;
// ✅ CORRECT - Using prepared statements
$results = $wpdb->get_results(
$wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}posts WHERE post_author = %d",
$user_id
)
);
// ❌ WRONG - Direct query without preparation
$results = $wpdb->get_results(
"SELECT * FROM wp_posts WHERE post_author = " . $user_id
);
```
### Cache Expensive Queries
```php
$cache_key = 'hvac_trainer_events_' . $user_id;
$events = wp_cache_get($cache_key);
if (false === $events) {
// Expensive query
$events = $this->get_trainer_events($user_id);
// Cache for 1 hour
wp_cache_set($cache_key, $events, '', HOUR_IN_SECONDS);
}
```
## AJAX Best Practices
### Proper AJAX Handler
```php
/**
* AJAX handler with security checks
*/
public function ajax_handler() {
// Verify nonce
if (!check_ajax_referer('hvac_ajax_nonce', 'nonce', false)) {
wp_send_json_error('Security check failed');
}
// Check capabilities
if (!current_user_can('edit_posts')) {
wp_send_json_error('Insufficient permissions');
}
// Sanitize input
$data = sanitize_text_field($_POST['data']);
// Process request
$result = $this->process_data($data);
// Return JSON response
if ($result) {
wp_send_json_success($result);
} else {
wp_send_json_error('Processing failed');
}
}
```
## Template Development
### WordPress Template Requirements
```php
<?php
/**
* Template Name: HVAC Dashboard
*
* @package HVAC_Community_Events
*/
// Security check
if (!defined('ABSPATH')) {
exit;
}
// ALWAYS include WordPress header
get_header();
// Template content
?>
<div class="hvac-wrapper">
<!-- Your content here -->
</div>
<?php
// ALWAYS include WordPress footer
get_footer();
```
### Template Hierarchy
```
templates/
├── page-trainer-dashboard.php # Trainer dashboard
├── page-master-dashboard.php # Master trainer dashboard
├── page-edit-event-custom.php # Custom event editor
└── page-trainer-profile.php # Profile page
```
## Error Handling
### Graceful Error Handling
```php
try {
$result = $this->risky_operation();
} catch (Exception $e) {
// Log error for debugging
error_log('HVAC Plugin Error: ' . $e->getMessage());
// Show user-friendly message
if (WP_DEBUG) {
wp_die('Error: ' . esc_html($e->getMessage()));
} else {
wp_die('An error occurred. Please try again later.');
}
}
```
## Performance Optimization
### Optimize Queries
```php
// ✅ CORRECT - Single query with JOIN
$results = $wpdb->get_results("
SELECT p.*, pm.meta_value as venue_id
FROM {$wpdb->posts} p
LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
WHERE p.post_type = 'tribe_events'
AND pm.meta_key = '_EventVenueID'
");
// ❌ WRONG - Multiple queries in loop
foreach ($events as $event) {
$venue = get_post_meta($event->ID, '_EventVenueID', true);
// Process...
}
```
### Lazy Loading
```php
// Only load heavy resources when needed
public function maybe_load_map_data() {
if (!is_page('find-trainer')) {
return;
}
// Load map data only on find-trainer page
$this->load_trainer_locations();
}
```
## Testing with Display Session
### Using Headless Testing
```bash
# Set display environment for headless testing
export DISPLAY=:0
export XAUTHORITY=/run/user/1000/.mutter-Xwaylandauth.90WDB3
# Run Playwright tests
node test-trainer-features.js
```
### Testing Best Practices
1. Always test on staging before production
2. Use actual user accounts for realistic testing
3. Verify both UI and functionality
4. Check browser console for errors
5. Test with different user roles
## Deployment Process
### Pre-deployment Checklist
```bash
# 1. Run validation
bin/pre-deployment-check.sh
# 2. Test on staging
scripts/deploy.sh staging
# 3. Verify staging
node test-all-features.js
# 4. Deploy to production (only when requested)
scripts/deploy.sh production
```
### Post-deployment Verification
```bash
# Clear caches
wp cache flush
wp rewrite flush
# Verify pages exist
wp post list --post_type=page --name=dashboard
# Check plugin activation
wp plugin list --name=hvac-community-events
```
## Common Pitfalls to Avoid
### ❌ DON'T
- Create standalone fixes outside plugin deployment
- Use hardcoded database prefixes
- Skip nonce verification
- Echo unsanitized output
- Assume jQuery methods exist without proper setup
- Check capabilities using role names
- Load assets globally
- Use PHP namespaces (WordPress compatibility)
### ✅ DO
- Deploy complete plugin updates
- Use `$wpdb->prefix`
- Always verify nonces
- Escape all output
- Use WordPress jQuery patterns
- Check roles properly with `in_array()`
- Load assets conditionally
- Use prefixed class/function names
## Debugging Tips
### Enable Debug Mode (Development Only)
```php
// wp-config.php
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
define('SCRIPT_DEBUG', true);
```
### Debug Logging
```php
// Log to debug.log
error_log('HVAC Debug: ' . print_r($data, true));
// Conditional logging
if (defined('WP_DEBUG') && WP_DEBUG) {
error_log('HVAC: Processing user ' . $user_id);
}
```
## Resources
- [WordPress Coding Standards](https://developer.wordpress.org/coding-standards/)
- [Plugin Security Best Practices](https://developer.wordpress.org/plugins/security/)
- [WordPress Plugin Handbook](https://developer.wordpress.org/plugins/)
- [Theme Integration Guide](https://developer.wordpress.org/themes/basics/)