/**
  * Creates the schema.org event meta data ouput.
  *
  * This is hooked to the btb_create_event_schema_org filter.
  *
  * @param string	$input The input string to which the output is appended.
  * @param BTB_Event	$event The event for which the meta data should be generated.
  * @param array		$times Array of BTB_Time objects for the event.
  * @param BTB_Venue	$venue The venue the event will happen.
  * @return string
  */
 public static function event_schema_org_filter($input, BTB_Event $event, array $times, $venue)
 {
     $out = $input;
     $description = btb_get_event_description($event, true);
     $eventurl = btb_get_description_page($event, true);
     $info_page = (int) get_option('btb_struct_data_orga_info_page', '');
     if ($info_page) {
         $organizer = array('@type' => 'Organization', 'url' => get_permalink($info_page));
     }
     $event_images = btb_get_event_images($event);
     $eligible_regions = get_option('btb_struct_data_eligible_regions', array());
     if ($event->struct_data_type == 'event' && $venue && $times) {
         $eventLocation = array('@type' => 'Place');
         $eventLocation["name"] = $venue->name;
         if ($venue->use_map_coords) {
             $geo = array('@type' => 'GeoCoordinates');
             $geo["latitude"] = $venue->latitude;
             $geo["longitude"] = $venue->longitude;
             $eventLocation["geo"] = $geo;
         }
         $elAddress = array('@type' => 'PostalAddress');
         if (!empty($venue->streetAndNumber())) {
             $elAddress["streetAddress"] = $venue->streetAndNumber();
         }
         if (!empty($venue->postal_code)) {
             $elAddress["postalCode"] = $venue->postal_code;
         }
         if (!empty($venue->region)) {
             $elAddress["addressRegion"] = $venue->region;
         }
         if (!empty($venue->city)) {
             $elAddress["addressLocality"] = $venue->city;
         }
         if (!empty($venue->country)) {
             $elAddress["addressCountry"] = $venue->country;
         }
         if (count($elAddress) > 1) {
             $eventLocation["address"] = $elAddress;
         }
         foreach ($times as $key => $time) {
             $out .= "\n<script type='application/ld+json'>\n";
             $schema = array('@context' => 'http://schema.org', '@type' => $event->event_type);
             $schema["name"] = $event->name;
             if (!empty($organizer)) {
                 $schema["organizer"] = $organizer;
             }
             $schema["startDate"] = $time->date_only ? date('Y-m-d', $time->start) : date('c', $time->start);
             if ($time->end > $time->start) {
                 $schemaEvent["endDate"] = $time->date_only ? date('Y-m-d', $time->end) : date('c', $time->end);
             }
             if ($description) {
                 $schema['description'] = $description;
             }
             $schema["url"] = $eventurl;
             if (!empty($event_images)) {
                 $full_img = $event_images['full'];
                 $event_image = array('@type' => 'ImageObject');
                 $event_image['contentUrl'] = esc_url($full_img[0]);
                 $event_image['width'] = array('@type' => 'QuantitativeValue', 'value' => $full_img[1], 'unitText' => 'px');
                 $event_image['height'] = array('@type' => 'QuantitativeValue', 'value' => $full_img[2], 'unitText' => 'px');
                 $thumb_img = $event_images['thumbnail'];
                 $event_thumbnail = array('@type' => 'ImageObject');
                 $event_thumbnail['contentUrl'] = esc_url($thumb_img[0]);
                 $event_thumbnail['width'] = array('@type' => 'QuantitativeValue', 'value' => $thumb_img[1], 'unitText' => 'px');
                 $event_thumbnail['height'] = array('@type' => 'QuantitativeValue', 'value' => $thumb_img[2], 'unitText' => 'px');
                 $event_image['thumbnail'] = $event_thumbnail;
                 $schema['image'] = $event_image;
             }
             $eventOffer = array('@type' => 'Offer');
             $eventOffer["price"] = number_format($time->price ? $time->price : $event->price, 2, '.', '');
             $eventOffer["priceCurrency"] = get_option('btb_currency_code', 'EUR');
             $eventOffer["url"] = get_permalink();
             $eventOffer["inventoryLevel"] = $time->free_slots;
             $eventOffer["availability"] = $time->free_slots ? "http://schema.org/InStock" : "http://schema.org/OutOfStock";
             if ($eligible_regions) {
                 if (is_array($eligible_regions) && !empty($eligible_regions)) {
                     $eventOffer['eligibleRegion'] = $eligible_regions;
                 }
             }
             $schema["offers"] = $eventOffer;
             $schema["location"] = $eventLocation;
             $out .= json_encode($schema);
             $out .= "\n</script>\n";
         }
     } elseif ($event->struct_data_type == 'product' || $event->struct_data_type == 'event' && !$venue || $event->struct_data_type == 'event' && !$times) {
         $out .= "\n<script type='application/ld+json'>\n";
         $schema = array('@context' => 'http://schema.org', '@type' => 'Product');
         $schema["name"] = $event->name;
         $schema["mainEntityOfPage"] = $eventurl;
         if ($description) {
             $schema['description'] = $description;
         }
         $schema["url"] = $eventurl;
         if (!empty($event_images)) {
             $full_img = $event_images['full'];
             $event_image = array('@type' => 'ImageObject');
             $event_image['contentUrl'] = esc_url($full_img[0]);
             $event_image['width'] = array('@type' => 'QuantitativeValue', 'value' => $full_img[1], 'unitText' => 'px');
             $event_image['height'] = array('@type' => 'QuantitativeValue', 'value' => $full_img[2], 'unitText' => 'px');
             $thumb_img = $event_images['thumbnail'];
             $event_thumbnail = array('@type' => 'ImageObject');
             $event_thumbnail['contentUrl'] = esc_url($thumb_img[0]);
             $event_thumbnail['width'] = array('@type' => 'QuantitativeValue', 'value' => $thumb_img[1], 'unitText' => 'px');
             $event_thumbnail['height'] = array('@type' => 'QuantitativeValue', 'value' => $thumb_img[2], 'unitText' => 'px');
             $event_image['thumbnail'] = $event_thumbnail;
             $schema['image'] = $event_image;
         }
         $priceHigh = 0;
         $priceLow = 0;
         if ($times) {
             // extract the prices for each time
             $prices = array();
             $free_slots = 0;
             foreach ($times as $key => $time) {
                 $prices[] = $time->price ? $time->price : $event->price;
                 $free_slots = $free_slots + $time->free_slots;
             }
             // sort the prices to determine highes and lowest price, if any
             sort($prices, SORT_NUMERIC);
             $priceHigh = end($prices);
             $priceLow = reset($prices);
         }
         // if there are different prices, use AggregateOffer otherwise Offer
         if ($priceHigh != $priceLow) {
             $offers = array('@type' => 'AggregateOffer');
             $offers['lowPrice'] = number_format($priceLow, 2, '.', '');
             $offers['highPrice'] = number_format($priceHigh, 2, '.', '');
         } else {
             $offers = array('@type' => 'Offer');
             $offers['price'] = $times ? number_format($priceLow, 2, '.', '') : number_format($event->price, 2, '.', '');
         }
         $offers['priceCurrency'] = get_option('btb_currency_code', 'EUR');
         $offers['url'] = get_permalink();
         if ($times) {
             $offers["inventoryLevel"] = $free_slots;
             $offers["availability"] = $free_slots ? "http://schema.org/InStock" : "http://schema.org/OutOfStock";
         }
         if (!empty($organizer)) {
             $offers["offeredBy"] = $organizer;
         }
         if ($eligible_regions) {
             if (is_array($eligible_regions) && !empty($eligible_regions)) {
                 $offers['eligibleRegion'] = $eligible_regions;
             }
         }
         $schema['offers'] = $offers;
         $out .= json_encode($schema);
         $out .= "\n</script>\n";
     }
     return $out;
 }
 /**
  * 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 Returns the full or short description of an event.
 *
 * Tries to find a description at first in the event itself, if that is empty and
 * the event has a description page, it searches for a description in the description
 * page.
 *
 * If @a $short_desc is true, the short description (excerpt) is returned. If you the
 * source for the meta description is set to something else than default in the plugin
 * settings, this source is used for the short description.
 *
 * @param BTB_Event $event The event to request the description for.
 * @param bool $short_desc If true, the short description (excerpt) will be returned.
 *
 * @return string The description or an empty string.
 */
