de:events-pro/v2/week/grid-body/multiday-events-day/multiday-event/bar/featured', [ $this, 'action_add_hybrid_event_marker' ], 15, 3 ); // "Classic" Event Single. add_action( 'tribe_events_single_event_after_the_content', [ $this, 'action_add_event_single_video_embed' ], 15, 0 ); add_action( 'tribe_events_single_meta_details_section_end', [ $this, 'action_add_event_single_details_block_link_button' ], 15, 0 ); add_action( 'tribe_template_before_include:events-pro/single/video-embed', [ $this, 'action_add_oembed_filter' ], 15, 3 ); add_action( 'tribe_template_after_include:events-pro/single/video-embed', [ $this, 'action_remove_oembed_filter' ], 15, 3 ); // Event Single Blocks. // We need to be sure that some hooks fire after global $post is available for checks. add_action( 'wp', [ $this, 'hook_block_template' ] ); add_action( 'tribe_template_before_include:events/blocks/event-datetime', [ $this, 'action_add_block_virtual_event_marker' ] ); add_action( 'tribe_template_before_include:events/blocks/event-datetime', [ $this, 'action_add_block_hybrid_event_marker' ] ); add_action( 'tribe_events_pro_shortcode_tribe_events_before_assets', [ $this, 'action_include_assets' ] ); // Generic Widgets. add_action( 'tribe_events_views_v2_widget_after_enqueue_assets', [ $this, 'action_widget_after_enqueue_assets' ], 10, 3 ); // Widget Events List. add_action( 'tribe_template_after_include:events/v2/widgets/widget-events-list/event/date/featured', [ $this, 'action_add_virtual_event_marker' ], 10, 3 ); add_action( 'tribe_template_after_include:events/v2/widgets/widget-events-list/event/date/featured', [ $this, 'action_add_hybrid_event_marker' ], 10, 3 ); // Widget Featured Venue. add_action( 'tribe_template_after_include:events-pro/v2/widgets/widget-featured-venue/events-list/event/date/featured', [ $this, 'action_add_virtual_event_marker' ], 10, 3 ); add_action( 'tribe_template_after_include:events-pro/v2/widgets/widget-featured-venue/events-list/event/date/featured', [ $this, 'action_add_hybrid_event_marker' ], 10, 3 ); /* Events by Week Widget */ add_action( 'tribe_template_after_include:events-pro/v2/widget-week/mobile-events/day/event/date/featured', [ $this, 'action_add_virtual_event_marker' ], 15, 3 ); /* Event Calendar Widget */ add_action( 'tribe_events_pro_shortcode_month_widget_add_hooks', [ $this, 'action_pro_shortcode_month_widget_add_hooks' ] ); add_action( 'tribe_events_pro_shortcode_month_widget_remove_hooks', [ $this, 'action_pro_shortcode_month_widget_remove_hooks' ] ); } /** * Adds the filters required by the plugin. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. */ protected function add_filters() { add_filter( 'tribe_template_origin_namespace_map', [ $this, 'filter_add_template_origin_namespace' ], 15 ); add_filter( 'tribe_template_path_list', [ $this, 'filter_template_path_list' ], 15, 2 ); add_filter( 'tribe_the_notices', [ $this, 'filter_include_single_control_mobile_markers' ], 15 ); add_filter( 'tribe_the_notices', [ $this, 'filter_include_single_hybrid_control_mobile_markers' ], 15 ); add_filter( 'tribe_events_event_schedule_details', [ $this, 'include_single_control_desktop_markers' ], 10, 2 ); add_filter( 'tribe_events_event_schedule_details', [ $this, 'include_single_hybrid_control_desktop_markers' ], 10, 2 ); add_filter( 'tribe_json_ld_event_object', [ $this, 'filter_json_ld_modifiers' ], 15, 3 ); add_filter( 'tribe_rest_event_data', [ $this, 'filter_rest_event_data' ], 10, 2 ); add_filter( 'post_class', [ $this, 'filter_add_post_class' ], 15, 3 ); add_filter( 'body_class', [ $this, 'filter_add_body_class' ], 10 ); // Filter event object properties to add the ones related to virtual events. add_filter( 'tribe_get_event', [ $this, 'filter_tribe_get_event' ] ); add_filter( 'tribe_get_event_after', [ $this, 'add_dynamic_properties' ] ); // Add the plugin locations to the Context. add_filter( 'tribe_context_locations', [ $this, 'filter_context_locations' ] ); // Add Video Source. add_filter( 'tribe_events_virtual_video_sources', [ $this, 'add_video_source' ], 10, 2 ); // Add autodetect source. add_filter( 'tec_events_virtual_autodetect_video_sources', [ $this, 'add_autodetect_source' ], 10, 3 ); // Add Event status. add_filter( 'tec_event_statuses', [ $this, 'filter_event_status' ], 10, 2 ); } /** * Register providers. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. */ protected function add_providers() { $this->container->register( Autodetect_Provider::class ); $this->container->register( Importer_Provider::class ); } /** * Registers the meeting providers. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. */ protected function add_meetings_support() { if ( ! Plugin::meetings_enabled() ) { return; } $this->container->register( Facebook_Provider::class ); $this->container->register( Google_Provider::class ); $this->container->register( Microsoft_Provider::class ); $this->container->register( Webex_Provider::class ); $this->container->register( YouTube_Provider::class ); $this->container->register( Zoom_Provider::class ); } /** * Add the control classes for the views v2 elements * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @param string|array $classes Space-separated string or array of class names to add to the class list. * @param array $class An array of additional class names added to the post. * @param int|\WP_Post $post Post ID or post object. * * @return array The filtered post classes. */ public function filter_add_post_class( $classes, $class, $post ) { $new_classes = $this->container->make( Template_Modifications::class )->get_post_classes( $post ); return array_merge( $classes, $new_classes ); } /** * Add the control classes for the views v2 elements * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @param string|array $classes Space-separated string or array of class names to add to the class list. * * @return array The filtered post body classes. */ public function filter_add_body_class( $classes ) { global $post; $new_classes = $this->container->make( Template_Modifications::class )->get_body_classes( $post ); return array_merge( $classes, $new_classes ); } /** * Includes Pro into the path namespace mapping, allowing for a better namespacing when loading files. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @param array $namespace_map Indexed array containing the namespace as the key and path to `strpos`. * * @return array Namespace map after adding Pro to the list. */ public function filter_add_template_origin_namespace( $namespace_map ) { /* @var $plugin Plugin */ $plugin = tribe( Plugin::class ); $namespace_map[ Plugin::SLUG ] = $plugin->plugin_path; return $namespace_map; } /** * Filters the list of folders TEC will look up to find templates to add the ones defined by PRO. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @param array $folders The current list of folders that will be searched template files. * @param Template $template Which template instance we are dealing with. * * @return array The filtered list of folders that will be searched for the templates. */ public function filter_template_path_list( array $folders, Template $template ) { /* @var $plugin Plugin */ $plugin = tribe( Plugin::class ); $path = (array) rtrim( $plugin->plugin_path, '/' ); // Pick up if the folder needs to be added to the public template path. $folder = [ 'src/views' ]; if ( ! empty( $folder ) ) { $path = array_merge( $path, $folder ); } $folders[ Plugin::SLUG ] = [ 'id' => Plugin::SLUG, 'namespace' => Plugin::SLUG, 'priority' => 10, 'path' => implode( DIRECTORY_SEPARATOR, $path ), ]; return $folders; } /** * Modifiers to the JSON LD object we use. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @param object $data The JSON-LD object. * @param array $args The arguments used to get data. * @param WP_Post $post The post object. * * @return object JSON LD object after modifications. */ public function filter_json_ld_modifiers( $data, $args, $post ) { return $this->container->make( JSON_LD::class )->modify_virtual_event( $data, $args, $post ); } /** * Filters event REST data to include new fields. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @param array $data The event data array. * @param WP_Post $event The post object. * * @return array The event data array after modification. */ public function filter_rest_event_data( $data, $event ) { return array_merge( $data, $this->container->make( Models\Event::class )->get_rest_properties( $event ) ); } /** * Renders the metabox template. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @param int $post_id The post ID of the event we are interested in. */ public function render_metabox( $post_id ) { echo $this->container->make( Metabox::class )->render_template( $post_id ); /* phpcs:ignore */ } /** * Renders the API controls related to the display of the API detais. * I.E. Webex or Zoom Meeting Links and numbers. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @param string $file The path to the template file, unused. * @param string $entry_point The name of the template entry point, unused. * @param \Tribe__Template $template The current template instance. */ public function render_classic_display_controls( $file, $entry_point, \Tribe__Template $template ) { $this->container->make( Metabox::class ) ->render_classic_display_controls( $template->get( 'post' ) ); } /** * Register the metabox fields in the correct action. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. */ public function on_init() { $this->container->make( Metabox::class )->register_fields(); } /** * Registers the plugin meta box for Blocks Editor support. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. */ public function on_add_meta_boxes() { $this->container->make( Metabox::class )->register_blocks_editor_legacy(); } /** * Register the metabox fields in the correct action. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @param int $post_id Which post ID we are dealing with when saving. * @param WP_Post $post WP Post instance we are saving. * @param boolean $update If we are updating the post or not. */ public function on_save_post( $post_id, $post, $update ) { $this->container->make( Metabox::class )->save( $post_id, $post, $update ); } /** * Include the Virtual Events URL anchor for the archive pages. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @param string $file Complete path to include the PHP File. * @param array $name Template name. * @param Template $template Current instance of the Template. */ public function action_add_virtual_event_marker( $file, $name, $template ) { $this->container->make( Template_Modifications::class ) ->add_virtual_event_marker( $file, $name, $template ); } /** * Include the Hybrid Events event marker for the archive pages. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @param string $file Complete path to include the PHP File. * @param array $name Template name. * @param Template $template Current instance of the Template. */ public function action_add_hybrid_event_marker( $file, $name, $template ) { $this->container->make( Template_Modifications::class ) ->add_hybrid_event_marker( $file, $name, $template ); } /** * Include the Virtual Events URL anchor for the single event block. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. */ public function action_add_block_virtual_event_marker() { $this->container->make( Template_Modifications::class ) ->add_single_block_virtual_event_marker(); } /** * Include the Hybrid Events URL anchor for the single event block. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. */ public function action_add_block_hybrid_event_marker() { $this->container->make( Template_Modifications::class ) ->add_single_block_hybrid_event_marker(); } /** * Include the video embed for event single. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. */ public function action_add_event_single_video_embed() { $this->container->make( Template_Modifications::class ) ->add_event_single_video_embed(); } /** * Include the link button for event single. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. */ public function action_add_event_single_link_button() { $this->container->make( Template_Modifications::class ) ->add_event_single_non_block_link_button(); } /** * Include the link button for event single details block. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. */ public function action_add_event_single_details_block_link_button() { $this->container->make( Template_Modifications::class ) ->add_event_single_link_button(); } /** * Add the oEmbed filter before the video embed template. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @param string $file Complete path to include the PHP File. * @param array $name Template name. * @param Template $template Current instance of the Template. */ public function action_add_oembed_filter( $file, $name, $template ) { add_filter( 'oembed_dataparse', [ $this, 'filter_make_oembed_responsive' ], 10, 3 ); } /** * Remove the oEmbed filter after the video embed template. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @param string $file Complete path to include the PHP File. * @param array $name Template name. * @param Template $template Current instance of the Template. */ public function action_remove_oembed_filter( $file, $name, $template ) { remove_filter( 'oembed_dataparse', [ $this, 'filter_make_oembed_responsive' ], 10, 3 ); } /** * Include the control markers for the single pages. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @param string $notices_html Previously set HTML. * * @return string Before event html with the new markers. */ public function filter_include_single_control_mobile_markers( $notices_html ) { $event = tribe_get_event( get_the_ID() ); if ( ! $event instanceof \WP_Post) { return $notices_html; } if ( ! $event->virtual ) { return $notices_html; } $template_modifications = $this->container->make( Template_Modifications::class ); return $template_modifications->add_single_control_mobile_markers( $notices_html ); } /** * Include the hybrid control markers for the single pages. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @param string $notices_html Previously set HTML. * * @return string Before event html with the new markers. */ public function filter_include_single_hybrid_control_mobile_markers( $notices_html ) { $event = tribe_get_event( get_the_ID() ); if ( ! $event instanceof \WP_Post ) { return $notices_html; } if ( ! $event->virtual ) { return $notices_html; } $template_modifications = $this->container->make( Template_Modifications::class ); return $template_modifications->add_single_hybrid_control_mobile_markers( $notices_html ); } /** * Include the control markers for the single pages. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @param string $schedule The output HTML. * @param int $event_id The post ID of the event we are interested in. * * @return string The output HTML. */ public function include_single_control_desktop_markers( $schedule, $event_id ) { // Avoid infinite loops with serialization. return tribe_suspending_filter( current_filter(), [ $this, __FUNCTION__ ], function () use ( $schedule, $event_id ) { $template_modifications = $this->container->make( Template_Modifications::class ); return $template_modifications->add_single_control_markers( $schedule, $event_id ); }, 2 ); } /** * Include the hybrid control markers for the single pages. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @param string $schedule The output HTML. * @param int $event_id The post ID of the event we are interested in. * * @return string The output HTML. */ public function include_single_hybrid_control_desktop_markers( $schedule, $event_id ) { // Avoid infinite loops with serialization. return tribe_suspending_filter( current_filter(), [ $this, __FUNCTION__ ], function () use ( $schedule, $event_id ) { $template_modifications = $this->container->make( Template_Modifications::class ); return $template_modifications->add_single_hybrid_control_markers( $schedule, $event_id ); }, 2 ); } /** * Filters the object returned by the `tribe_get_event` function to add to it properties related to virtual events. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @param WP_Post $post The events post object to be modified. * * @return \WP_Post The original event object decorated with properties related to virtual events. */ public function filter_tribe_get_event( $post ) { if ( ! $post instanceof WP_Post ) { // We should only act on event posts, else bail. return $post; } return $this->container->make( Models\Event::class )->add_properties( $post ); } /** * Add, to the Context, the locations used by the plugin. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @param array $context_locations The current Context locations. * * @return array The updated Context locations. */ public function filter_context_locations( array $context_locations ) { $context_locations['events_virtual_data'] = [ 'read' => [ Context::REQUEST_VAR => [ Metabox::$id ], ], ]; $context_locations['events_virtual_request'] = [ 'read' => [ Context::REQUEST_VAR => [ Plugin::$request_slug, Context_Provider::AUTH_STATE_QUERY_VAR ], ], ]; return $context_locations; } /** * Filters the oEmbed HTML to make it responsive. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @param string $html The returned oEmbed HTML. * @param object $data A data object result from an oEmbed provider. * @param string $url The URL of the content to be embedded. * * @return string The filtered oEmbed HTML. */ public function filter_make_oembed_responsive( $html, $data, $url ) { return $this->container->make( OEmbed::class )->make_oembed_responsive( $html, $data, $url ); } /** * Enqueue assets when we call a PRO shortcode. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. */ public function action_include_assets() { return $this->container->make( Assets::class )->load_on_shortcode(); } /** * Action to enqueue assets for virtual events for events list widget. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @param boolean $should_enqueue Whether assets are enqueued or not. * @param \Tribe__Context $context Context we are using to build the view. * @param View_Interface $view Which view we are using the template on. */ public function action_widget_after_enqueue_assets( $should_enqueue, $context, $view ) { $this->container->make( Widget::class )->action_enqueue_assets( $should_enqueue, $context, $view ); } /** * Adds dynamic, time-related, properties to the event object. * * This method deals with properties we set, for convenience, on the event object that should not * be cached as they are time-dependent; i.e. the time the properties are computed at matters and * caching their values would be incorrect. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @param mixed|\WP_Post $post The event post object, as read from the cache, if any. * * @return WP_Post The decorated event post object; its dynamic and time-dependent properties correctly set up. */ public function add_dynamic_properties( $post ) { if ( ! $post instanceof WP_Post ) { // We should only act on event posts, else bail. return $post; } return $this->container->make( Models\Event::class )->add_dynamic_properties( $post ); } /** * Triggers on the ECP month widget add_hooks() to add/remove icons strategically * * @since 7.0.0 Migrated to Events Pro from Events Virtual. */ public function action_pro_shortcode_month_widget_add_hooks() { remove_action( 'tribe_template_after_include:events/v2/month/mobile-events/mobile-day/mobile-event/title', [ $this, 'action_add_virtual_event_marker' ], 15 ); add_action( 'tribe_template_after_include:events/v2/month/mobile-events/mobile-day/mobile-event/date/featured', [ $this, 'action_add_virtual_event_marker' ], 15, 3 ); } /** * Triggers on the ECP month widget remove_hooks() to add/remove icons strategically * * @since 7.0.0 Migrated to Events Pro from Events Virtual. */ public function action_pro_shortcode_month_widget_remove_hooks() { add_action( 'tribe_template_after_include:events/v2/month/mobile-events/mobile-day/mobile-event/title', [ $this, 'action_add_virtual_event_marker' ], 15, 3 ); remove_action( 'tribe_template_after_include:events/v2/month/mobile-events/mobile-day/mobile-event/date/featured', [ $this, 'action_add_virtual_event_marker' ], 15 ); } /** * Run Updates on Plugin Upgrades. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. */ public function run_updates() { if ( ! class_exists( 'Tribe__Events__Updater' ) ) { return; // core needs to be updated for compatibility } $updater = new Updater( Plugin::VERSION ); if ( $updater->update_required() ) { $updater->do_updates(); } } /** * Add the Video Source. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @param array An array of video sources. * @param \WP_Post $post The current event post object, as decorated by the `tribe_get_event` function. * * @return array An array of video sources. */ public function add_video_source( $video_sources, $post ) { $video_sources[] = [ 'text' => _x( 'Search for video or meeting link', 'The label of the video source option.', 'tribe-events-calendar-pro' ), 'id' => Event_Meta::$key_video_source_id, 'value' => Event_Meta::$key_video_source_id, 'selected' => Event_Meta::$key_video_source_id === $post->virtual_video_source, ]; return $video_sources; } /** * Add the moved online event status. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @param array $statuses The event status options for an event. * @param string $current_status The current event status for the event or empty string if none. * * @return array The event status options for an event. */ public function filter_event_status( $statuses, $current_status ) { return $this->container->make( Status_Labels::class )->filter_event_statuses( $statuses, $current_status ); } /** * Add OEmbed to Autodetect Source. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @param array An array of autodetect sources. * @param string $autodetect_source The ID of the selected autodetect video source. * @param \WP_Post $post The current event post object, as decorated by the `tribe_get_event` function. * * @return array An array of video sources. */ public function add_autodetect_source( $autodetect_sources, $autodetect_source, $post ) { $autodetect_sources[] = [ 'text' => _x( 'OEmbed', 'The name of the autodetect source.', 'tribe-events-calendar-pro' ), 'id' => 'oembed', 'value' => 'oembed', 'selected' => 'oembed' === $autodetect_source, ]; return $autodetect_sources; } /** * Hook block templates - legacy or new VE block. * Has to be postponed to `wp` action or later so global $post is available for should_inject_new_block(). * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @todo: Should we move this to an abstract base provider? */ public function hook_block_template() { /* The action/location which the template is injected depends on whether or not V2 is enabled * and whether the virtual event block is present in the post content. */ $embed_inject_action = $this->get_virtual_embed_action(); add_action( $embed_inject_action, [ $this, 'action_add_event_single_video_embed', ], 10 ); add_action( $embed_inject_action, [ $this, 'action_add_event_single_link_button', ], 15 ); } /** * Get the action we embed the virtual event content on. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @return string The name of the action we embed on. */ public function get_virtual_embed_action() { return $this->should_inject_new_block() ? 'tribe_events_virtual_block_content' : 'tribe_template_after_include:events/blocks/event-datetime'; } /** * Determine whether we show the legacy virtual info HTML or the new block. * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * * @return boolean Show the new block if true, the legacy info if false. */ public function should_inject_new_block() { global $post; // If we can't get the post - we probably shouldn't be here. Bail. if ( empty( $post ) ) { return false; } // This is required to ensure virtual event details are embedded properly in the Elementor Event widget $is_single_event = tribe( Template_Bootstrap::class )->is_single_event(); $no_blocks = ! function_exists( 'has_block' ) || has_block( 'tribe/virtual-event', $post ) || ! $is_single_event; // If the block is missing, show the legacy info HTML. $new_block = ! $no_blocks ? false : true; /** * Allows filtering whether to load the legacy virtual info HTML over the new block. * Note if the new block is not present, returning true here can have unforeseen consequences! * * @since 7.0.0 Migrated to Events Pro from Events Virtual. * @todo [plugin-consolidation] Merge VE into ECP, hook to be deprecated and renamed. * * @param boolean $new_block Whether to load the new block or not * @param WP_Post $post The current global post object. */ return apply_filters( 'tec_events_virtual_should_inject_new_block', $new_block, $post ); } }