/** * 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; }
/** * 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(']]>', ']]>', $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; }