/**
  * Sync Booking with Google Calendar
  *
  * @param  int $booking_id Booking ID
  *
  * @return void
  */
 public function sync_booking($booking_id)
 {
     $event_id = get_post_meta($booking_id, '_wc_bookings_gcalendar_event_id', true);
     $booking = get_wc_booking($booking_id);
     $api_url = $this->calendars_uri . $this->calendar_id . '/events';
     $access_token = $this->get_access_token();
     $timezone = wc_booking_get_timezone_string();
     $product = $booking->get_product();
     $summary = '#' . $booking->id . ' - ' . $product->get_title();
     $description = '';
     // Add resources in description
     if ($resource = $booking->get_resource()) {
         $description .= __('Resource #', 'woocommerce-bookings') . $resource->ID . ' - ' . $resource->post_title;
     }
     // Add persons in description
     if ($booking->has_persons()) {
         $description .= '' != $description ? PHP_EOL . PHP_EOL : '';
         foreach ($booking->get_persons() as $id => $qty) {
             if (0 === $qty) {
                 continue;
             }
             $person_type = 0 < $id ? get_the_title($id) : __('Person(s)', 'woocommerce-bookings');
             $description .= sprintf(__('%s: %d', 'woocommerce-bookings'), $person_type, $qty) . PHP_EOL;
         }
     }
     // Set the event data
     $data = array('summary' => $summary, 'description' => $description);
     // Set the event start and end dates
     if ($booking->is_all_day()) {
         $data['start'] = array('date' => date('Y-m-d', $booking->start));
         $data['end'] = array('date' => date('Y-m-d', $booking->end));
     } else {
         $data['start'] = array('dateTime' => date('Y-m-d\\TH:i:s', $booking->start), 'timeZone' => $timezone);
         $data['end'] = array('dateTime' => date('Y-m-d\\TH:i:s', $booking->end), 'timeZone' => $timezone);
     }
     $data = apply_filters('woocommerce_bookings_gcalendar_sync', $data, $booking);
     // Connection params
     $params = array('method' => 'POST', 'body' => json_encode($data), 'sslverify' => false, 'timeout' => 60, 'headers' => array('Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $access_token));
     // Update event
     if ($event_id) {
         $api_url .= '/' . $event_id;
         $params['method'] = 'PUT';
     }
     if ('yes' == $this->debug) {
         $this->log->add($this->id, 'Synchronizing booking #' . $booking->id . ' with Google Calendar...');
     }
     $response = wp_remote_post($api_url, $params);
     if (!is_wp_error($response) && 200 == $response['response']['code'] && 'OK' == $response['response']['message']) {
         if ('yes' == $this->debug) {
             $this->log->add($this->id, 'Booking synchronized successfully!');
         }
         // Updated the Google Calendar event ID
         $response_data = json_decode($response['body'], true);
         update_post_meta($booking->id, '_wc_bookings_gcalendar_event_id', $response_data['id']);
     } else {
         if ('yes' == $this->debug) {
             $this->log->add($this->id, 'Error while synchronizing the booking #' . $booking->id . ': ' . print_r($response, true));
         }
     }
 }
 /**
  * Sync Booking with Google Calendar
  *
  * @param  int $booking_id Booking ID
  *
  * @return void
  */
 public function sync_booking($booking_id)
 {
     $event_id = get_post_meta($booking_id, '_wc_bookings_gcalendar_event_id', true);
     $booking = get_wc_booking($booking_id);
     $order = $booking->get_order();
     $api_url = $this->calendars_uri . $this->calendar_id . '/events';
     $access_token = $this->get_access_token();
     $timezone = wc_booking_get_timezone_string();
     // Need a order.
     if (!$order) {
         return;
     }
     $summary = '#' . $booking->id;
     $description = '';
     $order_items = $order->get_items();
     // Need order items.
     if (!$order_items) {
         return;
     }
     foreach ($order->get_items() as $item_id => $item) {
         if ('line_item' != $item['type']) {
             continue;
         }
         $summary .= ' - ' . $item['name'];
         if ($metadata = $order->has_meta($item_id)) {
             foreach ($metadata as $meta) {
                 // Skip hidden core fields
                 if (in_array($meta['meta_key'], apply_filters('woocommerce_hidden_order_itemmeta', array('_qty', '_tax_class', '_product_id', '_variation_id', '_line_subtotal', '_line_subtotal_tax', '_line_total', '_line_tax')))) {
                     continue;
                 }
                 // Booking fields.
                 if (in_array($meta['meta_key'], array(__('Booking Date', 'woocommerce-bookings'), __('Booking Time', 'woocommerce-bookings')))) {
                     continue;
                 }
                 $meta_value = $meta['meta_value'];
                 // Skip serialised meta
                 if (is_serialized($meta_value)) {
                     continue;
                 }
                 // Get attribute data
                 if (taxonomy_exists($meta['meta_key'])) {
                     $term = get_term_by('slug', $meta['meta_value'], $meta['meta_key']);
                     $attribute_name = str_replace('pa_', '', wc_clean($meta['meta_key']));
                     $attribute = $wpdb->get_var($wpdb->prepare("\n\t\t\t\t\t\t\t\t\tSELECT attribute_label\n\t\t\t\t\t\t\t\t\tFROM {$wpdb->prefix}woocommerce_attribute_taxonomies\n\t\t\t\t\t\t\t\t\tWHERE attribute_name = %s;\n\t\t\t\t\t\t\t\t", $attribute_name));
                     $meta['meta_key'] = !is_wp_error($attribute) && $attribute ? $attribute : $attribute_name;
                     $meta['meta_value'] = isset($term->name) ? $term->name : $meta['meta_value'];
                 }
                 $description .= sprintf(__('%s: %s', 'woocommerce-bookings'), rawurldecode($meta['meta_key']), rawurldecode($meta_value)) . PHP_EOL;
             }
         }
     }
     // Set the event data
     $data = array('summary' => wp_kses_post($summary), 'description' => wp_kses_post(utf8_encode($description)));
     // Set the event start and end dates
     if ($booking->is_all_day()) {
         $data['end'] = array('date' => date('Y-m-d', $booking->end));
         $data['start'] = array('date' => date('Y-m-d', $booking->start));
     } else {
         $data['end'] = array('dateTime' => date('Y-m-d\\TH:i:s', $booking->end), 'timeZone' => $timezone);
         $data['start'] = array('dateTime' => date('Y-m-d\\TH:i:s', $booking->start), 'timeZone' => $timezone);
     }
     $data = apply_filters('woocommerce_bookings_gcalendar_sync', $data, $booking);
     // Connection params
     $params = array('method' => 'POST', 'body' => json_encode($data), 'sslverify' => false, 'timeout' => 60, 'headers' => array('Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $access_token));
     // Update event
     if ($event_id) {
         $api_url .= '/' . $event_id;
         $params['method'] = 'PUT';
     }
     if ('yes' == $this->debug) {
         $this->log->add($this->id, 'Synchronizing booking #' . $booking->id . ' with Google Calendar...');
     }
     $response = wp_remote_post($api_url, $params);
     if (!is_wp_error($response) && 200 == $response['response']['code'] && 'OK' == $response['response']['message']) {
         if ('yes' == $this->debug) {
             $this->log->add($this->id, 'Booking synchronized successfully!');
         }
         // Updated the Google Calendar event ID
         $response_data = json_decode($response['body'], true);
         update_post_meta($booking->id, '_wc_bookings_gcalendar_event_id', $response_data['id']);
     } else {
         if ('yes' == $this->debug) {
             $this->log->add($this->id, 'Error while synchronizing the booking #' . $booking->id . ': ' . print_r($response, true));
         }
     }
 }
 /**
  * Generate the .ics content
  *
  * @return string
  */
 protected function generate()
 {
     $sitename = get_option('blogname');
     // Set the ics data.
     $ics = 'BEGIN:VCALENDAR' . $this->eol;
     $ics .= 'VERSION:2.0' . $this->eol;
     $ics .= 'PRODID:-//WooThemes//WooCommerce Bookings ' . WC_BOOKINGS_VERSION . '//EN' . $this->eol;
     $ics .= 'CALSCALE:GREGORIAN' . $this->eol;
     $ics .= 'X-WR-CALNAME:' . $this->sanitize_string($sitename) . $this->eol;
     $ics .= 'X-ORIGINAL-URL:' . $this->sanitize_string(home_url('/')) . $this->eol;
     $ics .= 'X-WR-CALDESC:' . $this->sanitize_string(sprintf(__('Bookings from %s', 'woocommerce-bookings'), $sitename)) . $this->eol;
     $ics .= 'X-WR-TIMEZONE:' . wc_booking_get_timezone_string() . $this->eol;
     foreach ($this->bookings as $booking) {
         $product = $booking->get_product();
         $all_day = $booking->is_all_day();
         $url = $booking->get_order() ? $booking->get_order()->get_view_order_url() : '';
         $summary = '#' . $booking->id . ' - ' . $product->get_title();
         $description = '';
         if ($resource = $booking->get_resource()) {
             $description .= __('Resource #', 'woocommerce-bookings') . $resource->ID . ' - ' . $resource->post_title . '\\n\\n';
         }
         if ($booking->has_persons()) {
             foreach ($booking->get_persons() as $id => $qty) {
                 if (0 === $qty) {
                     continue;
                 }
                 $person_type = 0 < $id ? get_the_title($id) : __('Person(s)', 'woocommerce-bookings');
                 $description .= sprintf(__('%s: %d', 'woocommerce-bookings'), $person_type, $qty) . '\\n';
             }
             $description .= '\\n';
         }
         if ('' != $product->post->post_excerpt) {
             $description .= __('Booking description:', 'woocommerce-bookings') . '\\n';
             $description .= wp_kses($product->post->post_excerpt, array());
         }
         $ics .= 'BEGIN:VEVENT' . $this->eol;
         $ics .= 'DTEND:' . $this->format_date($booking->end, $all_day) . $this->eol;
         $ics .= 'UID:' . $this->uid_prefix . $booking->id . $this->eol;
         $ics .= 'DTSTAMP:' . $this->format_date(time()) . $this->eol;
         $ics .= 'LOCATION:' . $this->eol;
         $ics .= 'DESCRIPTION:' . $this->sanitize_string($description) . $this->eol;
         $ics .= 'URL;VALUE=URI:' . $this->sanitize_string($url) . $this->eol;
         $ics .= 'SUMMARY:' . $this->sanitize_string($summary) . $this->eol;
         $ics .= 'DTSTART:' . $this->format_date($booking->start, $all_day) . $this->eol;
         $ics .= 'END:VEVENT' . $this->eol;
     }
     $ics .= 'END:VCALENDAR';
     return $ics;
 }