function btb_get_event_description(BTB_Event &$event, $short_desc = false)
{
    if ($short_desc) {
        $descsrc = get_option('btb_struct_data_src_desc', 'default');
        if ($descsrc == 'default') {
            if (!empty($event->short_desc)) {
                return $event->short_desc;
            } else {
                $desc_page = btb_get_description_page($event);
                if ($desc_page != $event->ID) {
                    $dp = get_post($desc_page);
                    return $dp->post_excerpt;
                } else {
                    return '';
                }
            }
        } elseif ($descsrc == 'yoastseo') {
            $desc = get_post_meta($event->ID, '_yoast_wpseo_metadesc', true);
            if ($desc) {
                return $desc;
            } else {
                $desc_page = btb_get_description_page($event);
                if ($desc_page) {
                    $desc = get_post_meta($desc_page, '_yoast_wpseo_metadesc', true);
                    if ($desc) {
                        return $desc;
                    } else {
                        return '';
                    }
                } else {
                    return '';
                }
            }
        }
    } else {
        if (!empty($event->description)) {
            return $event->description;
        } else {
            $desc_page = btb_get_description_page($event);
            if ($desc_page != $event->ID) {
                $dp = get_post($desc_page);
                return $dp->post_content;
            } else {
                return '';
            }
        }
    }
}