<?php
class Tribe__Tickets__Editor__Blocks__Rsvp extends Tribe__Editor__Blocks__Abstract {
/**
* Init class
*
* @since 4.9
*
* @return void
*/
public function hook() {
// Add AJAX calls.
add_action( 'wp_ajax_rsvp-form', [ $this, 'rsvp_form' ] );
add_action( 'wp_ajax_nopriv_rsvp-form', [ $this, 'rsvp_form' ] );
add_action( 'wp_ajax_rsvp-process', [ $this, 'rsvp_process' ] );
add_action( 'wp_ajax_nopriv_rsvp-process', [ $this, 'rsvp_process' ] );
}
/**
* Which is the name/slug of this block
*
* @since 4.9
*
* @return string
*/
public function slug() {
return 'rsvp';
}
/**
* Set the default attributes of this block
*
* @since 4.9
*
* @return array
*/
public function default_attributes() {
return [];
}
/**
* Since we are dealing with a Dynamic type of Block we need a PHP method to render it
*
* @since 4.9
*
* @param array $attributes Block attributes.
*
* @return string
*/
public function render( $attributes = [] ) {
/** @var Tribe__Tickets__Editor__Template $template */
$template = tribe( 'tickets.editor.template' );
$post_id = $template->get( 'post_id', null, false );
$tickets_view = Tribe__Tickets__Tickets_View::instance();
return $tickets_view->get_rsvp_block( $post_id, false );
}
/**
* Method to get all RSVP tickets
*
* @since 4.9
*
* @return array
*/
public function get_tickets( $post_id ) {
$tickets = [];
// Bail if there's no event id.
if ( ! $post_id ) {
return $tickets;
}
/** @var Tribe__Tickets__RSVP $rsvp */
$rsvp = tribe( 'tickets.rsvp' );
// Get the tickets IDs for this event.
$ticket_ids = $rsvp->get_tickets_ids( $post_id );
// Bail if we don't have tickets.
if ( ! $ticket_ids ) {
return $tickets;
}
// We only want RSVP tickets.
foreach ( $ticket_ids as $post ) {
// Get the ticket
$ticket = $rsvp->get_ticket( $post_id, $post );
if (
! $ticket instanceof Tribe__Tickets__Ticket_Object
|| $rsvp->class_name !== $ticket->provider_class
) {
continue;
}
$tickets[] = $ticket;
}
return $tickets;
}
/**
* Method to get the active RSVP tickets
*
* @since 4.9
*
* @return array
*/
public function get_active_tickets( $tickets ) {
$active_tickets = [];
foreach ( $tickets as $ticket ) {
// Continue if it's not in date range.
if ( ! $ticket->date_in_range() ) {
continue;
}
$active_tickets[] = $ticket;
}
return $active_tickets;
}
/**
* Method to get the all RSVPs past flag
* All RSVPs past flag is true if all RSVPs end date is earlier than current date
* If there are no RSVPs, false is returned
*
* @since 4.9
*
* @return bool
*/
public function get_all_tickets_past( $tickets ) {
if ( empty( $tickets ) ) {
return false;
}
$all_past = true;
foreach ( $tickets as $ticket ) {
$all_past = $all_past && $ticket->date_is_later();
}
return $all_past;
}
/**
* Get the threshold.
*
* @since 4.12.3
*
* @param int $post_id
*
* @return int
*/
public function get_threshold( $post_id = 0 ) {
/** @var Tribe__Settings_Manager $settings_manager */
$settings_manager = tribe( 'settings.manager' );
$threshold = $settings_manager::get_option( 'ticket-display-tickets-left-threshold', 0 );
/**
* Overwrites the threshold to display "# tickets left".
*
* @since 4.11.1
*
* @param int $threshold Stock threshold to trigger display of "# tickets left" text.
* @param int $post_id Event ID.
*/
$threshold = absint( apply_filters( 'tribe_display_rsvp_block_tickets_left_threshold', $threshold, $post_id ) );
return $threshold;
}
/**
* Show unlimited?
*
* @since 4.12.3
*
* @param bool $is_unlimited
*
* @return bool
*/
public function show_unlimited( $is_unlimited ) {
/**
* Allows hiding of "unlimited" to be toggled on/off conditionally.
*
* @since 4.11.1
*
* @param int $show_unlimited allow showing of "unlimited".
*/
return (bool) apply_filters( 'tribe_rsvp_block_show_unlimited_availability', false, $is_unlimited );
}
/**
* Register block assets
*
* @since 4.9
*
* @return void
*/
public function assets() {
$plugin = Tribe__Tickets__Main::instance();
tec_asset(
$plugin,
'tribe-tickets-gutenberg-rsvp',
'rsvp-block.js',
[ 'jquery' ],
null,
[
'localize' => [
'name' => 'TribeRsvp',
'data' => fn() => [
'ajaxurl' => admin_url( 'admin-ajax.php', ( is_ssl() ? 'https' : 'http' ) ),
'nonces' => [
'rsvpHandle' => wp_create_nonce( 'tribe_tickets_rsvp_handle' )
],
],
],
]
);
tec_asset(
$plugin,
'tribe-tickets-gutenberg-block-rsvp-style',
'rsvp/frontend.css'
);
tec_asset(
$plugin,
'tribe-tickets-rsvp-ari',
'v2/rsvp-ari.js',
[ 'jquery', 'wp-util', 'tribe-common' ],
null,
[
'groups' => 'tribe-tickets-rsvp',
'conditionals' => [ $this, 'should_enqueue_ari' ],
'localize' => [
'name' => 'TribeRsvp',
'data' => fn() => [
'ajaxurl' => admin_url( 'admin-ajax.php', ( is_ssl() ? 'https' : 'http' ) ),
'nonces' => [
'rsvpHandle' => wp_create_nonce( 'tribe_tickets_rsvp_handle' )
],
],
],
]
);
tec_asset(
$plugin,
'tribe-tickets-rsvp-manager',
'v2/rsvp-manager.js',
[
'jquery',
'tribe-common',
'tribe-tickets-rsvp-block',
'tribe-tickets-rsvp-tooltip',
'tribe-tickets-rsvp-ari',
],
null,
[
'localize' => [
'name' => 'TribeRsvp',
'data' => static function () {
return [
'ajaxurl' => admin_url( 'admin-ajax.php', ( is_ssl() ? 'https' : 'http' ) ),
'cancelText' => __( 'Are you sure you want to cancel?', 'event-tickets' ),
];
},
],
'groups' => 'tribe-tickets-rsvp',
]
);
tec_asset(
$plugin,
'tribe-tickets-rsvp-block',
'v2/rsvp-block.js',
[ 'jquery' ],
null,
[ 'groups' => 'tribe-tickets-rsvp' ]
);
tec_asset(
$plugin,
'tribe-tickets-rsvp-tooltip',
'v2/rsvp-tooltip.js',
[
'jquery',
'tribe-common',
'tribe-tooltipster',
],
null,
[
'groups' => 'tribe-tickets-rsvp',
]
);
tec_asset(
$plugin,
'tribe-tickets-rsvp-style',
'rsvp.css',
[ 'tribe-common-skeleton-style', 'tribe-common-responsive' ],
null
);
$stylesheet = Tribe__Templates::locate_stylesheet( 'tribe-events/tickets/rsvp.css' );
if ( $stylesheet ) {
tec_asset(
$plugin,
'tribe-tickets-rsvp-style-override',
$stylesheet,
[],
null
);
}
}
/**
* Determine whether we should enqueue the ARI assets.
*
* @since 5.0.0
*
* @return bool Whether we should enqueue the ARI assets.
*/
public function should_enqueue_ari() {
return class_exists( 'Tribe__Tickets_Plus__Main' );
}
/**
* Function that returns the RSVP form from an AJAX call
*
* @since 4.9
*
* @return void
*/
public function rsvp_form() {
$response = [
'html' => '',
'view' => 'rsvp-form',
];
$ticket_id = absint( tribe_get_request_var( 'ticket_id', 0 ) );
$going = tribe_get_request_var( 'going', 'yes' );
if ( 0 === $ticket_id ) {
wp_send_json_error( $response );
}
/** @var Tribe__Tickets__RSVP $rsvp */
$rsvp = tribe( 'tickets.rsvp' );
$ticket = $rsvp->get_ticket( get_the_id(), $ticket_id );
if ( ! $ticket instanceof Tribe__Tickets__Ticket_Object ) {
wp_send_json_error( $response );
}
$args = [
'post_id' => $ticket->get_event_id(),
'ticket' => $ticket,
'going' => $going,
];
/** @var Tribe__Tickets__Editor__Template $template */
$template = tribe( 'tickets.editor.template' );
$html = $template->template( 'blocks/rsvp/form/form', $args, false );
$response['html'] = $html;
wp_send_json_success( $response );
}
/**
* Function that process the RSVP
*
* @since 4.9
*
* @return void
*/
public function rsvp_process() {
$response = [
'html' => '',
'view' => 'rsvp-process',
];
$ticket_id = absint( tribe_get_request_var( 'ticket_id', 0 ) );
if ( 0 === $ticket_id ) {
wp_send_json_error( $response );
}
/** @var Tribe__Tickets__RSVP $rsvp */
$rsvp = tribe( 'tickets.rsvp' );
$has_tickets = false;
$event = $rsvp->get_event_for_ticket( $ticket_id );
$post_id = $event->ID;
$ticket = $rsvp->get_ticket( $post_id, $ticket_id );
/**
* RSVP specific action fired just before a RSVP-driven attendee tickets for an order are generated
*
* @param array $data $_POST Parameters comes from RSVP Form
*/
do_action( 'tribe_tickets_rsvp_before_order_processing' );
$attendee_details = $rsvp->parse_attendee_details();
if ( false === $attendee_details ) {
wp_send_json_error( $response );
}
$products = [];
if ( isset( $_POST['tribe_tickets'] ) ) {
$products = wp_list_pluck( $_POST['tribe_tickets'], 'ticket_id' );
} elseif ( isset( $_POST['product_id'] ) ) {
$products = (array) $_POST['product_id'];
}
// Iterate over each product.
foreach ( $products as $product_id ) {
if ( ! $ticket_qty = $rsvp->parse_ticket_quantity( $product_id ) ) {
// if there were no RSVP tickets for the product added to the cart, continue.
continue;
}
$has_tickets = ! is_wp_error( $rsvp->generate_tickets_for( $product_id, $ticket_qty, $attendee_details ) );
}
$order_id = $attendee_details['order_id'];
$attendee_order_status = $attendee_details['order_status'];
/**
* Fires when an RSVP attendee tickets have been generated.
*
* @param int $order_id ID of the RSVP order
* @param int $post_id ID of the post the order was placed for
* @param string $attendee_order_status 'yes' if the user indicated they will attend
*/
do_action( 'event_tickets_rsvp_tickets_generated', $order_id, $post_id, $attendee_order_status );
$send_mail_stati = [ 'yes' ];
/**
* Filters whether a confirmation email should be sent or not for RSVP tickets.
*
* This applies to attendance and non attendance emails.
*
* @param bool $send_mail Defaults to `true`.
*/
$send_mail = apply_filters( 'tribe_tickets_rsvp_send_mail', true );
if ( $send_mail && $has_tickets ) {
/**
* Filters the attendee order stati that should trigger an attendance confirmation.
*
* Any attendee order status not listed here will trigger a non attendance email.
*
* @param array $send_mail_stati An array of default stati triggering an attendance email.
* @param int $order_id ID of the RSVP order
* @param int $post_id ID of the post the order was placed for
* @param string $attendee_order_status 'yes' if the user indicated they will attend
*/
$send_mail_stati = apply_filters(
'tribe_tickets_rsvp_send_mail_stati',
$send_mail_stati,
$order_id,
$post_id,
$attendee_order_status
);
// No point sending tickets if their current intention is not to attend
if ( in_array( $attendee_order_status, $send_mail_stati, true ) ) {
$rsvp->send_tickets_email( $order_id, $post_id );
} else {
$rsvp->send_non_attendance_confirmation( $order_id, $post_id );
}
}
$args = [
'ticket' => $ticket,
];
$remaining = $ticket->remaining();
/** @var Tribe__Tickets__Editor__Template $template */
$template = tribe( 'tickets.editor.template' );
if ( ! $remaining ) {
$response['status_html'] = $template->template( 'blocks/rsvp/status', $args, false );
}
$response['remaining'] = $ticket->remaining();
$response['remaining_html'] = $template->template( 'blocks/rsvp/details/availability', $args, false );
$response['html'] = $template->template( 'blocks/rsvp/messages/success', $args, false );
wp_send_json_success( $response );
}
}
|