Tribe__Events__Community__Tickets__Main
Source
File: src/Tribe/Main.php
class Tribe__Events__Community__Tickets__Main { /** * Option name to save all plugin options as a serialized array. */ const OPTIONNAME = 'tribe_community_events_tickets_options'; /** * The current version of Community Events Tickets. */ const VERSION = '4.6.2'; /** * The Events Calendar Required Version. * * Use Tribe__Events__Community__Tickets__Plugin_Register instead. * * @deprecated 4.6 */ const REQUIRED_TEC_VERSION = '4.8'; /** * The Events Calendar Required Version. * * Use Tribe__Events__Community__Tickets__Plugin_Register instead. * * @deprecated 4.6 */ const REQUIRED_ET_VERSION = '4.10'; private $hook_prefix = 'tribe-events-community-tickets-'; /** * The event form. * * @var Tribe__Events__Community__Tickets__Event_Form */ private $event_form; /** * The FE payment options form. * * @var Tribe__Events__Community__Tickets__Payment_Options_Form */ private $payment_options_form; /** * Plugin templates. * * @var Tribe__Events__Community__Tickets__Templates */ private $templates; /** * Plugin update configuration object. * * @var Tribe__Events__Community__Tickets__PUE */ private $pue; /** * Default options * * @var array */ public $option_defaults = [ 'enable_community_tickets' => false, 'enable_image_uploads' => true, 'enable_split_payments' => false, 'payment_fee_setting' => 'absorb', 'paypal_api_password' => '', 'paypal_api_signature' => '', 'paypal_api_username' => '', 'paypal_application_id' => '', 'paypal_invoice_prefix' => '', 'paypal_receiver_email' => '', 'paypal_sandbox' => false, 'site_fee_flat' => 0, 'site_fee_on_free' => true, 'site_fee_percentage' => 0, 'site_fee_type' => 'none', ]; /** * Accepted payment fee settings * * @var array */ private $payment_fee_setting_options = [ 'absorb', 'pass', ]; /** * WP_Router routes for the plugin. * * @var array */ public $routes = []; /** * The plugin directory. * * @var string */ public $pluginDir; /** * The plugin path. * * @var string */ public $pluginPath; /** * The plugin slug. * * @var string */ public $pluginSlug; /** * The plugin URL. * * @var string */ public $pluginUrl; /** * The plugin options. * * @var array */ protected static $options; /** * Singleton to instantiate the Tickets clas */ public static function instance() { static $instance; if ( ! $instance ) { $instance = new self; } return $instance; } /** * Constructor! */ public function __construct() { $this->plugin_path = trailingslashit( EVENTS_COMMUNITY_TICKETS_DIR ); $this->plugin_dir = trailingslashit( basename( $this->plugin_path ) ); $this->plugin_url = trailingslashit( plugins_url( $this->plugin_dir ) ); $this->plugin_slug = 'events-community-tickets'; // Hook to 11 to make sure this gets initialized after events-tickets-woo add_action( 'tribe_plugins_loaded', array( $this, 'plugins_loaded' ) ); add_action( 'woocommerce_cart_calculate_fees', array( $this, 'calculate_cart_fees' ) ); } /** * Bootstrap the plugin with the plugins_loaded action */ public function plugins_loaded() { add_action( 'init', array( $this, 'init' ), 5 ); add_filter( 'user_has_cap', array( $this, 'user_has_edit_event_tickets_cap' ), 1, 3 ); add_filter( 'user_has_cap', array( $this, 'user_has_sell_event_tickets_cap' ), 2, 3 ); add_filter( 'user_has_cap', array( $this, 'user_has_edit_tribe_events_cap' ), 2, 3 ); // This allows event owners to fetch/read orders on posts they own add_filter( 'user_has_cap', array( $this, 'user_has_read_private_shop_orders' ), 10, 3 ); $mopath = $this->plugin_dir . 'lang/'; $domain = 'tribe-events-community-tickets'; // If we don't have Common classes load the old fashioned way if ( ! class_exists( 'Tribe__Main' ) ) { load_plugin_textdomain( $domain, false, $mopath ); } else { // This will load `wp-content/languages/plugins` files first Tribe__Main::instance()->load_text_domain( $domain, $mopath ); } if ( ! $this->should_run() ) { // Display notice indicating which plugins are required add_action( 'admin_notices', array( $this, 'admin_notices' ) ); return; } $this->pue = new Tribe__Events__Community__Tickets__PUE( "{$this->plugin_path}/events-community-tickets.php" ); require_once $this->plugin_path . 'src/functions/template-tags.php'; if ( ! is_admin() || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) { add_action( 'wp_enqueue_scripts', array( $this, 'register_resources' ) ); $this->event_form(); $this->payment_options_form(); $this->templates(); add_filter( 'user_has_cap', array( $this, 'give_subscribers_upload_files_cap' ), 10, 3 ); } add_action( 'admin_enqueue_scripts', array( $this, 'register_resources' ) ); add_action( 'admin_enqueue_scripts', array( $this, 'maybe_enqueue_admin_resources' ), 11 ); add_action( 'tribe_community_events_enqueue_resources', array( $this, 'maybe_enqueue_frontend' ) ); add_action( 'wp_enqueue_scripts', array( $this, 'maybe_enqueue_frontend' ) ); add_filter( 'tribe_events_template_paths', array( $this, 'add_template_paths' ) ); add_action( 'wp_router_generate_routes', array( $this, 'generate_routes' ) ); add_action( 'tribe_ce_event_list_table_row_actions', array( $this, 'report_links' ) ); add_filter( 'tribe_community_settings_tab', array( $this, 'community_tickets_settings' ) ); if ( $this->is_split_payments_enabled() ) { add_filter( 'woocommerce_payment_gateways', array( $this, 'add_adapter' ) ); } add_action( 'woocommerce_order_item_meta_start', array( $this, 'add_order_item_details' ), 10, 3 ); add_action( 'wp_ajax_tribe-ticket-add-Tribe__Events__Tickets__Woo__Main', array( $this, 'ajax_handler_ticket_save' ), 9 ); add_action( 'wp_ajax_tribe-ticket-edit-Tribe__Events__Tickets__Woo__Main', array( $this, 'ajax_handler_ticket_save' ), 9 ); // Determine if the ticket price can be updated add_filter( 'tribe_tickets_can_update_ticket_price', array( $this, 'can_update_ticket_price' ), 10, 2 ); add_filter( 'tribe_tickets_disallow_update_ticket_price_message', array( $this, 'disallow_update_ticket_price_message' ), 10, 2 ); add_action( 'tribe_tickets_plus_after_event_details_list', array( $this, 'order_report_organizer_data' ), 10, 2 ); add_filter( 'tribe_events_orders_report_site_fees_note', array( $this, 'order_report_site_fees_note' ), 10, 2 ); // Control the user's ability to delete tickets add_filter( 'tribe_tickets_current_user_can_delete_ticket', array( $this, 'can_delete_existing_ticket' ), 10, 2 ); // Control the user's ability to check in attendees add_filter( 'tribe_tickets_user_can_manage_attendees', array( $this, 'user_can_manage_own_event_attendees' ), 11, 3 ); // Compatibility with Event Tickets Plus add_action( 'wp_ajax_tribe-ticket-add-Tribe__Tickets__Woo__Main', array( $this, 'ajax_handler_ticket_save' ), 9 ); add_action( 'wp_ajax_tribe-ticket-edit-Tribe__Tickets__Woo__Main', array( $this, 'ajax_handler_ticket_save' ), 9 ); // Ticket fee settings add_filter( 'tribe_tickets_pass_fees_to_user', array( $this, 'pass_fees_to_user' ), 10, 2 ); add_filter( 'tribe_tickets_fee_percent', array( $this, 'get_fee_percent' ) ); add_filter( 'tribe_tickets_fee_flat', array( $this, 'get_fee_flat' ) ); add_filter( 'tribe_tickets_get_default_module', array( $this, 'filter_prevent_edd_provider' ) ); add_action( 'admin_init', array( $this, 'run_updates' ), 10, 0 ); } /** * Bootstrap of the Plugin on Init * * @since 4.6.2 */ public function init() { // Setup Main Service Provider tribe_register_provider( 'Tribe__Events__Community__Tickets__Service_Provider' ); } /** * On Community Tickets we do not allow EDD * * @since 4.6.2 * * @param string $provider Which provider is the default * * @return string */ public function filter_prevent_edd_provider( $provider ) { $is_admin = tribe_is_truthy( tribe_get_request_var( 'is_admin', is_admin() ) ); if ( $is_admin ) { return $provider; } return 'Tribe__Tickets_Plus__Commerce__WooCommerce__Main'; } /** * Register the community-tickets paths with TEC */ public function add_template_paths( $paths ) { $paths['community-tickets'] = $this->plugin_path; return $paths; } /** * Auto-appends the author ID onto the SKU */ public function ajax_handler_ticket_save() { if ( ! isset( $_POST['formdata'] ) ) { return; } if ( ! isset( $_POST['post_ID'] ) ) { return; } if ( ! $post = get_post( $_POST['post_ID'] ) ) { return; } $form_data = wp_parse_args( $_POST['formdata'] ); if ( empty( $form_data['ticket_name'] ) ) { $form_data['ticket_name'] = 'ticket'; } // make sure the SKU is set to the correct value $form_data['ticket_woo_sku'] = "{$post->ID}-{$post->post_author}-" . sanitize_title( $form_data['ticket_name'] ); $_POST['formdata'] = http_build_query( $form_data ); } /** * Add the adapter. * * @param array $methods WooCommerce payment methods. * * @return array PayPal Adaptive Payments gateway. */ public function add_adapter( $methods ) { $methods[] = 'Tribe__Events__Community__Tickets__Adapter__WooCommerce_PayPal'; return $methods; } /** * Gateway object accessor method * * @param $gateway string Which static gateway to retrieve * * @return array Array of instantiated gateways */ public function gateway( $gateway ) { static $gateways = array(); if ( empty( $gateways[ $gateway ] ) ) { $gateway_class = "Tribe__Events__Community__Tickets__Gateway__{$gateway}"; if ( ! class_exists( $gateway_class ) ) { return new WP_Error( "{$gateway_class} does not exist" ); } $gateways[ $gateway ] = new $gateway_class; } return $gateways[ $gateway ]; } /** * Registers scripts and styles. * Includes filters for version numbers * * @since 1.0 * * @return void */ public function register_resources() { tribe_asset_enqueue_group( 'event-tickets-admin' ); tribe_asset_enqueue_group( 'event-tickets-plus-admin' ); wp_register_script( 'events-community-tickets-admin', Tribe__Template_Factory::getMinFile( $this->plugin_url . 'src/resources/js/events-community-tickets-admin.js', true ), array( 'jquery' ), apply_filters( 'tribe_events_js_version', self::VERSION ) ); wp_register_script( 'events-community-tickets', Tribe__Template_Factory::getMinFile( $this->plugin_url . 'src/resources/js/events-community-tickets.js', true ), array( 'jquery' , 'tribe-bumpdown', 'event-tickets-plus-meta-report-js', 'event-tickets-plus-attendees-list-js', 'event-tickets-plus-meta-admin-js' ), apply_filters( 'tribe_events_js_version', self::VERSION ) ); wp_register_style( 'events-community-tickets-admin', Tribe__Template_Factory::getMinFile( $this->plugin_url . 'src/resources/css/events-community-tickets-admin.css', true ), array(), apply_filters( 'tribe_events_css_version', self::VERSION ) ); wp_register_style( 'events-community-tickets', Tribe__Template_Factory::getMinFile( $this->plugin_url . 'src/resources/css/events-community-tickets.css', true ), array( 'tribe-bumpdown-css', 'event-tickets-plus-admin-css', 'event-tickets-plus-meta-admin-css' ), apply_filters( 'tribe_events_css_version', self::VERSION ) ); wp_register_style( 'events-community-tickets-shortcodes', Tribe__Template_Factory::getMinFile( $this->plugin_url . 'src/resources/css/events-community-tickets-shortcodes.css', true ), array(), apply_filters( 'tribe_events_css_version', self::VERSION ) ); } /** * Enqueue the admin resources where needed * @since 1.0 * * @param string $screen * * @return void */ public function maybe_enqueue_admin_resources( $screen ) { if ( 'tribe_events_page_tribe-common' === $screen || 'tribe_events_page_tickets-orders' === $screen || 'tribe_events_page_tickets-attendees' === $screen ) { wp_enqueue_style( 'events-community-tickets-admin' ); wp_enqueue_script( 'events-community-tickets-admin' ); } } /** * Enqueue the front end resources, add nonces for forms * * @return void */ public function maybe_enqueue_frontend() { $nonces = array( 'add_ticket_nonce' => wp_create_nonce( 'add_ticket_nonce' ), 'edit_ticket_nonce' => wp_create_nonce( 'edit_ticket_nonce' ), 'remove_ticket_nonce' => wp_create_nonce( 'remove_ticket_nonce' ), 'ajaxurl' => admin_url( 'admin-ajax.php' ), ); wp_localize_script( 'events-community-tickets', 'TribeTickets', $nonces ); wp_localize_script( 'events-community-tickets', 'ajaxurl', admin_url( 'admin-ajax.php', ( is_ssl() ? 'https' : 'http' ) ) ); if ( ! tribe_is_community_my_events_page() && ! tribe_is_community_edit_event_page() ) { return; } if ( ! is_admin() ) { // enqueue the styles so our page nav looks ok wp_enqueue_style( 'events-community-tickets' ); } } /** * Event form object accessor method */ public function event_form() { if ( ! $this->event_form ) { $this->event_form = new Tribe__Events__Community__Tickets__Event_Form( $this ); } return $this->event_form; } /** * Payment options form object accessor method */ public function payment_options_form() { // Added @since 4.6.2 as the payments option page does not trigger isEditPage so styles are not enqueued Tribe__Events__Community__Main::instance()->isEditPage = true; if ( ! $this->payment_options_form ) { $this->payment_options_form = new Tribe__Events__Community__Tickets__Payment_Options_Form; $this->payment_options_form->set_default( 'payment_fee_setting', $this->get_payment_fee_setting() ); } return $this->payment_options_form; } /** * Templates object accessor method */ public function templates() { if ( ! $this->templates ) { $this->templates = new Tribe__Events__Community__Tickets__Templates; } return $this->templates; } /** * Each plugin required by this one to run * * @return array { * Required plugin * * @param string $short_name Shortened title of the plugin * @param string $class Main PHP class * @param string $thickbox_url URL to download plugin * @param string $min_version Optional. Minimum version of plugin needed. * @param string $ver_compare Optional. Constant that stored the currently active version. * } */ protected function get_requisite_plugins() { $requisite_plugins = array( array( 'short_name' => 'WooCommerce', 'class' => 'WooCommerce', 'thickbox_url' => 'plugin-install.php?tab=plugin-information&plugin=woocommerce&TB_iframe=true', ), ); return $requisite_plugins; } /** * Should the plugin run? Are all of the appropriate items in place? */ public function should_run() { foreach ( $this->get_requisite_plugins() as $plugin ) { if ( ! class_exists( $plugin['class'] ) ) { return false; } if ( ! isset( $plugin['min_version'] ) || ! isset( $plugin['ver_compare'] ) ) { continue; } $active_version = constant( $plugin['ver_compare'] ); if ( null === $active_version ) { return false; } if ( version_compare( $active_version, $plugin['min_version'], '<' ) ) { return false; } } return true; } /** * Hooked to the admin_notices action */ public function admin_notices() { if ( ! current_user_can( 'activate_plugins' ) ) { return; } $links = array(); foreach ( $this->get_requisite_plugins() as $plugin ) { $links[] = sprintf( '<a href="%1$s" class="thickbox" title="%2$s">%3$s</a>', esc_attr( $plugin['thickbox_url'] ), esc_attr( $plugin['short_name'] ), esc_html( $plugin['short_name'] ) ); } $message = sprintf( esc_html__( 'To begin using The Events Calendar: Community Events Tickets, please install and activate the latest version of %1$s', 'tribe-events-community-tickets' ), $links[0] ); printf( '<div class="error"><p>%s</p></div>', $message ); } /** * Add the upload_files capability to a user when they are uploading files */ public function give_subscribers_upload_files_cap( $all_caps, $caps, $args ) { // Bail if there isn't a cap or user_id if ( empty( $caps[0] ) || empty( $args[1] ) ) { return $all_caps; } $cap = $caps[0]; $user_id = absint( $args[1] ); if ( 'upload_files' !== $cap ) { return $all_caps; } // If the user isn't logged in, bail if ( ! is_user_logged_in() ) { return $all_caps; } // If the user isn't uploading media, bail if ( false === strpos( $_SERVER['REQUEST_URI'], '/wp-admin/async-upload.php' ) ) { return $all_caps; } // If the user is originating the request from the dashboard, bail if ( false !== strpos( $_SERVER['HTTP_REFERER'], '/wp-admin/' ) ) { return $all_caps; } $base_url = get_bloginfo( 'url' ); // If the request did not come from the site, bail if ( ! preg_match( "@^{$base_url}@", $_SERVER['HTTP_REFERER'] ) ) { return $all_caps; } $all_caps['upload_files'] = true; return $all_caps; } /** * Returns whether or not community tickets is enabled in settings */ public function is_enabled() { $options = get_option( self::OPTIONNAME ); if ( empty( $options['enable_community_tickets'] ) ) { return false; } if ( ! empty( $options['enable_split_payments'] ) && ( empty( $options['paypal_api_username'] ) || empty( $options['paypal_api_password'] ) || empty( $options['paypal_api_signature'] ) || empty( $options['paypal_application_id'] ) || empty( $options['paypal_receiver_email'] ) || empty( $options['paypal_invoice_prefix'] ) ) ) { return false; } return true; } /** * Returns whether or not split payments are enabled */ public function is_split_payments_enabled() { $options = get_option( self::OPTIONNAME ); if ( empty( $options['enable_split_payments'] ) ) { return false; } return (bool) $options['enable_split_payments']; } /** * Returns whether or not tickets are enabled for a given event * * @param mixed $event WP_Post or ID for event * * @return boolean */ public function is_enabled_for_event( $event ) { // If split payments are not enabled, we don't need to worry about the creator's paypal email address if ( ! $this->is_split_payments_enabled() ) { return true; } if ( ! $event ) { // If an event isn't passed in, assume we're creating an event and use the currently logged in user $user_id = get_current_user_id(); } else { if ( ! $event instanceof WP_Post ) { if ( ! is_numeric( $event ) ) { return false; } $event = get_post( $event ); } if ( ! $event ) { return false; } $user_id = $event->post_author; } $user_meta = $this->payment_options_form()->get_meta( $user_id ); return filter_var( $user_meta['paypal_account_email'], FILTER_VALIDATE_EMAIL ); } /** * Gets an event's payment fee setting */ public function get_payment_fee_setting( $event = null ) { if ( $event && ! $event instanceof WP_Post ) { $event = get_post( $event ); } $options = get_option( self::OPTIONNAME, array() ); $payment_fee_setting = isset( $options['payment_fee_setting'] ) ? $options['payment_fee_setting'] : $this->option_defaults['payment_fee_setting']; // If split payments are enabled, get the event creator's options if ( $event && $this->is_split_payments_enabled() ) { $event_creator = get_user_by( 'id', $event->post_author ); $creator_options = Tribe__Events__Community__Tickets__Payment_Options_Form::get_meta( $event_creator->ID ); if ( isset( $creator_options['payment_fee_setting'] ) ) { $payment_fee_setting = $creator_options['payment_fee_setting']; } } // default to absorb if the payment_fee_setting is unknown if ( ! in_array( $payment_fee_setting, $this->payment_fee_setting_options ) ) { $payment_fee_setting = $this->option_defaults['payment_fee_setting']; } return $payment_fee_setting; } /** * Add routes */ public function generate_routes( $router ) { $this->routes['payment-options'] = new Tribe__Events__Community__Tickets__Route__Payment_Options( $router ); $this->routes['attendees-report'] = new Tribe__Events__Community__Tickets__Route__Attendees_Report( $router ); $this->routes['sales-report'] = new Tribe__Events__Community__Tickets__Route__Sales_Report( $router ); } /** * Redirects if the user is not logged in * * @param int|null $event_id */ public function require_login( $event_id = null ) { if ( ! is_user_logged_in() ) { wp_redirect( tribe_get_events_link() ); die; } if ( empty( $event_id ) ) { return; } $event = get_post( $event_id ); if ( ! empty( $event ) && get_current_user_id() != $event->post_author ) { wp_redirect( tribe_get_events_link() ); die; } } /** * Hooked to the tribe_ce_event_list_table_row_actions action to add navigation for reports */ public function report_links( $post ) { if ( ! current_user_can( 'edit_event_tickets' ) ) { return; } if ( ! tribe_events_has_tickets( $post ) ) { return; } /** * Allow filtering of attendees button text on the event list. * * @since 3.12 * * @param string $attendees_button_text Current translated button text. */ $attendees_button_text = apply_filters( $this->hook_prefix . 'event-list-attendees-button-text', __( 'Attendees', 'tribe-events-community-tickets' ) ); /** * Allow filtering of sales button text on the event list. * * @since 3.12 * * @param string $sales_button_text Current translated button text. */ $sales_button_text = apply_filters( $this->hook_prefix . 'event-list-sales-button-text', __( 'Sales', 'tribe-events-community-tickets' ) ); ?> <br/> <strong><?php echo esc_html__( 'Reports:', 'tribe-events-community-tickets' ); ?></strong> <a class="tribe-attendee-report" href="<?php echo esc_url( $this->routes['attendees-report']->url( $post->ID ) ); ?>"> <?php echo esc_html( $attendees_button_text ); ?> </a> | <a class="tribe-sales-report" href="<?php echo esc_url( $this->routes['sales-report']->url( $post->ID ) ); ?>"> <?php echo esc_html( $sales_button_text ); ?> </a> <?php } /** * Filter the community settings tab to include community tickets settings * * @param $settings array Field settings for the community settings tab in the dashboard */ public function community_tickets_settings( $settings ) { include $this->plugin_path . 'src/admin-views/payment-options.php'; return $settings; } public function calculate_cart_fees( $wc_cart ) { $cart = new Tribe__Events__Community__Tickets__Cart; $cart->calculate_cart_fees( $wc_cart ); } /** * Determines whether or not the currently logged in user has the correct cap * * @param array $all_caps User capabilities * @param array $caps Caps being checked * @param array $args Additional user_cap args */ public function user_has_edit_event_tickets_cap( $all_caps, $caps, $args ) { static $options; // Bail if there isn't a cap or user_id if ( empty( $caps[0] ) || empty( $args[1] ) ) { return $all_caps; } $cap = $caps[0]; $user_id = $args[1]; // Bail if this isn't the cap we care about if ( 'edit_event_tickets' !== $cap ) { return $all_caps; } if ( ! $options ) { $options = get_option( self::OPTIONNAME ); } if ( ! isset( $all_caps[ $cap ] ) ) { // assume the user has it - by default all users with accounts have it $all_caps[ $cap ] = (bool) $options['edit_event_tickets_cap']; } // If split payments is enabled, let users create tickets if ( ! $this->is_enabled() ) { $all_caps[ $cap ] = false; return $all_caps; } return $all_caps; } /** * Determines whether or not the currently logged in user has the correct cap to sell tickets * (has PayPal info entered if split payments is enabled) * * @param array $all_caps User capabilities * @param array $caps Caps being checked * @param array $args Additional user_cap args */ public function user_has_sell_event_tickets_cap( $all_caps, $caps, $args ) { static $options; // Bail if there isn't a cap or user_id if ( empty( $caps[0] ) || empty( $args[1] ) ) { return $all_caps; } $cap = $caps[0]; $user_id = $args[1]; // Bail if this isn't the cap we care about if ( 'sell_event_tickets' !== $cap ) { return $all_caps; } if ( ! $options ) { $options = get_option( self::OPTIONNAME ); } if ( ! isset( $all_caps[ $cap ] ) ) { // Assume the user has it - by default all users with accounts have it $all_caps[ $cap ] = user_can( $user_id, 'edit_event_tickets' ); } // If split payments is enabled, let users create tickets if ( $this->is_split_payments_enabled() ) { // If enabled, make sure the user has their paypal email set $meta = get_user_meta( $user_id, Tribe__Events__Community__Tickets__Payment_Options_Form::$meta_key, true ); if ( empty( $meta['paypal_account_email'] ) ) { $all_caps[ $cap ] = false; return $all_caps; } } return $all_caps; } /** * Alter the read_private_shop_orders cap if the order contains a ticket that is attached to an event * created by the current user * * @param array $all_caps User capabilities * @param array $caps Caps being checked * @param array $args Additional user_cap args */ public function user_has_read_private_shop_orders( $all_caps, $caps, $args ) { // Bail if there isn't a cap or user_id if ( empty( $caps[0] ) || empty( $args[1] ) ) { return $all_caps; } $cap = $caps[0]; $user_id = absint( $args[1] ); // Bail if this isn't the cap we care about if ( 'read_private_shop_orders' !== $cap ) { return $all_caps; } // If there isn't a post id for the order, bail if ( empty( $args[2] ) ) { return $all_caps; } $order_id = absint( $args[2] ); $query_args = array( 'post_type' => 'tribe_wooticket', 'post_status' => 'publish', 'meta_key' => '_tribe_wooticket_order', 'meta_value' => $order_id, ); $posts = get_posts( $query_args ); foreach ( $posts as $post ) { $event_id = get_post_meta( $post->ID, '_tribe_wooticket_event', true ); $event = get_post( $event_id ); if ( $user_id === (int) $event->post_author ) { $all_caps[ $cap ] = true; return $all_caps; } } return $all_caps; } /** * Injects information about an order's line item * * @param int $unused_item_id Item ID * @param WC_Order_Item $item WooCommerce Order Item object * @param WC_Order $unused_order WooCommerce Order object */ public function add_order_item_details( $unused_item_id, $item, $unused_order ) { // If there isn't a product ID, bail if ( empty( $item['product_id'] ) ) { return; } // If there isn't a product post for the product id, bail if ( ! $product = get_post( $item['product_id'] ) ) { return; } // If there isn't an event ID, bail if ( ! $event_id = get_post_meta( $product->ID, '_tribe_wooticket_for_event', true ) ) { return; } // If there isn't an event post for the event ID, bail if ( ! $event = get_post( $event_id ) ) { return; } $title = get_the_title( $event_id ); include Tribe__Events__Templates::getTemplateHierarchy( 'community-tickets/modules/email-item-event-details' ); } /** * Injects organizer data into the orders report * * @param WP_Post $unused_event Event post * @param WP_User $unused_organizer Community Organizer user object */ public function order_report_organizer_data( $unused_event, $unused_organizer ) { include Tribe__Events__Templates::getTemplateHierarchy( 'community-tickets/modules/orders-report-after-organizer' ); } /** * Injects a meta note about site fees in the Order Report * * @param WP_Post $unused_event Event post * @param WP_User $unused_organizer Community Organizer user object */ public function order_report_site_fees_note( $unused_event, $unused_organizer ) { $options = get_option( self::OPTIONNAME, self::instance()->option_defaults ); $gateway = self::instance()->gateway( 'PayPal' ); $flat = $gateway->fee_flat; $percentage = $gateway->fee_percentage; if ( tribe( 'community.tickets.fees' )->is_flat_fee( $options['site_fee_type'] ) ) { $flat += (float) $options['site_fee_flat']; } if ( tribe( 'community.tickets.fees' )->is_percentage_fee( $options['site_fee_type'] ) ) { $percentage += (float) $options['site_fee_percentage']; } $flat_message = sprintf( __( 'Site Fee: %s per order', 'tribe-events-community-tickets' ), esc_html( tribe_format_currency( number_format( $flat, 2 ) ) ) ); $percentage_message = sprintf( __( 'Site Fee Percentage: %s%%', 'tribe-events-community-tickets' ), esc_html( $percentage ) ); // TODO: move this to the fee class if ( 'flat' === $options['site_fee_type'] ) { return $flat_message; } elseif ( 'percentage' === $options['site_fee_type'] ) { return $percentage_message; } elseif ( 'flat-and-percentage' === $options['site_fee_type'] ) { return "{$flat_message}, {$percentage_message}"; } } /** * Filters whether or not the ticket price can be updated * * @param boolean $can_update Can the ticket price be updated? * @param WP_Post $ticket Ticket object * * @return boolean */ public function can_update_ticket_price( $can_update, $ticket ) { if ( empty( $ticket->ID ) ) { return $can_update; } $total_sales = get_post_meta( $ticket->ID, 'total_sales', true ); if ( $total_sales ) { $can_update = false; } return $can_update; } /** * Filters the user's ability to delete existing tickets. * * The default behaviour is to disallow deletion of tickets once sales have * been made. This can be overridden via the following filter hook, which * this callback itself runs on: * * tribe_tickets_current_user_can_delete_ticket * * @param bool $can_delete * @param int $ticket_id * * @return bool */ public function can_delete_existing_ticket( $can_delete, $ticket_id ) { $event = tribe_events_get_ticket_event( $ticket_id ); if ( tribe_community_events_is_community_event( $event ) ) { $total_sales = get_post_meta( $ticket_id, 'total_sales', true ); if ( $total_sales ) { return false; } } return $can_delete; } /** * Filters the no-update message to display when updating tickets is disallowed * * @param string $message Message to display to user * @param WP_Post $ticket Ticket object * * @return string */ public function disallow_update_ticket_price_message( $message, $ticket ) { if ( empty( $ticket->ID ) ) { return $message; } $total_sales = get_post_meta( $ticket->ID, 'total_sales', true ); if ( $total_sales ) { $message = esc_html__( 'Editing ticket prices is not allowed once purchases have been made.', 'tribe-events-community-tickets' ); } return $message; } /** * Filters whether or not fees are being passed to the end user (purchaser) * * @param boolean $unused_pass_fees Whether or not to pass fees to user * @param int $event_id Event post ID * * return boolean */ public function pass_fees_to_user( $unused_pass_fees, $event_id ) { $fee_setting = $this->get_payment_fee_setting( $event_id ); return 'pass' === $fee_setting; } /** * Filters the fee percentage to apply to a ticket/order * * @param float $unused_fee_percent Fee percentage * * return float */ public function get_fee_percent( $unused_fee_percent ) { return $this->gateway( 'PayPal' )->fee_percentage(); } /** * Filters the flat fee to apply to a ticket/order * * @param float $unused_fee_flat Flat fee * * return float */ public function get_fee_flat( $unused_fee_flat ) { return $this->gateway( 'PayPal' )->fee_flat(); } /** * Get purchase limit * @deprecated 4.5.6 */ public function get_purchase_limit( $ticket_id = null ) { _deprecated_function( __METHOD__, '4.5.6' ); $options = get_option( self::OPTIONNAME, self::instance()->option_defaults ); $purchase_limit = isset( $options['purchase_limit'] ) ? absint( $options['purchase_limit'] ) : 0; if ( ! empty( $ticket_id ) ) { $ticket_limit = absint( get_post_meta( $ticket_id, '_ticket_purchase_limit', true ) ); if ( '' !== $ticket_limit ) { $purchase_limit = absint( $ticket_limit ); } } return $purchase_limit; } /** * Filters add-to-cart quantity to enforce purchase limit * * @param string $cart_item_key WooCommerce cart item index * @param int $product_id WC_Product ID * @deprecated 4.5.6 */ public function enforce_purchase_limit_on_add( $cart_item_key, $product_id ) { _deprecated_function( __METHOD__, '4.5.6' ); $item = WC()->cart->cart_contents[ $cart_item_key ]; // If this isn't a product with an event, then let's not mess with the quantity if ( ! get_post_meta( $product_id, '_tribe_wooticket_for_event', true ) ) { return; } $purchase_limit = $this->get_purchase_limit( $product_id ); if ( $item['quantity'] < $purchase_limit || 0 === $purchase_limit ) { return; } WC()->cart->set_quantity( $cart_item_key, $purchase_limit, false ); } /** * Filters update-cart quantity to enforce purchase limit * * @param int $quantity Amount to add/update * @param string $cart_item_key WooCommerce cart item index * * @return int * @deprecated 4.5.6 */ public function enforce_purchase_limit_on_update( $quantity, $cart_item_key ) { _deprecated_function( __METHOD__, '4.5.6' ); $product = WC()->cart->cart_contents[ $cart_item_key ]; // If this isn't a product with an event, then let's not mess with the quantity if ( ! get_post_meta( $product['product_id'], '_tribe_wooticket_for_event', true ) ) { return $quantity; } $purchase_limit = $this->get_purchase_limit( $product['product_id'] ); if ( $purchase_limit > 0 && $quantity > $purchase_limit ) { $quantity = $purchase_limit; } return $quantity; } /** * Filters update-cart quantity to enforce purchase limit * * @param int $purchase_limit The purchase limit for an item * @deprecated 4.5.6 */ public function set_default_purchase_limit( $purchase_limit ) { _deprecated_function( __METHOD__, '4.5.6' ); $purchase_limit = $this->get_purchase_limit(); return $purchase_limit; } /** * Maybe display a notice about purchase limits * @deprecated 4.5.6 */ public function maybe_display_purchase_limit( $ticket ) { _deprecated_function( __METHOD__, '4.5.6' ); if ( empty( $ticket->ID ) ) { return; } $purchase_limit = $this->get_purchase_limit( $ticket->ID ); if ( ! $purchase_limit ) { return; } ?> <div class="tribe-events-community-tickets-purchase-limit"> <?php printf( esc_html__( 'Limited to %1$s per order.', 'tribe-events-community-tickets' ), esc_html( $purchase_limit ) ); ?> </div> <?php } /** * Asserts whether the user is editing an own auto-draft event. * * @return bool */ protected function editing_ticket_on_own_autodraft( ) { if ( empty( $_POST['post_ID'] ) || empty( $_POST['nonce'] ) ) { return false; } $post = get_post( $_POST['post_ID'] ); if ( empty( $post ) || ! tribe_is_event( $post->ID ) ) { return false; } $legit_actions = array( 'add_ticket_nonce', 'edit_ticket_nonce', 'remove_ticket_nonce' ); do { $can = wp_verify_nonce( $_POST['nonce'], current( $legit_actions ) ); } while ( ! $can && next( $legit_actions ) ); return $can && ( $post->post_author == get_current_user_id() ) && ( $post->post_status == 'auto-draft' ); } /** * Alter the `edit_tribe_events` cap if the request comes during an AJAX * ticket save/update/remove operation on an event auto-draft. * * Even if the option that allows users that submitted Community * Events to edit their events later is off users submitting the first * draft of an event should still be able to create, update and remove * tickets from the event draft. * * @param array $all_caps User capabilities * @param array $caps Caps being checked * @param array $args Additional user_cap args */ public function user_has_edit_tribe_events_cap( $all_caps, $caps ) { if ( empty( $caps[0] ) || 'edit_tribe_events' !== $caps[0] ) { return $all_caps; } if ( Tribe__Main::instance()->doing_ajax() && $this->editing_ticket_on_own_autodraft() ) { $all_caps['edit_tribe_events'] = true; } return $all_caps; } /** * Allows event creator to edit attendees if allowUsersToEditSubmissions is true * * @since 4.6.1 * * @param boolean $user_can user can/can't edit * @param int $user_id ID of user to check, uses current user if empty * @param int $event_id Event ID. * * @return boolean */ public function user_can_manage_own_event_attendees( $user_can, $user_id, $event_id ) { if ( empty( $user_id ) ) { $user_id = get_current_user_id(); } // Cannot manage attendees without user. if ( empty( $user_id ) ) { return false; } // Cannot manage attendees without event. if ( empty( $event_id ) ) { return false; } // Can manage attendees from admin area. if ( is_admin() ) { return true; } // Cannot determine management if origin is not current origin. if ( 'community-events' !== get_post_meta( $event_id, '_EventOrigin', true ) ) { return $user_can; } // Cannot manage attendees that they do not own. if ( (int) $user_id !== (int) get_post_field( 'post_author', $event_id ) ) { return false; } // Cannot manage attendees if they are not allowed to edit submissions. if ( ! tribe( 'community.main' )->getOption( 'allowUsersToEditSubmissions' ) ) { return false; } return true; } /** * Get all options for the plugin. * * @since 4.6.2 * * @param bool $force * * @return array The current settings for the plugin. */ public static function get_options( $force = false ) { if ( ! isset( self::$options ) || $force ) { $options = get_option( self::OPTIONNAME, [] ); /** * Filter a the plugin options after retrieval from the database * * @since 4.6.2 * * @param array $options The unserialized values. */ self::$options = apply_filters( 'tribe_community_events_tickets_get_options', $options ); } return self::$options; } /** * Get value for a specific option. * * @since 4.6.2 * * @param string $option_name Name of option. * @param mixed $default Default value. * @param bool $force * * @return mixed Results of option query. */ public function get_option( $option_name, $default = '', $force = false ) { if ( ! $option_name ) { return; } if ( ! isset( self::$options ) || $force ) { self::get_options( $force ); } $option = $default; if ( isset( self::$options[ $option_name ] ) ) { $option = self::$options[ $option_name ]; } /** * Filter a single option value. * * @since 4.6.2 * * @param string $option Option value. * @param string $default Default value. * @param string $option_name Name of option. */ return apply_filters( 'tribe_get_single_option', $option, $default, $option_name ); } /** * Set value for a specific option. * * @since 4.6.2 * * @param string $option_name Name of option. * @param string $value Value to set. */ public function set_option( $option_name, $value ) { if ( ! $option_name ) { return; } if ( ! isset( self::$options ) ) { self::get_options(); } self::$options[ $option_name ] = $value; update_option( self::OPTIONNAME, self::$options ); } /** * Run Updater on Plugin Updates * * @since 4.5.4 */ public function run_updates() { if ( ! class_exists( 'Tribe__Events__Updater' ) ) { return; // Core needs to be updated for compatibility } $updater = new Tribe__Events__Community__Tickets__Updater( self::VERSION ); if ( $updater->update_required() ) { $updater->do_updates(); } } /** * Sets up class autoloading for this plugin * * @deprecated 4.6 * */ public function autoloading() { _deprecated_function( __METHOD__, '4.6' ); if ( ! class_exists( 'Tribe__Autoloader' ) ) { return; } $autoloader = Tribe__Autoloader::instance(); $autoloader->register_prefix( 'Tribe__Events__Community__Tickets__', dirname( __FILE__ ), 'events-community-tickets' ); $autoloader->register_autoloader(); } /** * Registers this plugin as being active for other tribe plugins and extensions * * @deprecated 4.6 * * @return bool Indicates if Tribe Common wants the plugin to run */ public function register_active_plugin() { _deprecated_function( __METHOD__, '4.6' ); if ( ! function_exists( 'tribe_register_plugin' ) ) { return true; } return tribe_register_plugin( EVENTS_COMMUNITY_TICKETS_FILE, __CLASS__, self::VERSION ); } }
Methods
- __construct — Constructor!
- add_adapter — Add the adapter.
- add_order_item_details — Injects information about an order's line item "unused" params are passed to the template.
- add_site_fee — Injects a meta note about site fees in the Order Report.
- add_template_paths — Register the community-tickets paths with TEC
- add_template_updates_check — Register Community Tickets with the template update checker.
- admin_notices — Hooked to the admin_notices action
- ajax_handler_ticket_save — Auto-appends the author ID onto the SKU
- bind_implementations — Binds implementations that are specific to CT
- bootstrap — Bootstrap the plugin with the plugins_loaded action.
- calculate_cart_fees — Calculate fees for cart.
- can_delete_existing_ticket — Filters the user's ability to delete existing tickets.
- can_update_ticket_price — Filters whether or not the ticket price can be updated.
- community_tickets_settings — Filter the community settings tab to include community tickets settings.
- disallow_update_ticket_price_message — Filters the no-update message to display when updating tickets is disallowed.
- event_form — Event form object accessor method
- filter_prevent_edd_provider — On Community Tickets we do not allow EDD
- gateway — Gateway object accessor method.
- generate_routes — Add routes
- get_fee_flat — Filters the flat fee to apply to a ticket/order.
- get_fee_percent — Filters the fee percentage to apply to a ticket/order.
- get_option — Get value for a specific option.
- get_options — Get all options for the plugin.
- get_payment_fee_setting — Gets an event's payment fee setting.
- give_subscribers_upload_files_cap — Add the upload_files capability to a user when they are uploading files
- hooks — All your hooks are belong to us!
- init — Bootstrap of the Plugin on Init
- instance — Singleton to instantiate the Community Tickets class
- is_enabled — Returns whether or not community tickets is enabled in settings
- is_enabled_for_event — Returns whether or not tickets are enabled for a given event
- is_really_admin — Combined checks to ensure that we're on the admin when we think we are.
- is_split_payments_enabled — Returns whether or not split payments are enabled
- load_text_domain — Load this plugin's text domain.
- maybe_enqueue_admin_resources — Enqueue the admin resources where needed.
- maybe_enqueue_frontend — Enqueue the front end resources, add nonces for forms
- order_report_organizer_data — Injects organizer data into the orders report "unused" params are passed to the template.
- order_report_site_fees_note — Injects a meta note about site fees in the Order Report
- pass_fees_to_user — Filters whether or not fees are being passed to the end user (purchaser).
- payment_options_form — Payment options form object accessor method
- plugins_loaded — Bootstrap the plugin with the plugins_loaded action
- register_resources — Registers scripts and styles.
- report_links — Hooked to the tribe_events_community_event_list_table_row_actions action to add navigation for reports.
- require_login — Redirects if the user is not logged in
- run_updates — Run Updater on Plugin Updates.
- set_option — Set value for a specific option.
- should_run — Should the plugin run? Are all of the appropriate items in place?
- templates — Templates object accessor method
- tickets_price_description — Modify the price field description if we've disabled price editing.
- tickets_price_disabled — Disable the price field if we've disabled price editing.
- user_can_manage_own_event_attendees — Allows event creator to edit attendees if allowUsersToEditSubmissions is true.
- user_has_edit_event_tickets_cap — Determines whether the currently logged in user has the correct cap.
- user_has_edit_tribe_events_cap — Alter the `edit_tribe_events` cap if the request comes during an AJAX ticket save/update/remove operation on an event auto-draft.
- user_has_read_private_shop_orders — Alter the read_private_shop_orders cap if the order contains a ticket that is attached to an event created by the current user.
- user_has_sell_event_tickets_cap — Determines whether or not the currently logged in user has the correct cap to sell tickets.