[],'promo'=>'','pending'=>0]; $raw = sanitize_text_field(wp_unslash($_COOKIE['ticketdrum_basket'] ?? '')); if ($raw!='' && strpos($raw,'.')!==false) { list($payload,$sig) = explode('.',$raw,2); if (hash_equals(substr(hash_hmac('sha256',$payload,wp_salt('auth')),0,20),$sig)) { $data = json_decode(base64_decode($payload),true); if (is_array($data)) { foreach (($data['tickets'] ?? []) as $tid=>$qty) if ((int)$tid>0 && (int)$qty>0) $basket['tickets'][(int)$tid] = min(100,(int)$qty); $basket['promo'] = substr(preg_replace('/[^A-Z0-9\-_]/','',strtoupper($data['promo'] ?? '')),0,50); $basket['pending'] = (int)($data['pending'] ?? 0); } } } return $basket; } function ticketdrum_basket_save($basket) { global $ticketdrum_basket; $ticketdrum_basket = $basket; if (headers_sent()) return; //Read-only contexts must not try to persist $payload = base64_encode(wp_json_encode($basket)); $sig = substr(hash_hmac('sha256',$payload,wp_salt('auth')),0,20); setcookie('ticketdrum_basket',$payload.'.'.$sig,[ 'expires' => time()+172800, 'path' => '/', 'secure' => is_ssl(), 'httponly' => true, 'samesite' => 'Lax', ]); $_COOKIE['ticketdrum_basket'] = $payload.'.'.$sig; } //Customisable interface labels: option name is ticketdrum_label_{key}; missing option = default function ticketdrum_labels() { return [ 'view_tickets' => [__('View available tickets button','ticketdrum'),__('View Tickets','ticketdrum')], 'ticket_type' => [__('Ticket table header','ticketdrum'),__('Ticket Type','ticketdrum')], 'checkout_button' => [__('Proceed to checkout button','ticketdrum'),__('Proceed to Checkout >','ticketdrum')], 'sold_out' => [__('Sold out message','ticketdrum'),__('Sold Out','ticketdrum')], 'booking_fee' => [__('Booking fee line at checkout','ticketdrum'),__('Booking fee','ticketdrum')], 'order_thanks' => [__('Order complete message','ticketdrum'),__('Thank you, your order has been received and you have been sent a confirmation email.','ticketdrum')], 'waitlist_intro' => [__('Waitlist invitation','ticketdrum'),__('Join the waitlist and we\'ll email you if tickets become available:','ticketdrum')], 'waitlist_button' => [__('Join waitlist button','ticketdrum'),__('Join waitlist','ticketdrum')], ]; } function ticketdrum_label($key) { $labels = ticketdrum_labels(); $saved = trim((string)get_option('ticketdrum_label_'.$key,'')); return $saved!=''?$saved:$labels[$key][1]; } function ticketdrum_currency_sign() { if (get_option('ticketdrum_currency','usd')=='usd') return '$'; elseif (get_option('ticketdrum_currency','usd')=='eur') return '€'; elseif (get_option('ticketdrum_currency','usd')=='gbp') return '£'; return ''; } function ticketdrum_currency_format($amount) { return ticketdrum_currency_sign().number_format($amount,2); } function ticketdrum_datetime_format($datetime,$length='default') { if ($length=='block') return ''.gmdate("j",strtotime($datetime)).' '.gmdate("M",strtotime($datetime)).''.gmdate("Y",strtotime($datetime)).''; else $format = "D jS M Y H:i"; return gmdate($format,strtotime($datetime)); } function ticketdrum_calculate_spaces_taken($event_id) { global $wpdb; $spaces_taken = 0; $purchases = $wpdb->get_results($wpdb->prepare("SELECT ticket_data FROM %i WHERE event_ids LIKE %s",TICKETDRUM_PURCHASES_TABLE,'%,'.$wpdb->esc_like((string)(int)$event_id).',%')); $event_tickets = $wpdb->get_results($wpdb->prepare("SELECT * FROM %i WHERE event_id=%d",TICKETDRUM_TICKETS_TABLE,$event_id)); foreach ($purchases as $purchase) { $ticket_data = json_decode($purchase->ticket_data,true); foreach ($ticket_data['tickets'] as $ticket) { if ($ticket['quantity']==0) continue; foreach ($event_tickets as $event_ticket) if ($event_ticket->id == $ticket['id']) $spaces_taken+= $event_ticket->attendee_count*$ticket['quantity']; } } return (int)$spaces_taken; } function ticketdrum_calculate_basket_totals() { global $wpdb,$ticketdrum_basket; $tickets = []; $tickets_description = ''; $subtotal = $tax = $total = 0; $event_ids = []; $ticket_ids = []; $events = []; $default_tax_rate = get_option('ticketdrum_tax_rate'); $tax_mode = get_option('ticketdrum_tax_mode'); foreach ($ticketdrum_basket['tickets'] as $ticket_id=>$quantity) { $ticket_details = $wpdb->get_row($wpdb->prepare("SELECT t.id,t.event_id,t.title,t.price,t.attendee_count,t.max_purchase_quantity,t.tax,t.custom_fields,e.custom_fields event_custom_fields FROM %i t LEFT JOIN %i e ON e.id=t.event_id WHERE t.active=1 AND t.id=%d",TICKETDRUM_TICKETS_TABLE,TICKETDRUM_EVENTS_TABLE,$ticket_id),ARRAY_A ); $event_details = $wpdb->get_row($wpdb->prepare("SELECT * from %i where id=%d",TICKETDRUM_EVENTS_TABLE,$ticket_details['event_id']),ARRAY_A); $ticket_tax_rate = (isset($ticket_details['tax']) && is_numeric($ticket_details['tax']))?$ticket_details['tax']:$default_tax_rate; $ticket_tax = 0; if ($tax_mode=='included') $ticket_tax = round($ticket_details['price'] - ($ticket_details['price']/(1+$ticket_tax_rate/100)),2); elseif ($tax_mode=='excluded') $ticket_tax = round($ticket_details['price'] * ($ticket_tax_rate/100),2); $tickets[] = [ 'id' => $ticket_details['id'], 'event_id' => $ticket_details['event_id'], 'title' => $ticket_details['title'], 'price' => $ticket_details['price'], 'tax' => $ticket_tax, 'attendee_count' => $ticket_details['attendee_count'], 'custom_fields' => (array)json_decode($ticket_details['custom_fields'],true), //'event_custom_fields' => (array)json_decode($ticket_details['event_custom_fields'],true), 'price_formatted' => number_format($ticket_details['price'],2), 'quantity' => $quantity, 'max_purchase_quantity' => $ticket_details['max_purchase_quantity'], 'line_total' => $ticket_details['price']*$quantity, /* translators: 1: quantity, 2: ticket type name, 3: unit price, e.g. "2x Adult @£5.00" */ 'description' => $quantity>0?sprintf(__('%1$sx %2$s @%3$s','ticketdrum'),$quantity,$ticket_details['title'],ticketdrum_currency_format($ticket_details['price'])):'', ]; $events[$event_details['id']] = [ 'title' => $event_details['title'], 'custom_fields' => (array)json_decode($ticket_details['event_custom_fields'],true), ]; $subtotal+= $quantity*$ticket_details['price']; $tax+= $quantity*$ticket_tax; if ($quantity>0) { $event_ids[] = $ticket_details['event_id']; $ticket_ids[] = $ticket_details['id']; } } foreach ($tickets as $ticket) if ($ticket['description']!='') $tickets_description.=$ticket['description'].", "; $tickets_description = trim($tickets_description,', '); $subtotal = round($subtotal,2); $total = $subtotal; if ($tax_mode=='excluded') $total = $subtotal + $tax; //Promo code discount (validated again here so expiry/limits always hold) $discount = 0; $promo_code = ''; if (($ticketdrum_basket['promo'] ?? '')!='') { $promo_check = ticketdrum_promocode_validate($ticketdrum_basket['promo'],array_unique($event_ids)); if ($promo_check['result']) { $promo = $promo_check['promo']; $promo_code = $promo['code']; //Event-specific codes only discount that event's lines $applicable_total = 0; foreach ($tickets as $t) if ($promo['event_id']==0 || (int)$t['event_id']==(int)$promo['event_id']) $applicable_total+= $t['line_total'] + ($tax_mode=='excluded'?$t['tax']*$t['quantity']:0); if ($promo['type']=='percent') $discount = round($applicable_total*($promo['amount']/100),2); else $discount = min($applicable_total,(float)$promo['amount']); $discount = min($discount,$total); $total = round($total-$discount,2); } } return [ 'discount' => $discount, 'discount_formatted' => ticketdrum_currency_format($discount), 'promo_code' => $promo_code, 'tickets' => $tickets, 'events' => $events, 'tickets_description' => $tickets_description, 'subtotal' => $subtotal, 'subtotal_formatted' => ticketdrum_currency_sign().number_format($subtotal,2), 'tax' => $tax, 'tax_formatted' => ticketdrum_currency_sign().number_format($tax,2), 'total' => $total, 'total_formatted' => ticketdrum_currency_sign().number_format($total,2), 'event_ids' => array_unique($event_ids), 'ticket_ids' => array_unique($ticket_ids), ]; } function ticketdrum_check_ticket_availability($ticket_id,$quantity_wanted) { global $wpdb; $max_available = (int)$wpdb->get_var($wpdb->prepare("SELECT max_available FROM %i WHERE id=%d",TICKETDRUM_TICKETS_TABLE,$ticket_id)); if ($max_available<=0) //0 = unlimited return ['result'=>true,'remaining'=>-1]; //Pending purchases count as holds so two buyers can't both take the last tickets global $ticketdrum_basket; $exclude_purchase_id = (int)($ticketdrum_basket['pending'] ?? 0); $sold = 0; $purchases = $wpdb->get_results($wpdb->prepare("SELECT id,ticket_data FROM %i WHERE ticket_ids LIKE %s AND status IN ('pending','paid') AND id!=%d",TICKETDRUM_PURCHASES_TABLE,'%,'.$wpdb->esc_like((string)(int)$ticket_id).',%',$exclude_purchase_id)); foreach ($purchases as $purchase) { $ticket_data = json_decode($purchase->ticket_data,true); if (!isset($ticket_data['tickets'])) continue; foreach ($ticket_data['tickets'] as $ticket) if ((int)$ticket['id']==(int)$ticket_id) $sold+= (int)$ticket['quantity']; } $remaining = max(0,$max_available-$sold); return ['result'=>($remaining>=$quantity_wanted),'remaining'=>$remaining]; } function ticketdrum_fee_config() { global $ticketdrum_payment_data; //Rates come from the TicketDrum API (per-site, remotely tunable); fall back to published pricing return [ 'fee_percent' => isset($ticketdrum_payment_data['fee_percent'])?(float)$ticketdrum_payment_data['fee_percent']:4.90, 'fee_fixed' => isset($ticketdrum_payment_data['fee_fixed'])?(float)$ticketdrum_payment_data['fee_fixed']:0.30, 'stripe_percent' => isset($ticketdrum_payment_data['stripe_percent'])?(float)$ticketdrum_payment_data['stripe_percent']:1.50, 'stripe_fixed' => isset($ticketdrum_payment_data['stripe_fixed'])?(float)$ticketdrum_payment_data['stripe_fixed']:0.20, 'paid_by' => get_option('ticketdrum_fee_paid_by','buyer')=='organiser'?'organiser':'buyer', ]; } function ticketdrum_calculate_fees($basket_data) { $config = ticketdrum_fee_config(); $paid_ticket_count = 0; foreach ($basket_data['tickets'] as $ticket) if ($ticket['price']>0) $paid_ticket_count+= (int)$ticket['quantity']; //Advertised all-in fee: fee_percent% of the basket + fee_fixed per paid ticket. Free tickets are free. $fee = 0; if ($basket_data['total']>0) $fee = round($basket_data['total']*($config['fee_percent']/100) + $paid_ticket_count*$config['fee_fixed'],2); $charge_total = $basket_data['total']; if ($config['paid_by']=='buyer') $charge_total = round($basket_data['total'] + $fee,2); //This is a direct charge, so Stripe bills its processing fee to the organiser's account. Net our //application fee down by Stripe's standard rate so the organiser's all-in cost equals the advertised fee. $stripe_cost = round($charge_total*($config['stripe_percent']/100) + $config['stripe_fixed'],2); $application_fee = max(0,round($fee - $stripe_cost,2)); return [ 'fee' => $fee, 'fee_formatted' => ticketdrum_currency_format($fee), 'fee_paid_by' => $config['paid_by'], 'paid_ticket_count' => $paid_ticket_count, 'charge_total' => $charge_total, 'charge_total_formatted' => ticketdrum_currency_format($charge_total), 'application_fee_cents' => (int)round($application_fee*100), ]; } //All plugin email is sent by WordPress itself, exactly like any other plugin's email. Nothing //about a buyer, an order or a ticket is ever sent to ticketdrum.com. Sites that need better //deliverability than their host's default mail can install any SMTP plugin: wp_mail honours it //automatically, with no configuration here. function ticketdrum_mail($to_email,$to_name,$subject,$html,$attachment_paths=[]) { return wp_mail($to_email,$subject,$html,['Content-Type: text/html; charset=UTF-8'],$attachment_paths); } function ticketdrum_send_purchase_emails($purchase_id) { global $wpdb; $purchase_data = $wpdb->get_row($wpdb->prepare("SELECT * FROM %i WHERE id=%d LIMIT 1",TICKETDRUM_PURCHASES_TABLE,$purchase_id),ARRAY_A); $purchase_data['ticket_data'] = json_decode($purchase_data['ticket_data'],true); $purchase_data['custom_fields'] = json_decode($purchase_data['custom_fields'],true); $purchase_data['event_custom_fields'] = []; foreach ($purchase_data['custom_fields'] as $custom_field_key=>$custom_field_value) if (strpos($custom_field_key,'event')===0) { $event_details = $wpdb->get_row($wpdb->prepare("SELECT id,title FROM %i WHERE id=%d",TICKETDRUM_EVENTS_TABLE,(int)str_replace('event','',$custom_field_key)),ARRAY_A ); $purchase_data['event_custom_fields'][] = [ 'title' => stripslashes($event_details['title']), 'fields' => stripslashes($custom_field_value) ]; } //Fetch event-level notification emails $event_notification_emails = []; foreach ($purchase_data['ticket_data']['tickets'] as $ticket) { if (!$ticket['quantity']) continue; $event_data = $wpdb->get_row($wpdb->prepare("SELECT notification_emails FROM %i WHERE id=%d LIMIT 1",TICKETDRUM_EVENTS_TABLE,$ticket['event_id']),ARRAY_A); $event_notification_emails = array_merge($event_notification_emails,explode(',',$event_data['notification_emails'])); } $event_notification_emails = array_unique($event_notification_emails); $event_notification_emails = array_map('trim', $event_notification_emails); $order_details = '

'.esc_html__('Name:','ticketdrum').' '.stripslashes($purchase_data['name']).'
'.esc_html__('Email:','ticketdrum').' '.$purchase_data['email'].'
'; if (isset($purchase_data['custom_fields']['checkout'])) foreach ($purchase_data['custom_fields']['checkout'] as $title=>$value) $order_details.= ''.stripslashes($title).': '.stripslashes($value).'
'; $order_details.= '

'; foreach ($purchase_data['ticket_data']['tickets'] as $ticket) { if (!$ticket['quantity']) continue; $event_details = $wpdb->get_row($wpdb->prepare("SELECT id,title FROM %i WHERE id=%d",TICKETDRUM_EVENTS_TABLE,$ticket['event_id']),ARRAY_A ); $ticket_details = $wpdb->get_row($wpdb->prepare("SELECT price FROM %i WHERE id=%d LIMIT 1",TICKETDRUM_TICKETS_TABLE,$ticket['id']),ARRAY_A); $order_details.=''; } if (count($purchase_data['event_custom_fields'] ?? [])>0) { $order_details.=''; } $order_details.= ''. //Show the booking fee only when the buyer paid it (total exceeds subtotal+tax) (($purchase_data['fee']>0 && round($purchase_data['total'],2) > round($purchase_data['subtotal']+$purchase_data['tax'],2))?'':'').'
'.esc_html__('Quantity','ticketdrum').''.esc_html__('Total','ticketdrum').'
'.stripslashes($event_details['title'] ?? '').'
'.stripslashes($ticket['title']); //Per-ticket custom fields are only present when the ticket type defines them $ticket_custom_field_sets = $purchase_data['custom_fields']['ticket'.$ticket['id']] ?? []; if (!is_array($ticket_custom_field_sets)) $ticket_custom_field_sets = []; foreach ($ticket_custom_field_sets as $ticket_custom_field_index=>$ticket_custom_fields) { if (!is_array($ticket_custom_fields)) continue; /* translators: %s: ticket number within the order */ $order_details.='

'.esc_html(sprintf(__('Ticket %s','ticketdrum'),number_format_i18n($ticket_custom_field_index+1))).''; foreach ($ticket_custom_fields as $title=>$value) $order_details.='
'.stripslashes($title).': '.stripslashes($value); $order_details.='

'; } $ticket_total = $ticket['quantity'] * (float)($ticket_details['price'] ?? 0); $order_details.='
'.$ticket['quantity'].' '.ticketdrum_currency_format($ticket_total).'
'; foreach ($purchase_data['event_custom_fields'] as $event_custom_field) { $order_details.='

'.stripslashes($event_custom_field['title']).''; foreach ($event_custom_field['fields'] as $title=>$value) $order_details.='
'.stripslashes($title).': '.stripslashes($value); $order_details.='

'; } $order_details.='
'.esc_html__('Subtotal','ticketdrum').''.ticketdrum_currency_format($purchase_data['subtotal']).'
'.get_option('ticketdrum_tax_title',__('Tax','ticketdrum')).''.ticketdrum_currency_format($purchase_data['tax']).'
'.esc_html__('Booking fee','ticketdrum').''.ticketdrum_currency_format($purchase_data['fee']).'
'.esc_html__('Total','ticketdrum').''.ticketdrum_currency_format($purchase_data['total']).'
'; $email_data_array = []; $ticketdrum_custom_formdata = stripslashes(get_option('ticketdrum_custom_formdata','')); if ($ticketdrum_custom_formdata!='' && json_decode($ticketdrum_custom_formdata,true)) { $custom_formdata = (array)json_decode($ticketdrum_custom_formdata,true); foreach ($custom_formdata as $cfd) { $cfd_clean = trim($cfd['clean']); if ($cfd_clean!='') $email_data_array[$cfd_clean] = $purchase_data['custom_fields']['checkout'][htmlentities(stripslashes($cfd['title']),ENT_QUOTES)]; } } $data_array = (array)$email_data_array; $data_array['purchase_id'] = sprintf('%04d', $purchase_id); $data_array['order_details'] = $order_details; $data_array['name'] = stripslashes($purchase_data['name']); $data_array['subtotal'] = ticketdrum_currency_format($purchase_data['subtotal']); $data_array['tax'] = ticketdrum_currency_format($purchase_data['tax']); $data_array['total'] = ticketdrum_currency_format($purchase_data['total']); /* translators: %s: site name */ $subject = sprintf(__('Order confirmation from %s','ticketdrum'),get_bloginfo()); $emailconfirmation_user = get_option('ticketdrum_emailconfirmation_user'); $emailconfirmation_admin = get_option('ticketdrum_emailconfirmation_admin'); foreach ($data_array as $k=>$v) { $emailconfirmation_user = str_replace('{$'.$k.'}', $v, $emailconfirmation_user); $emailconfirmation_admin = str_replace('{$'.$k.'}', $v, $emailconfirmation_admin); } //Attach the QR tickets PDF + calendar file, link to tickets/receipt/calendar/wallet $attachments = []; $tickets_pdf = ticketdrum_generate_tickets_pdf($purchase_id); if ($tickets_pdf) $attachments[] = $tickets_pdf; $ics_file = ticketdrum_generate_ics($purchase_id); if ($ics_file) $attachments[] = $ics_file; $purchase_token = ticketdrum_purchase_token($purchase_data); $emailconfirmation_user.= '

'.sprintf( /* translators: 1: tickets page URL, 2: receipt page URL */ __('Your tickets are attached to this email as a PDF. You can also view and print your tickets or view your receipt at any time.','ticketdrum'), esc_url(home_url('/?ticketdrum_tickets='.$purchase_token)),esc_url(home_url('/?ticketdrum_invoice='.$purchase_token))).'

'; //Add-to-calendar link for the first event on the order $first_event_id = 0; foreach ($purchase_data['ticket_data']['tickets'] as $t) if ($t['quantity'] && !$first_event_id) $first_event_id = (int)$t['event_id']; if ($first_event_id) { $cal_event = $wpdb->get_row($wpdb->prepare("SELECT * FROM %i WHERE id=%d",TICKETDRUM_EVENTS_TABLE,$first_event_id),ARRAY_A); if ($cal_event && strtotime($cal_event['start_datetime'])>0) /* translators: %s: Google Calendar link URL */ $emailconfirmation_user.= '

'.sprintf(__('Add to Google Calendar · a calendar file (.ics) is attached for Apple/Outlook.','ticketdrum'),esc_url(ticketdrum_google_calendar_link($cal_event))).'

'; } //Apple Wallet buttons (only when pass signing is configured) if (function_exists('ticketdrum_wallet_available') && ticketdrum_wallet_available()) { $wallet_purchase = $wpdb->get_row($wpdb->prepare("SELECT * FROM %i WHERE id=%d",TICKETDRUM_PURCHASES_TABLE,$purchase_id),ARRAY_A); $wallet_token = ticketdrum_purchase_token($wallet_purchase); $wallet_links = []; foreach (ticketdrum_build_ticket_units($wallet_purchase) as $wu) $wallet_links[] = ''.esc_html($wu['ticket_title']).''; if (count($wallet_links)>0) /* translators: %s: list of links, one per ticket */ $emailconfirmation_user.= '

'.sprintf(__('Add to Apple Wallet: %s','ticketdrum'),implode(' · ',$wallet_links)).'

'; } //Marketing footer: every buyer email is a chance to reach an event organiser $emailconfirmation_user.='

'.sprintf( /* translators: %s: link to the TicketDrum website */ __('Ticket management by %s','ticketdrum'),'TicketDrum').'

'; $emailconfirmation_user = ticketdrum_neaten_email_html($emailconfirmation_user); //Blank entries are easy to leave behind in a comma-separated settings field, and each one //would otherwise cost a wasted wp_mail call to nobody $notification_emails = explode(',',get_option('ticketdrum_emailconfirmation_emails',get_bloginfo('admin_email'))); $notification_emails = array_merge($notification_emails,$event_notification_emails); $notification_emails = array_map('trim', $notification_emails); $notification_emails = array_unique(array_filter($notification_emails,'is_email')); foreach ($notification_emails as $notification_email) ticketdrum_mail($notification_email,'',$subject,$emailconfirmation_admin); $send_result = ticketdrum_mail($purchase_data['email'],stripslashes($purchase_data['name']),$subject,$emailconfirmation_user,$attachments); foreach ($attachments as $attachment) @wp_delete_file($attachment); } function ticketdrum_display_custom_fields($custom_fields,$custom_field_group='custom',$custom_field_index=false) { foreach ($custom_fields AS $formkey=>$formfield) { $title_display = str_replace('{counter}',$custom_field_index+1,$formfield['title']); $title_display = str_replace('{counter_word}',ticketdrum_number_to_ordinal_word($custom_field_index+1),$title_display); echo '
'.esc_html($title_display).($formfield['required']?' *':'').($formfield['characterlimit']?' '.esc_html(sprintf( /* translators: %s: maximum number of characters */ _n('(maximum %s character)','(maximum %s characters)',(int)$formfield['characterlimit'],'ticketdrum'),number_format_i18n((int)$formfield['characterlimit']))):'').'
'; if ($formfield['type']=='text') echo ''; elseif ($formfield['type']=='textarea') // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- all dynamic parts esc_attr/esc_textarea/int-cast inline echo ''; elseif ($formfield['type']=='select') { echo ''; } echo '
'; } } function ticketdrum_waitlist_form($event_id) { ob_start(); ?>

get_row($wpdb->prepare("SELECT max_spaces_available FROM %i WHERE id=%d",TICKETDRUM_EVENTS_TABLE,$event_id),ARRAY_A); if ($wl_event && $wl_event['max_spaces_available']>0 && ticketdrum_calculate_spaces_taken($event_id)>=$wl_event['max_spaces_available']) { echo '

'.esc_html(ticketdrum_label('sold_out')).'

'.ticketdrum_waitlist_form((int)$event_id).'
'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- ticketdrum_waitlist_form() escapes its own output return; } $event = $wpdb->get_row($wpdb->prepare("SELECT * from %i where id=%d",TICKETDRUM_EVENTS_TABLE,$event_id)); if (!$event) return; //Event was deleted after the page linking to it was published $tickets = $wpdb->get_results($wpdb->prepare("SELECT id,title,price,max_purchase_quantity,attendee_count from %i WHERE event_id=%d AND active=1 ORDER BY title ASC",TICKETDRUM_TICKETS_TABLE,$event_id)); //Optional explicit ordering from the shortcode/block (list of ticket ids) if ($ticket_order) { $rank = array_flip(array_map('intval',$ticket_order)); usort($tickets,function($a,$b) use ($rank){ $ra = $rank[(int)$a->id] ?? PHP_INT_MAX; $rb = $rank[(int)$b->id] ?? PHP_INT_MAX; return $ra==$rb ? strcasecmp($a->title,$b->title) : $ra<=>$rb; }); } global $ticketdrum_basket; ?>
title));?>
start_datetime));?>
max_purchase_quantity>0)?(int)$ticket->max_purchase_quantity:10; ?>
title));?> price>0?wp_kses_post(ticketdrum_currency_format($ticket->price)):esc_html__('Free','ticketdrum');?>attendee_count>1) /* translators: %s: number of people one ticket admits */ echo ' · '.esc_html(sprintf(_n('admits %s','admits %s',(int)$ticket->attendee_count,'ticketdrum'),number_format_i18n((int)$ticket->attendee_count)));?>
', '', $messagehtml); $messagehtml = str_replace('', '', $messagehtml); $messagehtml = str_replace('', '', $messagehtml); $messagehtml = str_replace('', '', $messagehtml); return '
'.$messagehtml.'
'; } function ticketdrum_number_to_ordinal_word($num) { $first_word = array('eth','First','Second','Third','Fourth','Fifth','Sixth','Seventh','Eighth','Ninth','Tenth','Eleventh','Twelfth','Thirteenth','Fourteenth','Fifteenth','Sixteenth','Seventeenth','Eighteenth','Nineteenth','Twentieth'); $second_word =array('','','Twenty','Thirty','Forty','Fifty'); if($num <= 20) return $first_word[$num]; $first_num = substr($num,-1,1); $second_num = substr($num,-2,1); return $string = str_replace('y-eth','ieth',$second_word[$second_num].'-'.$first_word[$first_num]); }