Event Tickets for WooCommerce
Get this plugin$69
View PluginIntroduction
Getting Started
Creating Events
Venues & Organizers
Ticket Sales
Attendee Management
Check-in System
Recurring Events
Calendar & Display
PDF Tickets
Email Notifications
Waitlist
Dynamic Pricing
Seating Charts
Speaker Management
Import & Export
Gutenberg Blocks
Shortcodes
REST API
Webhooks
Settings
Developer Guide
FAQ
All Documentation
Developer Guide
Developer Guide
Extend and customize the plugin using hooks, filters, templates, and the API. This guide covers common customization scenarios.
Architecture overview
File structure
event-tickets-for-woocommerce/
├── assets/
│ ├── css/ # Stylesheets
│ └── js/ # JavaScript files
├── includes/
│ ├── admin/ # Admin functionality
│ ├── api/ # REST API endpoints
│ ├── blocks/ # Gutenberg blocks
│ ├── core/ # Core classes
│ ├── emails/ # Email classes
│ ├── export/ # Export functionality
│ ├── frontend/ # Frontend display
│ ├── import/ # Import functionality
│ ├── pdf/ # PDF generation
│ ├── seating/ # Seating charts
│ ├── speakers/ # Speaker management
│ ├── waitlist/ # Waitlist system
│ └── woocommerce/ # WooCommerce integration
├── languages/ # Translation files
└── templates/ # Template files
Class naming
All classes use the EMWC_ prefix:
EMWC_Event- Event modelEMWC_Attendee- Attendee modelEMWC_Admin- Admin functionality
Database tables
Custom tables with wp_emwc_ prefix:
wp_emwc_attendees- Attendee recordswp_emwc_checkins- Check-in historywp_emwc_waitlist- Waitlist entries
Hooks reference
Action hooks
Event Lifecycle
// Event created
do_action( 'emwc_event_created', $event_id, $event_data );
// Event updated
do_action( 'emwc_event_updated', $event_id, $event_data );
// Event deleted
do_action( 'emwc_event_deleted', $event_id );
// Event status changed
do_action( 'emwc_event_status_changed', $event_id, $new_status, $old_status );
Registration
// Registration completed
do_action( 'emwc_registration_completed', $attendee_id, $order_id, $event_id );
// Registration cancelled
do_action( 'emwc_registration_cancelled', $attendee_id, $order_id );
Check-in
// Attendee checked in
do_action( 'emwc_attendee_checked_in', $attendee_id, $event_id );
// Attendee checked out
do_action( 'emwc_attendee_checked_out', $attendee_id, $event_id );
Capacity
// Event sold out
do_action( 'emwc_event_sold_out', $event_id );
// Capacity available
do_action( 'emwc_capacity_available', $event_id, $spots_available );
Waitlist
// Joined waitlist
do_action( 'emwc_waitlist_joined', $waitlist_id, $event_id, $email );
// Promoted from waitlist
do_action( 'emwc_waitlist_promoted', $waitlist_id, $event_id );
Filter hooks
Event Data
// Modify event statuses
add_filter( 'emwc_event_statuses', function( $statuses ) {
$statuses['custom'] = __( 'Custom Status' );
return $statuses;
} );
// Modify event types
add_filter( 'emwc_event_types', function( $types ) {
return $types;
} );
Display
// Calendar event data
add_filter( 'emwc_calendar_event_data', function( $data, $event_id ) {
$data['custom'] = get_post_meta( $event_id, 'custom_field', true );
return $data;
}, 10, 2 );
// Event card output
add_filter( 'emwc_event_card_html', function( $html, $event_id ) {
return $html;
}, 10, 2 );
Tickets
// Ticket code format
add_filter( 'emwc_ticket_code_format', function( $format ) {
return 'TICKET-%s'; // %s is replaced with unique string
} );
// Ticket code length
add_filter( 'emwc_ticket_code_length', function( $length ) {
return 12;
} );
Attendee Fields
// Add custom attendee field
add_filter( 'emwc_attendee_fields', function( $fields ) {
$fields['dietary'] = array(
'label' => 'Dietary Requirements',
'type' => 'select',
'options' => array( 'none', 'vegetarian', 'vegan', 'gluten-free' ),
'required' => false
);
return $fields;
} );
Emails
// Email recipient
add_filter( 'emwc_admin_notification_recipient', function( $email ) {
return 'events@example.com';
} );
// Email subject
add_filter( 'emwc_email_subject', function( $subject, $email_id ) {
return $subject;
}, 10, 2 );
API
// API event response
add_filter( 'emwc_rest_event_response', function( $data, $event ) {
$data['custom_field'] = get_post_meta( $event->ID, 'custom', true );
return $data;
}, 10, 2 );
Template overrides
Override location
Copy templates from:
plugins/event-tickets-for-woocommerce/templates/
To:
your-theme/event-tickets-for-woocommerce/
Available templates
| Template | Purpose |
|---|---|
single-emwc_event.php | Single event page |
archive-emwc_event.php | Event archive |
single-emwc_speaker.php | Single speaker page |
archive-emwc_speaker.php | Speaker archive |
emails/*.php | Email templates |
Scroll to see all columns →
Template functions
// Get event
$event = emwc_get_event( $event_id );
// Get attendees for event
$attendees = emwc_get_event_attendees( $event_id );
// Check if event is sold out
$sold_out = emwc_is_event_sold_out( $event_id );
// Get remaining capacity
$remaining = emwc_get_remaining_capacity( $event_id );
Custom post type integration
Event meta keys
| Key | Description |
|---|---|
_emwc_start_date | Start date (Y-m-d) |
_emwc_end_date | End date |
_emwc_start_time | Start time (H:i) |
_emwc_end_time | End time |
_emwc_all_day | All day event (yes/no) |
_emwc_timezone | Event timezone |
_emwc_event_status | Event status |
_emwc_event_type | Event type |
_emwc_venue_id | Venue post ID |
_emwc_organizer_id | Organizer post ID |
_emwc_capacity | Maximum attendees |
_emwc_virtual_url | Virtual event URL |
_emwc_external_url | External registration URL |
Scroll to see all columns →
Querying events
// Upcoming events
$events = new WP_Query( array(
'post_type' => 'emwc_event',
'meta_key' => '_emwc_start_date',
'orderby' => 'meta_value',
'order' => 'ASC',
'meta_query' => array(
array(
'key' => '_emwc_start_date',
'value' => date( 'Y-m-d' ),
'compare' => '>=',
'type' => 'DATE'
)
)
) );
Database operations
Attendee table
global $wpdb;
$table = $wpdb->prefix . 'emwc_attendees';
// Get attendees for event
$attendees = $wpdb->get_results( $wpdb->prepare(
"SELECT * FROM {$table} WHERE event_id = %d AND status = 'active'",
$event_id
) );
Check-in table
$table = $wpdb->prefix . 'emwc_checkins';
// Log check-in
$wpdb->insert( $table, array(
'attendee_id' => $attendee_id,
'event_id' => $event_id,
'action' => 'check_in',
'checked_by' => get_current_user_id(),
'created_at' => current_time( 'mysql' )
) );
JavaScript integration
Global object
// Available on frontend
window.emwc = {
ajaxUrl: '/wp-admin/admin-ajax.php',
nonce: 'abc123...',
events: [ /* event data */ ]
};
AJAX handlers
// Custom AJAX call
jQuery.post( emwc.ajaxUrl, {
action: 'emwc_custom_action',
nonce: emwc.nonce,
data: { /* your data */ }
}, function( response ) {
console.log( response );
} );
Events
// Listen for check-in
jQuery( document ).on( 'emwc_checked_in', function( e, data ) {
console.log( 'Checked in:', data.attendee );
} );
Creating extensions
Plugin header
<?php
/**
* Plugin Name: EMWC Custom Extension
* Description: Custom functionality for Events Manager
* Version: 1.0.0
* Requires Plugins: event-tickets-for-woocommerce
*/
Dependency check
add_action( 'plugins_loaded', function() {
if ( ! class_exists( 'EMWC' ) ) {
add_action( 'admin_notices', function() {
echo '<div class="error"><p>EMWC Extension requires Event Tickets for WooCommerce.</p></div>';
} );
return;
}
// Initialize extension
} );
Adding admin pages
add_action( 'admin_menu', function() {
add_submenu_page(
'emwc-dashboard',
'Custom Page',
'Custom Page',
'manage_options',
'emwc-custom',
'render_custom_page'
);
} );
Testing
Unit testing
class Test_EMWC_Event extends WP_UnitTestCase {
public function test_event_creation() {
$event_id = wp_insert_post( array(
'post_type' => 'emwc_event',
'post_title' => 'Test Event',
'post_status' => 'publish'
) );
$this->assertNotEmpty( $event_id );
}
}
Debug mode
Enable debug logging:
define( 'EMWC_DEBUG', true );
Logs appear in wp-content/debug.log.
Best practices
Performance
- Cache expensive queries
- Use transients for repeated data
- Lazy load assets
Security
- Sanitize all input
- Escape all output
- Verify nonces
- Check capabilities
Compatibility
- Test with latest WordPress
- Test with latest WooCommerce
- Avoid overriding core functions
- Use hooks instead of modifying files