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.
125 lines
3.8 KiB
PHP
125 lines
3.8 KiB
PHP
<?php
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
final class EB4TEC_Venue_Sync {
|
|
|
|
public function __construct( private readonly EB4TEC_API_Client $api ) {}
|
|
|
|
public function pull_venue( string $eb_venue_id ): int|WP_Error {
|
|
if ( empty( $eb_venue_id ) ) {
|
|
return 0;
|
|
}
|
|
|
|
$result = $this->api->get_venue( $eb_venue_id );
|
|
if ( is_wp_error( $result ) ) {
|
|
return $result;
|
|
}
|
|
|
|
$existing_id = $this->find_tec_venue( $eb_venue_id );
|
|
|
|
$name = sanitize_text_field( $result['name'] ?? '' );
|
|
$address = $result['address'] ?? [];
|
|
|
|
$post_args = [
|
|
'post_title' => $name ?: __( 'Untitled Venue', 'eb4tec' ),
|
|
'post_type' => 'tribe_venue',
|
|
'post_status' => 'publish',
|
|
];
|
|
|
|
if ( $existing_id ) {
|
|
$post_args['ID'] = $existing_id;
|
|
$post_id = wp_update_post( $post_args, true );
|
|
} else {
|
|
$post_id = wp_insert_post( $post_args, true );
|
|
}
|
|
|
|
if ( is_wp_error( $post_id ) ) {
|
|
return $post_id;
|
|
}
|
|
|
|
$this->save_venue_meta( $post_id, $eb_venue_id, $address, $result );
|
|
|
|
return $post_id;
|
|
}
|
|
|
|
public function push_venue( int $post_id ): string|WP_Error {
|
|
$org_id = (string) get_option( 'eb4tec_org_id', '' );
|
|
if ( empty( $org_id ) ) {
|
|
return new WP_Error( 'eb4tec_no_org', __( 'Eventbrite organization ID not configured.', 'eb4tec' ) );
|
|
}
|
|
|
|
$eb_venue_id = get_post_meta( $post_id, '_eb4tec_venue_id', true );
|
|
$post = get_post( $post_id );
|
|
|
|
if ( ! $post ) {
|
|
return new WP_Error( 'eb4tec_no_post', __( 'Venue post not found.', 'eb4tec' ) );
|
|
}
|
|
|
|
$body = [
|
|
'venue' => [
|
|
'name' => $post->post_title,
|
|
'address' => [
|
|
'address_1' => (string) get_post_meta( $post_id, '_VenueAddress', true ),
|
|
'city' => (string) get_post_meta( $post_id, '_VenueCity', true ),
|
|
'region' => (string) get_post_meta( $post_id, '_VenueStateProvince', true ),
|
|
'postal_code' => (string) get_post_meta( $post_id, '_VenueZip', true ),
|
|
'country' => (string) get_post_meta( $post_id, '_VenueCountry', true ),
|
|
],
|
|
],
|
|
];
|
|
|
|
if ( $eb_venue_id ) {
|
|
$result = $this->api->update_venue( $eb_venue_id, $body );
|
|
} else {
|
|
$result = $this->api->create_venue( $org_id, $body );
|
|
}
|
|
|
|
if ( is_wp_error( $result ) ) {
|
|
return $result;
|
|
}
|
|
|
|
$new_id = $result['id'] ?? '';
|
|
if ( $new_id ) {
|
|
update_post_meta( $post_id, '_eb4tec_venue_id', sanitize_text_field( $new_id ) );
|
|
}
|
|
|
|
return $new_id ?: new WP_Error( 'eb4tec_no_venue_id', __( 'Eventbrite did not return a venue ID.', 'eb4tec' ) );
|
|
}
|
|
|
|
public function find_tec_venue( string $eb_venue_id ): int {
|
|
$query = new WP_Query( [
|
|
'post_type' => 'tribe_venue',
|
|
'post_status' => 'publish',
|
|
'posts_per_page' => 1,
|
|
'fields' => 'ids',
|
|
'meta_query' => [ [
|
|
'key' => '_eb4tec_venue_id',
|
|
'value' => $eb_venue_id,
|
|
] ],
|
|
] );
|
|
|
|
return $query->posts[0] ?? 0;
|
|
}
|
|
|
|
private function save_venue_meta( int $post_id, string $eb_venue_id, array $address, array $result ): void {
|
|
update_post_meta( $post_id, '_eb4tec_venue_id', sanitize_text_field( $eb_venue_id ) );
|
|
update_post_meta( $post_id, '_eb4tec_venue_last_synced', time() );
|
|
|
|
update_post_meta( $post_id, '_VenueAddress', sanitize_text_field( $address['address_1'] ?? '' ) );
|
|
update_post_meta( $post_id, '_VenueCity', sanitize_text_field( $address['city'] ?? '' ) );
|
|
update_post_meta( $post_id, '_VenueStateProvince', sanitize_text_field( $address['region'] ?? '' ) );
|
|
update_post_meta( $post_id, '_VenueZip', sanitize_text_field( $address['postal_code'] ?? '' ) );
|
|
update_post_meta( $post_id, '_VenueCountry', sanitize_text_field( $address['country'] ?? '' ) );
|
|
|
|
$lat = $address['latitude'] ?? '';
|
|
$lng = $address['longitude'] ?? '';
|
|
if ( $lat ) {
|
|
update_post_meta( $post_id, '_VenueGeoLat', sanitize_text_field( $lat ) );
|
|
}
|
|
if ( $lng ) {
|
|
update_post_meta( $post_id, '_VenueGeoLng', sanitize_text_field( $lng ) );
|
|
}
|
|
}
|
|
}
|