/** * 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; }
/** * @brief Retrieves venue data given an venue ID or venue object. * * @see btb_sanitize_venue() for optional $filter values. Also, the parameter $venue * must be given as a variable, since it is passed by reference. * * @param int|BTB_Venue $venue Venue ID or BTB_Venue object. * @param string $output Optional, default is Object. Accepts OBJECT, ARRAY_A or ARRAY_N. * @param string $filter Optional. Type fo filter to apply. Accepts 'raw', 'edit', 'db', 'display', * 'attribute' or 'js'. Default 'raw'. * @return BTB_Venue|array|null Type corresponding to $output on success or null on failure. * When $output is OBJECT, a `BTB_Venue` instance is returned. */ function btb_get_venue($venue, $output = OBJECT, $filter = 'raw') { if ($venue instanceof BTB_Venue) { $_venue = $venue; } elseif (is_object($venue)) { if (empty($venue->filter)) { $_venue = btb_sanitize_venue($venue, 'raw'); $_venue = new BTB_Venue($_venue); } elseif ('raw' == $venue->filter) { $_venue = new BTB_Venue($venue); } else { $_venue = BTB_Venue::get_instance($venue->ID); } } else { $_venue = BTB_Venue::get_instance($venue); } if (!$_venue) { return null; } $_venue = $_venue->filter($filter); if ($output == ARRAY_A) { return $_venue->to_array(); } elseif ($output == ARRAY_N) { return array_values($_venue->to_array()); } return $_venue; }