';
}
public static function entrance() {
self::assets('staff');
return '
'.esc_html__('Loading check-in…','groupentry').'
';
}
public static function menu() {
add_menu_page('GroupEntry','GroupEntry','groupentry_checkin','groupentry',[self::class,'admin_page'],'dashicons-tickets-alt',26);
}
public static function time_zone_options($settings) {
// Group cities only when their known clock changes match for this event and the next ten years.
$year=(int)substr($settings['date'],0,4);
$from=(new DateTimeImmutable(sprintf('%04d-01-01',max(1,$year-1)),new DateTimeZone('UTC')))->getTimestamp();
$until=(new DateTimeImmutable(sprintf('%04d-01-01',min(9999,$year+11)),new DateTimeZone('UTC')))->getTimestamp();
$at=new DateTimeImmutable($settings['date'].' '.$settings['start'],GroupEntry_Core::timezone($settings));
// Reuse the city labels WordPress translates, without translating dynamic plugin strings.
$city_labels=[];
preg_match_all('/'; }
return $html;
}
public static function admin_page() {
if (!GroupEntry_API::staff_permission()) { wp_die(esc_html__('Access denied.','groupentry')); }
self::assets('admin');
echo '
GroupEntry – Event Registration & Check-in
';
echo '
'.esc_html__('Loading…','groupentry').'
';
if (current_user_can('manage_options')) {
echo '';
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- WordPress escapes option text and attributes in this native dropdown.
wp_dropdown_pages(['name'=>'page_id','show_option_none'=>__('Select a registration page','groupentry'),'option_none_value'=>0]);
echo '';
echo '';
echo ''.esc_html__('Export registrations to CSV','groupentry').'';
echo '
';
}
public static function csv_cell($v) {
$v=(string)$v;
if (preg_match('/^[\s\x00-\x1F]*[=+\-@]/u',$v)) { $v="'".$v; }
return $v;
}
public static function export() {
if (!current_user_can('manage_options')) { wp_die(esc_html__('Access denied.','groupentry')); }
check_admin_referer('groupentry_export');
global $wpdb;
$r=GroupEntry_Core::table('registrations'); $p=GroupEntry_Core::table('participants'); $s=GroupEntry_Core::table('slots');
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Plugin-owned transaction state and live capacity require fresh database access.
$rows=$wpdb->get_results($wpdb->prepare('SELECT r.*,p.first_name,p.last_name,p.age,s.starts_at,s.ends_at FROM %i r JOIN %i p ON p.registration_id=r.id JOIN %i s ON s.id=r.slot_id ORDER BY s.starts_at,r.contact_last,r.id,p.id',$r,$p,$s),ARRAY_A);
nocache_headers(); header('Content-Type: text/csv; charset=UTF-8'); header('Content-Disposition: attachment; filename="groupentry-'.gmdate('Y-m-d').'.csv"');
$out=fopen('php://output','w'); echo "\xEF\xBB\xBF";
fputcsv($out,[__('Code','groupentry'),__('Date','groupentry'),__('Start','groupentry'),__('End','groupentry'),__('Contact first name','groupentry'),__('Contact last name','groupentry'),__('Email','groupentry'),__('Participant first name','groupentry'),__('Participant last name','groupentry'),__('Age','groupentry'),__('Status','groupentry'),__('Check-in time','groupentry'),__('Event time zone','groupentry'),__('Mail status','groupentry')],';','"','');
foreach($rows as $row) {
$cells=[$row['code'],substr($row['starts_at'],0,10),substr($row['starts_at'],11,5),substr($row['ends_at'],11,5),$row['contact_first'],$row['contact_last'],$row['email'],$row['first_name'],$row['last_name'],$row['age'],$row['status'],$row['checked_at']?wp_date('Y-m-d H:i',strtotime($row['checked_at'].' UTC'),GroupEntry_Core::timezone()):'',GroupEntry_Core::timezone()->getName(),$row['mail_status']];
fputcsv($out,array_map([self::class,'csv_cell'],$cells),';','"','');
}
exit; // PHP closes the output stream; no files are written to disk.
}
}