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.
120 lines
3.8 KiB
PHP
120 lines
3.8 KiB
PHP
<?php
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
final class EB4TEC_Cron {
|
|
|
|
const HOOK = 'eb4tec_scheduled_sync';
|
|
const SCHEDULE = 'eb4tec_sync';
|
|
|
|
public function __construct( private readonly EB4TEC_Event_Sync $event_sync ) {
|
|
add_filter( 'cron_schedules', [ $this, 'add_cron_interval' ] );
|
|
add_action( self::HOOK, [ $this, 'run_sync' ] );
|
|
add_action( 'admin_post_eb4tec_sync_now', [ $this, 'handle_sync_now' ] );
|
|
add_action( 'admin_notices', [ $this, 'admin_notices' ] );
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Static: called from activation / deactivation hooks and settings save
|
|
// ---------------------------------------------------------------------------
|
|
|
|
public static function schedule(): void {
|
|
if ( ! wp_next_scheduled( self::HOOK ) ) {
|
|
wp_schedule_event( time(), self::SCHEDULE, self::HOOK );
|
|
}
|
|
}
|
|
|
|
public static function unschedule(): void {
|
|
$timestamp = wp_next_scheduled( self::HOOK );
|
|
if ( $timestamp ) {
|
|
wp_unschedule_event( $timestamp, self::HOOK );
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Cron interval
|
|
// ---------------------------------------------------------------------------
|
|
|
|
public function add_cron_interval( array $schedules ): array {
|
|
$interval_key = (string) get_option( 'eb4tec_sync_interval', 'hourly' );
|
|
|
|
// Map WP core interval names to seconds; allow custom 'eb4tec_sync' key too.
|
|
$map = [
|
|
'hourly' => HOUR_IN_SECONDS,
|
|
'twicedaily' => 12 * HOUR_IN_SECONDS,
|
|
'daily' => DAY_IN_SECONDS,
|
|
];
|
|
|
|
$seconds = $map[ $interval_key ] ?? HOUR_IN_SECONDS;
|
|
|
|
$schedules[ self::SCHEDULE ] = [
|
|
'interval' => $seconds,
|
|
'display' => __( 'Eventbrite Sync', 'eb4tec' ),
|
|
];
|
|
|
|
return $schedules;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Sync execution
|
|
// ---------------------------------------------------------------------------
|
|
|
|
public function run_sync(): void {
|
|
$result = $this->event_sync->run_full_sync();
|
|
|
|
set_transient( 'eb4tec_last_sync_result', $result, DAY_IN_SECONDS );
|
|
update_option( 'eb4tec_last_sync_timestamp', time() );
|
|
}
|
|
|
|
public function handle_sync_now(): void {
|
|
if ( ! current_user_can( 'manage_options' ) ) {
|
|
wp_die( esc_html__( 'Insufficient permissions.', 'eb4tec' ) );
|
|
}
|
|
|
|
check_admin_referer( 'eb4tec_sync_now', '_eb4tec_sync_nonce' );
|
|
|
|
$this->run_sync();
|
|
|
|
$user_id = get_current_user_id();
|
|
set_transient( "eb4tec_sync_now_result_{$user_id}", get_transient( 'eb4tec_last_sync_result' ), 60 );
|
|
|
|
$redirect = wp_get_referer() ?: admin_url( 'edit.php?post_type=tribe_events&page=eb4tec-settings' );
|
|
wp_safe_redirect( $redirect );
|
|
exit;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Admin notices (sync result — shown on all admin screens)
|
|
// ---------------------------------------------------------------------------
|
|
|
|
public function admin_notices(): void {
|
|
if ( ! current_user_can( 'manage_options' ) ) {
|
|
return;
|
|
}
|
|
|
|
$screen = get_current_screen();
|
|
// Only show on TEC / EB4TEC admin screens.
|
|
if ( ! $screen || ! str_contains( $screen->id ?? '', 'tribe_events' ) ) {
|
|
return;
|
|
}
|
|
|
|
$user_id = get_current_user_id();
|
|
$sync_result = get_transient( "eb4tec_sync_now_result_{$user_id}" );
|
|
if ( ! is_array( $sync_result ) ) {
|
|
return;
|
|
}
|
|
|
|
delete_transient( "eb4tec_sync_now_result_{$user_id}" );
|
|
|
|
$msg = sprintf(
|
|
__( 'Eventbrite sync complete — %d pulled, %d pushed, %d errors.', 'eb4tec' ),
|
|
(int) ( $sync_result['pulled'] ?? 0 ),
|
|
(int) ( $sync_result['pushed'] ?? 0 ),
|
|
(int) ( $sync_result['errors'] ?? 0 )
|
|
);
|
|
$class = ( ( $sync_result['errors'] ?? 0 ) > 0 ) ? 'notice-warning' : 'notice-success';
|
|
|
|
echo '<div class="notice ' . esc_attr( $class ) . ' is-dismissible"><p>' . esc_html( $msg ) . '</p></div>';
|
|
}
|
|
}
|