'attendee', 'plural' => 'attendees', 'ajax' => true ) ); } /** * Display the search box. * We don't want Core's search box, because we implemented our own jQuery based filter, * so this function overrides the parent's one and returns empty. * * @since 3.1.0 * @access public * * @param string $text The search button text * @param string $input_id The search input id */ function search_box( $text, $input_id ) { return; } /** * Display the pagination. * We are not paginating the attendee list, so it returns empty. * * @since 3.1.0 * @access protected */ function pagination( $which ) { return ''; } /** * Checks the current user's permissions * * @since 3.1.0 * @access public */ function ajax_user_can() { return current_user_can( get_post_type_object( $this->screen->post_type )->cap->edit_posts ); } /** * Get a list of columns. The format is: * 'internal-name' => 'Title' * * @return array */ function get_columns() { $columns = array( 'cb' => '', 'order_id' => __( 'Order #', 'tribe-events-calendar' ), 'order_status' => __( 'Order Status', 'tribe-events-calendar' ), 'purchaser_name' => __( 'Purchaser name', 'tribe-events-calendar' ), 'purchaser_email' => __( 'Purchaser email', 'tribe-events-calendar' ), 'ticket' => __( 'Ticket type', 'tribe-events-calendar' ), 'attendee_id' => __( 'Ticket #', 'tribe-events-calendar' ), 'security' => __( 'Security Code', 'tribe-events-calendar' ), 'check_in' => __( 'Check in', 'tribe-events-calendar' ) ); return $columns; } /** * Handler for the columns that don't have a specific column_{name} handler function. * * @param $item * @param $column * * @return string */ function column_default( $item, $column ) { $value = empty( $item[$column] ) ? '' : $item[$column]; return apply_filters( 'tribe_events_tickets_attendees_table_column', $value, $item, $column ); } /** * Handler for the checkbox column * * @param $item * * @return string */ function column_cb( $item ) { return sprintf( '', esc_attr( $this->_args['singular'] ), esc_attr( $item['attendee_id'] . "|" . $item['provider'] ) ); } /** * Handler for the order id column * * @param $item * * @return string */ function column_order_id( $item ) { //back compat if ( empty( $item['order_id_link'] ) ) $id = sprintf( '%s', esc_url( get_edit_post_link( $item['order_id'], true ) ), esc_html( $item['order_id'] ) ); else $id = $item['order_id_link']; return $id; } /** * Handler for the order status column * * @todo revise in 3.4.3: we can then simplify this code and remove the checks against order_status string literals * @param $item * @return string */ function column_order_status( $item ) { $icon = ''; $warning = false; // Check if the order_warning flag has been set (to indicate the order has been cancelled, refunded etc) if ( isset( $item['order_warning']) && $item['order_warning'] ) $warning = true; // Additional check for backwards compatibility @todo remove this check clause in 3.4.3 if ( ! isset( $item['order_warning'] ) && strtolower( $item['order_status'] ) !== 'completed' && strtolower( $item['order_status'] ) !== 'paid' ) $warning = true; // If the warning flag is set, add the appropriate icon if ( $warning ) { $tec = TribeEvents::instance(); $icon = sprintf( " ", trailingslashit( $tec->pluginUrl ) . 'resources/warning.png' ); } // Look for an order_status_label, fall back on the actual order_status string @todo remove fallback in 3.4.3 $label = isset( $item['order_status_label'] ) ? $item['order_status_label'] : ucwords( $item['order_status'] ); return $icon . $label; } /** * Handler for the check in column * * @param $item * * @return string */ function column_check_in( $item ) { $checkin = sprintf( '%s', esc_attr( $item['attendee_id'] ), esc_attr( $item['provider'] ), __( 'Check in', 'tribe-events-calendar' ) ); $uncheckin = sprintf( '%s', esc_attr( $item['attendee_id'] ), esc_attr( $item['provider'] ), __( 'Undo Check in', 'tribe-events-calendar' ) ); return $checkin . $uncheckin; } /** * Generates content for a single row of the table * * @param object $item The current item */ function single_row( $item ) { static $row_class = ''; $row_class = ( $row_class == '' ? ' alternate ' : '' ); $checked = ''; if ( intval( $item["check_in"] ) === 1 ) $checked = ' tickets_checked '; echo ''; $this->single_row_columns( $item ); echo ''; } /** * Extra controls to be displayed between bulk actions and pagination. * * Used for the Print, Email and Export buttons, and for the jQuery based search. * */ function extra_tablenav( $which ) { echo '
'; echo sprintf( '', __( 'Print', 'tribe-events-calendar' ) ); echo sprintf( '', __( 'Email', 'tribe-events-calendar' ) ); echo sprintf( '%s', esc_url( add_query_arg( array( "attendees_csv" => true, "attendees_csv_nonce" => wp_create_nonce( 'attendees_csv_nonce' ) ) ) ), __( 'Export', 'tribe-events-calendar' ) ); echo '
'; if ( 'top' == $which ) { echo '
'; echo sprintf( '%s: ', __( "Filter by ticket #, order # or security code", "tribe-events-calendar" ) ); echo '
'; } } /** * Get an associative array ( option_name => option_title ) with the list * of bulk actions available on this table. * * @return array */ function get_bulk_actions() { $actions = array( 'check_in' => __( 'Check in', 'tribe-events-calendar' ), 'uncheck_in' => __( 'Undo Check in', 'tribe-events-calendar' ), 'delete_attendee' => __( 'Delete', 'tribe-events-calendar' ) ); return (array) apply_filters( 'tribe_events_tickets_attendees_table_bulk_actions', $actions ); } /** * Handler for the different bulk actions */ function process_bulk_action() { switch ( $this->current_action() ) { case 'check_in': $this->bulk_check_in(); break; case 'uncheck_in': $this->bulk_uncheck_in(); break; case 'delete_attendee': $this->bulk_delete(); break; default: do_action( 'tribe_events_tickets_attendees_table_process_bulk_action', $this->current_action() ); break; } } protected function bulk_check_in() { if ( ! isset( $_GET['attendee'] ) ) return; foreach ( (array) $_GET['attendee'] as $attendee ) { list( $id, $addon ) = $this->attendee_reference( $attendee ); if ( false === $id ) continue; $addon->checkin( $id ); } } protected function bulk_uncheck_in() { if ( ! isset( $_GET['attendee'] ) ) return; foreach ( (array) $_GET['attendee'] as $attendee ) { list( $id, $addon ) = $this->attendee_reference( $attendee ); if ( false === $id ) continue; $addon->uncheckin( $id ); } } protected function bulk_delete() { if ( ! isset( $_GET['attendee'] ) ) return; foreach ( (array) $_GET['attendee'] as $attendee ) { list( $id, $addon ) = $this->attendee_reference( $attendee ); if ( false === $id ) continue; $addon->delete_ticket( null, $id ); } } /** * Returns the attendee ID and instance of the specific ticketing solution or "addon" used * to handle it. * * This is used in the context of bulk actions where each attendee table entry is identified * by a string of the pattern {id}|{ticket_class} - where possible this method turns that into * an array consisting of the attendee object ID and the relevant ticketing object. * * If this cannot be determined, both array elements will be set to false. * * @param $reference * @return array */ protected function attendee_reference( $reference ) { $failed = array( false, false ); if ( false === strpos( $reference, '|' ) ) return $failed; $parts = explode( '|', $reference ); if ( count( $parts ) < 2 ) return $failed; $id = absint( $parts[0] ); if ( $id <= 0 ) return $failed; $addon = call_user_func( array( $parts[1], 'get_instance' ) ); if ( ! is_subclass_of( $addon, 'TribeEventsTickets' ) ) return $failed; return array( $id, $addon ); } /** * Prepares the list of items for displaying. */ function prepare_items() { $this->process_bulk_action(); $event_id = isset( $_GET['event_id'] ) ? $_GET['event_id'] : 0; $items = TribeEventsTickets::get_event_attendees( $event_id ); $this->items = $items; $total_items = count( $this->items ); $per_page = $total_items; $this->set_pagination_args( array( 'total_items' => $total_items, 'per_page' => $per_page, 'total_pages' => 1 ) ); } }