*/ class MEC_feature_wc extends MEC_base { /** * @var MEC_factory */ public $factory; /** * @var MEC_main */ public $main; /** * @var array */ public $settings; /** * @var array */ public $ml_settings; /** * Constructor method * @author Webnus */ public function __construct() { // Import MEC Factory $this->factory = $this->getFactory(); // Import MEC Main $this->main = $this->getMain(); // General Options $this->settings = $this->main->get_settings(); // MEC Multilingual Settings $this->ml_settings = $this->main->get_ml_settings(); } /** * Initialize * @author Webnus */ public function init() { // Pro version is required if(!$this->getPRO()) return; // WC Hooks if(isset($this->settings['wc_status']) and $this->settings['wc_status']) $this->factory->action('init', array($this, 'hooks')); } public function hooks() { // WooCommerce is not installed if(!class_exists('WooCommerce')) return; // WC library $wc = $this->getWC(); // WooCommerce $this->factory->action('woocommerce_order_status_completed', array($wc, 'completed')); $this->factory->action('woocommerce_thankyou', array($wc, 'paid')); $this->factory->action('woocommerce_new_order_item', array($wc, 'meta'), 10, 2); $this->factory->action('woocommerce_order_status_cancelled', array($wc, 'cancelled')); $this->factory->action('woocommerce_order_status_refunded', array($wc, 'cancelled')); $this->factory->action('woocommerce_after_checkout_validation', array($this, 'validate'),10,2); $this->factory->action('wp', [$this, 'single_product_page']); $this->factory->filter('woocommerce_order_item_display_meta_key', array($this, 'display_key'), 10, 2); $this->factory->filter('woocommerce_order_item_display_meta_value', array($this, 'display_value'), 10, 2); $this->factory->filter('woocommerce_cart_item_name', array($this, 'display_name'), 10, 2); $this->factory->filter('woocommerce_cart_item_thumbnail', array($this, 'display_thumbnail'), 10, 2); $this->factory->filter('woocommerce_quantity_input_args', array($this, 'adjust_quantity'), 10, 2); } public function display_key($display_key, $meta) { if($meta->key == 'mec_event_id') $display_key = esc_html__('Event', 'modern-events-calendar-lite'); elseif($meta->key == 'mec_date') $display_key = esc_html__('Date', 'modern-events-calendar-lite'); elseif($meta->key == 'mec_other_dates') $display_key = esc_html__('Other Dates', 'modern-events-calendar-lite'); elseif($meta->key == 'mec_transaction_id') $display_key = esc_html__('Transaction ID', 'modern-events-calendar-lite'); return $display_key; } public function display_value($display_value, $meta) { if($meta->key == 'mec_event_id') $display_value = ''.get_the_title($meta->value).''; elseif($meta->key == 'mec_transaction_id') $display_value = $meta->value; elseif($meta->key == 'mec_date') { $date_format = (isset($this->ml_settings['booking_date_format1']) and trim($this->ml_settings['booking_date_format1'])) ? $this->ml_settings['booking_date_format1'] : 'Y-m-d'; $time_format = get_option('time_format'); if(strpos($date_format, 'h') !== false or strpos($date_format, 'H') !== false or strpos($date_format, 'g') !== false or strpos($date_format, 'G') !== false) $datetime_format = $date_format; else $datetime_format = $date_format.' '.$time_format; $dates = explode(':', $meta->value); $start_datetime = date_i18n($datetime_format, $dates[0]); $end_datetime = date_i18n($datetime_format, $dates[1]); $display_value = sprintf(esc_html__('%s to %s', 'modern-events-calendar-lite'), $start_datetime, $end_datetime); } elseif($meta->key == 'mec_other_dates') { $date_format = (isset($this->ml_settings['booking_date_format1']) and trim($this->ml_settings['booking_date_format1'])) ? $this->ml_settings['booking_date_format1'] : 'Y-m-d'; $time_format = get_option('time_format'); if(strpos($date_format, 'h') !== false or strpos($date_format, 'H') !== false or strpos($date_format, 'g') !== false or strpos($date_format, 'G') !== false) $datetime_format = $date_format; else $datetime_format = $date_format.' '.$time_format; $dates = (is_array($meta->value) ? $meta->value : explode(',', $meta->value)); $date_values = []; foreach($dates as $date) { if(!trim($date)) continue; $timestamps = explode(':', $date); if(!isset($timestamps[0]) or !isset($timestamps[1])) continue; $start_datetime = date_i18n($datetime_format, $timestamps[0]); $end_datetime = date_i18n($datetime_format, $timestamps[1]); $date_values[] = sprintf(esc_html__('%s to %s', 'modern-events-calendar-lite'), $start_datetime, $end_datetime); } $display_value = implode('
', $date_values); } return $display_value; } public function display_name($name, $item) { if(!isset($item['mec_event_id']) or !trim($item['mec_event_id'])) return $name; if(!isset($item['mec_date']) or !trim($item['mec_date'])) return $name; $date_format = (isset($this->ml_settings['booking_date_format1']) and trim($this->ml_settings['booking_date_format1'])) ? $this->ml_settings['booking_date_format1'] : get_option('date_format'); $other_dates = (isset($item['mec_other_dates']) and is_array($item['mec_other_dates'])) ? $item['mec_other_dates'] : []; $dates = array_merge(array($item['mec_date']), $other_dates); $formatted_dates = []; foreach($dates as $d) { $timestamps = explode(':', $d); $formatted_dates[] = date_i18n($date_format, $timestamps[0]); } $name .= ' ('.implode(', ', $formatted_dates).')'; return $name; } public function display_thumbnail($image, $item) { if(!isset($item['mec_event_id']) or !trim($item['mec_event_id'])) return $image; if(!isset($item['product_id']) or !trim($item['product_id'])) return $image; $product_id = $item['product_id']; if(has_post_thumbnail($product_id)) return $image; $event_id = $item['mec_event_id']; if(has_post_thumbnail($event_id)) return get_the_post_thumbnail($event_id); return $image; } public function validate($data, $errors) { // Cart Items $items = WC()->cart->get_cart(); // Book $book = $this->getBook(); $printed = false; $all_items = []; foreach($items as $item) { $event_id = $item['mec_event_id'] ?? NULL; if(!$event_id) continue; $product_id = $item['product_id'] ?? NULL; $mec_ticket = get_post_meta($product_id, 'mec_ticket', true); $ex = explode(':', $mec_ticket); $ticket_id = $ex[1] ?? NULL; if(!$ticket_id) continue; $date = $item['mec_date'] ?? NULL; $timestamps = explode(':', $date); $timestamp = $timestamps[0]; $other_dates = (isset($item['mec_other_dates']) and is_array($item['mec_other_dates'])) ? $item['mec_other_dates'] : []; $all_dates = array_merge([$date], $other_dates); $quantity = $item['quantity'] ?? 1; if(count($all_dates) > 1 && $quantity % count($all_dates) === 0) $quantity = $quantity / count($all_dates); if(!isset($all_items[$event_id])) $all_items[$event_id] = []; if(!isset($all_items[$event_id][$ticket_id])) $all_items[$event_id][$ticket_id] = []; if(!isset($all_items[$event_id][$ticket_id][$timestamp])) $all_items[$event_id][$ticket_id][$timestamp] = $quantity; else $all_items[$event_id][$ticket_id][$timestamp] += $quantity; $availability = $book->get_tickets_availability($event_id, $timestamp); $tickets = get_post_meta($event_id, 'mec_tickets', true); // Ticket is not available if(!isset($availability[$ticket_id]) or ($availability[$ticket_id] != -1 and $availability[$ticket_id] < $quantity)) { $printed = true; if($availability[$ticket_id] == '0') $errors->add('validation', sprintf(esc_html__('%s ticket is sold out!', 'modern-events-calendar-lite'), $tickets[$ticket_id]['name'])); else $errors->add('validation', sprintf(esc_html__('Only %s slots remained for %s ticket so you cannot book %s ones.', 'modern-events-calendar-lite'), $availability[$ticket_id], $tickets[$ticket_id]['name'], $quantity)); } } // Error already printed if($printed) return; foreach($all_items as $event_id => $tickets) { // User Booking Limits list($limit, $unlimited) = $book->get_user_booking_limit($event_id); $total_quantity = 0; foreach($tickets as $ticket_id => $timestamps) { foreach($timestamps as $timestamp => $quantity) { $availability = $book->get_tickets_availability($event_id, $timestamp); $tickets = get_post_meta($event_id, 'mec_tickets', true); $total_quantity += $quantity; // Ticket is not available if(!isset($availability[$ticket_id]) or ($availability[$ticket_id] != -1 and $availability[$ticket_id] < $quantity)) { if($availability[$ticket_id] == '0') $errors->add('validation', sprintf(esc_html__('%s ticket is sold out!', 'modern-events-calendar-lite'), $tickets[$ticket_id]['name'])); else $errors->add('validation', sprintf(esc_html__('Only %s slots remained for %s ticket so you cannot book %s ones.', 'modern-events-calendar-lite'), $availability[$ticket_id], $tickets[$ticket_id]['name'], $quantity)); } } } // Take Care of User Limit if(!$unlimited and $total_quantity > $limit) { $errors->add('validation', sprintf($this->main->m('booking_restriction_message3', esc_html__("Maximum allowed number of tickets that you can book is %s.", 'modern-events-calendar-lite')), $limit)); } } } /** * @param $args * @param WC_Product $product * @return mixed */ public function adjust_quantity($args, $product) { $mec_product = get_post_meta($product->get_id(), 'mec_ticket', true); // Make the quantity input as read-only so nobody can change its value if($mec_product and isset($args['input_value']) and is_numeric($args['input_value'])) { $args['min_value'] = $args['input_value']; $args['max_value'] = $args['input_value']; } return $args; } public function single_product_page() { // WooCommerce Product if(is_product()) { global $post; // MEC Product $is_mec = get_post_meta($post->ID, 'mec_ticket', true); if($is_mec) { global $wp_query; $wp_query->set_404(); status_header(404); } } } }