=') && EVQRA_Registration_Manager::verify_schema()) return; $installed = EVQRA_Registration_Manager::install(); if ($installed && EVQRA_Registration_Manager::verify_schema()) { update_option('evqra_attendee_db_version', EVQRA_Registration_Manager::schema_version()); return; } if (defined('WP_DEBUG') && WP_DEBUG) { EVQRA_Core::debug_log( 'EventQora attendee schema verification failed; evqra_attendee_db_version was not advanced. The next request will retry the migration.'); } } public function maybe_install_cancellation_schema() { $current = get_option('evqra_cancellation_db_version', '0'); if (version_compare($current, EVQRA_Cancellation_Manager::schema_version(), '>=') && EVQRA_Cancellation_Manager::verify_schema()) return; $installed = EVQRA_Cancellation_Manager::install(); if ($installed && EVQRA_Cancellation_Manager::verify_schema()) { update_option('evqra_cancellation_db_version', EVQRA_Cancellation_Manager::schema_version()); return; } if (defined('WP_DEBUG') && WP_DEBUG) { EVQRA_Core::debug_log( 'EventQora cancellation schema verification failed; evqra_cancellation_db_version was not advanced. The next request will retry the migration.'); } } /** * Registers the 'evqra_event' custom post type. */ public function register_event_post_type() { $labels = [ 'name' => __('Events', 'eventqora'), 'singular_name' => __('Event', 'eventqora'), 'menu_name' => __('Events', 'eventqora'), 'name_admin_bar' => __('Event', 'eventqora'), 'add_new' => __('Add New', 'eventqora'), 'add_new_item' => __('Add New Event', 'eventqora'), 'edit_item' => __('Edit Event', 'eventqora'), 'new_item' => __('New Event', 'eventqora'), 'view_item' => __('View Event', 'eventqora'), 'search_items' => __('Search Events', 'eventqora'), 'not_found' => __('No events found.', 'eventqora'), 'not_found_in_trash' => __('No events found in Trash.', 'eventqora'), ]; $args = [ 'label' => __('Events', 'eventqora'), 'labels' => $labels, 'public' => true, 'has_archive' => false, 'menu_position' => 5, 'menu_icon' => 'dashicons-calendar-alt', 'rewrite' => ['slug' => 'events'], 'show_in_rest' => true, 'supports' => ['title', 'editor', 'excerpt', 'thumbnail', 'custom-fields'], 'capability_type' => 'post', ]; register_post_type('evqra_event', $args); } public function admin_columns($columns) { $date = $columns['date'] ?? __('Date', 'eventqora'); unset($columns['date']); return [ 'cb' => $columns['cb'] ?? '', 'title' => __('Event', 'eventqora'), 'evqra_status' => __('Status', 'eventqora'), 'evqra_start' => __('Start Date', 'eventqora'), 'evqra_time' => __('Time', 'eventqora'), 'evqra_venue' => __('Venue', 'eventqora'), 'evqra_org' => __('Organizer', 'eventqora'), 'evqra_cat' => __('Category', 'eventqora'), 'evqra_ticket' => __('Tickets', 'eventqora'), 'evqra_booking'=> __('Booking', 'eventqora'), 'evqra_featured' => __('Featured', 'eventqora'), 'date' => $date, ]; } public function sortable_admin_columns($columns) { $columns['evqra_start'] = 'evqra_start'; $columns['evqra_venue'] = 'evqra_venue'; $columns['evqra_org'] = 'evqra_org'; return $columns; } public function handle_admin_sorting($query) { if (!is_admin() || !$query->is_main_query() || $query->get('post_type') !== 'evqra_event') return; $orderby = $query->get('orderby'); $meta_key = ''; if ($orderby === 'evqra_start') { $meta_key = '_evqra_event_date'; } elseif ($orderby === 'evqra_venue') { $meta_key = '_evqra_event_venue_id'; } elseif ($orderby === 'evqra_org') { $meta_key = '_evqra_event_organizer_id'; } if ($meta_key !== '') { $query->set('meta_key', $meta_key); $query->set('orderby', 'meta_value'); } } public function render_admin_column($column, $post_id) { switch ($column) { case 'evqra_status': echo esc_html(ucwords(str_replace(['_', '-'], ' ', get_post_status($post_id)))); break; case 'evqra_start': $date = get_post_meta($post_id, '_evqra_event_date', true); echo $date ? esc_html(mysql2date(get_option('date_format'), $date)) : '—'; break; case 'evqra_time': $start = get_post_meta($post_id, '_evqra_event_time', true); $end = get_post_meta($post_id, '_evqra_event_end_time', true); if (!$start && !$end) { echo '—'; break; } $time = $start ?: ''; if ($end) $time .= ($time ? ' – ' : '') . $end; echo esc_html($time); break; case 'evqra_venue': $venue_id = absint(get_post_meta($post_id, '_evqra_event_venue_id', true)); if ($venue_id) { printf('%s', esc_url(get_edit_post_link($venue_id)), esc_html(get_the_title($venue_id))); } else { echo '—'; } break; case 'evqra_org': $organizer_id = absint(get_post_meta($post_id, '_evqra_event_organizer_id', true)); if ($organizer_id) { printf('%s', esc_url(get_edit_post_link($organizer_id)), esc_html(get_the_title($organizer_id))); } else { echo '—'; } break; case 'evqra_cat': $terms = get_the_terms($post_id, 'evqra_event_category'); if (empty($terms) || is_wp_error($terms)) { echo '—'; break; } echo esc_html(implode(', ', wp_list_pluck($terms, 'name'))); break; case 'evqra_ticket': $summary = $this->get_ticket_summary($post_id); echo $summary ? esc_html($summary) : esc_html__('No tickets', 'eventqora'); break; case 'evqra_booking': $mode = sanitize_key(get_post_meta($post_id, '_evqra_booking_mode', true)); if ($mode === '') $mode = 'none'; $labels = [ 'none' => __('Disabled', 'eventqora'), 'booking' => __('Booking', 'eventqora'), 'ticket' => __('Ticketing', 'eventqora'), // Backward compatibility for events imported before the canonical // ticketing mode was introduced. 'tickets' => __('Ticketing', 'eventqora'), ]; echo esc_html($labels[$mode] ?? ucwords(str_replace('_', ' ', $mode))); break; case 'evqra_featured': echo get_post_meta($post_id, '_evqra_event_featured', true) === '1' ? esc_html__('Yes', 'eventqora') : esc_html__('No', 'eventqora'); break; } } private function get_ticket_summary($event_id) { if (class_exists('EVQRA_Ticket_Inventory')) { $tickets = EVQRA_Ticket_Inventory::all_for_event($event_id); if ($tickets) { $capacity = 0; $sold = 0; $available = 0; foreach ($tickets as $ticket) { $capacity += (int) $ticket->capacity; $sold += (int) $ticket->sold; $available += (int) $ticket->available; } return sprintf( /* translators: %1$d is the number of available tickets; %2$d is the number of sold tickets. */ __('%1$d available / %2$d sold', 'eventqora'), $available, $sold ); } } $raw = get_post_meta($event_id, '_evqra_ticket_data', true); $data = is_string($raw) ? json_decode($raw, true) : []; if (!is_array($data)) return ''; $capacity = 0; foreach ($data as $category) { foreach (($category['types'] ?? []) as $ticket) { $capacity += max(0, (int) ($ticket['qty'] ?? 0)); } } /* translators: %d is the event ticket capacity. */ return $capacity > 0 ? sprintf(__('%d capacity', 'eventqora'), $capacity) : ''; } } new EVQRA_Event_Manager();