Skip to content

Commit

Permalink
Merge branch 'release/T24.chupacabra'
Browse files Browse the repository at this point in the history
  • Loading branch information
Camwyn committed Aug 22, 2024
2 parents 7adec0d + 13aca3e commit 54b05bd
Show file tree
Hide file tree
Showing 43 changed files with 591 additions and 184 deletions.
7 changes: 7 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

### [5.13.2] 2024-08-16

* Tweak - Start Sale and End Sale date will autopopulate when creating a new ticket. [ET-2103]
* Tweak - Update legacy Wallet Plus plugin notices to the new Tickets Plus plugin.
* Fix - Exporting all Attendees as a CSV file in the new Tickets Attendees Page. [ET-2094]
* Fix - Shared capacity will no longer be affected by any of the unlimited sales tickets on the same event. [ETP-920]

### [5.10.0] 2024-05-14

* Version - Event Tickets 5.10.0 is only compatible with The Events Calendar 6.5.0 and higher
Expand Down
4 changes: 0 additions & 4 deletions changelog/tweak-remove-etwp-upsell-notices

This file was deleted.

2 changes: 1 addition & 1 deletion event-tickets.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Plugin Name: Event Tickets
* Plugin URI: https://evnt.is/1acb
* Description: Event Tickets allows you to sell basic tickets and collect RSVPs from any post, page, or event.
* Version: 5.13.1
* Version: 5.13.2
* Requires at least: 6.3
* Requires PHP: 7.4
* Author: The Events Calendar
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "event-tickets",
"version": "5.13.1",
"version": "5.13.2",
"repository": "[email protected]:the-events-calendar/event-tickets.git",
"_zipname": "event-tickets",
"_zipfoldername": "event-tickets",
Expand Down
11 changes: 10 additions & 1 deletion readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Contributors: theeventscalendar, brianjessee, camwynsp, redscar, tribalmike, rafsuntaskin, aguseo, bordoni, borkweb, GeoffBel, jentheo, leahkoerper, lucatume, neillmcshea, vicskf, zbtirrell, juanfra
Tags: tickets, event registration, RSVP, ticket sales, attendee management
Stable tag: 5.13.1
Stable tag: 5.13.2
Requires at least: 6.3
Tested up to: 6.6.1
Requires PHP: 7.4
Expand Down Expand Up @@ -206,6 +206,15 @@ Check out our extensive [knowledgebase](https://evnt.is/18wm) for articles on us

== Changelog ==

= [5.13.2] 2024-09-20 =

* Fix - Exporting all Attendees as a CSV file in the new Tickets Attendees Page. [ET-2094]
* Fix - Shared capacity will no longer be affected by any of the unlimited sales tickets on the same event. [ETP-920]
* Tweak - Start Sale and End Sale date will autopopulate when creating a new ticket. [ET-2103]
* Tweak - Update legacy Wallet Plus plugin notices to the new Tickets Plus plugin.
* Tweak - Changed views: `v2/commerce/checkout/gateways`, `v2/commerce/checkout/purchaser-info`, `v2/commerce/checkout/purchaser-info/address`, `v2/commerce/checkout/purchaser-info/city`, `v2/commerce/checkout/purchaser-info/country`, `v2/commerce/checkout/purchaser-info/email`, `v2/commerce/checkout/purchaser-info/name`, `v2/commerce/checkout/purchaser-info/state`, `v2/commerce/checkout/purchaser-info/zip`, `v2/commerce/gateway/stripe/payment-element`
* Language - 2 new strings added, 33 updated, 0 fuzzied, and 0 obsoleted

= [5.13.1] 2024-08-06 =

* Fix - Ensure that users fill in all required billing address fields when Stripe advanced payment methods are available. [ETP-934]
Expand Down
7 changes: 6 additions & 1 deletion src/Tickets/Commerce/Flag_Actions/Increase_Sales.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class Increase_Sales extends Flag_Action_Abstract {
* {@inheritDoc}
*
* @since 5.2.0
* @since TBD Check shared capacity before sending to the `Ticket::increase_ticket_sales_by` method.
*/
public function handle( Status_Interface $new_status, $old_status, \WP_Post $post ) {
if ( empty( $post->items ) ) {
Expand All @@ -65,7 +66,11 @@ public function handle( Status_Interface $new_status, $old_status, \WP_Post $pos

$global_stock = new \Tribe__Tickets__Global_Stock( $ticket->get_event_id() );

tribe( Ticket::class )->increase_ticket_sales_by( $ticket->ID, $quantity, $ticket->global_stock_mode(), $global_stock );
// Is ticket shared capacity?
$global_stock_mode = $ticket->global_stock_mode();
$is_shared_capacity = ! empty( $global_stock_mode ) && 'own' !== $global_stock_mode;

tribe( Ticket::class )->increase_ticket_sales_by( $ticket->ID, $quantity, $is_shared_capacity, $global_stock );
}
}
}
3 changes: 2 additions & 1 deletion src/Tickets/Commerce/Ticket.php
Original file line number Diff line number Diff line change
Expand Up @@ -893,6 +893,7 @@ public function update_global_stock( $global_stock, $qty = 1, $increase = false
* @todo TribeCommerceLegacy: This should be moved into using a Flag Action.
*
* @since 5.1.9
* @since TBD Modified logic when updating global stock.
*
* @param int $ticket_id The ticket post ID.
* @param int $quantity The quantity to increase the ticket sales by.
Expand All @@ -917,7 +918,7 @@ public function increase_ticket_sales_by( $ticket_id, $quantity = 1, $shared_cap
$updated_total_sales
);

if ( 'own' !== $shared_capacity && $global_stock instanceof \Tribe__Tickets__Global_Stock ) {
if ( $shared_capacity && $global_stock instanceof \Tribe__Tickets__Global_Stock ) {
$this->update_global_stock( $global_stock, $quantity );
}

Expand Down
4 changes: 4 additions & 0 deletions src/Tickets/Flexible_Tickets/Series_Passes/Attendees.php
Original file line number Diff line number Diff line change
Expand Up @@ -1127,6 +1127,10 @@ public function delete_clones_on_delete( $post_id, $post ): void {
* @return int|array<int> The updated post ID or IDs.
*/
public function include_series_to_fetch_attendees( $post_id, $repository = null ): array {
if ( is_array( $post_id ) && 'all' === $post_id[0] ) {
return $post_id;
}

if ( ! $repository instanceof Tribe__Repository__Interface ) {
return $post_id;
}
Expand Down
129 changes: 71 additions & 58 deletions src/Tribe/Attendees.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use TEC\Tickets\Event;
use Tribe__Utils__Array as Arr;
use Tribe__Tickets__Tickets as Tickets;
use Tribe__Tickets__Ticket_Object as Ticket;
use Tribe__Tickets__Global_Stock as Global_Stock;
use TEC\Tickets\Admin\Attendees\Page as Attendees_Page;
Expand Down Expand Up @@ -174,7 +175,7 @@ public function print_checkedin_totals( $post_id ) {

$total_checked_in = $this->get_checkedin_total();
$check_in_percent = $this->get_checkedin_percentage( $post_id );
$total_attendees = Tribe__Tickets__Tickets::get_event_attendees_count( $post_id );
$total_attendees = Tickets::get_event_attendees_count( $post_id );

/** @var Tribe__Tickets__Admin__Views $admin_views */
$admin_views = tribe( 'tickets.admin.views' );
Expand Down Expand Up @@ -208,7 +209,7 @@ public function get_checkedin_total(): int {
*/
public function get_checkedin_percentage( $post_id ): string {
$total_checked_in = $this->get_checkedin_total();
$total = Tribe__Tickets__Tickets::get_event_attendees_count( $post_id );
$total = Tickets::get_event_attendees_count( $post_id );

// Remove the "Not Going" RSVPs.
$not_going = tribe( 'tickets.rsvp' )->get_attendees_count_not_going( $post_id );
Expand Down Expand Up @@ -278,7 +279,7 @@ public function filter_admin_row_actions( $actions ) {
return $actions;
}

$tickets = Tribe__Tickets__Tickets::get_event_tickets( $post->ID );
$tickets = Tickets::get_event_tickets( $post->ID );

// Only proceed if there are tickets.
if ( empty( $tickets ) ) {
Expand Down Expand Up @@ -434,6 +435,7 @@ public function load_pointers( $hook ) {
* Sets up the Attendees screen data.
*
* @since 4.6.2
* @since TBD Included param $all to allow for CSV export of all attendees.
*/
public function screen_setup() {
$page = tribe_get_request_var( 'page', false );
Expand Down Expand Up @@ -486,7 +488,7 @@ public function screen_setup() {
} else {
$this->attendees_table = new Tribe__Tickets__Attendees_Table();

$this->maybe_generate_csv();
$this->maybe_generate_csv( 'all' === tribe_get_request_var( 'event_id' ) );

add_filter( 'admin_title', [ $this, 'filter_admin_title' ], 10, 2 );
add_filter( 'admin_body_class', [ $this, 'filter_admin_body_class' ] );
Expand Down Expand Up @@ -554,16 +556,17 @@ public function render() {
* It's used both for the Email functionality, as well as the CSV export.
*
* @since 4.6.2
* @since TBD Included param $all to allow for CSV export of all attendees.
*
* @param $event_id
* @param int|string $event_id The ID of the event to export the list for or 'all' for all events.
*
* @return array
*/
private function generate_filtered_list( $event_id ) {
public function generate_filtered_list( $event_id ) {
/**
* Fire immediately prior to the generation of a filtered (exportable) attendee list.
*
* @param int $event_id
* @param int|string $event_id The ID of the event to export the list for or 'all' for all events.
*/
do_action( 'tribe_events_tickets_generate_filtered_attendees_list', $event_id );

Expand All @@ -575,7 +578,7 @@ private function generate_filtered_list( $event_id ) {
$filter_name = "manage_{$this->page_id}_columns";
add_filter( $filter_name, [ $this->attendees_table, 'get_columns' ], 15 );

$items = Tribe__Tickets__Tickets::get_event_attendees( $event_id );
$items = 'all' === $event_id ? Tickets::get_attendees_by_args()['attendees'] : Tickets::get_event_attendees( $event_id );

// Add Handler for Community Tickets to Prevent Notices in Exports.
if ( ! is_admin() ) {
Expand All @@ -596,6 +599,7 @@ private function generate_filtered_list( $event_id ) {
'purchaser',
'status',
'attendee_actions',
'attendee_event',
]
);

Expand Down Expand Up @@ -750,74 +754,82 @@ public function sanitize_csv_value( $value ) {
* If so, generates the download and finishes the execution.
*
* @since 4.6.2
* @since TBD Included param $all to allow for CSV export of all attendees.
*
* @param bool $all Whether to generate a CSV for attendees of all events or just the current one.
*
* @return void
*/
public function maybe_generate_csv() {
if ( empty( $_GET['attendees_csv'] ) || empty( $_GET['attendees_csv_nonce'] ) || empty( $_GET['event_id'] ) ) {
public function maybe_generate_csv( $all = false ) {
if (
! isset( $_GET['attendees_csv_nonce'] )
|| ! wp_verify_nonce( sanitize_key( $_GET['attendees_csv_nonce'] ), 'attendees_csv_nonce' )
|| empty( $_GET['attendees_csv'] )
|| ! current_user_can( 'manage_options' ) ) {
return;
}

$event_id = absint( $_GET['event_id'] );

$event_id = Event::filter_event_id( $event_id, 'attendee-csv-report' );

// Verify event ID is a valid integer and the nonce is accepted.
if ( empty( $event_id ) || ! wp_verify_nonce( $_GET['attendees_csv_nonce'], 'attendees_csv_nonce' ) ) {
return;
}
if ( ! $all ) {
$event_id = isset( $_GET['event_id'] ) ? absint( sanitize_key( $_GET['event_id'] ) ) : 0;
$event_id = Event::filter_event_id( $event_id, 'attendee-csv-report' );
$event = get_post( $event_id );

$event = get_post( $event_id );
if ( is_null( $event ) ) {
return;
}

// Verify event exists and current user has access to it.
if (
! $event instanceof WP_Post
|| ! $this->user_can( 'edit_posts', $event_id )
) {
return;
$items = $this->generate_filtered_list( $event_id );
} else {
$event_id = 'all';
$items = $this->generate_filtered_list( 'all' );
}

// Generate filtered list of attendees.
$items = $this->generate_filtered_list( $event_id );

// Sanitize items for CSV usage.
$items = $this->sanitize_csv_rows( $items );

/**
* Allow for filtering and modifying the list of attendees that will be exported via CSV for a given event.
*
* @param array $items The array of attendees that will be exported in this CSV file.
* @param int $event_id The ID of the event these attendees are associated with.
* @param int|string $event_id The ID of the event these attendees are associated with or 'all' for all events.
*/
$items = apply_filters( 'tribe_events_tickets_attendees_csv_items', $items, $event_id );

if ( ! empty( $items ) ) {
$charset = get_option( 'blog_charset' );
$filename = sanitize_file_name( $event->post_title . '-' . __( 'attendees', 'event-tickets' ) );

// Output headers so that the file is downloaded rather than displayed.
header( "Content-Type: text/csv; charset=$charset" );
header( "Content-Disposition: attachment; filename=$filename.csv" );

// Create the file pointer connected to the output stream.
$output = fopen( 'php://output', 'w' );

/**
* Allow filtering the field delimiter used in the CSV export file.
*
* @since 5.1.3
*
* @param string $delimiter The field delimiter used in the CSV export file.
*/
$delimiter = apply_filters( 'tribe_tickets_attendees_csv_export_delimiter', ',' );

// Output the lines into the file.
foreach ( $items as $item ) {
fputcsv( $output, $item, $delimiter );
}
if ( empty( $items ) ) {
return;
}

fclose( $output );
exit;
$charset = get_option( 'blog_charset' );

if ( ! $all ) {
$filename = sanitize_file_name( $event->post_title . '-' . _x( 'attendees', 'CSV export file name', 'event-tickets' ) );
} else {
$filename = sanitize_file_name( _x( 'All event attendees', 'CSV export file name', 'event-tickets' ) );
}

// Output headers so that the file is downloaded rather than displayed.
header( "Content-Type: text/csv; charset={$charset}" );
header( "Content-Disposition: attachment; filename={$filename}.csv" );

// Create the file pointer connected to the output stream.
$output = fopen( 'php://output', 'w' );

/**
* Allow filtering the field delimiter used in the CSV export file.
*
* @since 5.1.3
*
* @param string $delimiter The field delimiter used in the CSV export file.
*/
$delimiter = apply_filters( 'tribe_tickets_attendees_csv_export_delimiter', ',' );

// Output the lines into the file.
foreach ( $items as $item ) {
fputcsv( $output, $item, $delimiter ); // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.file_ops_fputcsv
}

fclose( $output );
exit;
}

/**
Expand All @@ -832,7 +844,6 @@ public function maybe_generate_csv() {
* @param ?string|?int $send_to The recipient's ID or email.
* If $type is 'user', this should be the user ID.
*
*
* @return true|WP_Error
*/
public function has_attendees_list_access( $event_id = null, ?string $nonce = null, ?string $type = 'user', $send_to = null ) {
Expand Down Expand Up @@ -1092,7 +1103,7 @@ public function update_attendee( $attendee, $attendee_data ) {
$provider = tribe_tickets_get_ticket_provider( (int) $attendee );
} elseif ( is_array( $attendee ) && isset( $attendee['provider'] ) ) {
// Try to get provider from the attendee data.
$provider = Tribe__Tickets__Tickets::get_ticket_provider_instance( $attendee['provider'] );
$provider = Tickets::get_ticket_provider_instance( $attendee['provider'] );
}

if ( ! $provider ) {
Expand All @@ -1106,6 +1117,7 @@ public function update_attendee( $attendee, $attendee_data ) {
* Generate the export URL for exporting attendees.
*
* @since 5.1.7
* @since TBD Included param $all to allow for CSV export of all attendees.
*
* @return string Relative URL for the export.
*/
Expand All @@ -1114,6 +1126,7 @@ public function get_export_url() {
[
'attendees_csv' => true,
'attendees_csv_nonce' => wp_create_nonce( 'attendees_csv_nonce' ),
'event_id' => tribe_get_request_var( 'event_id' ) ?? 'all',
]
);
}
Expand Down Expand Up @@ -1175,7 +1188,7 @@ public function include_export_button_title( $event_id, Tribe__Tickets__Attendee
* @return array<string,mixed> The context used to render the Attendees page.
*/
public function get_render_context( int $post_id ): array {
$tickets = Tribe__Tickets__Tickets::get_event_tickets( $post_id );
$tickets = Tickets::get_event_tickets( $post_id );
$tickets_by_type = [ 'rsvp' => [], 'default' => [] ];
$ticket_totals = [
'sold' => 0,
Expand Down
2 changes: 1 addition & 1 deletion src/Tribe/Main.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class Tribe__Tickets__Main {
/**
* Current version of this plugin.
*/
const VERSION = '5.13.1';
const VERSION = '5.13.2';

/**
* Used to store the version history.
Expand Down
Loading

0 comments on commit 54b05bd

Please sign in to comment.