*/ class MEC_feature_occurrences extends MEC_base { public $factory; public $main; public $settings; public $db; /** * Constructor method * @author Webnus */ public function __construct() { // Import MEC Factory $this->factory = $this->getFactory(); // Import MEC Main $this->main = $this->getMain(); // MEC Settings $this->settings = $this->main->get_settings(); // Import MEC DB $this->db = $this->getDB(); } /** * Initialize occurrences feature * @author Webnus */ public function init() { // Occurrences Status $occurrences_status = isset($this->settings['per_occurrences_status']) && $this->settings['per_occurrences_status'] && $this->getPRO(); // Feature is not enabled if(!$occurrences_status) return; // Tab $this->factory->filter('mec-single-event-meta-title', array($this, 'tab'), 10, 3); // Metabox $this->factory->action('mec_metabox_details', array($this, 'meta_box_occurrences'), 18); // Occurrences for FES if(!isset($this->settings['fes_section_occurrences']) or (isset($this->settings['fes_section_occurrences']) and $this->settings['fes_section_occurrences'])) $this->factory->action('mec_fes_metabox_details', array($this, 'meta_box_occurrences'), 18); // AJAX $this->factory->action('wp_ajax_mec_occurrences_add', array($this, 'add')); $this->factory->action('wp_ajax_mec_occurrences_delete', array($this, 'delete')); // Save Data $this->factory->action('mec_save_event_data', array($this, 'save'), 10, 2); $this->factory->filter('mec_occurrence_event_title', [$this, 'title'], 10, 2); } public function tab($tabs, $activated, $post) { $draft = !(isset($post->post_status) && $post->post_status != 'auto-draft'); $repeat_status = get_post_meta($post->ID, 'mec_repeat_status', true); if($draft or !$repeat_status) return $tabs; $tabs[__('Occurrences', 'modern-events-calendar-lite')] = 'mec-occurrences'; return $tabs; } /** * Show occurrences of event into the Add/Edit event page * * @author Webnus * @param WP_Post $post */ public function meta_box_occurrences($post) { FormBuilder::occurrences( $post ); } public function delete() { // Check if our nonce is set. if(!isset($_POST['_wpnonce'])) $this->main->response(array('success'=>0, 'code'=>'NONCE_MISSING')); // Verify that the nonce is valid. if(!wp_verify_nonce(sanitize_text_field($_POST['_wpnonce']), 'mec_occurrences_delete')) $this->main->response(array('success'=>0, 'code'=>'NONCE_IS_INVALID')); $occurrence_id = isset($_POST['id']) ? sanitize_text_field($_POST['id']) : ''; // Request is invalid! if(!trim($occurrence_id)) $this->main->response(array('success'=>0, 'code'=>'ID_IS_INVALID')); $this->db->q("DELETE FROM `#__mec_occurrences` WHERE `id`='".$this->db->escape($occurrence_id)."'"); $this->main->response(array('success'=>1)); } public function add() { // Check if our nonce is set. if(!isset($_POST['_wpnonce'])) $this->main->response(array('success'=>0, 'code'=>'NONCE_MISSING')); // Verify that the nonce is valid. if(!wp_verify_nonce(sanitize_text_field($_POST['_wpnonce']), 'mec_occurrences_add')) $this->main->response(array('success'=>0, 'code'=>'NONCE_IS_INVALID')); $date = isset($_POST['date']) ? sanitize_text_field($_POST['date']) : ''; $id = isset($_POST['id']) ? sanitize_text_field($_POST['id']) : ''; // Date is invalid! if(!trim($date) or !trim($id)) $this->main->response(array('success'=>0, 'code'=>'DATE_OR_ID_IS_INVALID')); $dates = explode(':', $date); // Add Occurrence $occurrence_id = $this->db->q("INSERT INTO `#__mec_occurrences` (`post_id`,`occurrence`,`params`) VALUES ('".$id."','".$dates[0]."','".json_encode(array())."')", 'insert'); $success = 1; ob_start(); $this->get_occurrence_form($occurrence_id); $html = ob_get_clean(); $this->main->response(array('success'=>$success, 'html'=>$html)); } public function get_occurrence_form($occurrence_id) { $params = $this->get($occurrence_id); $data = $this->get_data($occurrence_id); $event_id = $data['post_id'] ?? 0; $post = get_post($event_id); $date_format = get_option('date_format'); $time_format = get_option('time_format'); $datetime_format = $date_format.' '.$time_format; $event_status = (isset($params['event_status']) and trim($params['event_status'])) ? $params['event_status'] : 'EventScheduled'; $moved_online_link = (isset($params['moved_online_link']) and trim($params['moved_online_link'])) ? $params['moved_online_link'] : ''; $cancelled_reason = (isset($params['cancelled_reason']) and trim($params['cancelled_reason'])) ? $params['cancelled_reason'] : ''; $display_cancellation_reason_in_single_page = (isset($params['display_cancellation_reason_in_single_page']) and trim($params['display_cancellation_reason_in_single_page'])) ? $params['display_cancellation_reason_in_single_page'] : ''; $hourly_schedules = (isset($params['hourly_schedules']) and is_array($params['hourly_schedules'])) ? $params['hourly_schedules'] : []; $fields_data = (isset($params['fields']) and is_array($params['fields'])) ? $params['fields'] : get_post_meta($post->ID, 'mec_fields', true); // Status of Speakers Feature $speakers_status = isset($this->settings['speakers_status']) && $this->settings['speakers_status']; $speakers = get_terms('mec_speaker', array( 'orderby' => 'name', 'order' => 'ASC', 'hide_empty' => '0', )); // Cost $type = ((isset($this->settings['single_cost_type']) and trim($this->settings['single_cost_type'])) ? $this->settings['single_cost_type'] : 'numeric'); // Links $read_more = (isset($params['read_more']) ? esc_attr($params['read_more']) : ''); $more_info = (isset($params['more_info']) ? esc_attr($params['more_info']) : ''); $more_info_title = (isset($params['more_info_title']) ? esc_attr($params['more_info_title']) : ''); $more_info_target = (isset($params['more_info_target']) ? esc_attr($params['more_info_target']) : ''); // Locations $locations = get_terms('mec_location', array('orderby'=>'name', 'hide_empty'=>'0')); $location_id = (isset($params['location_id']) ? esc_attr($params['location_id']) : ''); $dont_show_map = (isset($params['dont_show_map']) ? esc_attr($params['dont_show_map']) : ''); // Organizers $organizers = get_terms('mec_organizer', array('orderby'=>'name', 'hide_empty'=>'0')); $organizer_id = (isset($params['organizer_id']) ? esc_attr($params['organizer_id']) : ''); // Tickets $tickets = get_post_meta($event_id, 'mec_tickets', true); if(!is_array($tickets)) $tickets = []; $occ_tickets = (isset($params['tickets']) and is_array($params['tickets'])) ? $params['tickets'] : []; // Bookings $bookings = $this->main->get_bookings($event_id, $data['occurrence']); // All Occurrences $occurrences = $this->get_dates($event_id, current_time('timestamp')); ?>
  • main->m('event_cost', esc_html__('SEO Schema / Event Status', 'modern-events-calendar-lite'))); ?>

    >

    main->m('bookings', esc_html__('Bookings', 'modern-events-calendar-lite'))); ?>

    getFormBuilder(); $builder->hourlySchedule([ 'hourly_schedules' => $hourly_schedules, 'speakers_status' => $speakers_status, 'speakers' => $speakers, 'wrapper_class' => '', 'prefix' => 'mec_occurrences_'.esc_attr($occurrence_id).'_', 'name_prefix' => 'mec[occurrences]['.esc_attr($occurrence_id).']', ]); ?>
    getEventFields(); $fields->form(array( 'id' => 'mec_occurrences_event_fields_'.esc_attr($occurrence_id), 'class' => 'no', 'post' => $post, 'data' => $fields_data, 'id_prefix' => 'mec_occurrences_'.esc_attr($occurrence_id).'_', 'name_prefix' => 'mec[occurrences]['.esc_attr($occurrence_id).']', 'mandatory_status' => false, )); ?>

    main->m('taxonomy_location', esc_html__('Location', 'modern-events-calendar-lite'))); ?>

    getPRO()): ?>

    main->m('taxonomy_organizer', esc_html__('Organizer', 'modern-events-calendar-lite'))); ?>

    main->m('event_cost', esc_html__('Event Cost', 'modern-events-calendar-lite'))); ?>

    class="mec-col-3" name="mec[occurrences][][cost]" id="mec_occurrences__cost" value="" title="" placeholder=""/>

    main->m('tickets', esc_html__('Tickets', 'modern-events-calendar-lite'))); ?>

    $ticket): if(!is_numeric($key)) continue; $occ_ticket = $occ_tickets[$key] ?? []; ?>

    ID, esc_attr($occurrence_id)); ?>
  • getBook(); foreach($occurrences as $occurrence) { // Clean Hourly Schedules $raw_hourly_schedules = $occurrence['hourly_schedules'] ?? []; if(isset($raw_hourly_schedules[':d:'])) unset($raw_hourly_schedules[':d:']); $hourly_schedules = []; foreach($raw_hourly_schedules as $raw_hourly_schedule) { if(isset($raw_hourly_schedule['schedules'][':i:'])) unset($raw_hourly_schedule['schedules'][':i:']); $hourly_schedules[] = $raw_hourly_schedule; } // Hourly Schedules $occurrence['hourly_schedules'] = $hourly_schedules; $location_id = $occurrence['location_id'] ?? ''; if($location_id) $location_ids[] = $location_id; $organizer_id = $occurrence['organizer_id'] ?? ''; if($organizer_id) $organizer_ids[] = $organizer_id; // Status $status = $occurrence['event_status'] ?? 'EventScheduled'; $bookings_status = $occurrence['cancel_bookings'] ?? ''; $move_bookings_to = $occurrence['move_bookings_to'] ?? ''; if($status === 'EventCancelled' && trim($bookings_status)) { $timestamp = $this->db->select("SELECT occurrence FROM `#__mec_occurrences` WHERE `id`='".esc_sql($occurrence['id'])."'", 'loadResult'); $bookings = $this->main->get_bookings($post_id, $timestamp); $occ_data = $this->get_data($occurrence['id']); foreach($bookings as $booking) { if($bookings_status === 'refund') $book->cancel($booking->ID, true); elseif($bookings_status === 'move' && trim($move_bookings_to) && isset($occ_data['occurrence'])) $book->move($booking->ID, $occ_data['occurrence'], $move_bookings_to); elseif($bookings_status === 'move_notify' && trim($move_bookings_to) && isset($occ_data['occurrence'])) { $book->move($booking->ID, $occ_data['occurrence'], $move_bookings_to); $book->move_notify($booking->ID, $move_bookings_to); } else $book->cancel($booking->ID, false); } } // Save Occurrence $this->db->q("UPDATE `#__mec_occurrences` SET `params`='".json_encode($occurrence, JSON_UNESCAPED_UNICODE)."' WHERE `id`='".$this->db->escape($occurrence['id'])."'"); } $organizer_ids = array_unique($organizer_ids); foreach($organizer_ids as $organizer_id) wp_set_object_terms($post_id, (int) $organizer_id, 'mec_organizer', true); $location_ids = array_unique($location_ids); foreach($location_ids as $location_id) wp_set_object_terms($post_id, (int) $location_id, 'mec_location', true); } public function get_dates($post_id, $start, $limit = 100) { return $this->db->select("SELECT `tstart`, `tend` FROM `#__mec_dates` WHERE `post_id`='".$this->db->escape($post_id)."' AND `tstart`>='".$this->db->escape($start)."' ORDER BY `tstart` ASC LIMIT ".$this->db->escape($limit)); } public function get($occurrence_id) { $JSON = $this->db->select("SELECT `params` FROM `#__mec_occurrences` WHERE `id`='".$this->db->escape($occurrence_id)."'", 'loadResult'); if(!trim($JSON)) return []; else { $params = json_decode($JSON, true); if(!is_array($params)) return []; else return $params; } } public function get_data($occurrence_id) { return $this->db->select("SELECT * FROM `#__mec_occurrences` WHERE `id`='".$this->db->escape($occurrence_id)."'", 'loadAssoc'); } public function get_all_occurrences($post_id, $start = NULL) { return $this->db->select("SELECT * FROM `#__mec_occurrences` WHERE `post_id`='".$this->db->escape($post_id)."' ".($start ? "AND `occurrence`>='".$this->db->escape($start)."'" : '')." ORDER BY `occurrence` DESC LIMIT 200", 'loadAssocList'); } public static function param($post_id, $timestamp, $key, $default = NULL) { // Main $main = new MEC_main(); // Cache $cache = $main->getCache(); // Get $params = $cache->rememberOnce('mec_occ_param_'.$post_id.'_'.$timestamp.'_'.$key, function() use($main, $post_id, $timestamp) { $db = $main->getDB(); $JSON = $db->select("SELECT `params` FROM `#__mec_occurrences` WHERE `post_id`='".$db->escape($post_id)."' AND `occurrence`='".$db->escape($timestamp)."' ORDER BY `id` DESC LIMIT 1", 'loadResult'); if(is_null($JSON) or !trim($JSON)) $params = []; else $params = json_decode($JSON, true); return is_array($params) ? $params : []; }); if($key == '*') return $params; elseif(isset($params[$key]) and !is_array($params[$key]) and trim($params[$key]) != '') return $params[$key]; elseif(isset($params[$key]) and is_array($params[$key])) return $params[$key]; else return $default; } public static function fetch($date_events = array()) { $occurrences = []; $where = ''; foreach($date_events as $events) { foreach($events as $event) { $timestamp = (isset($event->date) and isset($event->date['start']) and isset($event->date['start']['timestamp']) and $event->date['start']['timestamp']) ? $event->date['start']['timestamp'] : NULL; if(!$timestamp) continue; $occurrences[] = array($event->ID, $timestamp); $where .= "(`post_id`=".esc_sql($event->ID)." AND `occurrence`=".esc_sql($timestamp).") OR "; } } // No Occurrences if(!count($occurrences)) return; // Add to Cache self::cache_fetched_occurrences($occurrences, $where); } public static function fetch_single($event, $dates) { $occurrences = []; $where = ''; foreach($dates as $date) { $timestamp = (isset($date) and isset($date['start']) and isset($date['start']['timestamp']) and $date['start']['timestamp']) ? $date['start']['timestamp'] : NULL; if(!$timestamp) continue; $occurrences[] = array($event->ID, $timestamp); $where .= "(`post_id`=".esc_sql($event->ID)." AND `occurrence`=".esc_sql($timestamp).") OR "; } // No Occurrences if(!count($occurrences)) return; // Add to Cache self::cache_fetched_occurrences($occurrences, $where); } public static function cache_fetched_occurrences($occurrences, $where) { // Main $main = new MEC_main(); // Db $db = $main->getDB(); // Records $records = $db->select("SELECT `post_id`, `occurrence`, `params` FROM `#__mec_occurrences` WHERE ".rtrim($where, 'OR ')); // Mapped Records $mapped_records = []; foreach($records as $record) { $JSON = $record->params; if(!trim($JSON)) $params = []; else $params = json_decode($JSON, true); $mapped_records[$record->post_id.':'.$record->occurrence] = (is_array($params) ? $params : array()); } // Cache $cache = $main->getCache(); // Add to Cache foreach($occurrences as $occurrence) { $post_id = $occurrence[0]; $timestamp = $occurrence[1]; $value = $mapped_records[$post_id . ':' . $timestamp] ?? []; $cache->set('mec_occ_param_'.$post_id.'_'.$timestamp, $value); } } public function title($title, $event) { $time = $event->data->time ?? []; if(is_array($time) && count($time) && isset($time['start_timestamp']) && $time['start_timestamp']) { $title = MEC_feature_occurrences::param($event->ID, $time['start_timestamp'], 'title', $title); } return $title; } }