Example #1
0
 /**
  * Convert an event from a feed into a new Ai1ec_Event object and add it to
  * the calendar.
  *
  * @param Ai1ec_Event $event    Event object.
  * @param vcalendar   $calendar Calendar object.
  * @param bool        $export   States whether events are created for export.
  * @param array       $params   Additional parameters for export.
  *
  * @return void
  */
 protected function _insert_event_in_calendar(Ai1ec_Event $event, vcalendar $calendar, $export = false, array $params = array())
 {
     $tz = $this->_registry->get('date.timezone')->get_default_timezone();
     $e =& $calendar->newComponent('vevent');
     $uid = '';
     if ($event->get('ical_uid')) {
         $uid = addcslashes($event->get('ical_uid'), "\\;,\n");
     } else {
         $uid = $event->get_uid();
         $event->set('ical_uid', $uid);
         $event->save(true);
     }
     $e->setProperty('uid', $this->_sanitize_value($uid));
     $e->setProperty('url', get_permalink($event->get('post_id')));
     // =========================
     // = Summary & description =
     // =========================
     $e->setProperty('summary', $this->_sanitize_value(html_entity_decode(apply_filters('the_title', $event->get('post')->post_title), ENT_QUOTES, 'UTF-8')));
     $content = apply_filters('the_content', $event->get('post')->post_content);
     $content = str_replace(']]>', ']]>', $content);
     $content = html_entity_decode($content, ENT_QUOTES, 'UTF-8');
     // Prepend featured image if available.
     $size = null;
     $avatar = $this->_registry->get('view.event.avatar');
     if ($img_url = $avatar->get_post_thumbnail_url($event, $size)) {
         $content = '<div class="ai1ec-event-avatar alignleft timely"><img src="' . esc_attr($img_url) . '" width="' . $size[0] . '" height="' . $size[1] . '" /></div>' . $content;
     }
     if (isset($params['no_html']) && $params['no_html']) {
         $e->setProperty('description', $this->_sanitize_value(strip_tags(strip_shortcodes($content))));
         if (!empty($content)) {
             $html_content = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">\\n' . '<HTML>\\n<HEAD>\\n<TITLE></TITLE>\\n</HEAD>\\n<BODY>' . $content . '</BODY></HTML>';
             $e->setProperty('X-ALT-DESC', $this->_sanitize_value($html_content), array('FMTTYPE' => 'text/html'));
             unset($html_content);
         }
     } else {
         $e->setProperty('description', $this->_sanitize_value($content));
     }
     $revision = (int) current(array_keys(wp_get_post_revisions($event->get('post_id'))));
     $e->setProperty('sequence', $revision);
     // =====================
     // = Start & end times =
     // =====================
     $dtstartstring = '';
     $dtstart = $dtend = array();
     if ($event->is_allday()) {
         $dtstart['VALUE'] = $dtend['VALUE'] = 'DATE';
         // For exporting all day events, don't set a timezone
         if ($tz && !$export) {
             $dtstart['TZID'] = $dtend['TZID'] = $tz;
         }
         // For exportin' all day events, only set the date not the time
         if ($export) {
             $e->setProperty('dtstart', $this->_sanitize_value($event->get('start')->format('Ymd')), $dtstart);
             $e->setProperty('dtend', $this->_sanitize_value($event->get('end')->format('Ymd')), $dtend);
         } else {
             $e->setProperty('dtstart', $this->_sanitize_value($event->get('start')->format("Ymd\\T")), $dtstart);
             $e->setProperty('dtend', $this->_sanitize_value($event->get('end')->format("Ymd\\T")), $dtend);
         }
     } else {
         if ($tz) {
             $dtstart['TZID'] = $dtend['TZID'] = $tz;
         }
         // This is used later.
         $dtstartstring = $event->get('start')->format("Ymd\\THis");
         $e->setProperty('dtstart', $this->_sanitize_value($dtstartstring), $dtstart);
         $e->setProperty('dtend', $this->_sanitize_value($event->get('end')->format("Ymd\\THis")), $dtend);
     }
     // ========================
     // = Latitude & longitude =
     // ========================
     if (floatval($event->get('latitude')) || floatval($event->get('longitude'))) {
         $e->setProperty('geo', $event->get('latitude'), $event->get('longitude'));
     }
     // ===================
     // = Venue & address =
     // ===================
     if ($event->get('venue') || $event->get('address')) {
         $location = array($event->get('venue'), $event->get('address'));
         $location = array_filter($location);
         $location = implode(' @ ', $location);
         $e->setProperty('location', $this->_sanitize_value($location));
     }
     $categories = array();
     $language = get_bloginfo('language');
     foreach ($this->_taxonomy_model->get_post_categories($event->get('post_id')) as $cat) {
         $categories[] = $cat->name;
     }
     $e->setProperty('categories', implode(',', $categories), array("LANGUAGE" => $language));
     $tags = array();
     foreach ($this->_taxonomy_model->get_post_tags($event->get('post_id')) as $tag) {
         $tags[] = $tag->name;
     }
     if (!empty($tags)) {
         $e->setProperty('X-TAGS', implode(',', $tags), array("LANGUAGE" => $language));
     }
     // ==================
     // = Cost & tickets =
     // ==================
     if ($event->get('cost')) {
         $e->setProperty('X-COST', $this->_sanitize_value($event->get('cost')));
     }
     if ($event->get('ticket_url')) {
         $e->setProperty('X-TICKETS-URL', $this->_sanitize_value($event->get_nonloggable_url($event->get('ticket_url'))));
     }
     // ====================================
     // = Contact name, phone, e-mail, URL =
     // ====================================
     $contact = array($event->get('contact_name'), $event->get('contact_phone'), $event->get('contact_email'), $event->get_nonloggable_url($event->get('contact_url')));
     $contact = array_filter($contact);
     $contact = implode('; ', $contact);
     $e->setProperty('contact', $this->_sanitize_value($contact));
     // ====================
     // = Recurrence rules =
     // ====================
     $rrule = array();
     $recurrence = $event->get('recurrence_rules');
     if (!empty($recurrence)) {
         $rules = array();
         foreach (explode(';', $event->get('recurrence_rules')) as $v) {
             if (strpos($v, '=') === false) {
                 continue;
             }
             list($k, $v) = explode('=', $v);
             $k = strtoupper($k);
             // If $v is a comma-separated list, turn it into array for iCalcreator
             switch ($k) {
                 case 'BYSECOND':
                 case 'BYMINUTE':
                 case 'BYHOUR':
                 case 'BYDAY':
                 case 'BYMONTHDAY':
                 case 'BYYEARDAY':
                 case 'BYWEEKNO':
                 case 'BYMONTH':
                 case 'BYSETPOS':
                     $exploded = explode(',', $v);
                     break;
                 default:
                     $exploded = $v;
                     break;
             }
             // iCalcreator requires a more complex array structure for BYDAY...
             if ($k == 'BYDAY') {
                 $v = array();
                 foreach ($exploded as $day) {
                     $v[] = array('DAY' => $day);
                 }
             } else {
                 $v = $exploded;
             }
             $rrule[$k] = $v;
         }
     }
     // ===================
     // = Exception rules =
     // ===================
     $exceptions = $event->get('exception_rules');
     $exrule = array();
     if (!empty($exceptions)) {
         $rules = array();
         foreach (explode(';', $exceptions) as $v) {
             if (strpos($v, '=') === false) {
                 continue;
             }
             list($k, $v) = explode('=', $v);
             $k = strtoupper($k);
             // If $v is a comma-separated list, turn it into array for iCalcreator
             switch ($k) {
                 case 'BYSECOND':
                 case 'BYMINUTE':
                 case 'BYHOUR':
                 case 'BYDAY':
                 case 'BYMONTHDAY':
                 case 'BYYEARDAY':
                 case 'BYWEEKNO':
                 case 'BYMONTH':
                 case 'BYSETPOS':
                     $exploded = explode(',', $v);
                     break;
                 default:
                     $exploded = $v;
                     break;
             }
             // iCalcreator requires a more complex array structure for BYDAY...
             if ($k == 'BYDAY') {
                 $v = array();
                 foreach ($exploded as $day) {
                     $v[] = array('DAY' => $day);
                 }
             } else {
                 $v = $exploded;
             }
             $exrule[$k] = $v;
         }
     }
     // add rrule to exported calendar
     if (!empty($rrule)) {
         $e->setProperty('rrule', $this->_sanitize_value($rrule));
     }
     // add exrule to exported calendar
     if (!empty($exrule)) {
         $e->setProperty('exrule', $this->_sanitize_value($exrule));
     }
     // ===================
     // = Exception dates =
     // ===================
     // For all day events that use a date as DTSTART, date must be supplied
     // For other other events which use DATETIME, we must use that as well
     // We must also match the exact starting time
     $exception_dates = $event->get('exception_dates');
     if (!empty($exception_dates)) {
         $params = array('VALUE' => 'DATE-TIME', 'TZID' => $tz);
         $dt_suffix = $event->get('start')->format('\\THis');
         foreach (explode(',', $exception_dates) as $exdate) {
             $exdate = $this->_registry->get('date.time', $exdate)->format('Ymd');
             $e->setProperty('exdate', array($exdate . $dt_suffix), $params);
         }
     }
     return $calendar;
 }
