<?php
/**
* Main plugin class.
*/
use Tribe\Tickets\Admin\Provider as Admin_Provider;
use Tribe\Tickets\Events\Service_Provider as Events_Service_Provider;
use Tribe\Tickets\Promoter\Service_Provider as Promoter_Service_Provider;
use Tribe\Tickets\Admin\Settings;
use TEC\Common\StellarWP\Assets\Config as Assets_Config;
use TEC\Tickets\Admin\Onboarding\Tickets_Landing_Page;
/**
* Class Tribe__Tickets__Main.
*/
class Tribe__Tickets__Main {
/**
* Current version of this plugin.
*/
const VERSION = '5.27.3';
/**
* Used to store the version history.
*
* @since 4.11.0
*
* @var string
*/
public $version_history_slug = 'previous_event_tickets_versions';
/**
* Used to store the latest version.
*
* @since 4.11.0
*
* @var string
*/
public $latest_version_slug = 'latest_event_tickets_version';
/**
* Min Version of WordPress.
*
* @since 4.10
*
* @var string
*/
protected $min_wordpress = '4.9';
/**
* Min Version of PHP.
*
* @since 4.10
*
* @var string
*/
protected $min_php = '7.4.0';
/**
* Min Version of The Events Calendar.
*
* @since 4.10
*
* @var string
*/
protected $min_tec_version = '6.15.12-dev';
/**
* Name of the provider.
*
* @var string
*/
public $plugin_name;
/**
* Directory of the plugin.
*
* @var string
*/
public $plugin_dir;
/**
* Path of the plugin.
*
* @var string
*/
public $plugin_path;
/**
* URL of the plugin.
*
* @var string
*/
public $plugin_url;
/**
* @var string
*/
public $plugin_slug;
/**
* @var Tribe__Tickets__Legacy_Provider_Support
*/
public $legacy_provider_support;
/**
* @var Tribe__Tickets__Shortcodes__User_Event_Confirmation_List
*/
private $user_event_confirmation_list_shortcode;
/**
* @var Tribe__Tickets__Admin__Move_Tickets
*/
protected $move_tickets;
/**
* @var Tribe__Tickets__Attendance_Totals
*/
protected $attendance_totals;
/**
* @var Tribe__Tickets__Admin__Move_Ticket_Types
*/
protected $move_ticket_types;
/**
* @deprecated 5.23.0
*
* @var Tribe__Admin__Activation_Page
*/
protected $activation_page;
/**
* @var Tribe__Tickets__Plugin_Register
*/
protected $registered;
/**
* @var bool Prevent autoload initialization
*/
private $should_prevent_autoload_init = false;
/**
* @var string tribe-common VERSION regex
*/
private $common_version_regex = "/const\s+VERSION\s*=\s*'([^']+)'/m";
/**
* Static Singleton Holder
* @var self
*/
protected static $instance;
/**
* Get (and instantiate, if necessary) the instance of the class
*
* @return self
*/
public static function instance() {
if ( ! self::$instance ) {
self::$instance = new self;
}
return self::$instance;
}
/**
* Where in the themes we will look for templates
*
* @since 4.9
*
* @var string
*/
public $template_namespace = 'tickets';
/**
* Class constructor
*/
protected function __construct() {
// Set up some of the plugin's properties.
$this->plugin_slug = 'tickets';
$this->plugin_path = trailingslashit( EVENT_TICKETS_DIR );
$this->plugin_dir = trailingslashit( basename( $this->plugin_path ) );
$dir_prefix = str_contains( EVENT_TICKETS_DIR, '/vendor/' )
? basename( dirname( EVENT_TICKETS_DIR, 2 ) ) . '/vendor/'
: '';
$this->plugin_url = trailingslashit( plugins_url( $dir_prefix . $this->plugin_dir ) );
}
/**
* Set the plugin name.
*
* @since 5.19.1
*/
public function set_plugin_name() {
$this->plugin_name = esc_html_x( 'Tickets', 'provider_plugin_name', 'event-tickets' );
}
/**
* Attach our initial hooks and filters
*
* @since 5.18.0
* @since 5.19.1 Called `set_plugin_name` on `init` hook.
*
* @return void
*/
public function do_hooks() {
add_action( 'init', [ $this, 'set_plugin_name' ] );
add_filter( 'tribe_events_integrations_should_load_freemius', '__return_false' );
$this->maybe_set_common_lib_info();
add_action( 'plugins_loaded', [ $this, 'should_autoload' ], -3 );
add_action( 'plugins_loaded', [ $this, 'plugins_loaded' ], -2 );
register_activation_hook( EVENT_TICKETS_MAIN_PLUGIN_FILE, [ $this, 'on_activation' ] );
register_deactivation_hook( EVENT_TICKETS_MAIN_PLUGIN_FILE, [ $this, 'on_deactivation' ] );
}
/**
* Fires when the plugin is activated.
*/
public function on_activation() {
// Will be used to set up Stripe webhook on admin_init.
set_transient( 'tec_tickets_commerce_setup_stripe_webhook', true );
// Set plugin activation time for all installs.
if ( ! is_admin() ) {
return;
}
// Avoid a race condition and fatal by waiting until Common is loaded before we try to run this.
add_action(
'tribe_common_loaded',
[ $this, 'set_activation_time' ]
);
$this->redirect_to_wizard_on_activation();
}
/**
* Redirect to the wizard on activation.
*
* @since 5.23.0
*
* @return void
*/
public function redirect_to_wizard_on_activation() {
if ( is_network_admin() ) {
// Never redirect on network admin.
return;
}
// Get the checked plugins from the request. If there are more than one, we're doing a bulk activation.
$checked = isset( $_POST['checked'] ) ? count( $_POST['checked'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
if ( ! empty( $checked ) ) {
// If multiple plugins are being activated, set the wizard redirect transient, this should only trigger redirection on a ET admin page visit.
set_transient( '_tec_tickets_wizard_redirect', 1, 30 );
} else {
// If a single plugin is being activated, set the activation redirect transient for immediate redirection.
set_transient( '_tec_tickets_activation_redirect', 1, 30 );
}
}
/**
* Set the plugin activation time.
* Activated on plugin activation, runs on tribe_common_loaded.
*
* @since 5.5.9
*
* @return void
*/
public function set_activation_time() {
tribe_update_option( 'tec_tickets_activation_time', time() );
}
/**
* Fires when the plugin is deactivated.
*
* @since 5.5.9
*/
public function on_deactivation() {
// Remove plugin activation time on deactivation.
if ( is_admin() ) {
tribe_remove_option( 'tec_tickets_activation_time' );
}
tribe( TEC\Tickets\Commerce\Gateways\Stripe\Webhooks::class )->disable_webhook();
}
/**
* Setup of Common Library
*/
public function maybe_set_common_lib_info() {
$common_version = file_get_contents( $this->plugin_path . 'common/src/Tribe/Main.php' );
// if there isn't a tribe-common version, bail.
if ( ! preg_match( $this->common_version_regex, $common_version, $matches ) ) {
add_action( 'admin_head', [ $this, 'missing_common_libs' ] );
return;
}
$common_version = $matches[1];
/**
* If we don't have a version of Common or a Older version of the Lib
* overwrite what should be loaded by the auto-loader
*/
if (
empty( $GLOBALS['tribe-common-info'] )
|| version_compare( $GLOBALS['tribe-common-info']['version'], $common_version, '<' )
) {
$GLOBALS['tribe-common-info'] = [
'dir' => "{$this->plugin_path}common/src/Tribe",
'version' => $common_version,
];
}
}
/**
* Resets the global common info back to TEC's common path
*
* @since 4.10.6.2
*/
private function reset_common_lib_info_back_to_tec() {
if ( ! class_exists( 'Tribe__Events__Main', false ) ) {
return;
}
// if we get in here, we need to reset the global common to TEC's version so that we don't cause a fatal
$tec = Tribe__Events__Main::instance();
$main_source = file_get_contents( $tec->plugin_path . 'common/src/Tribe/Main.php' );
// if there isn't a VERSION, don't override the common path
if ( ! preg_match( $this->common_version_regex, $main_source, $matches ) ) {
return;
}
$GLOBALS['tribe-common-info'] = [
'dir' => "{$tec->plugin_path}common/src/Tribe",
'version' => $matches[1],
];
}
/**
* Handles the soft-disabling of the plugin if requirements are not met.
*
* @since 5.9.3
*/
public function should_autoload(): void {
$invalid = $this->maybe_bail_if_invalid_wp_or_php();
$invalid = $this->maybe_bail_if_old_tec_is_present() || $invalid;
if ( ! $invalid ) {
return;
}
// Include dummy functions to prevent fatals with other plugins.
require_once $this->plugin_path . 'src/functions/soft-disable.php';
// If we get here, we need to reset the global common to TEC's version so that we don't cause a fatal.
$this->reset_common_lib_info_back_to_tec();
$this->should_prevent_autoload_init = true;
}
/**
* Prevents bootstrapping and autoloading if the version of TEC that is running is too old
*
* @since 4.10.6.2
* @since 5.9.3 added boolean "invalid" return value. True if the check fails, false if it passes.
*/
public function maybe_bail_if_old_tec_is_present(): bool {
// early check for an older version of The Events Calendar to prevent fatal error
if ( ! class_exists( 'Tribe__Events__Main', false ) ) {
return false;
}
if ( version_compare( Tribe__Events__Main::VERSION, $this->min_tec_version, '>=' ) ) {
return false;
}
add_action( 'admin_notices', [ $this, 'tec_compatibility_notice' ] );
add_action( 'network_admin_notices', [ $this, 'tec_compatibility_notice' ] );
add_action( 'tribe_plugins_loaded', [ $this, 'remove_exts' ], 0 );
/*
* After common was loaded by another source (e.g. The Events Calendar) let's append this plugin source files
* to the ones the Autoloader will search. Since we're appending them, the ones registered by the plugin
* "owning" common will be searched first.
*/
add_action( 'tribe_common_loaded', [ $this, 'register_plugin_autoload_paths' ] );
return true;
}
/**
* Prevents bootstrapping and autoloading if the version of WP or PHP are too old
*
* @since 4.10.6.2
* @since 5.9.3 added boolean "invalid" return value. True if the check fails, false if it passes.
*/
public function maybe_bail_if_invalid_wp_or_php(): bool {
if ( self::supported_version( 'wordpress' ) && self::supported_version( 'php' ) ) {
return false;
}
add_action( 'admin_notices', [ $this, 'not_supported_error' ] );
add_action( 'network_admin_notices', [ $this, 'not_supported_error' ] );
return true;
}
/**
* Finalize the initialization of this plugin
*/
public function plugins_loaded() {
if ( $this->should_prevent_autoload_init ) {
/**
* Fires if Event Tickets cannot load due to compatibility or other problems.
*/
do_action( 'tribe_tickets_plugin_failed_to_load' );
return;
}
/**
* Before any methods from this plugin are called, we initialize our Autoloading
* After this method we can use any `Tribe__` classes
*/
$this->init_autoloading();
add_filter( 'tec_common_parent_plugin_file', [ $this, 'include_parent_plugin_path_to_common' ] );
// Start Up Common.
Tribe__Main::instance();
add_action( 'tribe_common_loaded', [ $this, 'bootstrap' ], 0 );
}
/**
* Adds our main plugin file to the list of paths.
*
* @since 6.1.0
*
*
* @param array<string> $paths The paths to TCMN parent plugins.
*
* @return array<string>
*/
public function include_parent_plugin_path_to_common( $paths ): array {
$paths[] = EVENT_TICKETS_MAIN_PLUGIN_FILE;
return $paths;
}
/**
* Load Text Domain on tribe_common_loaded as it requires common
*
* @since 4.10
* @since 5.23.0 Added Tyson group paths.
*/
public function bootstrap() {
/*
* Register the `/build` directory assets as a different group to ensure back-compatibility.
* This needs to happen early in the plugin bootstrap routine.
*/
Assets_Config::add_group_path(
self::class,
$this->plugin_path,
'build/',
true
);
/*
* Register the `/build` directory as root for packages.
* The difference from the group registration above is that packages are not expected to use prefix directories
* like `/js` or `/css`.
*/
Assets_Config::add_group_path(
self::class . '-packages',
$this->plugin_path,
'build/',
false
);
$this->hooks();
$this->register_active_plugin();
$this->bind_implementations();
$this->user_event_confirmation_list_shortcode();
$this->move_tickets();
$this->move_ticket_types();
Tribe__Tickets__JSON_LD__Order::hook();
Tribe__Tickets__JSON_LD__Type::hook();
/** @var Tribe__Tickets__Privacy */
tribe( 'tickets.privacy' );
/**
* Fires when Event Tickets is fully loaded.
*
* @since 5.22.0
*/
do_action( 'tec_tickets_fully_loaded' );
/**
* Fires once Event Tickets has completed basic setup.
*
* @deprecated 5.22.0 Use `tec_tickets_fully_loaded` instead.
*/
do_action_deprecated( 'tribe_tickets_plugin_loaded', [], '5.22.0', 'Use `tec_tickets_fully_loaded` instead.' );
}
/**
* Registers the implementations in the container
*
* @since 4.7
*/
public function bind_implementations() {
tribe_singleton( 'tickets.main', $this );
// Initialize the Service Provider for Tickets.
tribe_register_provider( Tribe__Tickets__Service_Provider::class );
// Tickets Commerce providers.
tribe_register_provider( TEC\Tickets\Provider::class );
tribe_singleton( 'tickets.rsvp', new Tribe__Tickets__RSVP );
tribe_singleton( 'tickets.commerce.cart', 'Tribe__Tickets__Commerce__Cart' );
tribe_singleton( 'tickets.commerce.currency', 'Tribe__Tickets__Commerce__Currency', [ 'hook' ] );
tribe_singleton( 'tickets.commerce.paypal', new Tribe__Tickets__Commerce__PayPal__Main );
tribe_singleton( 'tickets.redirections', 'Tribe__Tickets__Redirections' );
tribe_register_provider( TEC\Tickets\Configuration\Provider::class );
tribe_singleton( Tribe__Tickets__Theme_Compatibility::class, Tribe__Tickets__Theme_Compatibility::class );
// Event Tickets Provider to manage Events.
tribe_register_provider( Events_Service_Provider::class );
// ORM.
tribe_register_provider( 'Tribe__Tickets__Service_Providers__ORM' );
// REST API v1
tribe_register_provider( 'Tribe__Tickets__REST__V1__Service_Provider' );
// REST Editor APIs
tribe_register_provider( 'Tribe__Tickets__Editor__REST__V1__Service_Provider' );
// Blocks editor
tribe_register_provider( TEC\Tickets\Blocks\Controller::class );
// Privacy
tribe_singleton( 'tickets.privacy', 'Tribe__Tickets__Privacy', [ 'hook' ] );
// Views V2
tribe_register_provider( Tribe\Tickets\Events\Views\V2\Service_Provider::class );
// Admin home.
tribe_register_provider( Tribe\Tickets\Admin\Home\Service_Provider::class );
// Admin settings.
tribe_register_provider( Tribe\Tickets\Admin\Settings\Service_Provider::class );
// Admin manager.
tribe_register_provider( Tribe\Tickets\Admin\Manager\Service_Provider::class );
// Promoter.
tribe_register_provider( Promoter_Service_Provider::class );
// Admin provider.
tribe_register_provider( Admin_Provider::class );
// Set up IAN Client - In-App Notifications.
tribe_register_provider( TEC\Tickets\Notifications\Provider::class );
/**
* Allows other plugins and services to override/change the bound implementations.
*
* DO NOT put anything after this unless you _need to_ and know the implications!
*
* @since 5.23.0
*/
do_action( 'tec_tickets_bound_implementations' );
}
/**
* Registers this plugin as being active for other tribe plugins and extensions
*/
protected function register_active_plugin() {
$this->registered = new Tribe__Tickets__Plugin_Register();
}
/**
* Hooked to admin_notices, this error is thrown when Event Tickets is run alongside a version of
* TEC that is too old
*/
public function tec_compatibility_notice() {
$active_plugins = get_option( 'active_plugins' );
$plugin_short_path = null;
foreach ( $active_plugins as $plugin ) {
if ( false !== strstr( $plugin, 'the-events-calendar.php' ) ) {
$plugin_short_path = $plugin;
break;
}
}
$upgrade_path = wp_nonce_url(
add_query_arg(
[
'action' => 'upgrade-plugin',
'plugin' => $plugin_short_path,
], get_admin_url() . 'update.php'
), 'upgrade-plugin_' . $plugin_short_path
);
$min_version = str_replace( '-dev', '', $this->min_tec_version );
$output = '<div class="error">';
// Translators: %1$s is the min required version of The Events Calendar. %2$s Is the update link opening `<a>`. %3$s Is the update link closing `</a>`.
$output .= '<p>' . sprintf( __( 'When The Events Calendar and Event Tickets are both activated, The Events Calendar must be running version %1$s or greater. Please %2$supdate now.%3$s', 'event-tickets' ), $min_version, '<a href="' . esc_url( $upgrade_path ) . '">', '</a>' ) . '</p>';
$output .= '</div>';
echo $output;
}
/**
* Prevents Extensions from running if TEC is on an Older Version
*
* @since 4.10.0.1
*
*/
public function remove_exts() {
remove_all_actions( 'tribe_plugins_loaded', 10 );
}
/**
* Test whether the current version of PHP or WordPress is supported.
*
* @since 4.10
*
* @param string $system Which system to test the version of such as 'php' or 'wordpress'.
*
* @return boolean Whether the current version of PHP or WordPress is supported.
*/
public function supported_version( $system ) {
if ( $supported = wp_cache_get( $system, 'tribe_version_test' ) ) {
return $supported;
}
switch ( strtolower( $system ) ) {
case 'wordpress' :
$supported = version_compare( get_bloginfo( 'version' ), $this->min_wordpress, '>=' );
break;
case 'php' :
$supported = version_compare( phpversion(), $this->min_php, '>=' );
break;
}
/**
* Filter whether the current version of PHP or WordPress is supported.
*
* @since 4.10
*
* @param boolean $supported Whether the current version of PHP or WordPress is supported.
* @param string $system Which system to test the version of such as 'php' or 'wordpress'.
*/
$supported = apply_filters( 'tribe_tickets_supported_system_version', $supported, $system );
wp_cache_set( $system, $supported, 'tribe_version_test' );
return $supported;
}
/**
* Display a WordPress or PHP incompatibility error.
*
* @since 4.10
*/
public function not_supported_error() {
if ( ! self::supported_version( 'wordpress' ) ) {
echo '<div class="error"><p>' . esc_html( sprintf( __( 'Sorry, Event Tickets requires WordPress %s or higher. Please upgrade your WordPress install.', 'event-tickets' ), $this->min_wordpress ) ) . '</p></div>';
}
if ( ! self::supported_version( 'php' ) ) {
echo '<div class="error"><p>' . esc_html( sprintf( __( 'Sorry, Event Tickets requires PHP %s or higher. Talk to your Web host about moving you to a newer version of PHP.', 'event-tickets' ), $this->min_php ) ) . '</p></div>';
}
}
/**
* Set the Event Tickets version in the options table if it's not already set.
*/
public function maybe_set_et_version() {
if ( version_compare( Tribe__Settings_Manager::get_option( $this->latest_version_slug ), self::VERSION, '<' ) ) {
$previous_versions = Tribe__Settings_Manager::get_option( $this->version_history_slug )
? Tribe__Settings_Manager::get_option( $this->version_history_slug )
: [];
$previous_versions[] = Tribe__Settings_Manager::get_option( $this->latest_version_slug )
? Tribe__Settings_Manager::get_option( $this->latest_version_slug )
: '0';
Tribe__Settings_Manager::set_option( $this->version_history_slug, $previous_versions );
Tribe__Settings_Manager::set_option( $this->latest_version_slug, self::VERSION );
}
}
/**
* Sets up autoloading
*/
protected function init_autoloading() {
$autoloader = $this->get_autoloader_instance();
$this->register_plugin_autoload_paths();
require_once $this->plugin_path . 'src/template-tags/tickets.php';
require_once $this->plugin_path . 'src/template-tags/commerce.php';
// deprecated classes are registered in a class to path fashion
foreach ( glob( $this->plugin_path . 'src/deprecated/*.php' ) as $file ) {
$class_name = str_replace( '.php', '', basename( $file ) );
$autoloader->register_class( $class_name, $file );
}
$autoloader->register_autoloader();
}
/**
* Set up hooks for this class.
*/
public function hooks() {
add_action( 'tribe_load_text_domains', [ $this, 'load_text_domain' ] );
add_action( 'init', [ $this, 'init' ] );
// Connect upgrade script.
add_action( 'init', [ $this, 'run_updates' ], 0, 0 );
add_filter( 'tribe_post_types', [ $this, 'inject_post_types' ] );
// Setup Help Tab texting.
add_action( 'tribe_help_pre_get_sections', [ $this, 'add_help_section_support_content' ] );
add_action( 'tribe_help_pre_get_sections', [ $this, 'add_help_section_featured_content' ] );
add_action( 'tribe_help_pre_get_sections', [ $this, 'add_help_section_extra_content' ] );
add_filter( 'tribe_support_registered_template_systems', [ $this, 'add_template_updates_check' ] );
add_action( 'tec_tickets_fully_loaded', [ 'Tribe__Support', 'getInstance' ] );
// Setup Front End Display.
add_action( 'tribe_events_inside_cost', 'tribe_tickets_buy_button', 10, 0 );
// Hook to oEmbeds.
add_action( 'tribe_events_embed_after_the_cost_value', [ $this, 'inject_buy_button_into_oembed' ] );
add_action( 'embed_head', [ $this, 'embed_head' ] );
// Attendee screen enhancements.
add_action( 'tribe_events_tickets_attendees_event_details_top', [ $this, 'setup_attendance_totals' ], 20 );
// CSV Import options.
if ( class_exists( 'Tribe__Events__Main', false ) ) {
add_filter( 'tribe_events_import_options_rows', [ Tribe__Tickets__CSV_Importer__Rows::instance(), 'filter_import_options_rows' ] );
add_filter( 'tribe_aggregator_csv_post_types', [ Tribe__Tickets__CSV_Importer__Rows::instance(), 'filter_csv_post_types' ] );
add_filter( 'tribe_aggregator_csv_column_mapping', [ Tribe__Tickets__CSV_Importer__Column_Names::instance(), 'filter_rsvp_column_mapping' ] );
add_filter( 'tribe_event_import_rsvp_tickets_column_names', [ Tribe__Tickets__CSV_Importer__Column_Names::instance(), 'filter_rsvp_column_names' ] );
add_action( 'tribe_tickets_ticket_deleted', [ 'Tribe__Tickets__Attendance', 'delete_attendees_caches' ] );
}
// Add the RSVP importer if the File_Importer class is present.
if ( class_exists( 'Tribe__Events__Importer__File_Importer' ) ) {
add_filter( 'tribe_events_import_rsvp_tickets_importer', [ 'Tribe__Tickets__CSV_Importer__RSVP_Importer', 'instance' ], 10, 2 );
}
/**
* Load our assets.
*
* @see \Tribe__Tickets__Assets::enqueue_scripts()
* @see \Tribe__Tickets__Assets::admin_enqueue_scripts()
* @see \Tribe__Tickets__Assets::enqueue_editor_scripts()
* @see \Tribe__Tickets__Assets::add_data_strings()
*/
add_action( 'init', tribe_callback( 'tickets.assets', 'enqueue_scripts' ) );
add_action( 'init', tribe_callback( 'tickets.assets', 'admin_enqueue_scripts' ) );
add_action( 'admin_enqueue_scripts', tribe_callback( 'tickets.assets', 'enqueue_editor_scripts' ) );
add_filter( 'tribe_asset_data_add_object_tribe_l10n_datatables', tribe_callback( 'tickets.assets', 'add_data_strings' ) );
// Redirections.
add_action( 'wp_loaded', tribe_callback( 'tickets.redirections', 'maybe_redirect' ) );
// Cart handling.
add_action( 'init', tribe_callback( 'tickets.commerce.cart', 'hook' ) );
// Theme Compatibility.
add_filter( 'body_class', [ tribe( Tribe__Tickets__Theme_Compatibility::class ), 'add_body_classes' ], 55 );
}
/**
* Append the text about Event Tickets to the support section on the Help page
*
* @filter "tribe_help_pre_get_sections"
* @param Tribe__Admin__Help_Page $help The Help Page Instance
* @return void
*/
public function add_help_section_support_content( $help ) {
$help->add_section_content( 'support', '<strong>' . esc_html__( 'Support for Event Tickets', 'event-tickets' ) . '</strong>', 20 );
$help->add_section_content( 'support', [
'<strong><a href="https://evnt.is/18ne" target="_blank">' . esc_html__( 'Settings overview', 'event-tickets' ) . '</a></strong>',
'<strong><a href="https://evnt.is/18nf" target="_blank">' . esc_html__( 'Features overview', 'event-tickets' ) . '</a></strong>',
'<strong><a href="https://evnt.is/18jb" target="_blank">' . esc_html__( 'Troubleshooting common problems', 'event-tickets' ) . '</a></strong>',
'<strong><a href="https://evnt.is/18ng" target="_blank">' . esc_html__( 'Customizing Event Tickets', 'event-tickets' ) . '</a></strong>',
], 20 );
}
/**
* Append the text about Event Tickets to the Feature box section on the Help page
*
* @filter "tribe_help_pre_get_sections"
* @param Tribe__Admin__Help_Page $help The Help Page Instance
* @return void
*/
public function add_help_section_featured_content( $help ) {
// If The Events Calendar is active dont add
if ( $help->is_active( 'the-events-calendar', true ) ) {
return;
}
$link = '<a href="https://evnt.is/18nd" target="_blank">' . esc_html__( 'New User Primer', 'event-tickets' ) . '</a>';
$help->add_section_content( 'feature-box', sprintf( _x( 'We are committed to helping you sell %1$s for your event. Check out our handy %2$s to get started.', 'help feature box section', 'event-tickets' ), tribe_get_ticket_label_plural_lowercase( 'help_feature_box_section' ), $link ), 20 );
}
/**
* Append the text about Event Tickets to the Extra Help section on the Help page
*
* @filter "tribe_help_pre_get_sections"
* @param Tribe__Admin__Help_Page $help The Help Page Instance
* @return void
*/
public function add_help_section_extra_content( $help ) {
if ( ! $help->is_active( [ 'events-calendar-pro', 'event-tickets-plus' ] ) && $help->is_active( 'the-events-calendar' ) ) {
// We just skip because it's treated on TEC
return;
} elseif ( ! $help->is_active( 'the-events-calendar' ) ) {
if ( ! $help->is_active( 'event-tickets-plus' ) ) {
$link = '<a href="https://wordpress.org/support/plugin/event-tickets/" target="_blank">' . esc_html__( 'open-source forum on WordPress.org', 'event-tickets' ) . '</a>';
$help->add_section_content( 'extra-help', sprintf( __( 'If you have tried the above steps and are still having trouble, you can post a new thread to our %s. Our support staff monitors these forums once a week and would be happy to assist you there.', 'event-tickets' ), $link ), 20 );
$link_forum = '<a href="https://evnt.is/4w/" target="_blank">' . esc_html__( 'premium support on our website', 'event-tickets' ) . '</a>';
$link_plus = '<a href="https://evnt.is/18ni" target="_blank">' . esc_html__( 'Event Tickets Plus', 'event-tickets' ) . '</a>';
$help->add_section_content( 'extra-help', sprintf( __( 'Looking for more immediate support? We offer %1$s with the purchase of any of our premium plugins (like %2$s). Pick up a license and you can post there directly and expect a response within 24-48 hours during weekdays.', 'event-tickets' ), $link_forum, $link_plus ), 20 );
$link = '<a href="https://evnt.is/4w/" target="_blank">' . esc_html__( 'post a thread', 'event-tickets' ) . '</a>';
$help->add_section_content( 'extra-help', sprintf( __( 'Already have Event Tickets Plus? You can %s in our premium support forums. Our support team monitors the forums and will respond to your thread within 24-48 hours (during the week).', 'event-tickets' ), $link ), 20 );
} else {
$link = '<a href="https://evnt.is/4w/" target="_blank">' . esc_html__( 'post a thread', 'event-tickets' ) . '</a>';
$help->add_section_content( 'extra-help', sprintf( __( 'If you have a valid license for one of our paid plugins, you can %s in our premium support forums. Our support team monitors the forums and will respond to your thread within 24-48 hours (during the week).', 'event-tickets' ), $link ), 20 );
}
}
}
/**
* Register Event Tickets with the template update checker.
*
* @since 5.0.3 Updated template structure.
*
* @param array $plugins
*
* @return array
*/
public function add_template_updates_check( $plugins ) {
$plugins[ __( 'Event Tickets', 'event-tickets' ) ] = [
self::VERSION,
$this->plugin_path . 'src/views',
trailingslashit( get_stylesheet_directory() ) . 'tribe/tickets',
];
return $plugins;
}
/**
* Load the Event Tickets text domain after Tribe Common's.
*
* @since 4.12.0
*
* @return bool
*/
public function load_text_domain() {
return Tribe__Main::instance( $this )->load_text_domain( 'event-tickets', $this->plugin_dir . 'lang/' );
}
/**
* Hooked to the init action
*/
public function init() {
// Provide continued support for legacy ticketing modules.
$this->legacy_provider_support = new Tribe__Tickets__Legacy_Provider_Support;
$this->settings_tab();
$this->tickets_view();
Tribe__Credits::init();
$this->maybe_set_et_version();
$this->maybe_set_options_for_old_installs();
}
/**
* Allows us to set options based on installed version.
* Also a good place for things that need to be changed
* or set if they are missing (like meta keys).
*
* @since 4.11.0
*/
public function maybe_set_options_for_old_installs() {
/**
* This Try/Catch is present to deal with a problem on Autoloading from version 5.1.0 ET+ with ET 5.0.3.
*
* @todo Needs to be revised once proper autoloading rules are done for Common, ET and ET+.
*/
try {
/** @var \Tribe__Tickets__Attendee_Registration__Main $ar_reg */
$ar_reg = tribe( 'tickets.attendee_registration' );
} catch ( \Exception $exception ) {
return;
}
// If the (bool) option is not set, and this install predated the modal, let's set the option to false.
$modal_option = $ar_reg->is_modal_enabled();
if ( ! $modal_option && $modal_option !== false ) {
$modal_version_check = tribe_installed_before( Tribe__Tickets__Main::instance(), '4.11.0' );
if ( $modal_version_check ) {
/** @var $settings_manager Tribe__Settings_Manager */
$settings_manager = tribe( 'settings.manager' );
$settings_manager::set_option( 'ticket-attendee-modal', false );
}
}
}
/**
* rsvp ticket object accessor
*/
public function rsvp() {
return tribe( 'tickets.rsvp' );
}
/**
* Creates the Tickets FrontEnd facing View class
*
* This will happen on `plugins_loaded` by default
*
* @return Tribe__Tickets__Tickets_View
*/
public function tickets_view() {
return Tribe__Tickets__Tickets_View::hook();
}
/**
* Default attendee list shortcode handler.
*
* @return Tribe__Tickets__Shortcodes__User_Event_Confirmation_List
*/
public function user_event_confirmation_list_shortcode() {
if ( empty( $this->user_event_confirmation_list_shortcode ) ) {
$this->user_event_confirmation_list_shortcode = new Tribe__Tickets__Shortcodes__User_Event_Confirmation_List;
}
return $this->user_event_confirmation_list_shortcode;
}
/**
* @return Tribe__Tickets__Admin__Move_Tickets
*/
public function move_tickets() {
if ( empty( $this->move_tickets ) ) {
$this->move_tickets = new Tribe__Tickets__Admin__Move_Tickets;
$this->move_tickets->setup();
}
return $this->move_tickets;
}
/**
* @return Tribe__Tickets__Admin__Move_Ticket_Types
*/
public function move_ticket_types() {
if ( empty( $this->move_ticket_types ) ) {
$this->move_ticket_types = new Tribe__Tickets__Admin__Move_Ticket_Types;
$this->move_ticket_types->setup();
}
return $this->move_ticket_types;
}
/**
* @deprecated 5.23.0
*
* @return Tribe__Admin__Activation_Page
*/
public function activation_page() {
_deprecated_function( __METHOD__, '5.23.0', 'Now handled by TEC\Tickets\Admin\Onboarding\Controller' );
if ( empty( $this->activation_page ) ) {
$this->activation_page = new Tribe__Admin__Activation_Page( [
'slug' => 'event-tickets',
'admin_page' => 'tickets_page_tec-tickets-settings',
'admin_url' => tribe( Settings::class )->get_url(),
'version' => self::VERSION,
'activation_transient' => Tickets_Landing_Page::ACTIVATION_REDIRECT_OPTION,
'plugin_path' => $this->plugin_dir . 'event-tickets.php',
'version_history_slug' => $this->version_history_slug,
'welcome_page_title' => esc_html__( 'Welcome to Event Tickets!', 'event-tickets' ),
'welcome_page_template' => $this->plugin_path . 'src/admin-views/admin-welcome-message.php',
] );
tec_asset(
$this,
'tribe-tickets-welcome-message',
'admin/welcome-message.js',
[ 'jquery' ],
'admin_enqueue_scripts',
[
'conditionals' => [ $this->activation_page, 'is_welcome_page' ],
]
);
}
return $this->activation_page;
}
/**
* Adds RSVP attendance totals to the summary box of the attendance
* screen.
*
* Expects to fire during 'tribe_tickets_attendees_page_inside', ie
* before the attendee screen is rendered.
*
* @since 4.2.4
* @since 5.8.2 Add the `$event_id` parameter.
*
* @param int|bool $event_id The post ID to set up attendance totals for.
*/
public function setup_attendance_totals( $event_id = null ) {
$this->attendance_totals( $event_id )->integrate_with_attendee_screen();
}
/**
* Returns the attendance totals object.
*
* @since 4.2.4
* @since 5.8.2 Added the `$event_id` parameter.
*
* @param int|null $event_id The post ID to set up attendance totals for.
*
* @return Tribe__Tickets__Attendance_Totals The attendance totals object.
*/
public function attendance_totals( $event_id = null ) {
if ( empty( $this->attendance_totals ) ) {
$this->attendance_totals = new Tribe__Tickets__Attendance_Totals;
}
$this->attendance_totals->set_event_id( $event_id );
return $this->attendance_totals;
}
/**
* Provides the CSS version number for CSS files
*
* @return string
*/
public function css_version() {
static $version;
if ( ! $version ) {
$version = apply_filters( 'tribe_tickets_css_version', self::VERSION );
}
return $version;
}
/**
* Provides the JS version number for JS scripts
*
* @return string
*/
public function js_version() {
static $version;
if ( ! $version ) {
$version = apply_filters( 'tribe_tickets_js_version', self::VERSION );
}
return $version;
}
/**
* Settings page object accessor.
*
* @return \Tribe\Tickets\Admin\Settings
*/
public function settings_tab() {
return tribe( \Tribe\Tickets\Admin\Settings::class );
}
/**
* Settings page object accessor.
*
* @since 5.4.0
*
* @return \Tribe\Tickets\Admin\Settings
*/
public function settings() {
return $this->settings_tab();
}
/**
* Returns the supported post types for tickets
*
* @return array<string>
*/
public function post_types() {
$options = (array) get_option( Tribe__Main::OPTIONNAME, [] );
// If the ticket-enabled-post-types index has never been set, default it to tribe_events and page.
if ( ! array_key_exists( 'ticket-enabled-post-types', $options ) ) {
$defaults = [
'tribe_events',
'page',
];
$options['ticket-enabled-post-types'] = $defaults;
tribe_update_option( 'ticket-enabled-post-types', $defaults );
}
// Remove WooCommerce Product and EDD post types to prevent recursion fatal error on save.
$filtered_post_types = array_diff( (array) $options['ticket-enabled-post-types'], [ 'product', 'download' ] );
/**
* Filters the list of post types that support tickets
*
* @param array $post_types Array of post types
*/
return apply_filters( 'tribe_tickets_post_types', $filtered_post_types );
}
/**
* Injects post types into the tribe-common post_types array
*/
public function inject_post_types( $post_types ) {
$post_types = array_merge( $post_types, $this->post_types() );
return $post_types;
}
/**
* Injects a buy/RSVP button into oEmbeds for events when necessary
*/
public function inject_buy_button_into_oembed() {
$event_id = get_the_ID();
if ( ! tribe_events_has_tickets( $event_id ) ) {
return;
}
$tickets = Tribe__Tickets__Tickets::get_all_event_tickets( $event_id );
$has_non_rsvp = false;
$available = false;
foreach ( $tickets as $ticket ) {
if ( 'Tribe__Tickets__RSVP' !== $ticket->provider_class ) {
$has_non_rsvp = true;
}
if (
$ticket->date_in_range()
&& $ticket->is_in_stock()
) {
$available = true;
}
}
// if there aren't any tickets available, bail
if ( ! $available ) {
return;
}
$button_text = $has_non_rsvp ? __( 'Buy', 'event-tickets' ) : tribe_get_rsvp_label_singular( 'button_text' );
/**
* Filters the text that appears in the buy/rsvp button on event oEmbeds
*
* @var string The button text
* @var int Event ID
*/
$button_text = apply_filters( 'event_tickets_embed_buy_button_text', $button_text, $event_id );
ob_start();
?>
<a class="tribe-event-buy" href="<?php echo esc_url( tribe_get_event_link() ); ?>" title="<?php the_title_attribute() ?>" rel="bookmark"><?php echo esc_html( $button_text ); ?></a>
<?php
$buy_button = ob_get_clean();
/**
* Filters the buy button that appears on event oEmbeds
*
* @var string The button markup
* @var int Event ID
*/
echo apply_filters( 'event_tickets_embed_buy_button', $buy_button, $event_id );
}
/**
* Adds content to the embed head tag
*
* The embed header DOES NOT have wp_head() executed inside of it. Instead, any scripts/styles
* are explicitly output
*/
public function embed_head() {
$css_path = Tribe__Assets::maybe_get_min_file( $this->plugin_url . 'src/resources/css/tickets-embed.css' );
$css_path = add_query_arg( 'ver', self::VERSION, $css_path );
?>
<link rel="stylesheet" id="tribe-tickets-embed-css" href="<?php echo esc_url( $css_path ); ?>" type="text/css" media="all">
<?php
}
/**
* Make necessary database updates on admin_init
*
* @since 4.7.1
*
*/
public function run_updates() {
if ( ! class_exists( 'Tribe__Updater' ) ) {
return;
}
$updater = new Tribe__Tickets__Updater( self::VERSION );
if ( $updater->update_required() ) {
$updater->do_updates();
}
}
/**
* Returns the autoloader singleton instance to use in a context-aware manner.
*
* @since 4.10.6
*
* @return \Tribe__Autoloader Teh singleton common Autoloader instance.
*/
public function get_autoloader_instance() {
if ( ! class_exists( 'Tribe__Autoloader' ) ) {
require_once $GLOBALS['tribe-common-info']['dir'] . '/Autoloader.php';
Tribe__Autoloader::instance()->register_prefixes( [
'Tribe__' => $GLOBALS['tribe-common-info']['dir'],
] );
}
return Tribe__Autoloader::instance();
}
/**
* Registers the plugin autoload paths in the Common Autoloader instance.
*
* @since 4.10.6
*/
public function register_plugin_autoload_paths() {
$prefixes = [
'Tribe__Tickets__' => $this->plugin_path . 'src/Tribe',
];
$this->get_autoloader_instance()->register_prefixes( $prefixes );
}
}
|