| Current File : /home/digitaw/www/wp-content/plugins/event-tickets/src/Tickets/Admin/Tickets/List_Table.php |
<?php
/**
* The list table for the Admin Tickets screen.
*
* @since 5.14.0
*
* @package TEC\Tickets\Admin
*/
namespace TEC\Tickets\Admin\Tickets;
use Tribe__Tickets__Commerce__Currency;
use Tribe__Tickets__Ticket_Object;
use WP_List_Table;
use DateTime;
use TEC\Tickets\Commerce as TicketsCommerce;
use Tribe\Tickets\Admin\Settings;
use Tribe__Template;
use Tribe__Tickets__Main;
use WP_Post;
use WP_Query;
use TEC\Events_Pro\Custom_Tables\V1\Links\Provider as Custom_Tables_Links_Provider;
/**
* Class List_Table.
*
* @since 5.14.0
*
* @package TEC\Tickets\Admin
*/
class List_Table extends WP_List_Table {
/**
* The user option that will store how many attendees should be shown per page.
*
* @var string
*/
protected $per_page_option;
/**
* The template object.
*
* @var Tribe__Template
*/
protected $template;
/**
* Default status filter.
*
* @var string
*/
public static $default_status = 'all';
/**
* Default Sort By.
*
* @var string
*/
public static $default_sort_by = 'end';
/**
* Default Sort Order.
*
* @var string
*/
public static $default_sort_order = 'desc';
/**
* The query for the tickets.
*
* @var WP_Query $query
*/
protected $query;
/**
* List of events by ID.
*
* @var array
*/
protected $events_by_id = [];
/**
* List of event edit URLs.
*
* @var array
*/
protected $event_edit_urls = [];
/**
* Get the template object.
*
* @since 5.14.0
*
* @return Tribe__Template
*/
protected function get_template() {
if ( ! empty( $this->template ) ) {
return $this->template;
}
$this->template = tribe( 'tickets.admin.views' );
return $this->template;
}
/**
* Get the default status for the Admin Tickets Table.
*
* @since 5.14.0
*
* @return string
*/
public static function get_default_status() {
/**
* Filters the default status for the Admin Tickets Table.
*
* @since 5.14.0
*
* @param string $default_status The default status for the Admin Tickets Table.
*
* @return string
*/
return apply_filters( 'tec_tickets_admin_tickets_table_default_status', self::$default_status );
}
/**
* Get the default sort by for the Admin Tickets Table.
*
* @since 5.14.0
*
* @return string
*/
public static function get_default_sort_by() {
/**
* Filters the default sort by for the Admin Tickets Table.
*
* @since 5.14.0
*
* @param string $default_sort_by The default sort by for the Admin Tickets Table.
*
* @return string
*/
return apply_filters( 'tec_tickets_admin_tickets_table_default_sort_by', self::$default_sort_by );
}
/**
* Get the default sort order for the Admin Tickets Table.
*
* @since 5.14.0
*
* @return string
*/
public static function get_default_sort_order() {
/**
* Filters the default sort order for the Admin Tickets Table.
*
* @since 5.14.0
*
* @param string $default_sort_order The default sort order for the Admin Tickets Table.
*
* @return string
*/
return apply_filters( 'tec_tickets_admin_tickets_table_default_sort_order', self::$default_sort_order );
}
/**
* The constructor.
*
* @since 5.14.0
*/
public function __construct() {
$screen = get_current_screen();
parent::__construct(
[
'singular' => 'ticket',
'plural' => 'tickets',
'ajax' => false,
'screen' => $screen,
]
);
$this->per_page_option = Screen_Options::$per_page_user_option;
if ( ! is_null( $screen ) ) {
$screen->add_option(
'per_page',
[
'label' => __( 'Number of tickets per page:', 'event-tickets' ),
'option' => $this->per_page_option,
]
);
}
}
/**
* Returns the columns for the list table.
*
* @since 5.14.0
*
* @return array
*/
public function get_table_columns(): array {
$table_columns = [
'name' => esc_html__( 'Ticket Name', 'event-tickets' ),
'id' => esc_html__( 'Ticket ID', 'event-tickets' ),
'event' => esc_html__( 'Event', 'event-tickets' ),
'start' => esc_html__( 'Sale Starts', 'event-tickets' ),
'end' => esc_html__( 'Sale Ends', 'event-tickets' ),
'days_left' => esc_html__( 'Days Left', 'event-tickets' ),
'price' => esc_html__( 'Price', 'event-tickets' ),
'sold' => esc_html__( 'Sold', 'event-tickets' ),
'remaining' => esc_html__( 'Remaining', 'event-tickets' ),
'sales' => esc_html__( 'Sales', 'event-tickets' ),
];
/**
* Filters the columns for the Admin Tickets Table.
*
* @since 5.14.0
*
* @param array $table_columns The columns for the Admin Tickets Table.
*
* @return array
*/
return apply_filters( 'tec_tickets_admin_tickets_table_columns', $table_columns );
}
/**
* Get a list of columns. The format is:
* 'internal-name' => 'Title'
*
* @since 5.14.0
*
* @return array
*/
public function get_columns(): array {
return $this->get_table_columns();
}
/**
* Get primary column for the list table.
*
* @since 5.14.0
*
* @return string
*/
protected function get_primary_column_name(): string {
return 'name';
}
/**
* Get hidden columns for the list table.
*
* @since 5.14.0
*
* @return array
*/
public function get_hidden_columns(): array {
$screen = get_current_screen();
if ( is_null( $screen ) ) {
return $this->get_default_hidden_columns();
}
return get_hidden_columns( $screen );
}
/**
* Returns the columns for the list table.
*
* @since 5.14.0
*
* @return array
*/
public static function get_default_hidden_columns(): array {
$default_hidden_columns = [
'id',
'start',
'days_left',
'sales',
];
/**
* Filter the default hidden columns for the Admin Tickets Table.
*
* @since 5.14.0
*
* @param array $default_hidden_columns The default hidden columns for the Admin Tickets Table.
*
* @return array
*/
return apply_filters( 'tec_tickets_admin_tickets_table_default_hidden_columns', $default_hidden_columns );
}
/**
* Returns the sortable columns for the list table.
*
* @since 5.14.0
*
* @return array
*/
public function get_sortable_columns() {
$sortable_columns = [
'name' => [ 'name', true ],
'id' => [ 'id', true ],
'start' => [ 'start', true ],
'end' => [ 'end', 'desc' ], // Start with DESC order.
'days_left' => [ 'days_left', true ],
'price' => [ 'price', true ],
'sold' => [ 'sold', true ],
];
/**
* Filters the sortable columns for the Admin Tickets Table.
*
* @since 5.14.0
*
* @param array $sortable_columns The sortable columns for the Admin Tickets Table.
*
* @return array
*/
return apply_filters( 'tec_tickets_admin_tickets_table_sortable_columns', $sortable_columns );
}
/**
* Get the ticket type icon.
*
* @since 5.14.0
*
* @param Tribe__Tickets__Ticket_Object $item The current item.
*
* @return string HTML for the ticket type icon.
*/
protected function get_ticket_type_icon( $item ) {
ob_start();
do_action( 'tec_tickets_editor_list_table_title_icon_' . $item->type() );
return ob_get_clean();
}
/**
* Get the default column value.
*
* @since 5.14.0
*
* @param Tribe__Tickets__Ticket_Object $item The current item.
* @param string $column_name The column name.
*
* @return string
*/
public function column_default( $item, $column_name ): string {
// If the column name is empty or the item does not have the column name, return an empty string.
if ( empty( $column_name ) || ! isset( $item->$column_name ) ) {
return '';
}
// If value is not a string or a number, return an empty string.
if ( ! is_string( $item->$column_name ) && ! is_numeric( $item->$column_name ) ) {
return '';
}
$default = esc_html( $item->$column_name );
/**
* Filters the default column value for the Admin Tickets Table.
*
* @since 5.14.0
*
* @param string $default The default column value for the Admin Tickets Table.
* @param Tribe__Tickets__Ticket_Object $item The current item.
* @param string $column_name The column name.
*
* @return string
*/
$default = apply_filters( 'tec_tickets_admin_tickets_table_column_default', $default, $item, $column_name );
/**
* Filters the default column value for the Admin Tickets Table.
*
* @since 5.14.0
*
* @param string $default The default column value for the Admin Tickets Table.
* @param Tribe__Tickets__Ticket_Object $item The current item.
*
* @return string
*/
return apply_filters( "tec_tickets_admin_tickets_table_column_default_{$column_name}", $default, $item );
}
/**
* Get the event edit URL.
*
* @since 5.14.0
*
* @param int $event_id The event ID.
*
* @return string
*/
protected function get_event_edit_url( $event_id ) {
if ( isset( $this->event_edit_urls[ $event_id ] ) ) {
return $this->event_edit_urls[ $event_id ];
}
if ( isset( $this->events_by_id[ $event_id ] ) ) {
$event = $this->events_by_id[ $event_id ];
} else {
$event = get_post( $event_id );
$this->events_by_id[ $event_id ] = $event;
}
$ecp_installed = has_action( 'tribe_common_loaded', 'tribe_register_pro' );
if ( $ecp_installed ) {
remove_filter( 'get_edit_post_link', [ tribe( Custom_Tables_Links_Provider::class ), 'update_event_edit_link' ], 10 );
}
$edit_post_url = get_edit_post_link( $event );
if ( $ecp_installed ) {
add_filter( 'get_edit_post_link', [ tribe( Custom_Tables_Links_Provider::class ), 'update_event_edit_link' ], 10, 2 );
}
$this->event_edit_urls[ $event_id ] = $edit_post_url;
return $edit_post_url;
}
/**
* Get the column name value.
*
* @since 5.14.0
*
* @param Tribe__Tickets__Ticket_Object $item The current item.
*
* @return string
*/
public function column_name( $item ): string {
if ( $item instanceof WP_Post ) {
return get_the_title( $item );
}
$event = $item->get_event();
if ( ! $event ) {
return esc_html( $item->name );
}
$edit_post_link = sprintf(
'<a href="%s" class="tec-tickets-admin-tickets-table-event-link" target="_blank" rel="nofollow noopener">%s</a>',
esc_url( $this->get_event_edit_url( $event->ID ) ),
esc_html( $item->name )
);
$template = $this->get_template();
$context = [
'icon_html' => $this->get_ticket_type_icon( $item ),
'ticket_link' => $edit_post_link,
];
$name = $template->template( 'admin-tickets/column/name', $context, false );
/**
* Filters the name for the Admin Tickets Table.
*
* @since 5.14.0
*
* @param string $name The name for the Admin Tickets Table.
* @param Tribe__Tickets__Ticket_Object $item The current item.
*
* @return string
*/
return apply_filters( 'tec_tickets_admin_tickets_table_column_name', $name, $item );
}
/**
* Get the column ID value.
*
* @since 5.14.0
*
* @param Tribe__Tickets__Ticket_Object $item The current item.
*
* @return string
*/
public function column_id( $item ): string {
$id = (string) $item->ID;
/**
* Filters the ID for the Admin Tickets Table.
*
* @since 5.14.0
*
* @param string $id The ID for the Admin Tickets Table.
* @param Tribe__Tickets__Ticket_Object $item The current item.
*
* @return string
*/
return apply_filters( 'tec_tickets_admin_tickets_table_column_id', $id, $item );
}
/**
* Get the column event value.
*
* @since 5.14.0
*
* @param Tribe__Tickets__Ticket_Object|WP_Post $item The current item.
*
* @return string
*/
public function column_event( $item ): string {
// If the item is a post, it means the post type is disabled in the ticket settings.
if ( $item instanceof WP_Post ) {
$msg_line_1 = esc_html__( 'This ticket is connected to a disabled post type.', 'event-tickets' );
$ticket_settings_url = add_query_arg( [ 'page' => Settings::$settings_page_id ], admin_url( 'admin.php' ) );
$ticket_settings_link = sprintf(
'<a href="%s" class="tec-tickets-admin-tickets-table-event-link" rel="nofollow noopener">%s</a>',
esc_url( $ticket_settings_url ),
esc_html__( 'Ticket Settings Page', 'event-tickets' )
);
$msg_line_2 = sprintf(
// Translators: %s: Ticket Settings Page link.
esc_html__( 'You can enable this post type on the %s.', 'event-tickets' ),
$ticket_settings_link
);
return wp_kses_post( sprintf( '<i>%s<br>%s</i>', $msg_line_1, $msg_line_2 ) );
}
// If the item is a ticket object, get the event.
$event = $item->get_event();
if ( ! $event ) {
return esc_html__( 'No associated event', 'event-tickets' );
}
$edit_post_link = sprintf(
'<a href="%s" class="tec-tickets-admin-tickets-table-event-link" target="_blank" rel="nofollow noopener">%s</a>',
esc_url( $this->get_event_edit_url( $event->ID ) ),
get_the_title( $event )
);
$orders_report_url = add_query_arg(
[
'post_type' => $event->post_type,
'page' => $this->get_order_page_slug(),
'event_id' => $event->ID,
],
admin_url( 'edit.php' )
);
$orders_report_link = sprintf(
'<a href="%s" class="tec-tickets-admin-tickets-table-event-link" target="_blank" rel="nofollow noopener">%s</a>',
esc_url( $orders_report_url ),
esc_html__( 'Orders', 'event-tickets' )
);
$attendees_report_url = add_query_arg(
[
'post_type' => $event->post_type,
'page' => 'tickets-attendees',
'event_id' => $event->ID,
],
admin_url( 'edit.php' )
);
$attendees_report_link = sprintf(
'<a href="%s" class="tec-tickets-admin-tickets-table-event-link" target="_blank" rel="nofollow noopener">%s</a>',
esc_url( $attendees_report_url ),
esc_html__( 'Attendees', 'event-tickets' )
);
$actions = [
'orders' => $orders_report_link,
'attendees' => $attendees_report_link,
];
/**
* Filters the actions for the event in the Admin Tickets Table.
*
* @since 5.14.0
*
* @param array $actions The actions for the event in the Admin Tickets Table.
*/
$actions = apply_filters( 'tec_tickets_admin_tickets_table_event_actions', $actions, $event, $item );
$event = sprintf( '%1$s %2$s', $edit_post_link, $this->row_actions( $actions ) );
/**
* Filters the event for the Admin Tickets Table.
*
* @since 5.14.0
*
* @param string $event The event for the Admin Tickets Table.
* @param Tribe__Tickets__Ticket_Object $item The current item.
*
* @return string
*/
return apply_filters( 'tec_tickets_admin_tickets_table_column_event', $event, $item );
}
/**
* Get the column start date value.
*
* @since 5.14.0
*
* @param Tribe__Tickets__Ticket_Object|WP_Post $item The current item.
*
* @return string
*/
public function column_start( $item ): string {
if ( $item instanceof WP_Post ) {
return '-';
}
$date_format = get_option( 'date_format' );
$ts = $item->start_date();
$start = sprintf(
'<time datetime="%1$s" title="%2$s">%3$s</time>',
esc_attr( \Tribe__Date_Utils::reformat( $ts, 'c' ) ),
esc_html( \Tribe__Date_Utils::reformat( $ts, $date_format . ' ' . get_option( 'time_format' ) ) ),
esc_html( \Tribe__Date_Utils::reformat( $ts, $date_format ) )
);
/**
* Filters the start date for the Admin Tickets Table.
*
* @since 5.14.0
*
* @param string $start The start date for the Admin Tickets Table.
* @param Tribe__Tickets__Ticket_Object $item The current item.
*
* @return string
*/
return apply_filters( 'tec_tickets_admin_tickets_table_column_start_date', $start, $item );
}
/**
* Get the column end date value.
*
* @since 5.14.0
*
* @param Tribe__Tickets__Ticket_Object|WP_Post $item The current item.
*
* @return string
*/
public function column_end( $item ): string {
if ( $item instanceof WP_Post ) {
return '-';
}
$date_format = get_option( 'date_format' );
$ts = $item->end_date();
$end = sprintf(
'<time datetime="%1$s" title="%2$s">%3$s</time>',
esc_attr( \Tribe__Date_Utils::reformat( $ts, 'c' ) ),
esc_html( \Tribe__Date_Utils::reformat( $ts, $date_format . ' ' . get_option( 'time_format' ) ) ),
esc_html( \Tribe__Date_Utils::reformat( $ts, $date_format ) )
);
/**
* Filters the end date for the Admin Tickets Table.
*
* @since 5.14.0
*
* @param string $end The end date for the Admin Tickets Table.
* @param Tribe__Tickets__Ticket_Object $item The current item.
*
* @return string
*/
return apply_filters( 'tec_tickets_admin_tickets_table_column_end_date', $end, $item );
}
/**
* Get the column days_left value.
*
* @since 5.14.0
*
* @param Tribe__Tickets__Ticket_Object|WP_Post $item The current item.
*
* @return string
*/
public function column_days_left( $item ): string {
if ( $item instanceof WP_Post ) {
return '-';
}
$datetime = $item->end_date( false );
$now = new DateTime();
$interval = $now->diff( $datetime );
if ( $interval->invert ) {
return '-';
}
$days_left = (string) $interval->days;
/**
* Filters the number of days left for the Admin Tickets Table.
*
* @since 5.14.0
*
* @param string $days_left The number of days left for the Admin Tickets Table.
* @param Tribe__Tickets__Ticket_Object $item The current item.
*
* @return string
*/
return apply_filters( 'tec_tickets_admin_tickets_table_column_days_left', $days_left, $item );
}
/**
* Format currency.
*
* @since 5.14.0
*
* @param float $price The price to format.
* @param int $event_id The event/post ID.
*
* @return string
*/
protected function format_currency( $price, $event_id ) {
/** @var Tribe__Tickets__Commerce__Currency $currency */
$currency = tribe( 'tickets.commerce.currency' );
$currency_symbol = $currency->get_provider_symbol( Page::get_current_provider(), $event_id );
$symbol_position = $currency->get_provider_symbol_position( Page::get_current_provider(), $event_id );
$formatted_price = $currency->get_formatted_currency( number_format( (float) $price, 2 ), $event_id, Page::get_current_provider() );
return 'prefix' === $symbol_position ? $currency_symbol . $formatted_price : $formatted_price . $currency_symbol;
}
/**
* Get the column price value.
*
* @since 5.14.0
*
* @param Tribe__Tickets__Ticket_Object|WP_Post $item The current item.
*
* @return string
*/
public function column_price( $item ): string {
if ( $item instanceof WP_Post ) {
return '-';
}
$price = $this->format_currency( $item->price, $item->get_event() );
/**
* Filters the price for the Admin Tickets Table.
*
* @since 5.14.0
*
* @param string $price The price for the Admin Tickets Table.
* @param Tribe__Tickets__Ticket_Object $item The current item.
*
* @return string
*/
return apply_filters( 'tec_tickets_admin_tickets_table_column_price', $price, $item );
}
/**
* Get the column sold value.
*
* @since 5.14.0
*
* @param Tribe__Tickets__Ticket_Object|WP_Post $item The current item.
*
* @return string
*/
public function column_sold( $item ): string {
if ( $item instanceof WP_Post ) {
return '-';
}
$sold = (string) $item->qty_sold();
/**
* Filters the number of tickets sold for the Admin Tickets Table.
*
* @since 5.14.0
*
* @param string $sold The number of tickets sold for the Admin Tickets Table.
* @param Tribe__Tickets__Ticket_Object $item The current item.
*
* @return string
*/
return apply_filters( 'tec_tickets_admin_tickets_table_column_sold', $sold, $item );
}
/**
* Get the column remaining value.
*
* @since 5.14.0
*
* @param Tribe__Tickets__Ticket_Object|WP_Post $item The current item.
*
* @return string
*/
public function column_remaining( $item ): string {
if ( $item instanceof WP_Post ) {
return '-';
}
// If there is no event, do not attempt to calculate remaining tickets.
if ( empty( $item->get_event() ) ) {
return 0;
}
$available = $item->available();
$remaining = $available < 0 ? '-' : (string) $available;
/**
* Filters the number of tickets remaining for the Admin Tickets Table.
*
* @since 5.14.0
*
* @param string $remaining The number of tickets remaining for the Admin Tickets Table.
* @param Tribe__Tickets__Ticket_Object $item The current item.
*
* @return string
*/
return apply_filters( 'tec_tickets_admin_tickets_table_column_remaining', $remaining, $item );
}
/**
* Get the column sales value.
*
* @since 5.14.0
*
* @param Tribe__Tickets__Ticket_Object|WP_Post $item The current item.
*
* @return string
*/
public function column_sales( $item ): string {
if ( $item instanceof WP_Post ) {
return '-';
}
$sales = $this->format_currency( ( $item->qty_sold() * $item->price ), $item->get_event() );
/**
* Filters the total sales for the Admin Tickets Table.
*
* @since 5.14.0
*
* @param string $sales The total sales for the Admin Tickets Table.
* @param Tribe__Tickets__Ticket_Object $item The current item.
*
* @return string
*/
return apply_filters( 'tec_tickets_admin_tickets_table_column_sales', $sales, $item );
}
/**
* Modify the sort arguments.
*
* @since 5.14.0
*
* @param array $args The arguments used to query the tickets for the Admin Tickets Table.
*
* @return array
*/
public function modify_sort_args( $args ): array {
$orderby = tribe_get_request_var( 'orderby', self::get_default_sort_by() );
switch ( $orderby ) {
case 'name':
$args['orderby'] = 'post_title';
break;
case 'id':
$args['orderby'] = 'ID';
break;
case 'start':
$args['orderby'] = 'meta_value';
$args['meta_key'] = '_ticket_start_date';
$args['meta_type'] = 'DATETIME';
break;
case 'end':
$args['orderby'] = 'meta_value';
$args['meta_key'] = '_ticket_end_date';
$args['meta_type'] = 'DATETIME';
break;
case 'days_left':
$args['orderby'] = 'meta_value';
$args['meta_key'] = '_ticket_end_date';
$args['meta_type'] = 'DATETIME';
break;
case 'price':
$args['orderby'] = 'meta_value_num';
$args['meta_key'] = '_price';
break;
case 'sold':
$args['orderby'] = 'meta_value_num';
$args['meta_key'] = 'total_sales';
break;
}
$args['order'] = tribe_get_request_var( 'order', self::get_default_sort_order() );
return $args;
}
/**
* Modify the filter arguments.
*
* @since 5.14.0
*
* @param array $args The arguments used to query the tickets for the Admin Tickets Table.
*
* @return array
*/
public function modify_filter_args( $args ) {
$filter = tribe_get_request_var( Page::STATUS_KEY, self::get_default_status() );
if ( empty( $filter ) || 'all' === $filter ) {
return $args;
}
if ( ! isset( $args['meta_query'] ) ) {
// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
$args['meta_query'] = [];
}
switch ( $filter ) {
case 'active':
$args['meta_query'][] = [
'key' => '_ticket_start_date',
'value' => current_time( 'mysql' ),
'compare' => '<=',
'type' => 'DATETIME',
];
$args['meta_query'][] = [
'key' => '_ticket_end_date',
'value' => current_time( 'mysql' ),
'compare' => '>',
'type' => 'DATETIME',
];
break;
case 'past':
$args['meta_query'][] = [
'key' => '_ticket_end_date',
'value' => current_time( 'mysql' ),
'compare' => '<=',
'type' => 'DATETIME',
];
break;
case 'upcoming':
$args['meta_query'][] = [
'key' => '_ticket_start_date',
'value' => current_time( 'mysql' ),
'compare' => '>',
'type' => 'DATETIME',
];
break;
case 'discounted':
$args['meta_query'][] = [
'key' => '_sale_price',
'compare' => 'EXISTS',
];
$args['meta_query'][] = [
'key' => '_sale_price_start_date',
'value' => current_time( 'mysql' ),
'compare' => '<',
'type' => 'DATETIME',
];
$args['meta_query'][] = [
'key' => '_sale_price_end_date',
'value' => current_time( 'mysql' ),
'compare' => '>',
'type' => 'DATETIME',
];
break;
}
if ( count( $args['meta_query'] ) > 1 ) {
$args['meta_query']['relation'] = 'AND';
}
return $args;
}
/**
* Get the query args for the list table.
*
* @since 5.14.0
*
* @return array|bool
*/
public function get_query_args() {
$current_page = $this->get_pagenum();
$per_page = $this->get_items_per_page( $this->per_page_option );
$args = [
'admin_tickets_list_table' => true,
'offset' => ( $current_page - 1 ) * $per_page,
'posts_per_page' => $per_page,
'return_total_found' => true,
'post_type' => Page::get_current_post_type(),
'post_status' => 'any',
];
$args = $this->modify_filter_args( $args );
$args = $this->modify_sort_args( $args );
/**
* Filters the arguments used to query the tickets for the Admin Tickets Table.
*
* @since 5.14.0
*
* @param array $args The arguments used to query the tickets for the Admin Tickets Table.
*
* @return array
*/
return apply_filters( 'tec_tickets_admin_tickets_table_query_args', $args );
}
/**
* Primes the queries for caching purposes.
*
* @since 5.14.0
*
* @param array $items The items to prime the queries for.
*/
public function prime_queries( $items ) {
$event_ids = wp_list_pluck( $items, 'event_id' );
$event_query = new WP_Query(
[
'post__in' => $event_ids,
'posts_per_page' => -1,
'post_type' => Tribe__Tickets__Main::instance()->post_types(),
'post_status' => 'any',
'update_post_meta_cache' => true,
]
);
if ( $event_query->found_posts ) {
foreach ( $event_query->posts as $event ) {
$this->events_by_id[ $event->ID ] = $event;
}
}
// Only continue if we're looking at Tickets Commerce tickets.
if ( Page::get_current_provider() !== TicketsCommerce\Module::class ) {
return;
}
// @todo @codingmusician - Add query priming solutions for other providers.
$ticket_ids = wp_list_pluck( $items, 'ID' );
$cache = tribe_cache();
$attendees_by_ticket_id = $cache->get( 'tec_tickets_attendees_by_ticket_id' );
if ( ! is_array( $attendees_by_ticket_id ) ) {
$attendees_by_ticket_id = [];
}
foreach ( $ticket_ids as $ticket_id ) {
$cache->set(
'tec_tickets_quantities_by_status_' . $ticket_id,
tribe( TicketsCommerce\Ticket::class )->get_status_quantity( $ticket_id )
);
$attendees_by_ticket_id[ $ticket_id ] = [];
}
$attendee_query = new WP_Query(
[
// phpcs:ignore WordPress.WP.PostsPerPage.posts_per_page_posts_per_page
'posts_per_page' => 250,
'post_type' => $this->get_attendee_post_type(),
// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
'meta_query' => [
[
'key' => TicketsCommerce\Attendee::$ticket_relation_meta_key,
'value' => $ticket_ids,
'compare' => 'IN',
],
],
]
);
if ( 0 === $attendee_query->found_posts ) {
return;
}
foreach ( $attendee_query->posts as $attendee ) {
$ticket_id = get_post_meta( $attendee->ID, TicketsCommerce\Attendee::$ticket_relation_meta_key, true );
if ( ! $ticket_id ) {
continue;
}
$attendees_by_ticket_id[ $ticket_id ][] = $attendee;
}
$cache->set( 'tec_tickets_attendees_by_ticket_id', $attendees_by_ticket_id );
}
/**
* Prepares the list of items for displaying.
*
* @since 5.14.0
*/
public function prepare_items() {
add_filter( 'posts_clauses', [ $this, 'filter_query_clauses' ], 10, 2 );
$args = $this->get_query_args();
$this->query = new WP_Query( $args );
$total_items = $this->query->found_posts;
$items = $this->query->posts;
remove_filter( 'posts_clauses', [ $this, 'filter_query_clauses' ], 10 );
$this->prime_queries( $items );
$provider = Page::get_current_provider_object();
foreach ( $items as $i => $item ) {
$ticket_object = $provider->get_ticket( $item->event_id, $item->ID );
if ( ! empty( $ticket_object ) ) {
$ticket_object->raw = $item;
}
$this->items[] = empty( $ticket_object ) ? $item : $ticket_object;
}
$pagination_args = [
'total_items' => $total_items,
'per_page' => $this->get_items_per_page( $this->per_page_option ),
];
$this->_column_headers = [
$this->get_table_columns(),
$this->get_hidden_columns(),
$this->get_sortable_columns(),
];
$this->set_pagination_args( $pagination_args );
}
/**
* Filter the query clauses.
*
* @since 5.14.0
*
* @param array $clauses The query clauses.
* @param WP_Query $query The WP_Query object.
*
* @return array
*/
public function filter_query_clauses( $clauses, $query ) {
// Only modify if not the main query and is the Admin Tickets Table query.
if ( $query->is_main_query() || empty( $query->query_vars['admin_tickets_list_table'] ) ) {
return $clauses;
}
global $wpdb;
$event_meta_key = $this->get_event_meta_key();
// Add join clauses to retrieve the event title.
$clauses['join'] .= $wpdb->prepare(
" LEFT JOIN {$wpdb->postmeta} AS ticket_event ON ( {$wpdb->posts}.ID = ticket_event.post_id ) AND ticket_event.meta_key = %s ",
$event_meta_key
);
$clauses['join'] .= " LEFT JOIN {$wpdb->posts} AS event_data ON event_data.ID = ticket_event.meta_value ";
$clauses['fields'] .= ', event_data.ID AS event_id';
// If there is no search, return the clauses.
$search = tribe_get_request_var( 's' );
if ( empty( $search ) ) {
return $clauses;
}
// Add the event title to the fields.
$clauses['fields'] .= ', event_data.post_title AS event_title';
// Add the where clause.
$clauses['where'] .= $wpdb->prepare(
" AND ( {$wpdb->posts}.post_title LIKE %s OR event_data.post_title LIKE %s )",
'%' . $wpdb->esc_like( $search ) . '%',
'%' . $wpdb->esc_like( $search ) . '%'
);
return $clauses;
}
/**
* Get order page slug.
*
* @since 5.14.0
*
* @return string
*/
protected function get_order_page_slug(): string {
// Tickets Commerce has its own order page slug. All others are 'tickets-orders'.
if ( Page::get_current_provider() === TicketsCommerce\Module::class ) {
return TicketsCommerce\Reports\Orders::$page_slug;
}
return 'tickets-orders';
}
/**
* Get event meta key.
*
* @since 5.14.0
*
* @return string
*/
protected function get_event_meta_key(): string {
$provider_info = Page::get_provider_info();
$provider = Page::get_current_provider();
if ( ! isset( $provider_info[ $provider ] ) || empty( $provider_info[ $provider ]['event_meta_key'] ) ) {
return '';
}
return $provider_info[ $provider ]['event_meta_key'];
}
/**
* Get attendee post type based on provider.
*
* @since 5.14.0
*
* @return string
*/
protected function get_attendee_post_type(): string {
$provider_info = Page::get_provider_info();
$provider = Page::get_current_provider();
if ( ! isset( $provider_info[ $provider ] ) || empty( $provider_info[ $provider ]['attendee_post_type'] ) ) {
return '';
}
return $provider_info[ $provider ]['attendee_post_type'];
}
/**
* Display the filter and search input.
*
* @since 5.14.0
*
* @param string $which The location of the extra table nav.
*/
public function extra_tablenav( $which ) {
if ( 'top' !== $which ) {
return;
}
$current_status = tribe_get_request_var( Page::STATUS_KEY, self::get_default_status() );
$template = $this->get_template();
$context = [
'list_table' => $this,
'status_options' => $this->get_status_options(),
'current_status' => $current_status,
'search_id' => 'tec-tickets-admin-tickets-search-input',
'search_value' => tribe_get_request_var( 's' ),
'show_provider_filter' => $this->show_ticket_provider_filter(),
'provider_options' => Page::get_provider_options(),
'current_provider' => Page::get_current_provider(),
];
$template->template( 'admin-tickets/filters', $context );
}
/**
* Get the default status options.
*
* @since 5.14.0
*
* @return array
*/
protected function get_status_options(): array {
$status_options = [
'active' => esc_html__( 'Active Tickets', 'event-tickets' ),
'past' => esc_html__( 'Past Tickets', 'event-tickets' ),
'upcoming' => esc_html__( 'Upcoming Tickets', 'event-tickets' ),
'discounted' => esc_html__( 'Discounted Tickets', 'event-tickets' ),
'all' => esc_html__( 'All Tickets', 'event-tickets' ),
];
/**
* Filters the status options for the Admin Tickets Table.
*
* @since 5.14.0
*
* @param array $status_options The status options for the Admin Tickets Table.
*
* @return array
*/
return apply_filters( 'tec_tickets_admin_tickets_table_status_options', $status_options );
}
/**
* Whether or not to display the ticket provider filter.
*
* @since 5.14.0
*
* @return boolean
*/
protected function show_ticket_provider_filter(): bool {
$providers = Page::get_provider_info();
// Only show if more than one provider.
return count( $providers ) > 1;
}
/**
* @inheritDoc
*/
public function no_items() {
esc_html_e( 'No tickets found for the active filter.', 'event-tickets' );
}
}