Example #2
0
 /**
  * Convert an event from a feed into a new Ai1ec_Event object and add it to
  * the calendar.
  *
  * @param Ai1ec_Event $event    Event object.
  * @param vcalendar   $calendar Calendar object.
  * @param bool        $export   States whether events are created for export.
  * @param array       $params   Additional parameters for export.
  *
  * @return void
  */
 protected function _insert_event_in_calendar(Ai1ec_Event $event, vcalendar $calendar, $export = false, array $params = array())
 {
     $tz = $this->_registry->get('date.timezone')->get_default_timezone();
     $e =& $calendar->newComponent('vevent');
     $uid = '';
     if ($event->get('ical_uid')) {
         $uid = addcslashes($event->get('ical_uid'), "\\;,\n");
     } else {
         $uid = $event->get_uid();
         $event->set('ical_uid', $uid);
         $event->save(true);
     }
     $e->setProperty('uid', $this->_sanitize_value($uid));
     $e->setProperty('url', get_permalink($event->get('post_id')));
     // =========================
     // = Summary & description =
     // =========================
     $e->setProperty('summary', $this->_sanitize_value(html_entity_decode(apply_filters('the_title', $event->get('post')->post_title), ENT_QUOTES, 'UTF-8')));
     $content = apply_filters('ai1ec_the_content', apply_filters('the_content', $event->get('post')->post_content));
     $post_meta_values = get_post_meta($event->get('post_id'), '', false);
     $cost_type = null;
     if ($post_meta_values) {
         foreach ($post_meta_values as $key => $value) {
             if ('_ai1ec_cost_type' === $key) {
                 $cost_type = $value[0];
             }
             if (isset($params['xml']) && $params['xml'] && false !== preg_match('/^x\\-meta\\-/i', $key)) {
                 $e->setProperty($key, $this->_sanitize_value($value));
             }
         }
     }
     if (false === ai1ec_is_blank($cost_type)) {
         $e->setProperty('X-COST-TYPE', $this->_sanitize_value($cost_type));
     }
     $url = '';
     $api = $this->_registry->get('model.api.api-ticketing');
     $api_event_id = $api->get_api_event_id($event->get('post_id'));
     if ($api_event_id) {
         //getting all necessary informations that will be necessary on imported ticket events
         $e->setProperty('X-API-EVENT-ID', $api_event_id);
         $e->setProperty('X-API-URL', $api->get_api_event_url($event->get('post_id')));
         $e->setProperty('X-CHECKOUT-URL', $api->get_api_event_checkout_url($event->get('post_id')));
         $e->setProperty('X-API-EVENT-CURRENCY', $api->get_api_event_currency($event->get('post_id')));
     } else {
         if ($event->get('ticket_url')) {
             $url = $event->get('ticket_url');
         }
     }
     //Adding Ticket URL to the Description field
     if (false === ai1ec_is_blank($url)) {
         $content = $this->_remove_ticket_url($content);
         $content = $content . '<p>' . __('Tickets: ', AI1EC_PLUGIN_NAME) . '<a class="ai1ec-ticket-url-exported" href="' . $url . '">' . $url . '</a>.</p>';
     }
     $content = str_replace(']]>', ']]&gt;', $content);
     $content = html_entity_decode($content, ENT_QUOTES, 'UTF-8');
     // Prepend featured image if available.
     $size = null;
     $avatar = $this->_registry->get('view.event.avatar');
     $matches = $avatar->get_image_from_content($content);
     // if no img is already present - add thumbnail
     if (empty($matches)) {
         $post_id = get_post_thumbnail_id($event->get('post_id'));
         $images = null;
         $added = null;
         foreach (array('thumbnail', 'medium', 'large', 'full') as $_size) {
             $attributes = wp_get_attachment_image_src($post_id, $_size);
             if (false !== $attributes) {
                 $key_str = sprintf('%d_%d', $attributes[1], $attributes[2]);
                 if (null === $added || false === isset($added[$key_str])) {
                     $added[$key_str] = true;
                     array_unshift($attributes, $_size);
                     $images[] = implode(';', $attributes);
                 }
             }
         }
         if (null !== $images) {
             $e->setProperty('X-WP-IMAGES-URL', $this->_sanitize_value(implode(',', $images)));
         }
         if ($img_url = $avatar->get_post_thumbnail_url($event, $size)) {
             $content = '<div class="ai1ec-event-avatar alignleft timely"><img src="' . esc_attr($img_url) . '" width="' . $size[0] . '" height="' . $size[1] . '" /></div>' . $content;
         }
     }
     if (isset($params['no_html']) && $params['no_html']) {
         $e->setProperty('description', $this->_sanitize_value(strip_tags(strip_shortcodes($content))));
         if (!empty($content)) {
             $html_content = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">\\n' . '<HTML>\\n<HEAD>\\n<TITLE></TITLE>\\n</HEAD>\\n<BODY>' . $content . '</BODY></HTML>';
             $e->setProperty('X-ALT-DESC', $this->_sanitize_value($html_content), array('FMTTYPE' => 'text/html'));
             unset($html_content);
         }
     } else {
         $e->setProperty('description', $this->_sanitize_value($content));
     }
     $revision = (int) current(array_keys(wp_get_post_revisions($event->get('post_id'))));
     $e->setProperty('sequence', $revision);
     // =====================
     // = Start & end times =
     // =====================
     $dtstartstring = '';
     $dtstart = $dtend = array();
     if ($event->is_allday()) {
         $dtstart['VALUE'] = $dtend['VALUE'] = 'DATE';
         // For exporting all day events, don't set a timezone
         if ($tz && !$export) {
             $dtstart['TZID'] = $dtend['TZID'] = $tz;
         }
         // For exportin' all day events, only set the date not the time
         if ($export) {
             $e->setProperty('dtstart', $this->_sanitize_value($event->get('start')->format('Ymd')), $dtstart);
             $e->setProperty('dtend', $this->_sanitize_value($event->get('end')->format('Ymd')), $dtend);
         } else {
             $e->setProperty('dtstart', $this->_sanitize_value($event->get('start')->format("Ymd\\T")), $dtstart);
             $e->setProperty('dtend', $this->_sanitize_value($event->get('end')->format("Ymd\\T")), $dtend);
         }
     } else {
         if ($tz) {
             $dtstart['TZID'] = $dtend['TZID'] = $tz;
         }
         // This is used later.
         $dtstartstring = $event->get('start')->format("Ymd\\THis");
         $e->setProperty('dtstart', $this->_sanitize_value($dtstartstring), $dtstart);
         if (false === (bool) $event->get('instant_event')) {
             $e->setProperty('dtend', $this->_sanitize_value($event->get('end')->format("Ymd\\THis")), $dtend);
         }
     }
     // ========================
     // = Latitude & longitude =
     // ========================
     if (floatval($event->get('latitude')) || floatval($event->get('longitude'))) {
         $e->setProperty('geo', $event->get('latitude'), $event->get('longitude'));
     }
     // ===================
     // = Venue & address =
     // ===================
     if ($event->get('venue') || $event->get('address')) {
         $location = array($event->get('venue'), $event->get('address'));
         $location = array_filter($location);
         $location = implode(' @ ', $location);
         $e->setProperty('location', $this->_sanitize_value($location));
     }
     $categories = array();
     $language = get_bloginfo('language');
     foreach ($this->_taxonomy_model->get_post_categories($event->get('post_id')) as $cat) {
         if ('events_categories' === $cat->taxonomy) {
             $categories[] = $cat->name;
         }
     }
     $e->setProperty('categories', implode(',', $categories), array("LANGUAGE" => $language));
     $tags = array();
     foreach ($this->_taxonomy_model->get_post_tags($event->get('post_id')) as $tag) {
         $tags[] = $tag->name;
     }
     if (!empty($tags)) {
         $e->setProperty('X-TAGS', implode(',', $tags), array("LANGUAGE" => $language));
     }
     // ==================
     // = Cost & tickets =
     // ==================
     if ($event->get('cost')) {
         $e->setProperty('X-COST', $this->_sanitize_value($event->get('cost')));
     }
     if ($event->get('ticket_url')) {
         $e->setProperty('X-TICKETS-URL', $this->_sanitize_value($event->get('ticket_url')));
     }
     // =================
     // = Instant Event =
     // =================
     if ($event->is_instant()) {
         $e->setProperty('X-INSTANT-EVENT', $this->_sanitize_value($event->is_instant()));
     }
     // ====================================
     // = Contact name, phone, e-mail, URL =
     // ====================================
     $contact = array($event->get('contact_name'), $event->get('contact_phone'), $event->get('contact_email'), $event->get('contact_url'));
     $contact = array_filter($contact);
     $contact = implode('; ', $contact);
     $e->setProperty('contact', $this->_sanitize_value($contact));
     // ====================
     // = Recurrence rules =
     // ====================
     $rrule = array();
     $recurrence = $event->get('recurrence_rules');
     $recurrence = $this->_filter_rule($recurrence);
     if (!empty($recurrence)) {
         $rules = array();
         foreach (explode(';', $recurrence) as $v) {
             if (strpos($v, '=') === false) {
                 continue;
             }
             list($k, $v) = explode('=', $v);
             $k = strtoupper($k);
             // If $v is a comma-separated list, turn it into array for iCalcreator
             switch ($k) {
                 case 'BYSECOND':
                 case 'BYMINUTE':
                 case 'BYHOUR':
                 case 'BYDAY':
                 case 'BYMONTHDAY':
                 case 'BYYEARDAY':
                 case 'BYWEEKNO':
                 case 'BYMONTH':
                 case 'BYSETPOS':
                     $exploded = explode(',', $v);
                     break;
                 default:
                     $exploded = $v;
                     break;
             }
             // iCalcreator requires a more complex array structure for BYDAY...
             if ($k == 'BYDAY') {
                 $v = array();
                 foreach ($exploded as $day) {
                     $v[] = array('DAY' => $day);
                 }
             } else {
                 $v = $exploded;
             }
             $rrule[$k] = $v;
         }
     }
     // ===================
     // = Exception rules =
     // ===================
     $exceptions = $event->get('exception_rules');
     $exceptions = $this->_filter_rule($exceptions);
     $exrule = array();
     if (!empty($exceptions)) {
         $rules = array();
         foreach (explode(';', $exceptions) as $v) {
             if (strpos($v, '=') === false) {
                 continue;
             }
             list($k, $v) = explode('=', $v);
             $k = strtoupper($k);
             // If $v is a comma-separated list, turn it into array for iCalcreator
             switch ($k) {
                 case 'BYSECOND':
                 case 'BYMINUTE':
                 case 'BYHOUR':
                 case 'BYDAY':
                 case 'BYMONTHDAY':
                 case 'BYYEARDAY':
                 case 'BYWEEKNO':
                 case 'BYMONTH':
                 case 'BYSETPOS':
                     $exploded = explode(',', $v);
                     break;
                 default:
                     $exploded = $v;
                     break;
             }
             // iCalcreator requires a more complex array structure for BYDAY...
             if ($k == 'BYDAY') {
                 $v = array();
                 foreach ($exploded as $day) {
                     $v[] = array('DAY' => $day);
                 }
             } else {
                 $v = $exploded;
             }
             $exrule[$k] = $v;
         }
     }
     // add rrule to exported calendar
     if (!empty($rrule) && !isset($rrule['RDATE'])) {
         $e->setProperty('rrule', $this->_sanitize_value($rrule));
     }
     // add exrule to exported calendar
     if (!empty($exrule) && !isset($exrule['EXDATE'])) {
         $e->setProperty('exrule', $this->_sanitize_value($exrule));
     }
     // ===================
     // = Exception dates =
     // ===================
     // For all day events that use a date as DTSTART, date must be supplied
     // For other other events which use DATETIME, we must use that as well
     // We must also match the exact starting time
     $recurrence_dates = $event->get('recurrence_dates');
     $recurrence_dates = $this->_filter_rule($recurrence_dates);
     if (!empty($recurrence_dates)) {
         $params = array('VALUE' => 'DATE-TIME', 'TZID' => $tz);
         $dt_suffix = $event->get('start')->format('\\THis');
         foreach (explode(',', $recurrence_dates) as $exdate) {
             // date-time string in EXDATES is formatted as 'Ymd\THis\Z', that
             // means - in UTC timezone, thus we use `format_to_gmt` here.
             $exdate = $this->_registry->get('date.time', $exdate)->format_to_gmt('Ymd');
             $e->setProperty('rdate', array($exdate . $dt_suffix), $params);
         }
     }
     $exception_dates = $event->get('exception_dates');
     $exception_dates = $this->_filter_rule($exception_dates);
     if (!empty($exception_dates)) {
         $params = array('VALUE' => 'DATE-TIME', 'TZID' => $tz);
         $dt_suffix = $event->get('start')->format('\\THis');
         foreach (explode(',', $exception_dates) as $exdate) {
             // date-time string in EXDATES is formatted as 'Ymd\THis\Z', that
             // means - in UTC timezone, thus we use `format_to_gmt` here.
             $exdate = $this->_registry->get('date.time', $exdate)->format_to_gmt('Ymd');
             $e->setProperty('exdate', array($exdate . $dt_suffix), $params);
         }
     }
     return $calendar;
 }