| Current File : /home/digitaw/www/wp-content/plugins/event-tickets/src/Tickets/Blocks/Tickets/Block.php |
<?php
/**
* Provides the information required to register the Tickets block server-side.
*
* @since 5.8.0
*
* @package TEC\Tickets\Blocks\Tickets;
*/
namespace TEC\Tickets\Blocks\Tickets;
use Tribe__Editor__Blocks__Abstract as Abstract_Block;
use Tribe__Tickets__Editor__Template as Template;
use Tribe__Tickets__Main as Tickets_Main;
use Tribe__Tickets__RSVP as RSVP;
use Tribe__Tickets__Status__Manager as Status_Manager;
use Tribe__Tickets__Ticket_Object as Ticket_Object;
use Tribe__Tickets__Tickets as Tickets;
use Tribe__Tickets__Tickets_Handler as Tickets_Handler;
use Tribe__Tickets__Tickets_View as Tickets_View;
use TEC\Common\Asset;
/**
* Class Block.
*
* @since 5.8.0
*
* @package TEC\Tickets\Blocks\Tickets;
*/
class Block extends Abstract_Block {
/**
* The slug of the editor script.
*
* @since 5.20.0
*
* @var string
*/
public const EDITOR_SCRIPT_SLUG = 'tec-tickets-tickets-block-editor-script';
/**
* The slug of the editor style.
*
* @since 5.20.0
*
* @var string
*/
public const EDITOR_STYLE_SLUG = 'tec-tickets-tickets-block-editor-style';
/**
* The slug of the frontend script.
*
* @since 5.20.0
*
* @var string
*/
public const FRONTEND_SCRIPT_SLUG = 'tribe-tickets-block';
/**
* Hooks the block on the required actions.
*
* @since 5.8.0
*/
public function hook() {
add_action( 'wp_ajax_ticket_availability_check', [ $this, 'ticket_availability' ] );
add_action( 'wp_ajax_nopriv_ticket_availability_check', [ $this, 'ticket_availability' ] );
}
/**
* Which is the name/slug of this block
*
* @since 4.9
*
* @return string
*/
public function slug() {
return 'tickets';
}
/**
* Since we are dealing with a Dynamic type of Block we need a PHP method to render it
*
* @since 4.9
*
* @param array<string,mixed> $attributes The attributes to use when rendering the block.
*
* @return string
*/
public function render( $attributes = [] ) {
/** @var Template $template */
$template = tribe( 'tickets.editor.template' );
$post_id = $template->get( 'post_id', null, false );
$tickets_view = Tickets_View::instance();
return $tickets_view->get_tickets_block( $post_id, false );
}
/**
* Register block assets
*
* @since 4.9
*
* @return void
*/
public function assets() {
// Check whether we use v1 or v2. We need to update this when we deprecate tickets v1.
$tickets_js = tribe_tickets_new_views_is_enabled() ? 'v2/tickets-block.js' : 'tickets-block.js';
$plugin = Tickets_Main::instance();
tec_asset(
$plugin,
self::FRONTEND_SCRIPT_SLUG,
$tickets_js,
[
'jquery',
'wp-util',
'wp-i18n',
'wp-hooks',
'tribe-common',
],
null,
[
'type' => 'js',
'groups' => [ 'tribe-tickets-block-assets' ],
'localize' => [
[
'name' => 'TribeTicketOptions',
'data' => [ 'Tribe__Tickets__Tickets', 'get_asset_localize_data_for_ticket_options' ],
],
[
'name' => 'TribeCurrency',
'data' => [ 'Tribe__Tickets__Tickets', 'get_asset_localize_data_for_currencies' ],
],
[
'name' => 'TribeCartEndpoint',
'data' => static function () {
return [ 'url' => tribe_tickets_rest_url( '/cart/' ) ];
},
],
[
'name' => 'TribeMessages',
'data' => [ $this, 'set_messages' ],
],
[
'name' => 'TribeTicketsURLs',
'data' => [ 'Tribe__Tickets__Tickets', 'get_asset_localize_data_for_cart_checkout_urls' ],
],
],
]
);
Tickets::$frontend_script_enqueued = true;
}
/**
* Overrides the parent method to register the editor scripts.
*
* @since 5.8.0
*
* @return void
*/
public function register() {
parent::register();
add_action( 'admin_enqueue_scripts', [ $this, 'register_editor_scripts' ] );
}
/**
* Check for ticket availability
*
* @since 4.9
*
* @param int[] $tickets The IDs of tickets to check.
*
* @return void
*/
public function ticket_availability( $tickets = [] ) {
$response = [ 'html' => '' ];
$tickets ??= tribe_get_request_var( 'tickets', [] );
// Bail if we receive no tickets.
if ( empty( $tickets ) ) {
wp_send_json_error( $response );
}
/** @var Tickets_Handler $tickets_handler */
$tickets_handler = tribe( 'tickets.handler' );
/** @var Template $tickets_editor */
$tickets_editor = tribe( 'tickets.editor.template' );
// Parse the tickets and create the array for the response.
foreach ( $tickets as $ticket_id ) {
$ticket = Tickets::load_ticket_object( $ticket_id );
if (
! $ticket instanceof Ticket_Object
|| empty( $ticket->ID )
) {
continue;
}
$available = $ticket->available();
$max_at_a_time = $tickets_handler->get_ticket_max_purchase( $ticket->ID );
$response['tickets'][ $ticket_id ]['available'] = $available;
$response['tickets'][ $ticket_id ]['max_purchase'] = $max_at_a_time;
// If there are no more available we will send the template part HTML to update the DOM.
if ( 0 === $available ) {
$response['tickets'][ $ticket_id ]['unavailable_html'] = $tickets_editor->template( 'blocks/tickets/quantity-unavailable', $ticket, false );
}
}
wp_send_json_success( $response );
}
/**
* Get all tickets for event/post, other than RSVP type because they're presented in a separate block.
*
* @since 4.9
*
* @param int $post_id Post ID.
*
* @return array
*/
public function get_tickets( $post_id ) {
$all_tickets = Tickets::get_all_event_tickets( $post_id );
if ( ! $all_tickets ) {
return [];
}
/** @var RSVP $rsvp */
$rsvp = tribe( 'tickets.rsvp' );
$tickets = [];
// We only want RSVP tickets.
foreach ( $all_tickets as $ticket ) {
if (
! $ticket instanceof Ticket_Object
|| $rsvp->class_name === $ticket->provider_class
) {
continue;
}
$tickets[] = $ticket;
}
return $tickets;
}
/**
* Get provider ID/slug.
*
* @since 4.9
* @since 4.12.3 Retrieve slug from updated Ticktes Status Manager method.
*
* @param Tickets $provider Provider class instance.
*
* @return string
*/
public function get_provider_id( $provider ) {
/** @var Status_Manager $status */
$status = tribe( 'tickets.status' );
$slug = $status->get_provider_slug( $provider );
if (
empty( $slug )
|| 'rsvp' === $slug
) {
$slug = 'tpp';
}
return $slug;
}
/**
* Get all tickets on sale
*
* @since 4.9
*
* @param array $tickets Array of all tickets.
*
* @return array
*/
public function get_tickets_on_sale( $tickets ) {
$tickets_on_sale = [];
foreach ( $tickets as $ticket ) {
if ( tribe_events_ticket_is_on_sale( $ticket ) ) {
$tickets_on_sale[] = $ticket;
}
}
return $tickets_on_sale;
}
/**
* Get whether all ticket sales have passed or not
*
* @since 4.9
*
* @param array $tickets Array of all tickets.
*
* @return bool
*/
public function get_is_sale_past( $tickets ) {
$is_sale_past = ! empty( $tickets );
foreach ( $tickets as $ticket ) {
$is_sale_past = ( $is_sale_past && $ticket->date_is_later() );
}
return $is_sale_past;
}
/**
* Get whether no ticket sales have started yet
*
* @since 4.11.0
*
* @param array $tickets Array of all tickets.
*
* @return bool
*/
public function get_is_sale_future( $tickets ) {
$is_sale_future = ! empty( $tickets );
foreach ( $tickets as $ticket ) {
$is_sale_future = ( $is_sale_future && $ticket->date_is_earlier() );
}
return $is_sale_future;
}
/**
* Localized messages for errors, etc in javascript. Added in assets() above.
* Set up this way to amke it easier to add messages as needed.
*
* @since 4.11.0
*
* @return array<string,string> The localized messages.
*/
public function set_messages() {
return [
'api_error_title' => _x( 'API Error', 'Error message title, will be followed by the error code.', 'event-tickets' ),
'connection_error' => __( 'Refresh this page or wait a few minutes before trying again. If this happens repeatedly, please contact the Site Admin.', 'event-tickets' ),
'capacity_error' => sprintf(
/* Translators: %s - the singular, lowercase label for a ticket. */
__( 'The %s for this event has sold out and has been removed from your cart.', 'event-tickets' ),
tribe_get_ticket_label_singular_lowercase()
),
'validation_error_title' => __( 'Whoops!', 'event-tickets' ),
/* Translators: %s - the HTML of the number of tickets with validation errors. */
'validation_error' => '<p>' . sprintf( _x( 'You have %s ticket(s) with a field that requires information.', 'The %s will change based on the error produced.', 'event-tickets' ), '<span class="tribe-tickets__notice--error__count">0</span>' ) . '</p>',
];
}
/**
* {@inheritDoc}
*
* @since 5.8.0
*/
public function get_registration_block_type() {
return __DIR__ . '/block.json';
}
/**
* {@inheritDoc}
*
* @since 5.8.0
*
* @param array<string,mixed> $args The default arguments the block would be registered with if this method is not
* overridden.
*
* @return array<string,mixed> The arguments to use when registering the block.
*/
public function get_registration_args( array $args ): array {
$args['title'] = _x( 'Tickets', 'Block title', 'event-tickets' );
$args['description'] = _x( 'Sell tickets and register attendees.', 'Block description', 'event-tickets' );
return $args;
}
/**
* Registers the editor scripts.
*
* @since 5.8.0
* @since 5.20.0 - Changed from WP methods to StellarWP/assets.
*
* @return void
*/
public function register_editor_scripts() {
Asset::add(
self::EDITOR_SCRIPT_SLUG,
'Tickets/editor.js',
Tickets_Main::VERSION
)
->add_to_group_path( 'et-tickets-blocks' )
->set_dependencies(
'tribe-tickets-gutenberg-vendor',
'tribe-common-gutenberg-vendor'
)
->in_header()
->register();
Asset::add(
self::EDITOR_STYLE_SLUG,
'Tickets/style-editor.css',
Tickets_Main::VERSION
)
->add_to_group_path( 'et-tickets-blocks' )
->set_dependencies( 'tribe-tickets-gutenberg-main-styles' )
->register();
}
}