<?php
/**
* Class Tribe__Tickets__Editor
*
* @since 4.9
*/
class Tribe__Tickets__Editor extends Tribe__Editor {
/**
* Variable used as a flag to detect if we should flush the tickets blocks
*
* @since 4.9.2
*
* @var string
*/
public $meta_key_flush_flag = '_tribe_tickets_flush_blocks';
/**
* Hooks actions from the editor into the correct places
*
* @since 4.9
*
* @return bool
*/
public function hook() {
// Add Rest API support
add_filter( 'tribe_tickets_register_ticket_post_type_args', array( $this, 'add_rest_support' ) );
// Update Post content to use correct child blocks for tickets
add_filter( 'tribe_blocks_editor_update_classic_content', array( $this, 'update_tickets_block_with_childs' ), 10, 3 );
// Add RSVP and tickets blocks
add_action( 'admin_init', array( $this, 'add_tickets_block_in_editor' ) );
add_filter( 'tribe_events_editor_default_classic_template', array( $this, 'filter_default_template_classic_blocks' ), 15 );
add_action( 'tribe_events_tickets_post_capacity', tribe_callback( 'tickets.admin.views', 'template', 'editor/button-view-orders' ) );
add_action( 'tribe_events_tickets_metabox_edit_main', array( $this, 'filter_get_price_fields' ), 10, 2 );
add_action( 'tribe_events_tickets_capacity', tribe_callback( 'tickets.admin.views', 'template', 'editor/total-capacity' ) );
add_action( 'tribe_events_tickets_ticket_table_add_header_column', tribe_callback( 'tickets.admin.views', 'template', 'editor/column-head-price' ) );
add_action( 'tribe_events_tickets_ticket_table_add_tbody_column', array( $this, 'add_column_content_price' ), 10, 2 );
add_action( "tec_tickets_editor_list_table_title_icon_rsvp", tribe_callback( 'tickets.admin.views', 'template', 'editor/icons/rsvp' ) );
add_action( "tec_tickets_editor_list_table_title_icon_default", tribe_callback( 'tickets.admin.views', 'template', 'editor/icons/ticket' ) );
// Maybe add flag from classic editor
add_action( 'load-post.php', array( $this, 'flush_blocks' ), 0 );
add_action( 'tribe_tickets_update_blocks_from_classic_editor', array( $this, 'update_blocks' ) );
}
/**
* Adds the ticket block into the editor
*
* @since 4.9
*
*
* @param array $template Array of all the templates used by default
* @param string $post_type The current post type
*
* @return array
*/
public function add_tickets_block_in_editor() {
// Post types where the block shouldn't be displayed by default
if ( ! class_exists( 'Tribe__Events__Main' ) ) {
return;
}
foreach ( $this->get_enabled_post_types() as $post_type ) {
$post_type_object = get_post_type_object( $post_type );
if ( ! $post_type_object || $post_type !== Tribe__Events__Main::POSTTYPE ) {
continue;
}
$template = isset( $post_type_object->template )
? (array) $post_type_object->template
: array();
$template[] = array( 'tribe/tickets' );
$template[] = array( 'tribe/rsvp' );
$post_type_object->template = $template;
}
}
/**
* Filters and adds the ticket block into the default classic blocks
*
* @since 4.9
*
* @param array $template
*
* @return array
*/
public function filter_default_template_classic_blocks( $template = array() ) {
$template[] = array( 'tribe/tickets' );
$template[] = array( 'tribe/rsvp' );
$template[] = array( 'tribe/attendees' );
return $template;
}
/**
* Check if current admin page is post type `tribe_events`
*
* @since 4.9
* @since 5.5.0 renamed from `current_type_support_tickets`
*
* @param mixed $post_type
*
* @return bool
*/
public function current_post_supports_tickets( $post_type = null ) {
$post_types = $this->get_enabled_post_types();
if ( ! is_null( $post_type ) ) {
return in_array( $post_type, $post_types, true );
}
$is_valid_type = false;
$helper = Tribe__Admin__Helpers::instance();
foreach ( $this->get_enabled_post_types() as $type ) {
$is_valid_type = $helper->is_post_type_screen( $type );
if ( $is_valid_type ) {
break;
}
}
if ( ! $is_valid_type ) {
return false;
}
global $post_id;
/**
* Allows overriding the ability of a post to support tickets, as long as the post_type supports tickets.
*
* @since 5.5.0
*
* @param bool $can_have_tickets the post type slug
* @param int $post_id the post id
*/
return apply_filters( 'event_tickets_post_supports_tickets', true, $post_id );
}
/**
* Making sure we have correct post content for tickets blocks after going into Gutenberg
*
* @since 4.9
*
* @param string $content Content that will be updated
* @param WP_Post $post Which post we will migrate
* @param array $blocks Which blocks we are updating with
*
* @return bool
*/
public function update_tickets_block_with_childs( $content, $post, $blocks ) {
$search = '<!-- wp:tribe/tickets /-->';
// Do we have a tickets blocks already setup? (we should)
if ( false === strpos( $content, $search ) ) {
return $content;
}
$replace = $this->get_tickets_as_blocks( $post->ID );
// Do the actual replace for tickets blocks
$content = str_replace( $search, implode( "\n\r", $replace ), $content );
return $content;
}
/**
* Return an array with all the tickets as a group of items in an array as strings as blocks
* formats ready to be inserted into the post_content of a post
*
* @since 4.9.2
*
* @param int $post_id The Post ID of the event.
*
* @return array
*/
public function get_tickets_as_blocks( $post_id ) {
$tickets = Tribe__Tickets__Tickets::get_all_event_tickets( $post_id );
$blocks[] = '<!-- wp:tribe/tickets --><div class="wp-block-tribe-tickets">';
foreach ( $tickets as $key => $ticket ) {
// Skip RSVP items
if ( 'Tribe__Tickets__RSVP' === $ticket->provider_class ) {
continue;
}
// Insert into the replace a single Child ticket
$blocks[] = '<!-- wp:tribe/tickets-item {"hasBeenCreated":true,"ticketId":' . $ticket->ID . '} --><div class="wp-block-tribe-tickets-item"></div><!-- /wp:tribe/tickets-item -->';
}
$blocks[] = '</div><!-- /wp:tribe/tickets -->';
return $blocks;
}
/**
* Return the supported post types for tickets
*
* @return array
*/
public function get_enabled_post_types() {
return (array) tribe_get_option( 'ticket-enabled-post-types', array() );
}
/**
* Add the event tickets category into the block categories
*
* @since 4.9
*
* @param array $categories The categories to be displayed.
* @param WP_Post $post The post object.
* @return array
*/
public function block_categories( $categories ) {
if ( ! $this->current_post_supports_tickets() ) {
return $categories;
}
return array_merge(
$categories,
array(
array(
'slug' => 'tribe-tickets',
'title' => __( 'Tickets Blocks', 'event-tickets' ),
'icon' => 'tec-tickets',
),
)
);
}
/**
* Prints and returns the Price fields
*
* @since 4.9
*
* @param int $post_id Post ID
* @param int $ticket_id Ticket ID
*
* @return string
*/
public function filter_get_price_fields( $post_id, $ticket_id ) {
$provider = Tribe__Tickets__Tickets::get_event_ticket_provider_object( $post_id );
$context = [
'post_id' => $post_id,
'ticket_id' => $ticket_id,
'provider' => $provider,
];
return tribe( 'tickets.admin.views' )->template( 'editor/fieldset/price', $context );
}
/**
* Prints and returns the Body for the Price Column
*
* @since 4.9
*
* @param Tribe__Tickets__Ticket_Object $ticket Ticket object
* @param mixed $provider_obj The ticket provider object
*
* @return string
*/
public function add_column_content_price( $ticket, $provider_obj ) {
/** @var Tribe__Tickets__Admin__Views $admin_views */
$admin_views = tribe( 'tickets.admin.views' );
$context = [
'ticket' => $ticket,
'provider_obj' => $provider_obj,
];
return $admin_views->template( 'editor/column-body-price', $context );
}
/**
* Function called by `load-post.php` action when the editor screen is loaded, insert a new meta
* field value as a flag into the post / event if the classic editor is displayed and has blocks
* in case it has blocks to trigger a new action `tribe_tickets_update_blocks_from_classic_editor`
*
*
* @since 4.9.2
*
* @return bool
*/
public function flush_blocks() {
/** @var Tribe__Editor $editor */
$editor = tribe( 'editor' );
// Bail because we dont have access to any of the classes we need for Blocks Editor.
if ( ! $editor->should_load_blocks() ) {
return false;
}
$post_id = absint( tribe_get_request_var( 'post' ) );
if (
empty( $post_id )
|| ! is_numeric( $post_id )
|| ! tribe_events_has_tickets( $post_id )
) {
return false;
}
/** @var Tribe__Tickets__Editor__Template__Overwrite $template_overwrite */
$template_overwrite = tribe( 'tickets.editor.template.overwrite' );
// Set meta key only if is classic editor and bail.
if ( $template_overwrite->has_classic_editor( $post_id ) ) {
update_post_meta( $post_id, $this->meta_key_flush_flag, 1 );
return false;
}
/**
* Don't process the first time a post is converted into blocks which means has_blocks, will
* return false the first time this is called in the post as the conversion from classic into
* blocks has not done yet, as this is process by 'tribe_blocks_editor_flag_post_classic_editor'
* so we only care if we already have blocks so we can search and remove old tickets blocks to
* replace with the new schema of tickets.
*/
if ( ! has_blocks( $post_id ) ) {
return false;
}
$has_meta_flush = metadata_exists( 'post', $post_id, $this->meta_key_flush_flag );
if ( $has_meta_flush ) {
/**
* Fire an action to update the blocks associated with a post
*
* @since 4.9.2
*/
do_action( 'tribe_tickets_update_blocks_from_classic_editor', $post_id );
return delete_post_meta( $post_id, $this->meta_key_flush_flag );
}
return false;
}
/**
* Update tickets blocks when the action: `tribe_tickets_update_blocks_from_classic_editor`
* is fired. When this action is fired couple of actions happens:
*
* 1. Remove all the inner blocks and replaces with just the name of the tickets block
* 2. Replace the placeholder ticket block with all the tickets associated with the Event / POST as blocks
* 3. Update the content of the post
*
* @since 4.9.2
*
* @param int|WP_Post $post_id The Post ID of the event.
*
* @return bool
*/
public function update_blocks( $post_id ) {
$post = get_post( $post_id );
if ( ! ( $post instanceof WP_Post ) ) {
return false;
}
/** @var Tribe__Editor__Utils $editor_utils */
$editor_utils = tribe( 'editor.utils' );
$block_name = $editor_utils->to_tribe_block_name( 'tickets' );
// Replace all the inner blocks with a general block name with no tickets inside.
$editor_utils->remove_inner_blocks( $post_id, $block_name, "<!-- $block_name /-->" );
$content = get_post_field( 'post_content', $post_id );
$post_content = $this->update_tickets_block_with_childs( $content, $post, array() );
return wp_update_post( array(
'ID' => $post->ID,
'post_content' => $post_content,
) );
}
}
|