/**
     * Get listings via ajax
     */
    public function get_listings()
    {
        global $wp_post_types;
        $result = array();
        $search_location = sanitize_text_field(stripslashes($_REQUEST['search_location']));
        $search_keywords = sanitize_text_field(stripslashes($_REQUEST['search_keywords']));
        $search_datetimes = isset($_REQUEST['search_datetimes']) ? $_REQUEST['search_datetimes'] : '';
        $search_categories = isset($_REQUEST['search_categories']) ? $_REQUEST['search_categories'] : '';
        $search_event_types = isset($_REQUEST['search_event_types']) ? $_REQUEST['search_event_types'] : '';
        $search_ticket_prices = isset($_REQUEST['search_ticket_prices']) ? $_REQUEST['search_ticket_prices'] : '';
        $post_type_label = $wp_post_types['event_listing']->labels->name;
        $orderby = sanitize_text_field($_REQUEST['orderby']);
        if (is_array($search_datetimes)) {
            $search_datetimes = array_filter(array_map('sanitize_text_field', array_map('stripslashes', $search_datetimes)));
        } else {
            $search_datetimes = array_filter(array(sanitize_text_field(stripslashes($search_datetimes))));
        }
        if (is_array($search_categories)) {
            $search_categories = array_filter(array_map('sanitize_text_field', array_map('stripslashes', $search_categories)));
        } else {
            $search_categories = array_filter(array(sanitize_text_field(stripslashes($search_categories))));
        }
        if (is_array($search_event_types)) {
            $search_event_types = array_filter(array_map('sanitize_text_field', array_map('stripslashes', $search_event_types)));
        } else {
            $search_event_types = array_filter(array(sanitize_text_field(stripslashes($search_event_types))));
        }
        if (is_array($search_ticket_prices)) {
            $search_ticket_prices = array_filter(array_map('sanitize_text_field', array_map('stripslashes', $search_ticket_prices)));
        } else {
            $search_ticket_prices = array_filter(array(sanitize_text_field(stripslashes($search_ticket_prices))));
        }
        $args = array('search_location' => $search_location, 'search_keywords' => $search_keywords, 'search_datetimes' => $search_datetimes, 'search_categories' => $search_categories, 'search_event_types' => $search_event_types, 'search_ticket_prices' => $search_ticket_prices, 'orderby' => $orderby, 'order' => sanitize_text_field($_REQUEST['order']), 'offset' => (absint($_REQUEST['page']) - 1) * absint($_REQUEST['per_page']), 'posts_per_page' => absint($_REQUEST['per_page']));
        if (isset($_REQUEST['cancelled']) && ($_REQUEST['cancelled'] === 'true' || $_REQUEST['cancelled'] === 'false')) {
            $args['cancelled'] = $_REQUEST['cancelled'] === 'true' ? true : false;
        }
        if (isset($_REQUEST['featured']) && ($_REQUEST['featured'] === 'true' || $_REQUEST['featured'] === 'false')) {
            $args['featured'] = $_REQUEST['featured'] === 'true' ? true : false;
            $args['orderby'] = 'featured' === $orderby ? 'date' : $orderby;
        }
        ob_start();
        $events = get_event_listings(apply_filters('event_manager_get_listings_args', $args));
        $result['found_events'] = false;
        if ($events->have_posts()) {
            $result['found_events'] = true;
            ?>

			<?php 
            while ($events->have_posts()) {
                $events->the_post();
                ?>

				<?php 
                get_event_manager_template_part('content', 'event_listing');
                ?>

			<?php 
            }
            ?>

		<?php 
        } else {
            ?>

			<?php 
            get_event_manager_template_part('content', 'no-events-found');
            ?>

		<?php 
        }
        $result['html'] = ob_get_clean();
        $result['filter_value'] = array();
        //categories
        if ($search_categories) {
            $showing_categories = array();
            foreach ($search_categories as $category) {
                $category_object = get_term_by(is_numeric($category) ? 'id' : 'slug', $category, 'event_listing_category');
                if (!is_wp_error($category_object)) {
                    $showing_categories[] = $category_object->name;
                }
            }
            $result['filter_value'][] = implode(', ', $showing_categories);
        }
        //event types
        if ($search_event_types) {
            $showing_event_types = array();
            foreach ($search_event_types as $event_type) {
                $event_type_object = get_term_by(is_numeric($event_type) ? 'id' : 'slug', $event_type, 'event_listing_type');
                if (!is_wp_error($event_type_object)) {
                    $showing_event_types[] = $event_type_object->name;
                }
            }
            $result['filter_value'][] = implode(', ', $showing_event_types);
        }
        //datetimes
        if ($search_datetimes) {
            $showing_datetimes = array();
            foreach ($search_datetimes as $datetime) {
                $showing_datetimes[] = GAM_Event_Manager_Filters::get_datetime_value($datetime);
            }
            $result['filter_value'][] = implode(', ', $showing_datetimes);
        }
        //ticket prices
        if ($search_ticket_prices) {
            $showing_ticket_prices = array();
            foreach ($search_ticket_prices as $ticket_price) {
                $showing_ticket_prices[] = GAM_Event_Manager_Filters::get_ticket_price_value($ticket_price);
            }
            $result['filter_value'][] = implode(', ', $showing_ticket_prices);
        }
        if ($search_keywords) {
            $result['filter_value'][] = '&ldquo;' . $search_keywords . '&rdquo;';
        }
        $last_filter_value = array_pop($result['filter_value']);
        $result_implode = implode(', ', $result['filter_value']);
        if (count($result['filter_value']) >= 1) {
            $result['filter_value'] = explode(" ", $result_implode);
            $result['filter_value'][] = " &amp; ";
        } else {
            if (!empty($last_filter_value)) {
                $result['filter_value'] = explode(" ", $result_implode);
            }
        }
        $result['filter_value'][] = $last_filter_value . " " . $post_type_label;
        if ($search_location) {
            $result['filter_value'][] = sprintf(__('located in &ldquo;%s&rdquo;', 'gam-event-manager'), $search_location);
        }
        if (1 === sizeof($result['filter_value'])) {
            $result['showing_applied_filters'] = true;
        }
        $result['filter_value'] = apply_filters('event_manager_get_listings_custom_filter_text', sprintf(__('Showing all %s', 'gam-event-manager'), implode(' ', $result['filter_value'])));
        // Generate RSS link
        $result['showing_links'] = event_manager_get_filtered_links(array('search_keywords' => $search_keywords, 'search_location' => $search_location, 'search_datetimes' => $search_datetimes, 'search_categories' => $search_categories, 'search_event_types' => $search_event_types, 'search_ticket_prices' => $search_ticket_prices));
        // Generate pagination
        if (isset($_REQUEST['show_pagination']) && $_REQUEST['show_pagination'] === 'true') {
            $result['pagination'] = get_event_listing_pagination($events->max_num_pages, absint($_REQUEST['page']));
        }
        $result['max_num_pages'] = $events->max_num_pages;
        wp_send_json(apply_filters('event_manager_get_listings_result', $result, $events));
    }
    /**
     * output_events function.
     *
     * @access public
     * @param mixed $args
     * @return void
     */
    public function output_events($atts)
    {
        ob_start();
        extract($atts = shortcode_atts(apply_filters('event_manager_output_events_defaults', array('per_page' => get_option('event_manager_per_page'), 'orderby' => 'featured', 'order' => 'DESC', 'show_filters' => true, 'show_categories' => true, 'show_event_types' => true, 'show_ticket_prices' => true, 'show_category_multiselect' => get_option('event_manager_enable_default_category_multiselect', false), 'show_event_type_multiselect' => get_option('event_manager_enable_default_event_type_multiselect', false), 'show_pagination' => false, 'show_more' => true, 'categories' => '', 'event_types' => '', 'ticket_prices' => '', 'featured' => null, 'cancelled' => null, 'location' => '', 'keywords' => '', 'selected_datetime' => '', 'selected_category' => '', 'selected_event_type' => '', 'selected_ticket_price' => '')), $atts));
        //Categories
        if (!get_option('event_manager_enable_categories')) {
            $show_categories = false;
        }
        //Event types
        if (!get_option('event_manager_enable_event_types')) {
            $show_event_types = false;
        }
        //Event ticket prices
        if (!get_option('event_manager_enable_event_ticket_prices')) {
            $show_ticket_prices = false;
        }
        // String and bool handling
        $show_filters = $this->string_to_bool($show_filters);
        $show_categories = $this->string_to_bool($show_categories);
        $show_event_types = $this->string_to_bool($show_event_types);
        $show_ticket_prices = $this->string_to_bool($show_ticket_prices);
        $show_category_multiselect = $this->string_to_bool($show_category_multiselect);
        $show_event_type_multiselect = $this->string_to_bool($show_event_type_multiselect);
        $show_more = $this->string_to_bool($show_more);
        $show_pagination = $this->string_to_bool($show_pagination);
        if (!is_null($featured)) {
            $featured = is_bool($featured) && $featured || in_array($featured, array('1', 'true', 'yes')) ? true : false;
        }
        if (!is_null($cancelled)) {
            $cancelled = is_bool($cancelled) && $cancelled || in_array($cancelled, array('1', 'true', 'yes')) ? true : false;
        }
        //set value for the event datetimes
        $datetimes = GAM_Event_Manager_Filters::get_datetimes_filter();
        //Set value for the ticket prices
        $ticket_prices = GAM_Event_Manager_Filters::get_ticket_prices_filter();
        // Array handling
        $datetimes = is_array($datetimes) ? $datetimes : array_filter(array_map('trim', explode(',', $datetimes)));
        $categories = is_array($categories) ? $categories : array_filter(array_map('trim', explode(',', $categories)));
        $event_types = is_array($event_types) ? $event_types : array_filter(array_map('trim', explode(',', $event_types)));
        $ticket_prices = is_array($ticket_prices) ? $ticket_prices : array_filter(array_map('trim', explode(',', $ticket_prices)));
        // Get keywords, location, datetime, category, event type and ticket price from query string if set
        if (!empty($_GET['search_keywords'])) {
            $keywords = sanitize_text_field($_GET['search_keywords']);
        }
        if (!empty($_GET['search_location'])) {
            $location = sanitize_text_field($_GET['search_location']);
        }
        if (!empty($_GET['search_datetime'])) {
            $selected_datetime = sanitize_text_field($_GET['search_datetime']);
        }
        if (!empty($_GET['search_category'])) {
            $selected_category = sanitize_text_field($_GET['search_category']);
        }
        if (!empty($_GET['search_event_type'])) {
            $selected_event_type = sanitize_text_field($_GET['search_event_type']);
        }
        if (!empty($_GET['search_ticket_price'])) {
            $selected_ticket_price = sanitize_text_field($_GET['search_ticket_price']);
        }
        if ($show_filters) {
            get_event_manager_template('event-filters.php', array('per_page' => $per_page, 'orderby' => $orderby, 'order' => $order, 'datetimes' => $datetimes, 'selected_datetime' => $selected_datetime, 'show_categories' => $show_categories, 'show_category_multiselect' => $show_category_multiselect, 'categories' => $categories, 'selected_category' => $selected_category, 'show_event_types' => $show_event_types, 'show_event_type_multiselect' => $show_event_type_multiselect, 'event_types' => $event_types, 'selected_event_type' => $selected_event_type, 'show_ticket_prices' => $show_ticket_prices, 'ticket_prices' => $ticket_prices, 'selected_ticket_price' => $selected_ticket_price, 'atts' => $atts, 'location' => $location, 'keywords' => $keywords));
            get_event_manager_template('event-listings-start.php');
            get_event_manager_template('event-listings-end.php');
            if (!$show_pagination && $show_more) {
                echo '<a class="load_more_events" id="load_more_events" href="#" style="display:none;"><strong>' . __('Load more events', 'gam-event-manager') . '</strong></a>';
            }
        } else {
            $events = get_event_listings(apply_filters('event_manager_output_events_args', array('search_location' => $location, 'search_keywords' => $keywords, 'search_datetimes' => $datetimes, 'search_categories' => $categories, 'search_event_types' => $event_types, 'search_ticket_prices' => $ticket_prices, 'orderby' => $orderby, 'order' => $order, 'posts_per_page' => $per_page, 'featured' => $featured, 'cancelled' => $cancelled)));
            if ($events->have_posts()) {
                ?>

				<?php 
                get_event_manager_template('event-listings-start.php');
                ?>

				<?php 
                while ($events->have_posts()) {
                    $events->the_post();
                    ?>

					<?php 
                    get_event_manager_template_part('content', 'event_listing');
                    ?>

				<?php 
                }
                ?>

				<?php 
                get_event_manager_template('event-listings-end.php');
                ?>

				<?php 
                if ($events->found_posts > $per_page && $show_more) {
                    ?>

					<?php 
                    wp_enqueue_script('gam-event-manager-ajax-filters');
                    ?>

					<?php 
                    if ($show_pagination) {
                        ?>

						<?php 
                        echo get_event_listing_pagination($events->max_num_pages);
                        ?>

					<?php 
                    } else {
                        ?>

						<a class="load_more_events" id="load_more_events" href="#"><strong><?php 
                        _e('Load more listings', 'gam-event-manager');
                        ?>
</strong></a>

					<?php 
                    }
                    ?>

				<?php 
                }
                ?>

			<?php 
            } else {
                do_action('event_manager_output_events_no_results');
            }
            wp_reset_postdata();
        }
        $data_attributes_string = '';
        $data_attributes = array('location' => $location, 'keywords' => $keywords, 'show_filters' => $show_filters ? 'true' : 'false', 'show_pagination' => $show_pagination ? 'true' : 'false', 'per_page' => $per_page, 'orderby' => $orderby, 'order' => $order, 'datetimes' => implode(',', $datetimes), 'categories' => implode(',', $categories), 'event_types' => implode(',', $event_types), 'ticket_prices' => implode(',', $ticket_prices));
        if (!is_null($featured)) {
            $data_attributes['featured'] = $featured ? 'true' : 'false';
        }
        if (!is_null($cancelled)) {
            $data_attributes['cancelled'] = $cancelled ? 'true' : 'false';
        }
        foreach ($data_attributes as $key => $value) {
            $data_attributes_string .= 'data-' . esc_attr($key) . '="' . esc_attr($value) . '" ';
        }
        $event_listings_output = apply_filters('event_manager_event_listings_output', ob_get_clean());
        return '<div class="event_listings" ' . $data_attributes_string . '>' . $event_listings_output . '</div>';
    }