'; echo '

' . esc_html__( 'Eventbrite Attendees', 'eb4tec' ) . '

'; $this->render_event_selector( $selected_post_id ); if ( ! $selected_post_id ) { echo '

' . esc_html__( 'Select an event above to view its attendees.', 'eb4tec' ) . '

'; echo ''; return; } $eb_event_id = (string) get_post_meta( $selected_post_id, '_eb4tec_event_id', true ); if ( ! $eb_event_id ) { echo '

' . esc_html__( 'This event is not linked to an Eventbrite event.', 'eb4tec' ) . '

'; echo ''; return; } $response = $this->api->get_attendees( $eb_event_id, $page_num ); if ( is_wp_error( $response ) ) { echo '

' . esc_html( $response->get_error_message() ) . '

'; echo ''; return; } $attendees = $response['attendees'] ?? []; $pagination = $response['pagination'] ?? []; $total = (int) ( $pagination['object_count'] ?? 0 ); $page_count = (int) ( $pagination['page_count'] ?? 1 ); // Export button. echo '
'; wp_nonce_field( "eb4tec_export_attendees_{$eb_event_id}", '_eb4tec_export_nonce' ); echo ''; echo ''; echo ''; submit_button( sprintf( __( 'Export All %d Attendees to CSV', 'eb4tec' ), $total ), 'secondary', 'submit', false ); echo '
'; $this->render_attendee_table( $attendees, $selected_post_id ); $this->render_pagination( $page_num, $page_count, $selected_post_id ); echo ''; } private function render_event_selector( int $selected_post_id ): void { $events = get_posts( [ 'post_type' => 'tribe_events', 'post_status' => [ 'publish', 'draft' ], 'posts_per_page' => 200, 'orderby' => 'title', 'order' => 'ASC', 'meta_query' => [ [ 'key' => '_eb4tec_event_id', 'compare' => 'EXISTS', ] ], ] ); $base_url = admin_url( 'edit.php?post_type=tribe_events&page=eb4tec-attendees' ); echo '

'; echo ' '; echo ''; echo '

'; } private function render_attendee_table( array $attendees, int $post_id ): void { if ( empty( $attendees ) ) { echo '

' . esc_html__( 'No attendees found for this event.', 'eb4tec' ) . '

'; return; } // Build a map of EB attendee ID → WC order number from stored order meta. $order_map = $this->build_order_map( $post_id ); echo ''; echo ''; $headers = [ __( 'Name', 'eb4tec' ), __( 'Email', 'eb4tec' ), __( 'WC Order #', 'eb4tec' ), __( 'Ticket Class', 'eb4tec' ), __( 'Status', 'eb4tec' ), __( 'Checked In', 'eb4tec' ), __( 'Registered', 'eb4tec' ), ]; foreach ( $headers as $h ) { echo ''; } echo ''; foreach ( $attendees as $attendee ) { $profile = $attendee['profile'] ?? []; $name = esc_html( $profile['name'] ?? '' ); $email = esc_html( $profile['email'] ?? '' ); $status = esc_html( $attendee['status'] ?? '' ); $checked = ! empty( $attendee['checked_in'] ) ? esc_html__( 'Yes', 'eb4tec' ) : esc_html__( 'No', 'eb4tec' ); $tc_name = esc_html( $attendee['ticket_class'] ['name'] ?? '' ); $created = esc_html( $attendee['created'] ?? '' ); $eb_att_id = $attendee['id'] ?? ''; $order_num = isset( $order_map[ $eb_att_id ] ) ? '#' . $order_map[ $eb_att_id ] : '—'; echo ""; } echo '
' . esc_html( $h ) . '
{$name}{$email}{$order_num}{$tc_name}{$status}{$checked}{$created}
'; } private function render_pagination( int $current, int $total_pages, int $post_id ): void { if ( $total_pages <= 1 ) { return; } $base_url = add_query_arg( 'event_post_id', $post_id, admin_url( 'edit.php?post_type=tribe_events&page=eb4tec-attendees' ) ); echo '
'; for ( $p = 1; $p <= $total_pages; $p++ ) { $url = esc_url( add_query_arg( 'paged', $p, $base_url ) ); $class = ( $p === $current ) ? 'button button-primary' : 'button'; echo "{$p} "; } echo '
'; } // --------------------------------------------------------------------------- // CSV export // --------------------------------------------------------------------------- public function handle_csv_export(): void { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'Insufficient permissions.', 'eb4tec' ) ); } $eb_event_id = sanitize_text_field( $_POST['eb_event_id'] ?? '' ); $post_id = (int) ( $_POST['event_post_id'] ?? 0 ); if ( ! $eb_event_id ) { wp_die( esc_html__( 'No event ID provided.', 'eb4tec' ) ); } check_admin_referer( "eb4tec_export_attendees_{$eb_event_id}", '_eb4tec_export_nonce' ); $order_map = $this->build_order_map( $post_id ); $attendees = $this->fetch_all_attendees( $eb_event_id ); if ( is_wp_error( $attendees ) ) { wp_die( esc_html( $attendees->get_error_message() ) ); } $event_title = $post_id ? sanitize_file_name( get_the_title( $post_id ) ) : $eb_event_id; $filename = "attendees-{$event_title}-" . date( 'Y-m-d' ) . '.csv'; header( 'Content-Type: text/csv; charset=utf-8' ); header( 'Content-Disposition: attachment; filename="' . $filename . '"' ); header( 'Pragma: no-cache' ); header( 'Expires: 0' ); $output = fopen( 'php://output', 'w' ); fputcsv( $output, [ __( 'Name', 'eb4tec' ), __( 'Email', 'eb4tec' ), __( 'Order Number', 'eb4tec' ), __( 'Ticket Class', 'eb4tec' ), __( 'Status', 'eb4tec' ), __( 'Checked In', 'eb4tec' ), __( 'Registration Date', 'eb4tec' ), ] ); foreach ( $attendees as $attendee ) { $profile = $attendee['profile'] ?? []; $eb_att_id = $attendee['id'] ?? ''; $order_num = $order_map[ $eb_att_id ] ?? ''; fputcsv( $output, [ $profile['name'] ?? '', $profile['email'] ?? '', $order_num, $attendee['ticket_class']['name'] ?? '', $attendee['status'] ?? '', ! empty( $attendee['checked_in'] ) ? 'Yes' : 'No', $attendee['created'] ?? '', ] ); } fclose( $output ); exit; } private function fetch_all_attendees( string $eb_event_id ): array|WP_Error { $page = 1; $attendees = []; do { $response = $this->api->get_attendees( $eb_event_id, $page ); if ( is_wp_error( $response ) ) { return $response; } $attendees = array_merge( $attendees, $response['attendees'] ?? [] ); $has_more = ! empty( $response['pagination']['has_more_items'] ); $page++; } while ( $has_more ); return $attendees; } /** * Build a map of Eventbrite attendee ID → WooCommerce order number. * Searches orders that have this event's post ID stored in meta. */ private function build_order_map( int $post_id ): array { if ( ! $post_id ) { return []; } $orders = wc_get_orders( [ 'meta_key' => '_eb4tec_event_post_id', 'meta_value' => $post_id, 'limit' => -1, 'return' => 'ids', ] ); $map = []; foreach ( $orders as $order_id ) { $attendee_ids = json_decode( get_post_meta( $order_id, '_eb4tec_attendee_ids', true ) ?: '[]', true ); foreach ( $attendee_ids as $att_id ) { $map[ $att_id ] = $order_id; } } return $map; } }