/**
  * Processes the btb_checkout_overview shortcode.
  *
  * Based on the set style it calls a sub function to render the output.
  *
  * @param array $atts The shortcode attributes. See class description for explanation.
  */
 public static function btb_checkout_overview_func($atts)
 {
     if (isset($_GET['booking']) && isset($_GET['btbnonce']) && !isset($_POST['btb_checkout_nonce'])) {
         if (!wp_verify_nonce($_GET['btbnonce'], 'btb_direct_booking_nonce')) {
             return;
         }
         $master_instance = get_option('btb_instance_type', 'master') == 'master';
         if ($master_instance) {
             $booking = btb_get_booking($_GET['booking'], OBJECT, 'display');
         } else {
             $booking = btb_get_booking_from_api($_GET['booking'], OBJECT, 'display');
         }
         if (!$booking) {
             return;
         }
         if ($booking->post_type !== "btb_booking") {
             return;
         }
         if ($master_instance) {
             $time = btb_get_time($booking->booked_time, OBJECT, 'display');
         } else {
             $time = btb_get_time_from_api($booking->booked_time, OBJECT, 'display');
         }
         if (!$time) {
             return;
         }
         if ($time->post_type !== "btb_time") {
             return;
         }
         if ($master_instance) {
             $event = btb_get_event($time->event, OBJECT, 'display');
         } else {
             $event = btb_get_event_from_api($time->event, OBJECT, 'display');
         }
         if (!$event) {
             return;
         }
         if ($event->post_type !== "btb_event") {
             return;
         }
         $a = shortcode_atts(array('headline' => ''), $atts);
         switch (get_option('btb_style', 'custom')) {
             case 'avada':
                 return self::btb_checkout_overview_avada($a, $booking, $time, $event);
             case 'bootstrap3':
                 return self::btb_checkout_overview_bs3($a, $booking, $time, $event);
             default:
                 return self::btb_checkout_overview_default($a, $booking, $time, $event);
         }
     }
 }
 /**
  * Sends e-mails to customer and wordpress owner.
  *
  * @param BTB_Booking &$booking The booking object to send mails for.
  * @return int 1 if successfull, 0 if mail to owner failed, -1 if mail to customer failed, -2 if both mails failed
  */
 private static function send_mails(&$booking)
 {
     $notifyemail = get_option('btb_notify_to', '');
     // email address of the site owne to notify about new bookings
     $fromemail = get_option('btb_confirm_from', '');
     // email address used as from address when sending booking to customer
     if (empty($notifyemail) && empty($fromemail)) {
         return -2;
     }
     $tags = array('{{salutation}}', '{{title}}', '{{first_name}}', '{{last_name}}', '{{company}}', '{{address}}', '{{address2}}', '{{zip}}', '{{city}}', '{{country}}', '{{mail}}', '{{phone}}', '{{notes}}', '{{event_name}}', '{{event_url}}', '{{event_start_date}}', '{{event_end_date}}', '{{event_start_time}}', '{{event_end_time}}', '{{slots}}', '{{single_price}}', '{{total_price}}', '{{booking_code}}', '{{booking_time}}');
     if (get_option('btb_instance_type', 'master') == 'master') {
         $event = btb_get_event($booking->booked_event);
         $time = btb_get_time($booking->booked_time);
     } else {
         $event = btb_get_event_from_api($booking->booked_event, OBJECT, 'display');
         $time = btb_get_time_from_api($booking->booked_time, OBJECT, 'display');
     }
     date_default_timezone_set(get_option('timezone_string', 'UTC'));
     $replacements = array($booking->title == "mr" ? sprintf(__('Dear Mr. %s %s', 'bt-booking'), $booking->first_name, $booking->last_name) : sprintf(__('Dear Mrs. %s %s', 'bt-booking'), $booking->first_name, $booking->last_name), $booking->title == "mr" ? __('Mr.', 'bt-booking', 'bt-booking') : __('Mrs.', 'bt-booking'), $booking->first_name, $booking->last_name, $booking->company ? $booking->company : '', $booking->address, $booking->address2, $booking->zip, $booking->city, BTBookingCountries::get_country_by_code($booking->country), $booking->email, $booking->phone, $booking->notes, $event->name, btb_get_description_page($event, true), date_i18n(_x('m/d/Y', 'Event date shown in e-mails', 'bt-booking'), $time->start), date_i18n(_x('m/d/Y', 'Event date shown in e-mails', 'bt-booking'), $time->end), $time->date_only ? '' : date_i18n(_x('h:iA', 'Event time shown in e-mails', 'bt-booking'), $time->start), $time->date_only ? '' : date_i18n(_x('h:iA', 'Event time shown in e-mails', 'bt-booking'), $time->end), $booking->booked_slots, get_option('btb_currency', '€') . ' ' . number_format_i18n($booking->price, 2), get_option('btb_currency', '€') . ' ' . number_format_i18n($booking->price * $booking->booked_slots, 2), $booking->code, date_i18n(_x('m/d/Y h:iA', 'Booking time shown in e-mails', 'bt-booking'), $booking->booking_time));
     $ret = 1;
     if (!empty($notifyemail) && !empty($fromemail)) {
         if (!self::send_mail_to_owner($tags, $replacements, $notifyemail, $fromemail, $booking)) {
             $ret = 0;
         }
     } else {
         $ret = 0;
     }
     if (!empty($fromemail)) {
         if (!self::send_mail_to_customer($tags, $replacements, $booking, $fromemail)) {
             $ret = $ret - 2;
         }
     } else {
         $ret = $ret - 2;
     }
     return $ret;
 }
/**
 * @brief Retrieve list of times from a master instance, either all or for specific event.
 *
 * @param int $event			BTB_Event ID.
 * @param string $filter		Optional. Type of filter to apply. Accepts 'raw', 'edit', 'db', 'display',
 *								'attribute' or 'js'. Default 'display'.
 * @param bool $upcoming_only	If true, only upcoming event times will be returned.
 * @return array of BTB_Event objects.
 */
function btb_get_times_from_api($event = 0, $filter = 'display', $upcoming_only = false)
{
    $r_url = get_option('btb_master_url', '');
    if (empty($r_url)) {
        return false;
    }
    $r_url .= '/wp-json/wp/v2/btb-times-api';
    $query = array('filter' => array());
    $query['filter']['orderby'] = 'meta_value_num';
    $query['filter']['meta_key'] = 'btb_start';
    $query['filter']['order'] = 'ASC';
    if ($event) {
        $query['filter']['post_parent'] = $event;
    }
    // seems not to work currently
    // 	if ($upcoming_only) {
    // 		$query['filter']['meta_query'] = array(
    // 											array(
    // 												'key' => 'btb_start',
    // 												'value' => strval(time()),
    // 												'compare' => urlencode('>')
    // 											)
    // 										);
    // 	}
    if (!empty($query)) {
        $r_url .= '?';
        $r_url .= http_build_query($query);
    }
    $r_times = wp_remote_get($r_url);
    $times = json_decode($r_times['body']);
    if (empty($times)) {
        return array();
    }
    $santimes = array();
    foreach ($times as $time) {
        $t = new BTB_Time();
        $t->from_api_response($time, $event);
        $_t = btb_get_time($t, OBJECT, $filter);
        if ($upcoming_only) {
            if ($_t->start > time()) {
                $santimes[] = $_t;
            }
        } else {
            $santimes[] = $_t;
        }
    }
    // WP REST API seems not to sort the result as it should,
    // so we sort it manually.
    usort($santimes, "btb_sort_times_by_start");
    return $santimes;
}