eventbrite-for-the-events-c.../includes/class-eb4tec-shortcodes.php
Laurence Horrocks-Barlow f3bc795d9a Initial release of Eventbrite for The Events Calendar (v1.0.0)
Bidirectional sync between Eventbrite and The Events Calendar, with
WooCommerce ticket purchasing that bypasses Eventbrite's processing
fees by registering buyers as free attendees via API. Includes venue/
organizer sync, QR code ticket generation, attendee management with
CSV export, scheduled sync via WP-Cron, and real-time Eventbrite
webhooks.
2026-05-17 08:48:04 +01:00

162 lines
4.6 KiB
PHP

<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
final class EB4TEC_Shortcodes {
public function __construct(
private readonly EB4TEC_API_Client $api,
private readonly EB4TEC_Ticket_Manager $ticket_manager,
) {
add_action( 'init', [ $this, 'register_shortcodes' ] );
}
public function register_shortcodes(): void {
add_shortcode( 'eb4tec_capacity', [ $this, 'capacity_shortcode' ] );
add_shortcode( 'eb4tec_tickets', [ $this, 'tickets_shortcode' ] );
}
/**
* [eb4tec_capacity event_id="123" post_id="456"]
* Renders remaining ticket capacity for an event.
*/
public function capacity_shortcode( array $atts ): string {
$post_id = $this->resolve_post_id( $atts );
if ( ! $post_id ) {
return '';
}
$total = (int) get_post_meta( $post_id, '_eb4tec_capacity', true );
$available = $this->ticket_manager->get_available_capacity( $post_id );
if ( $total <= 0 ) {
return '';
}
if ( $available <= 0 ) {
return '<span class="eb4tec-capacity eb4tec-capacity--sold-out">' .
esc_html__( 'Sold out', 'eb4tec' ) .
'</span>';
}
return sprintf(
'<span class="eb4tec-capacity">%s</span>',
esc_html( sprintf(
/* translators: 1: available spots, 2: total capacity */
_n( '%1$d of %2$d spot remaining', '%1$d of %2$d spots remaining', $available, 'eb4tec' ),
$available,
$total
) )
);
}
/**
* [eb4tec_tickets event_id="123" post_id="456"]
* Renders a list of public Eventbrite ticket classes with a Buy button.
*/
public function tickets_shortcode( array $atts ): string {
$post_id = $this->resolve_post_id( $atts );
if ( ! $post_id ) {
return '';
}
$eb_event_id = (string) get_post_meta( $post_id, '_eb4tec_event_id', true );
if ( ! $eb_event_id ) {
return '';
}
$result = $this->api->get_ticket_classes( $eb_event_id );
if ( is_wp_error( $result ) ) {
return '';
}
$ticket_classes = $result['ticket_classes'] ?? [];
$wp_label = strtolower( (string) get_option( 'eb4tec_wp_ticket_label', 'WordPress Purchase' ) );
$product_id = (int) get_post_meta( $post_id, '_eb4tec_wp_product_id', true );
$buy_url = $product_id ? get_permalink( $product_id ) : '';
// Filter out the hidden WordPress Purchase class.
$public_classes = array_filter( $ticket_classes, function( array $tc ) use ( $wp_label ): bool {
return strtolower( $tc['name'] ?? '' ) !== $wp_label;
} );
if ( empty( $public_classes ) ) {
return '';
}
$output = '<ul class="eb4tec-ticket-classes">';
foreach ( $public_classes as $tc ) {
$name = esc_html( $tc['name'] ?? '' );
$description = esc_html( $tc['description'] ?? '' );
$free = ! empty( $tc['free'] );
$price = $free ? esc_html__( 'Free', 'eb4tec' ) : esc_html( $tc['cost']['display'] ?? '' );
$sold_out = ! empty( $tc['sold_out'] );
$hidden = ! empty( $tc['hidden'] );
if ( $hidden ) {
continue;
}
$output .= '<li class="eb4tec-ticket-class">';
$output .= '<strong class="eb4tec-ticket-name">' . $name . '</strong>';
if ( $description ) {
$output .= ' <span class="eb4tec-ticket-description">' . $description . '</span>';
}
$output .= ' <span class="eb4tec-ticket-price">' . $price . '</span>';
if ( $sold_out ) {
$output .= ' <span class="eb4tec-ticket-sold-out">' . esc_html__( 'Sold out', 'eb4tec' ) . '</span>';
}
$output .= '</li>';
}
$output .= '</ul>';
// Add Buy Tickets button if a WC product exists.
if ( $buy_url ) {
$available = $this->ticket_manager->get_available_capacity( $post_id );
if ( $available > 0 ) {
$output .= sprintf(
'<a href="%s" class="button eb4tec-buy-button">%s</a>',
esc_url( $buy_url ),
esc_html__( 'Buy Tickets', 'eb4tec' )
);
} else {
$output .= '<span class="eb4tec-sold-out-badge">' . esc_html__( 'Sold Out', 'eb4tec' ) . '</span>';
}
}
return $output;
}
private function resolve_post_id( array $atts ): int {
$atts = shortcode_atts( [
'post_id' => 0,
'event_id' => '',
], $atts );
if ( ! empty( $atts['post_id'] ) ) {
return (int) $atts['post_id'];
}
if ( ! empty( $atts['event_id'] ) ) {
// Look up TEC post by Eventbrite event ID.
$query = new WP_Query( [
'post_type' => 'tribe_events',
'post_status' => [ 'publish', 'draft' ],
'posts_per_page' => 1,
'fields' => 'ids',
'meta_query' => [ [
'key' => '_eb4tec_event_id',
'value' => sanitize_text_field( $atts['event_id'] ),
] ],
] );
return $query->posts[0] ?? 0;
}
// Default to the current event in the loop.
return get_the_ID() ?: 0;
}
}