File: /var/www/html/triad-infosec/wp-content/plugins/events-calendar-pro/src/Tribe/Editor.php
<?php
/**
* Class Tribe__Events__Pro__Editor
*
* @since 4.5
*/
class Tribe__Events__Pro__Editor extends Tribe__Editor {
/**
* Attach hooks into the editor
*
* @since 4.5
*/
public function hook() {
add_action( 'tribe_events_pro_after_custom_field_content', array( $this, 'after_custom_field_content' ), 10, 3 );
add_filter( 'tribe_settings_after_save_additional-fields', array( $this, 'save_custom_field_values' ) );
add_filter( 'tribe_events_editor_default_template', array( $this, 'add_additional_fields_in_editor' ) );
add_filter( 'tribe_events_editor_default_classic_template', array( $this, 'add_additional_fields_in_editor' ) );
add_filter( 'tribe_blocks_editor_update_classic_content_params', array( $this, 'migrate_additional_fields_params_to_blocks' ), 10, 3 );
add_filter( 'tribe_events_editor_default_classic_template', array( $this, 'add_related_events_in_editor' ), 50 );
add_filter( 'tribe_events_editor_default_template', array( $this, 'add_related_events_in_editor' ), 50 );
global $wp_version;
if ( version_compare( $wp_version, '5.8', '<' ) ) {
add_action( 'block_categories', array( $this, 'register_additional_fields_category' ), 10, 2 );
} else {
add_action( 'block_categories_all', array( $this, 'register_additional_fields_category_all' ), 10, 2 );
}
$this->assets();
}
/**
* Attach a new input after each custom field input is rendered, the value is being stored in a hidden field and
* creates a fake <button> to have A11y benefits like focus and so on. The "fake checkbox" is used as we need to send
* to the request the value of this operation regardless of is true / false so using a native checkbox send only
* the value when the checkbox is mark as "checked", with this approach the "hidden" field is always being send into
* the request regardless of the state of it so we can have a valid reference all the time to the value of each custom
* field.
*
* @since 4.5
*
* @param $ticket
* @param $index
* @param $count
*
* @return mixed
*/
public function after_custom_field_content( $ticket, $index, $count ) {
$value = '1';
if ( isset( $ticket['gutenberg_editor'] ) ) {
$value = $ticket['gutenberg_editor'] ? '1' : '0';
}
$args = array(
'input_id' => 'gutenberg_editor_' . esc_attr( $index ),
'value' => $value,
'index' => $index,
'class_name' => $value === '1' ? 'tribe-custom-field-gutenberg-checkbox--checked' : '',
'count' => $count,
);
$html = tribe( 'events-pro.editor.admin.template' )->template( array( 'custom-fields', 'gutenberg' ), $args, false );
echo $html;
}
/**
* Update the options after the additional fields tabs is saved
*
* @since 4.5
*
* @return mixed
*/
public function save_custom_field_values() {
$options = Tribe__Settings_Manager::get_options();
if ( empty( $options['custom-fields'] ) || ! is_array( $options['custom-fields'] ) ) {
return $options;
}
$gutenberg_fields = $this->gutenberg_custom_fields_canonical_keys(
tribe_get_request_var( 'custom-field-gutenberg-editor', array() )
);
foreach ( $options['custom-fields'] as $index => $field ) {
$checked = isset( $gutenberg_fields[ $index ] ) && '1' === $gutenberg_fields[ $index ];
$options['custom-fields'][ $index ]['gutenberg_editor'] = $checked;
}
Tribe__Settings_Manager::set_options( $options, false );
}
/**
* Make sure the keys of the gutenberg custom fields match the same logic as the custom fields, this logic is
* basically if the key or index of a gutenberg field has `_` at the start it means it belongs to an existing
* meta field and in order to have the right key we just need to remove the '_' from the start on the other hand
* if does not have one it means it's a new created field which requires to grab the highest max value available
* at this point and increase from there every time this scenario is presented.
*
* @since 4.5
*
* @param array $gutenberg_custom_fields An array with the gutenberg custom fields
*
* @return array An array with only number as index representing the location of the custom field block
*/
public function gutenberg_custom_fields_canonical_keys( $gutenberg_custom_fields ) {
$max_index = $this->get_custom_fields_max_index();
$mapped = array();
foreach ( $gutenberg_custom_fields as $index => $field ) {
if ( 0 === strpos( $index, '_' ) ) {
$assigned_index = substr( $index, 1 );
} else {
$assigned_index = ++$max_index;
}
$mapped[ $assigned_index ] = $field;
}
return $mapped;
}
/**
* Return the highest number for the custom fields, this value is created and updated by PRO. Fallback to a zero
* value if is not present on the settings or there are no custom fields present yet.
*
* @since 4.5
*
* @return int
*/
private function get_custom_fields_max_index() {
$current_options = Tribe__Settings_Manager::get_options();
if ( isset( $current_options['custom-fields-max-index'] ) ) {
return $current_options['custom-fields-max-index'];
} else if ( isset( $current_options['custom-fields'] ) ) {
return count( $current_options['custom-fields'] ) + 1;
} else {
return 0;
}
}
/**
* Register and Load styles and JS behavior into the admin views
*
* @since 4.5
*/
public function assets() {
$events_pro = Tribe__Events__Pro__Main::instance();
tribe_asset(
$events_pro,
'gutenberg-events-pro-admin-additional-fields-admin-style',
'app/admin/additional-fields.css',
array(),
'admin_enqueue_scripts',
array(
'conditionals' => array( $this, 'maybe_load_custom_field_assets' ),
)
);
tribe_asset(
$events_pro,
'gutenberg-events-pro-admin-additional-fields-behavior',
'admin/admin-additional-fields.js',
array(),
'admin_enqueue_scripts',
array(
'conditionals' => array( $this, 'maybe_load_custom_field_assets' ),
)
);
}
/**
* Callback used to load the assets only when the Additional Fields tab is selected
*
* @since 4.5
*
* @return bool
*/
public function maybe_load_custom_field_assets() {
$screen = get_current_screen();
if ( ! $screen instanceof WP_Screen || $screen->id !== 'tribe_events_page_tec-events-settings' ) {
return false;
}
$tab = tribe_get_request_var( 'tab' );
return 'additional-fields' === $tab;
}
/**
* Add the event custom fields on post that are events only
*
* @since 4.5
*
* @param array<array<string|string>> $categories An array of categories each an array
* in the format property => value.
* @param WP_Post $post The post object we're editing.
*
* @return array
*/
public function register_additional_fields_category( $categories, $post ) {
// Handle where someone is using this outside of this object
global $wp_version;
if ( version_compare( $wp_version, '5.8', '>=' ) ) {
_deprecated_function( __FUNCTION__, '5.8.2', 'register_additional_fields_category_all' );
}
// Make sure it's an event post.
if ( ! tribe_is_event( $post ) ) {
return $categories;
}
return array_merge(
$categories,
[
[
'slug' => 'tribe-events-pro-additional-fields',
'title' => __( 'Additional Fields', 'tribe-events-calendar-pro' ),
],
]
);
}
/**
* Add the event custom fields on post that are events only
*
* @since 4.5
*
* @param array<array<string|string>> $categories An array of categories each an array
* in the format property => value.
* @param WP_Block_Editor_Context $context The Block Editor Context object.
* In WP versions prior to 5.8 this was the post object.
*
* @return array
*/
public function register_additional_fields_category_all( $categories, $context ) {
if ( ! $context instanceof WP_Block_Editor_Context ) {
return $categories;
}
// Make sure we have the post available.
if ( empty( $context->post ) ) {
return $categories;
}
// Make sure it's an event post.
if ( ! tribe_is_event( $context->post ) ) {
return $categories;
}
return array_merge(
$categories,
[
[
'slug' => 'tribe-events-pro-additional-fields',
'title' => __( 'Additional Fields', 'tribe-events-calendar-pro' ),
],
]
);
}
/**
* Add additional fields templates for new events
*
* @since 4.5
*
* @param array $templates
*
* @return array An array with the templates
*/
public function add_additional_fields_in_editor( $templates ) {
$additional_fields_templates = tribe( 'events-pro.editor.fields' )->get_block_names( true );
if ( empty( $additional_fields_templates ) ) {
return $templates;
}
$blocks = array();
$inserted = false;
$insertion_points = array( 'tribe/classic-event-details', 'tribe/event-venue' );
foreach ( $templates as $template ) {
$blocks[] = $template;
if (
! $inserted
&& is_array( $template )
&& in_array( $template[0], $insertion_points, true )
) {
foreach ( $additional_fields_templates as $additional_field ) {
$blocks[] = array( $additional_field );
}
$inserted = true;
}
}
return $blocks;
}
/**
* Generate the attributes from additional fields that are doing the migration into the new blocks
* UI, it sets the attributes of the additional fields that are marked
* as "Include this field on all new events in the Gutenberg block editor" it sets 4
* attributes based on the meta value associated with the additional field
*
* @since 4.5
*
* @param $params
* @param $slug
* @param $post
*
* @return array
*/
public function migrate_additional_fields_params_to_blocks( $params, $slug, $post ) {
/** @var Tribe__Events__Pro__Editor__Additional_Fields $editor */
$editor = tribe( 'events-pro.editor.fields' );
$additional_fields_templates = $editor->get_block_names( true, true );
$block_names = array_keys( $additional_fields_templates );
if (
empty( $block_names )
|| empty( $additional_fields_templates )
|| empty( $additional_fields_templates[ $slug ] )
|| ! ( $post instanceof WP_Post )
|| $slug !== $params // if $slug !== $params it means params has been set already as s
) {
return $params;
}
$field = $additional_fields_templates[ $slug ];
$value = strval( get_post_meta( $post->ID, $field['name'], true ) );
$output = $value;
if ( 'checkbox' === $field['type'] ) {
$output = $this->format_checkbox_field( $value );
}
return array(
'isPristine' => empty( $value ),
'output' => $output,
'value' => $value,
'label' => $field['label'],
);
}
/**
* Format a string using the new blocks UI to shape the values of a meta
*
* @since 4.5
*
* @param string $value
* @param string $initial_separator
* @param string $end_separator
*
* @return string
*/
public function format_checkbox_field( $value = '', $initial_separator = ', ', $end_separator = ' & ' ) {
$pieces = explode( '|', $value );
$last = '';
if ( count( $pieces ) >= 3 ) {
$last = trim( array_pop( $pieces ) );
}
$output = implode( $initial_separator, $pieces );
if ( '' === $last ) {
return $output;
}
return implode( $end_separator, array( $output, $last ) );
}
/**
* Filters and adds the related events block into the default classic blocks
*
* @since 4.6.2
*
* @param array $template
*
* @return array
*/
public function add_related_events_in_editor( $template = array() ) {
$hide_related_events = tribe_get_option( 'hideRelatedEvents', false );
if ( $hide_related_events ) {
return $template;
}
$template[] = array( 'tribe/related-events' );
return $template;
}
}