Example #1
0
 /**
  * Generates an excerpt from the given content string.
  *
  * Adapted from WordPress's `wp_trim_excerpt' function that is not useful
  * for applying to custom content.
  *
  * @param string $text The content to trim.
  *
  * @return string The excerpt.
  */
 public function trim_excerpt(Ai1ec_Event $event, $length = 35, $more = '[...]')
 {
     global $post;
     $original_post = $post;
     $post = $event->get('post');
     $raw_excerpt = $event->get('post')->post_content;
     if (!isset($raw_excerpt[0])) {
         $raw_excerpt = ' ';
     }
     $text = preg_replace('#<\\s*script[^>]*>.+<\\s*/\\s*script\\s*>#x', '', apply_filters('the_excerpt', $raw_excerpt));
     $text = strip_shortcodes($text);
     $text = str_replace(']]>', ']]&gt;', $text);
     $text = strip_tags($text);
     $excerpt_length = apply_filters('excerpt_length', $length);
     $excerpt_more = apply_filters('excerpt_more', $more);
     $words = preg_split('/\\s+/', $text, $excerpt_length + 1, PREG_SPLIT_NO_EMPTY);
     if (count($words) > $excerpt_length) {
         array_pop($words);
         $text = implode(' ', $words);
         $text = $text . $excerpt_more;
     } else {
         $text = implode(' ', $words);
     }
     $post = $original_post;
     return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
 }
 /**
  * Render the full article for the event
  *
  * @param Ai1ec_Event $event
  */
 public function get_full_article(Ai1ec_Event $event)
 {
     $title = apply_filters('the_title', $event->get('post')->post_title, $event->get('post_id'));
     $content = $this->get_content($event) . wpautop(apply_filters('ai1ec_the_content', apply_filters('the_content', $event->get('post')->post_content)));
     $args = compact('title', 'content');
     $loader = $this->_registry->get('theme.loader');
     return $loader->get_file('event-single-full.twig', $args, false)->get_content();
 }
Example #3
0
 /**
  * Faded version of event category color
  */
 protected function _get_color(Ai1ec_Event $event, $type)
 {
     static $categories_cache = array('rgba' => array(), 'faded' => array());
     $methods = array('rgba' => 'get_event_category_rgba_color', 'faded' => 'get_event_category_faded_color');
     $categories = $this->_registry->get('model.taxonomy')->get_post_categories($event->get('post_id'));
     if (!empty($categories)) {
         if (!isset($categories_cache[$type][$categories[0]->term_id])) {
             $method = $methods[$type];
             $categories_cache[$type][$categories[0]->term_id] = $this->{$method}($categories[0]->term_id);
         }
         return $categories_cache[$type][$categories[0]->term_id];
     }
     return '';
 }
Example #4
0
 /**
  * Contact info as HTML
  */
 public function get_contact_html(Ai1ec_Event $event)
 {
     $contact = '';
     if ($event->get('contact_name')) {
         $contact .= '<div class="ai1ec-contact-name">' . '<i class="ai1ec-fa ai1ec-fa-fw ai1ec-fa-user"></i> ' . esc_html($event->get('contact_name')) . '</div> ';
     }
     if ($event->get('contact_phone')) {
         $contact .= '<div class="ai1ec-contact-phone">' . '<i class="ai1ec-fa ai1ec-fa-fw ai1ec-fa-phone"></i> ' . esc_html($event->get('contact_phone')) . '</div> ';
     }
     if ($event->get('contact_email')) {
         $contact .= '<div class="ai1ec-contact-email">' . '<a href="mailto:' . esc_attr($event->get('contact_email')) . '">' . '<i class="ai1ec-fa ai1ec-fa-fw ai1ec-fa-envelope-o"></i> ' . __('Email', AI1EC_PLUGIN_NAME) . '</a></div> ';
     }
     if ($event->get('contact_url')) {
         $contact .= '<div class="ai1ec-contact-url">' . '<a target="_blank" href="' . esc_attr($event->get('contact_url')) . '"><i class="ai1ec-fa ai1ec-fa-fw ai1ec-fa-link"></i> ' . apply_filters('ai1ec_contact_url', __('Event website', AI1EC_PLUGIN_NAME)) . ' <i class="ai1ec-fa ai1ec-fa-external-link"></i></a></div>';
     }
     return $contact;
 }
Example #5
0
 /**
  * Renders the html of the page and returns it.
  *
  * @param Ai1ec_Event $event
  *
  * @return string the html of the page
  */
 public function get_content(Ai1ec_Event $event)
 {
     $settings = $this->_registry->get('model.settings');
     $rrule = $this->_registry->get('recurrence.rule');
     $taxonomy = $this->_registry->get('view.event.taxonomy');
     $location = $this->_registry->get('view.event.location');
     $ticket = $this->_registry->get('view.event.ticket');
     $content = $this->_registry->get('view.event.content');
     $time = $this->_registry->get('view.event.time');
     $subscribe_url = AI1EC_EXPORT_URL . '&ai1ec_post_ids=' . $event->get('post_id');
     $event->set_runtime('tickets_url_label', $ticket->get_tickets_url_label($event, false));
     $event->set_runtime('content_img_url', $content->get_content_img_url($event));
     $extra_buttons = apply_filters('ai1ec_rendering_single_event_actions', '', $event);
     $venues_html = apply_filters('ai1ec_rendering_single_event_venues', nl2br($location->get_location($event)), $event);
     // objects are passed by reference so an action is ok
     do_action('ai1ec_single_event_page_before_render', $event);
     $args = array('event' => $event, 'recurrence' => $rrule->rrule_to_text($event->get('recurrence_rules')), 'exclude' => $time->get_exclude_html($event, $rrule), 'categories' => $taxonomy->get_categories_html($event), 'tags' => $taxonomy->get_tags_html($event), 'location' => $venues_html, 'map' => $location->get_map_view($event), 'contact' => $ticket->get_contact_html($event), 'back_to_calendar' => $content->get_back_to_calendar_button_html(), 'subscribe_url' => $subscribe_url, 'subscribe_url_no_html' => $subscribe_url . '&no_html=true', 'edit_instance_url' => null, 'edit_instance_text' => null, 'google_url' => 'http://www.google.com/calendar/render?cid=' . urlencode($subscribe_url), 'show_subscribe_buttons' => !$settings->get('turn_off_subscription_buttons'), 'hide_featured_image' => $settings->get('hide_featured_image'), 'extra_buttons' => $extra_buttons, 'text_add_calendar' => __('Add to Calendar', AI1EC_PLUGIN_NAME), 'subscribe_buttons_text' => $this->_registry->get('view.calendar.subscribe-button')->get_labels(), 'text_when' => __('When:', AI1EC_PLUGIN_NAME), 'text_where' => __('Where:', AI1EC_PLUGIN_NAME), 'text_cost' => __('Cost:', AI1EC_PLUGIN_NAME), 'text_contact' => __('Contact:', AI1EC_PLUGIN_NAME), 'text_free' => __('Free', AI1EC_PLUGIN_NAME), 'text_categories' => __('Categories', AI1EC_PLUGIN_NAME), 'text_tags' => __('Tags', AI1EC_PLUGIN_NAME));
     if (!empty($args['recurrence']) && $event->get('instance_id') && current_user_can('edit_ai1ec_events')) {
         $args['edit_instance_url'] = admin_url('post.php?post=' . $event->get('post_id') . '&action=edit&instance=' . $event->get('instance_id'));
         $args['edit_instance_text'] = sprintf(Ai1ec_I18n::__('Edit this occurrence (%s)'), $event->get('start')->format_i18n('M j'));
     }
     $loader = $this->_registry->get('theme.loader');
     return $loader->get_file('event-single.twig', $args, false)->get_content();
 }
Example #6
0
 /**
  * Read post meta for post-attachment and return its URL as a string.
  *
  * @param Ai1ec_Event $event             Event object.
  * @param array       $ordered_img_sizes Image sizes order.
  * @param null        $size              (width, height) array of returned
  *                                       image.
  *
  * @return  string|null
  */
 protected function _get_post_attachment_url(Ai1ec_Event $event, array $ordered_img_sizes, &$size = null)
 {
     // Since WP does will return null if the wrong size is targeted,
     // we iterate over an array of sizes, breaking if a URL is found.
     foreach ($ordered_img_sizes as $size) {
         $attributes = wp_get_attachment_image_src(get_post_thumbnail_id($event->get('post_id')), $size);
         if ($attributes) {
             $url = array_shift($attributes);
             $size = $attributes;
             break;
         }
     }
     return empty($url) ? null : $url;
 }
Example #7
0
 /**
  * Adds runtime properties to the event.
  *
  * @param Ai1ec_Event $event
  */
 protected function _add_runtime_properties(Ai1ec_Event $event)
 {
     global $post;
     $original_post = $post;
     $post = $event->get('post');
     $instance_permalink = get_permalink($event->get('post_id'));
     $instance_permalink = add_query_arg('instance_id', $event->get('instance_id'), $instance_permalink);
     $event->set_runtime('instance_permalink', $instance_permalink);
     $event->set_runtime('filtered_title', apply_filters('the_title', $event->get('post')->post_title, $event->get('post_id'), true));
     $calendar_state = $this->_registry->get('calendar.state');
     $calendar_state->set_append_content(false);
     $event->set_runtime('filtered_content', apply_filters('ai1ec_the_content', apply_filters('the_content', $event->get('post')->post_content)));
     $calendar_state->set_append_content(true);
     $taxonomy = $this->_registry->get('view.event.taxonomy');
     $ticket = $this->_registry->get('view.event.ticket');
     $event->set_runtime('color_style', $taxonomy->get_color_style($event));
     $event->set_runtime('category_colors', $taxonomy->get_category_colors($event));
     $event->set_runtime('ticket_url_label', $ticket->get_tickets_url_label($event, false));
     $event->set_runtime('edit_post_link', get_edit_post_link($event->get('post_id')));
     $event_post = $this->_registry->get('view.event.post');
     $event->set_runtime('post_excerpt', $event_post->trim_excerpt($event));
     $color = $this->_registry->get('view.event.color');
     $event->set_runtime('faded_color', $color->get_faded_color($event));
     $event->set_runtime('rgba_color', $color->get_rgba_color($event));
     $event->set_runtime('short_start_time', $this->_registry->get('view.event.time')->get_short_time($event->get('start')));
     $this->_add_view_specific_runtime_properties($event);
     $post = $original_post;
 }
Example #8
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(']]>', ']]&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');
     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 #9
0
 /**
  * Parse the fields of an Event to the structure used by API
  */
 protected function _parse_event_fields_to_api_structure(Ai1ec_Event $event, WP_Post $post, $post_ticket_types, $api_fields_values)
 {
     $calendar_id = $this->_get_ticket_calendar();
     if ($calendar_id <= 0) {
         return null;
     }
     //fields of ai1ec events table used by API
     $body['latitude'] = $event->get('latitude');
     $body['longitude'] = $event->get('longitude');
     $body['post_id'] = $event->get('post_id');
     $body['calendar_id'] = $calendar_id;
     $body['dtstart'] = $event->get('start')->format_to_javascript();
     $body['dtend'] = $event->get('end')->format_to_javascript();
     $body['timezone'] = $event->get('timezone_name');
     $body['venue_name'] = $event->get('venue');
     $body['address'] = $event->get('address');
     $body['city'] = $event->get('city');
     $body['province'] = $event->get('province');
     $body['postal_code'] = $event->get('postal_code');
     $body['country'] = $event->get('country');
     $body['contact_name'] = $event->get('contact_name');
     $body['contact_phone'] = $event->get('contact_phone');
     $body['contact_email'] = $event->get('contact_email');
     $body['contact_website'] = $event->get('contact_url');
     $body['uid'] = $event->get('ical_uid');
     $body['title'] = $post->post_title;
     $body['description'] = $post->post_content;
     $body['url'] = get_permalink($post->ID);
     $body['status'] = $post->post_status;
     $body['tax_rate'] = 0;
     $utc_current_time = $this->_registry->get('date.time')->format_to_javascript();
     $body['created_at'] = $utc_current_time;
     $body['updated_at'] = $utc_current_time;
     //removing blank values
     foreach ($body as $key => $value) {
         if (ai1ec_is_blank($value)) {
             unset($body[$key]);
         }
     }
     if (null !== $api_fields_values && is_array($api_fields_values)) {
         foreach ($api_fields_values as $key => $value) {
             $body[$key] = $api_fields_values[$key];
             if ('visibility' === $key) {
                 if (0 === strcasecmp('private', $value)) {
                     $body['status'] = 'private';
                 } else {
                     if (0 === strcasecmp('password', $value)) {
                         $body['status'] = 'password';
                     }
                 }
             }
         }
     }
     $tickets_types = array();
     if (isset($post_ticket_types)) {
         $index = 0;
         foreach ($post_ticket_types as $ticket_type_ite) {
             if (false === isset($ticket_type_ite['id']) && isset($ticket_type_ite['remove'])) {
                 //ignoring new tickets that didn't go to api yet
                 continue;
             }
             $tickets_types[$index++] = $this->_parse_tickets_type_post_to_api_structure($ticket_type_ite, $event);
         }
     }
     $body['ticket_types'] = $tickets_types;
     return $body;
 }
 /**
  * Generate and store instance entries in database for given event.
  *
  * @param Ai1ec_Event $event Instance of event to create entries for.
  *
  * @return bool Success.
  */
 protected function _create_instances_collection(Ai1ec_Event $event)
 {
     $events = array();
     $event_item = array('post_id' => $event->get('post_id'), 'start' => $event->get('start')->format_to_gmt(), 'end' => $event->get('end')->format_to_gmt());
     $duration = $event->get('end')->diff_sec($event->get('start'));
     $_start = $event->get('start')->format_to_gmt();
     $_end = $event->get('end')->format_to_gmt();
     // Always cache initial instance
     $events[$_start] = $event_item;
     if ($event->get('recurrence_rules') || $event->get('recurrence_dates')) {
         $start_timezone = $this->_registry->get('model.option')->get('timezone_string');
         $events += $this->create_instances_by_recurrence($event, $event_item, $_start, $duration, $start_timezone);
     }
     $search_helper = $this->_registry->get('model.search');
     foreach ($events as &$event_item) {
         // Find out if this event instance is already accounted for by an
         // overriding 'RECURRENCE-ID' of the same iCalendar feed (by comparing the
         // UID, start date, recurrence). If so, then do not create duplicate
         // instance of event.
         $start = $event_item['start'];
         $matching_event_id = null;
         if ($event->get('ical_uid')) {
             $matching_event_id = $search_helper->get_matching_event_id($event->get('ical_uid'), $event->get('ical_feed_url'), $event->get('start'), false, $event->get('post_id'));
         }
         // If no other instance was found
         if (null !== $matching_event_id) {
             $event_item = false;
         }
     }
     return array_filter($events);
 }
Example #11
0
 /**
  * Filters past or out of range exception dates.
  *
  * @param Ai1ec_Event $event Event.
  *
  * @return array Filtered exception dates.
  */
 protected function _filter_exception_dates(Ai1ec_Event $event)
 {
     $start = (int) $event->get('start')->format();
     $exception_dates = explode(',', $event->get('exception_dates'));
     $dates = array();
     foreach ($exception_dates as $date) {
         $ex_date = (int) $this->_registry->get('date.time', $date)->format();
         if ($ex_date > $start) {
             $dates[] = $date;
         }
     }
     return $dates;
 }
 /**
  * Filter Groups as HTML, either as blocks or inline.
  *
  * @param Ai1ec_Event  $event  Rendered Event.
  * @param array        $filter_group Filter Group (Option Model)
  * @param string       $format Return 'blocks' or 'inline' formatted result.
  *
  * @return string String of HTML for filter group blocks.
  */
 public function get_filter_group_html(Ai1ec_Event $event, $filter_group, $format = 'blocks')
 {
     $filter_groups = $this->_taxonomy_model->get_post_taxonomy($event->get('post_id'), $filter_group['taxonomy_name']);
     $icon_name = '';
     if ('ai1eccfgi-null' !== $filter_group['icon']) {
         $icon_name = $filter_group['icon'];
     } else {
         $icon_name = 'ai1ec-icon-timely';
     }
     foreach ($filter_groups as &$group) {
         $href = $this->_registry->get('html.element.href', array($filter_group['taxonomy_name'] . '_ids' => $group->term_id));
         $class = $data_type = $title = '';
         if ($group->description) {
             $title = 'title="' . esc_attr($group->description) . '" ';
         }
         $html = '';
         $class .= ' ai1ec-category';
         $color_style = '';
         if ('inline' === $format) {
             $taxonomy = $this->_registry->get('model.taxonomy');
             $color_style = $taxonomy->get_category_color($group->term_id);
             if ($color_style !== '') {
                 $color_style = 'style="color: ' . $color_style . ';" ';
             }
             $class .= '-inline';
         }
         $html .= '<a ' . $data_type . ' class="' . $class . ' ai1ec-term-id-' . $group->term_id . ' p-category" ' . $title . $color_style . 'href="' . $href->generate_href() . '">';
         if ('blocks' === $format) {
             $html .= $this->get_category_color_square($group->term_id) . ' ';
         } else {
             $html = $html . '<i ' . $color_style . ' class="ai1ec-fa ' . $icon_name . '"></i>';
         }
         $html .= esc_html($group->name) . '</a>';
         $group = $html;
     }
     return implode(' ', $filter_groups);
 }
 /**
  * custom_columns function
  *
  * Adds content for custom columns
  *
  * @return void
  **/
 function custom_columns($column, $post_id)
 {
     global $ai1ec_events_helper;
     switch ($column) {
         case 'ai1ec_event_date':
             try {
                 $e = new Ai1ec_Event($post_id);
                 echo $e->get_timespan_html();
             } catch (Exception $e) {
                 // event wasn't found, output empty string
                 echo "";
             }
             break;
     }
 }
 /**
  * Outputs event-specific details as HTML to be prepended to post content
  * when displayed in an excerpt format.
  *
  * @param Ai1ec_Event $event  The event being displayed
  */
 function excerpt_view($event)
 {
     global $ai1ec_view_helper, $ai1ec_calendar_helper;
     $location = str_replace("\n", ', ', rtrim($event->get_location()));
     $args = array('event' => $event, 'location' => $location);
     $ai1ec_view_helper->display_theme('event-excerpt.php', $args);
 }
 /**
  * Create a duplicate from a posts' instance
  */
 function duplicate_post_create_duplicate($post, $status = '')
 {
     $new_post_author = $this->duplicate_post_get_current_user();
     $new_post_status = $status;
     if (empty($new_post_status)) {
         $new_post_status = $post->post_status;
     }
     $new_post_status = $this->get_new_post_status($new_post_status);
     $new_post = array('menu_order' => $post->menu_order, 'comment_status' => $post->comment_status, 'ping_status' => $post->ping_status, 'pinged' => $post->pinged, 'post_author' => $new_post_author->ID, 'post_content' => $post->post_content, 'post_date' => $post->post_date, 'post_date_gmt' => get_gmt_from_date($post->post_date), 'post_excerpt' => $post->post_excerpt, 'post_parent' => $post->post_parent, 'post_password' => $post->post_password, 'post_status' => $new_post_status, 'post_title' => $post->post_title, 'post_type' => $post->post_type, 'to_ping' => $post->to_ping);
     $new_post_id = wp_insert_post($new_post);
     $edit_event_url = esc_attr(admin_url("post.php?post={$new_post_id}&action=edit"));
     $message = Ai1ec_Helper_Factory::create_admin_message_instance(sprintf(__('<p>The event <strong>%s</strong> was cloned succesfully. <a href="%s">Edit cloned event</a></p>', AI1EC_PLUGIN_NAME), $post->post_title, $edit_event_url));
     $message->set_message_type('updated');
     $this->admin_notice_helper->add_renderable_children($message);
     // If you have written a plugin which uses non-WP database tables to save
     // information about a post you can hook this action to dupe that data.
     if ($post->post_type == 'page' || function_exists('is_post_type_hierarchical') && is_post_type_hierarchical($post->post_type)) {
         do_action('dp_duplicate_page', $new_post_id, $post);
     } else {
         do_action('dp_duplicate_post', $new_post_id, $post);
     }
     if ('ai1ec_event' === $post->post_type) {
         try {
             $old_event = new Ai1ec_Event($post->ID);
             $old_event->post_id = $new_post_id;
             unset($old_event->post);
             $old_event->save();
         } catch (Ai1ec_Event_Not_Found $exception) {
             /* ignore */
         }
     }
     delete_post_meta($new_post_id, '_dp_original');
     add_post_meta($new_post_id, '_dp_original', $post->ID);
     // If the copy gets immediately published, we have to set a proper slug.
     if ($new_post_status == 'publish' || $new_post_status == 'future') {
         $post_name = wp_unique_post_slug($post->post_name, $new_post_id, $new_post_status, $post->post_type, $post->post_parent);
         $new_post = array();
         $new_post['ID'] = $new_post_id;
         $new_post['post_name'] = $post_name;
         // Update the post into the database
         wp_update_post($new_post);
     }
     return $new_post_id;
 }
Example #16
0
 protected function _add_view_specific_runtime_properties(Ai1ec_Event $event)
 {
     $event->set_runtime('multiday', $event->get('_orig')->is_multiday());
 }
Example #17
0
 /**
  * Tags as HTML
  */
 public function get_tags_html(Ai1ec_Event $event)
 {
     $tags = $this->_taxonomy_model->get_post_tags($event->get('post_id'));
     if (!$tags) {
         $tags = array();
     }
     foreach ($tags as &$tag) {
         $href = $this->_registry->get('html.element.href', array('tag_ids' => $tag->term_id));
         $class = '';
         $data_type = '';
         $title = '';
         if ($tag->description) {
             $title = 'title="' . esc_attr($tag->description) . '" ';
         }
         $tag = '<a ' . $data_type . ' class="ai1ec-tag ' . $class . ' ai1ec-term-id-' . $tag->term_id . '" ' . $title . 'href="' . $href->generate_href() . '">' . '<i class="ai1ec-fa ai1ec-fa-tag"></i>' . esc_html($tag->name) . '</a>';
     }
     return implode(' ', $tags);
 }
 /**
  * Handle AJAX request for submission of front-end create event form.
  *
  * @return null
  */
 public function submit_front_end_create_event_form()
 {
     global $ai1ec_view_helper, $ai1ec_calendar_helper, $ai1ec_events_helper;
     $ai1ec_settings = Ai1ec_Settings::get_instance();
     $error = false;
     $html = '';
     $default_error_msg = __('There was an error creating your event.', AI1EC_PLUGIN_NAME) . ' ' . __('Please try again or contact the site administrator for help.', AI1EC_PLUGIN_NAME);
     $valid = $this->validate_front_end_create_event_form($message);
     // If valid submission, proceed with event creation.
     if ($valid) {
         // Determine post publish status.
         if (current_user_can('publish_ai1ec_events')) {
             $post_status = 'publish';
         } else {
             if (current_user_can('edit_ai1ec_events')) {
                 $post_status = 'pending';
             } else {
                 if ($ai1ec_settings->allow_anonymous_submissions) {
                     $post_status = 'pending';
                 }
             }
         }
         // Strip slashes if ridiculous PHP setting magic_quotes_gpc is enabled.
         foreach ($_POST as $param_name => $param) {
             if ('ai1ec' === substr($param_name, 0, 5) && is_scalar($param)) {
                 $_POST[$param_name] = stripslashes($param);
             }
         }
         // Build post array from submitted data.
         $post = array('post_type' => AI1EC_POST_TYPE, 'post_author' => get_current_user_id(), 'post_title' => $_POST['post_title'], 'post_content' => $_POST['post_content'], 'post_status' => $post_status);
         // Copy posted event data to new empty event object.
         $event = new Ai1ec_Event();
         $event->post = $post;
         $event->categories = isset($_POST['ai1ec_categories']) ? implode(',', $_POST['ai1ec_categories']) : '';
         $event->tags = isset($_POST['ai1ec_tags']) ? $_POST['ai1ec_tags'] : '';
         $event->allday = isset($_POST['ai1ec_all_day_event']) ? (bool) $_POST['ai1ec_all_day_event'] : 0;
         $event->instant_event = isset($_POST['ai1ec_instant_event']) ? (bool) $_POST['ai1ec_instant_event'] : 0;
         $event->start = isset($_POST['ai1ec_start_time']) ? $_POST['ai1ec_start_time'] : '';
         if ($event->instant_event) {
             $event->end = $event->start + 1800;
         } else {
             $event->end = isset($_POST['ai1ec_end_time']) ? $_POST['ai1ec_end_time'] : '';
         }
         $event->address = isset($_POST['ai1ec_address']) ? $_POST['ai1ec_address'] : '';
         $event->show_map = isset($_POST['ai1ec_google_map']) ? (bool) $_POST['ai1ec_google_map'] : 0;
         $scalar_field_list = array('ai1ec_venue' => FILTER_SANITIZE_STRING, 'ai1ec_cost' => FILTER_SANITIZE_STRING, 'ai1ec_is_free' => FILTER_SANITIZE_NUMBER_INT, 'ai1ec_ticket_url' => FILTER_VALIDATE_URL, 'ai1ec_contact_name' => FILTER_SANITIZE_STRING, 'ai1ec_contact_phone' => FILTER_SANITIZE_STRING, 'ai1ec_contact_email' => FILTER_VALIDATE_EMAIL, 'ai1ec_contact_url' => FILTER_VALIDATE_URL);
         foreach ($scalar_field_list as $scalar_field => $field_filter) {
             $scalar_value = filter_input(INPUT_POST, $scalar_field, $field_filter);
             if (!empty($scalar_value)) {
                 $use_name = substr($scalar_field, 6);
                 $event->{$use_name} = $scalar_value;
             }
         }
         // Save the event to the database.
         try {
             $event->save();
             $ai1ec_events_helper->cache_event($event);
             // Check if uploads are enabled and there is an uploaded file.
             if ((is_user_logged_in() || $ai1ec_settings->allow_anonymous_submissions && $ai1ec_settings->allow_anonymous_uploads) && !empty($_FILES['ai1ec_image']['name'])) {
                 require_once ABSPATH . 'wp-admin/includes/image.php';
                 require_once ABSPATH . 'wp-admin/includes/file.php';
                 require_once ABSPATH . 'wp-admin/includes/media.php';
                 $attach_id = media_handle_upload('ai1ec_image', $event->post_id);
                 if (is_int($attach_id)) {
                     update_post_meta($event->post_id, '_thumbnail_id', $attach_id);
                 }
             }
             // Send the mail
             $admin_notification = Ai1ec_Notification_Factory::create_notification_instance(array(get_option('admin_email')), $ai1ec_settings->admin_add_new_event_mail_body, Ai1ec_Notification_Factory::EMAIL_NOTIFICATION, $ai1ec_settings->admin_add_new_event_mail_subject);
             $edit_url = 'post.php?post=' . $event->post_id . '&action=edit';
             $translations = array('[event_title]' => $_POST['post_title'], '[site_title]' => get_bloginfo('name'), '[site_url]' => site_url(), '[event_admin_url]' => admin_url($edit_url));
             $admin_notification->set_translations($translations);
             $sent = $admin_notification->send();
             if (current_user_can('publish_ai1ec_events')) {
                 $message = sprintf(__('Thank you for your submission. Your event <em>%s</em> was published successfully.', AI1EC_PLUGIN_NAME), $post['post_title']);
                 $link_text = __('View Your Event', AI1EC_PLUGIN_NAME);
                 $link_url = get_permalink($event->post_id);
             } else {
                 $message = sprintf(__('Thank you for your submission. Your event <em>%s</em> will be reviewed and published once approved.', AI1EC_PLUGIN_NAME), $post['post_title']);
                 $link_text = __('Back to Calendar', AI1EC_PLUGIN_NAME);
                 $link_url = $ai1ec_calendar_helper->get_calendar_url();
             }
         } catch (Exception $e) {
             trigger_error(sprintf(__('There was an error during event creation: %s', AI1EC_PLUGIN_NAME), $e->getMessage()), E_USER_WARNING);
             $error = true;
             $message = $default_error_msg;
         }
         $args = array('message_type' => $error ? 'error' : 'success', 'message' => $message, 'link_text' => $link_text, 'link_url' => $link_url);
         $html = $ai1ec_view_helper->get_theme_view('create-event-message.php', $args);
     } else {
         $error = true;
     }
     $response = array('error' => $error, 'message' => $message, 'html' => $html);
     $ai1ec_view_helper->xml_response($response);
 }
 /**
  * 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
  *
  * @return void
  */
 function insert_event_in_calendar(Ai1ec_Event $event, vcalendar &$calendar, $export = false)
 {
     global $ai1ec_events_helper;
     $tz = Ai1ec_Meta::get_option('timezone_string');
     $e =& $calendar->newComponent('vevent');
     $uid = '';
     if ($event->ical_uid) {
         $uid = addcslashes($event->ical_uid, "\\;,\n");
     } else {
         $uid = sprintf($this->get_uid_format(), $event->post->ID);
     }
     $e->setProperty('uid', $this->_sanitize_value($uid));
     $e->setProperty('url', get_permalink($event->post_id));
     // =========================
     // = Summary & description =
     // =========================
     $e->setProperty('summary', $this->_sanitize_value(html_entity_decode(apply_filters('the_title', $event->post->post_title), ENT_QUOTES, 'UTF-8')));
     $content = apply_filters('the_content', $event->post->post_content);
     $content = str_replace(']]>', ']]&gt;', $content);
     $content = html_entity_decode($content, ENT_QUOTES, 'UTF-8');
     // Prepend featured image if available.
     $size = null;
     if ($img_url = $event->get_post_thumbnail_url($size)) {
         $content = '<div class="ai1ec-event-avatar alignleft timely"><img src="' . esc_attr($img_url) . '" width="' . $size[0] . '" height="' . $size[1] . '" /></div>' . $content;
     }
     $e->setProperty('description', $this->_sanitize_value($content));
     // =====================
     // = Start & end times =
     // =====================
     $dtstartstring = '';
     $dtstart = $dtend = array();
     if ($event->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(gmdate("Ymd", $ai1ec_events_helper->gmt_to_local($event->start))), $dtstart);
             $e->setProperty('dtend', $this->_sanitize_value(gmdate("Ymd", $ai1ec_events_helper->gmt_to_local($event->end))), $dtend);
         } else {
             $e->setProperty('dtstart', $this->_sanitize_value(gmdate("Ymd\\T", $ai1ec_events_helper->gmt_to_local($event->start))), $dtstart);
             $e->setProperty('dtend', $this->_sanitize_value(gmdate("Ymd\\T", $ai1ec_events_helper->gmt_to_local($event->end))), $dtend);
         }
     } else {
         if ($tz) {
             $dtstart["TZID"] = $dtend["TZID"] = $tz;
         }
         // This is used later.
         $dtstartstring = gmdate("Ymd\\THis", $ai1ec_events_helper->gmt_to_local($event->start));
         $e->setProperty('dtstart', $this->_sanitize_value($dtstartstring), $dtstart);
         $e->setProperty('dtend', $this->_sanitize_value(gmdate("Ymd\\THis", $ai1ec_events_helper->gmt_to_local($event->end))), $dtend);
     }
     // ========================
     // = Latitude & longitude =
     // ========================
     if (floatval($event->latitude) || floatval($event->longitude)) {
         $e->setProperty('geo', $event->latitude, $event->longitude);
     }
     // ===================
     // = Venue & address =
     // ===================
     if ($event->venue || $event->address) {
         $location = array($event->venue, $event->address);
         $location = array_filter($location);
         $location = implode(' @ ', $location);
         $e->setProperty('location', $this->_sanitize_value($location));
     }
     $categories = array();
     $language = get_bloginfo('language');
     foreach (wp_get_post_terms($event->post_id, 'events_categories') as $cat) {
         $categories[] = $cat->name;
     }
     $e->setProperty('categories', implode(',', $categories), array("LANGUAGE" => $language));
     $tags = array();
     foreach (wp_get_post_terms($event->post_id, 'events_tags') as $tag) {
         $tags[] = $tag->name;
     }
     if (!empty($tags)) {
         $e->setProperty('X-TAGS', implode(',', $tags), array("LANGUAGE" => $language));
     }
     // ==================
     // = Cost & tickets =
     // ==================
     if ($event->cost) {
         $e->setProperty('X-COST', $this->_sanitize_value($event->cost));
     }
     if ($event->ticket_url) {
         $e->setProperty('X-TICKETS-URL', $this->_sanitize_value($event->ticket_url));
     }
     // ====================================
     // = Contact name, phone, e-mail, URL =
     // ====================================
     $contact = array($event->contact_name, $event->contact_phone, $event->contact_email, $event->contact_url);
     $contact = array_filter($contact);
     $contact = implode('; ', $contact);
     $e->setProperty('contact', $this->_sanitize_value($contact));
     // ====================
     // = Recurrence rules =
     // ====================
     $rrule = array();
     if (!empty($event->recurrence_rules)) {
         $rules = array();
         foreach (explode(';', $event->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 =
     // ===================
     $exrule = array();
     if (!empty($event->exception_rules)) {
         $rules = array();
         foreach (explode(';', $event->exception_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;
             }
             $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
     if (!empty($event->exception_dates)) {
         foreach (explode(',', $event->exception_dates) as $exdate) {
             if ($event->allday) {
                 // the local date will be always something like 20121122T000000Z
                 // we just need the date
                 $exdate = substr($ai1ec_events_helper->exception_dates_to_local($exdate), 0, 8);
                 $e->setProperty('exdate', array($exdate), array('VALUE' => 'DATE'));
             } else {
                 $params = array();
                 if ($tz) {
                     $params["TZID"] = $tz;
                 }
                 $exdate = $ai1ec_events_helper->exception_dates_to_local($exdate);
                 // get only the date + T
                 $exdate = substr($exdate, 0, 9);
                 // Take the time from
                 $exdate .= substr($dtstartstring, 9);
                 $e->setProperty('exdate', array($exdate), $params);
             }
         }
     }
 }
Example #20
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;
 }
Example #21
0
 /**
  * Returns the latitude/longitude coordinates as a textual string
  * parsable by the Geocoder API.
  *
  * @param  Ai1ec_Event &$event The event to return data from
  *
  * @return string              The latitude & longitude string, or null
  */
 public function get_latlng(Ai1ec_Event $event)
 {
     // If the coordinates are set, use those, otherwise use the address.
     $location = NULL;
     // If the coordinates are set by hand use them.
     if ($event->get('show_coordinates')) {
         $longitude = floatval($event->get('longitude'));
         $latitude = floatval($event->get('latitude'));
         $location = $latitude . ',' . $longitude;
     }
     return $location;
 }
 /**
  * Handle AJAX request for submission of front-end create event form.
  *
  * @return null
  */
 public function submit_front_end_create_event_form()
 {
     global $ai1ec_view_helper, $ai1ec_calendar_helper, $ai1ec_settings, $ai1ec_events_helper;
     $error = false;
     $html = '';
     $default_error_msg = __('There was an error creating your event.', AI1EC_PLUGIN_NAME) . ' ' . __('Please try again or contact the site administrator for help.', AI1EC_PLUGIN_NAME);
     $valid = $this->validate_front_end_create_event_form($message);
     // If valid submission, proceed with event creation.
     if ($valid) {
         // Determine post publish status.
         if (current_user_can('publish_ai1ec_events')) {
             $post_status = 'publish';
         } else {
             if (current_user_can('edit_ai1ec_events')) {
                 $post_status = 'pending';
             } else {
                 if ($ai1ec_settings->allow_anonymous_submissions) {
                     $post_status = 'pending';
                 }
             }
         }
         // Strip slashes if ridiculous PHP setting magic_quotes_gpc is enabled.
         if (get_magic_quotes_gpc()) {
             foreach ($_POST as &$param) {
                 $param = stripslashes($param);
             }
         }
         // Build post array from submitted data.
         $post = array('post_type' => AI1EC_POST_TYPE, 'post_author' => get_current_user_id(), 'post_title' => $_POST['post_title'], 'post_content' => $_POST['post_content'], 'post_status' => $post_status);
         // Copy posted event data to new empty event object.
         $event = new Ai1ec_Event();
         $event->post = $post;
         $event->categories = isset($_POST['ai1ec_categories']) ? implode(',', $_POST['ai1ec_categories']) : '';
         $event->tags = isset($_POST['ai1ec_tags']) ? $_POST['ai1ec_tags'] : '';
         $event->allday = isset($_POST['ai1ec_all_day_event']) ? (bool) $_POST['ai1ec_all_day_event'] : 0;
         $event->instant_event = isset($_POST['ai1ec_instant_event']) ? (bool) $_POST['ai1ec_instant_event'] : 0;
         $event->start = isset($_POST['ai1ec_start_time']) ? $_POST['ai1ec_start_time'] : '';
         if ($event->instant_event) {
             $event->end = $event->start + 1800;
         } else {
             $event->end = isset($_POST['ai1ec_end_time']) ? $_POST['ai1ec_end_time'] : '';
         }
         $event->address = isset($_POST['ai1ec_address']) ? $_POST['ai1ec_address'] : '';
         $event->show_map = isset($_POST['ai1ec_google_map']) ? (bool) $_POST['ai1ec_google_map'] : 0;
         // Save the event to the database.
         try {
             $event->save();
             $ai1ec_events_helper->cache_event($event);
             // Check if uploads are enabled and there is an uploaded file.
             if ((is_user_logged_in() || $ai1ec_settings->allow_anonymous_submissions && $ai1ec_settings->allow_anonymous_uploads) && !empty($_FILES['ai1ec_image']['name'])) {
                 require_once ABSPATH . 'wp-admin/includes/image.php';
                 require_once ABSPATH . 'wp-admin/includes/file.php';
                 require_once ABSPATH . 'wp-admin/includes/media.php';
                 $attach_id = media_handle_upload('ai1ec_image', $event->post_id);
                 if (is_int($attach_id)) {
                     update_post_meta($event->post_id, '_thumbnail_id', $attach_id);
                 }
             }
             if (current_user_can('publish_ai1ec_events')) {
                 $message = sprintf(__('Thank you for your submission. Your event <em>%s</em> was published successfully.', AI1EC_PLUGIN_NAME), $post['post_title']);
                 $link_text = __('View Your Event', AI1EC_PLUGIN_NAME);
                 $link_url = get_permalink($event->post_id);
             } else {
                 $message = sprintf(__('Thank you for your submission. Your event <em>%s</em> will be reviewed and published once approved.', AI1EC_PLUGIN_NAME), $post['post_title']);
                 $link_text = __('Back to Calendar', AI1EC_PLUGIN_NAME);
                 $link_url = $ai1ec_calendar_helper->get_calendar_url();
             }
         } catch (Exception $e) {
             trigger_error(sprintf(__('There was an error during event creation: %s', AI1EC_PLUGIN_NAME), $e->getMessage()), E_USER_WARNING);
             $error = true;
             $message = $default_error_msg;
         }
         $args = array('message_type' => $error ? 'error' : 'success', 'message' => $message, 'link_text' => $link_text, 'link_url' => $link_url);
         $html = $ai1ec_view_helper->get_theme_view('create-event-message.php', $args);
     } else {
         $error = true;
     }
     $response = array('error' => $error, 'message' => $message, 'html' => $html);
     $ai1ec_view_helper->xml_response($response);
 }
Example #23
0
 protected function _add_view_specific_runtime_properties(Ai1ec_Event $event)
 {
     $taxonomy = $this->_registry->get('view.event.taxonomy');
     $avatar = $this->_registry->get('view.event.avatar');
     $event->set_runtime('categories_html', $taxonomy->get_categories_html($event));
     $event->set_runtime('tags_html', $taxonomy->get_tags_html($event));
     $event->set_runtime('content_img_url', $avatar->get_content_img_url($event));
 }
 protected function _add_view_specific_runtime_properties(Ai1ec_Event $event)
 {
     $end_day = $this->_registry->get('date.time', $event->get('end'))->adjust(-1, 'second')->format_i18n('d');
     $event->set_runtime('multiday_end_day', $end_day);
 }
Example #25
0
 /**
  * Generate and store instance entries in database for given event.
  *
  * @param Ai1ec_Event $event Instance of event to create entries for.
  *
  * @return bool Success.
  */
 protected function _create_instances_collection(Ai1ec_Event $event)
 {
     $events = array();
     $event_item = array('post_id' => $event->get('post_id'), 'start' => $event->get('start')->format_to_gmt(), 'end' => $event->get('end')->format_to_gmt());
     $duration = $event->get('end')->diff_sec($event->get('start'));
     $_start = $event->get('start')->format_to_gmt();
     $_end = $event->get('end')->format_to_gmt();
     // Always cache initial instance
     $events[$_start] = $event_item;
     if ($event->get('recurrence_rules') || $event->get('recurrence_dates')) {
         /**
          * NOTE: this timezone switch is intentional, because underlying
          * library doesn't allow us to pass it as an argument. Though no
          * lesser importance shall be given to the restore call bellow.
          */
         $start_datetime = $event->get('start');
         $start_datetime->assert_utc_timezone();
         $start_timezone = $this->_registry->get('date.timezone')->get_name($start_datetime->get_timezone());
         $events += $this->create_instances_by_recurrence($event, $event_item, $_start, $duration, $start_timezone);
     }
     $search_helper = $this->_registry->get('model.search');
     foreach ($events as &$event_item) {
         // Find out if this event instance is already accounted for by an
         // overriding 'RECURRENCE-ID' of the same iCalendar feed (by comparing the
         // UID, start date, recurrence). If so, then do not create duplicate
         // instance of event.
         $start = $event_item['start'];
         $matching_event_id = null;
         if ($event->get('ical_uid')) {
             $matching_event_id = $search_helper->get_matching_event_id($event->get('ical_uid'), $event->get('ical_feed_url'), $event->get('start'), false, $event->get('post_id'));
         }
         // If no other instance was found
         if (null !== $matching_event_id) {
             $event_item = false;
         }
     }
     return array_filter($events);
 }
 /**
  * add_vcalendar_events_to_db method
  *
  * Process vcalendar instance - add events to database
  *
  * @param vcalendar $v              Calendar to retrieve data from
  * @param stdClass  $feed           Instance of feed (see Ai1ecIcs plugin)
  * @param string    $comment_status WP comment status: 'open' or 'closed'
  * @param int       $do_show_map    Map display status (DB boolean: 0 or 1)
  *
  * @return int Count of events added to database
  */
 public function add_vcalendar_events_to_db(vcalendar $v, $feed, $comment_status, $do_show_map = 0)
 {
     global $ai1ec_events_helper;
     $count = 0;
     $do_show_map = Ai1ec_Number_Utility::db_bool($do_show_map);
     $v->sort();
     // Reverse the sort order, so that RECURRENCE-IDs are listed before the
     // defining recurrence events, and therefore take precedence during
     // caching.
     $v->components = array_reverse($v->components);
     // TODO: select only VEVENT components that occur after, say, 1 month ago.
     // Maybe use $v->selectComponents(), which takes into account recurrence
     // Fetch default timezone in case individual properties don't define it
     $timezone = $v->getProperty('X-WR-TIMEZONE');
     $timezone = (string) $timezone[1];
     // go over each event
     while ($e = $v->getComponent('vevent')) {
         // Event data array.
         $data = array();
         // =====================
         // = Start & end times =
         // =====================
         $start = $e->getProperty('dtstart', 1, true);
         $end = $e->getProperty('dtend', 1, true);
         // For cases where a "VEVENT" calendar component
         // specifies a "DTSTART" property with a DATE value type but none
         // of "DTEND" nor "DURATION" property, the event duration is taken to
         // be one day.  For cases where a "VEVENT" calendar component
         // specifies a "DTSTART" property with a DATE-TIME value type but no
         // "DTEND" property, the event ends on the same calendar date and
         // time of day specified by the "DTSTART" property.
         if (empty($end)) {
             // #1 if duration is present, assign it to end time
             $end = $e->getProperty('duration', 1, true, true);
             if (empty($end)) {
                 // #2 if only DATE value is set for start, set duration to 1 day
                 if (!isset($start['value']['hour'])) {
                     $end = array('value' => array('year' => $start['value']['year'], 'month' => $start['value']['month'], 'day' => $start['value']['day'] + 1, 'hour' => 0, 'min' => 0, 'sec' => 0, 'tz' => $start['value']['tz']));
                 } else {
                     // #3 set end date to start time
                     $end = $start;
                 }
             }
         }
         $categories = $e->getProperty("CATEGORIES", false, true);
         $imported_cat = array();
         // If the user chose to preserve taxonomies during import, add categories.
         if ($categories && $feed->keep_tags_categories) {
             $imported_cat = $this->add_categories_and_tags($categories['value'], $imported_cat, false, true);
         }
         $feed_categories = $feed->feed_category;
         if (!empty($feed_categories)) {
             $imported_cat = $this->add_categories_and_tags($feed_categories, $imported_cat, false, false);
         }
         $tags = $e->getProperty("X-TAGS", false, true);
         $imported_tags = array();
         // If the user chose to preserve taxonomies during import, add tags.
         if ($tags && $feed->keep_tags_categories) {
             $imported_tags = $this->add_categories_and_tags($tags[1]['value'], $imported_tags, true, true);
         }
         $feed_tags = $feed->feed_tags;
         if (!empty($feed_tags)) {
             $imported_tags = $this->add_categories_and_tags($feed_tags, $imported_tags, true, true);
         }
         // Event is all-day if no time components are defined
         $allday = $this->_is_timeless($start['value']) && $this->_is_timeless($end['value']);
         // Also check the proprietary MS all-day field.
         $ms_allday = $e->getProperty('X-MICROSOFT-CDO-ALLDAYEVENT');
         if (!empty($ms_allday) && $ms_allday[1] == 'TRUE') {
             $allday = true;
         }
         $start = $this->time_array_to_timestamp($start, $timezone);
         $end = $this->time_array_to_timestamp($end, $timezone);
         if (false === $start || false === $end) {
             trigger_error('Failed to parse one or more dates given timezone "' . var_export($timezone, true) . '".', E_USER_WARNING);
             continue;
         }
         // If all-day, and start and end times are equal, then this event has
         // invalid end time (happens sometimes with poorly implemented iCalendar
         // exports, such as in The Event Calendar), so set end time to 1 day
         // after start time.
         if ($allday && $start === $end) {
             $end += 24 * 60 * 60;
         }
         $data += compact('start', 'end', 'allday');
         // =======================================
         // = Recurrence rules & recurrence dates =
         // =======================================
         if ($rrule = $e->createRrule()) {
             $rrule = trim(end(explode(':', $rrule)));
         }
         if ($exrule = $e->createExrule()) {
             $exrule = trim(end(explode(':', $exrule)));
         }
         if ($rdate = $e->createRdate()) {
             $rdate = trim(end(explode(':', $rdate)));
         }
         // ===================
         // = Exception dates =
         // ===================
         $exdate_array = array();
         if ($exdates = $e->createExdate()) {
             // We may have two formats:
             // one exdate with many dates ot more EXDATE rules
             $exdates = explode("EXDATE", $exdates);
             foreach ($exdates as $exd) {
                 if (empty($exd)) {
                     continue;
                 }
                 $exdate_array[] = trim(end(explode(':', $exd)));
             }
         }
         // This is the local string.
         $exdate_loc = implode(',', $exdate_array);
         $gmt_exdates = array();
         // Now we convert the string to gmt. I must do it here
         // because EXDATE:date1,date2,date3 must be parsed
         if (!empty($exdate_loc)) {
             foreach (explode(',', $exdate_loc) as $date) {
                 // If the date is > 8 char that's a datetime, we just want the
                 // date part for the exclusion rules
                 if (strlen($date) > 8) {
                     $date = substr($date, 0, 8);
                 }
                 $gmt_exdates[] = $ai1ec_events_helper->exception_dates_to_gmt($date);
             }
         }
         $exdate = implode(',', $gmt_exdates);
         // ========================
         // = Latitude & longitude =
         // ========================
         $latitude = $longitude = NULL;
         $geo_tag = $e->getProperty('geo');
         if (is_array($geo_tag)) {
             if (isset($geo_tag['latitude']) && isset($geo_tag['longitude'])) {
                 $latitude = (double) $geo_tag['latitude'];
                 $longitude = (double) $geo_tag['longitude'];
             }
         } else {
             if (!empty($geo_tag) && false !== strpos($geo_tag, ';')) {
                 list($latitude, $longitude) = explode(';', $geo_tag, 2);
                 $latitude = (double) $latitude;
                 $longitude = (double) $longitude;
             }
         }
         unset($geo_tag);
         if (NULL !== $latitude) {
             $data += compact('latitude', 'longitude');
             // Check the input coordinates checkbox, otherwise lat/long data
             // is not present on the edit event page
             $data['show_coordinates'] = 1;
         }
         // ===================
         // = Venue & address =
         // ===================
         $address = $venue = '';
         $location = $e->getProperty('location');
         $matches = array();
         // This regexp matches a venue / address in the format
         // "venue @ address" or "venue - address".
         preg_match('/\\s*(.*\\S)\\s+[\\-@]\\s+(.*)\\s*/', $location, $matches);
         // if there is no match, it's not a combined venue + address
         if (empty($matches)) {
             // if there is a comma, probably it's an address
             if (false === strpos($location, ',')) {
                 $venue = $location;
             } else {
                 $address = $location;
             }
         } else {
             $venue = isset($matches[1]) ? $matches[1] : '';
             $address = isset($matches[2]) ? $matches[2] : '';
         }
         // =====================================================
         // = Set show map status based on presence of location =
         // =====================================================
         if (1 === $do_show_map && NULL === $latitude && empty($address)) {
             $do_show_map = 0;
         }
         // ==================
         // = Cost & tickets =
         // ==================
         $cost = $e->getProperty('X-COST');
         $cost = $cost ? $cost[1] : '';
         $ticket_url = $e->getProperty('X-TICKETS-URL');
         $ticket_url = $ticket_url ? $ticket_url[1] : '';
         // ===============================
         // = Contact name, phone, e-mail =
         // ===============================
         $organizer = $e->getProperty('organizer');
         if ('MAILTO:' === substr($organizer, 0, 7) && false === strpos($organizer, '@')) {
             $organizer = substr($organizer, 7);
         }
         $contact = $e->getProperty('contact');
         $elements = explode(';', $contact, 4);
         foreach ($elements as $el) {
             $el = trim($el);
             // Detect e-mail address.
             if (false !== strpos($el, '@')) {
                 $data['contact_email'] = $el;
             } elseif (false !== strpos($el, '://')) {
                 $data['contact_url'] = $el;
             } elseif (preg_match('/\\d/', $el)) {
                 $data['contact_phone'] = $el;
             } else {
                 $data['contact_name'] = $el;
             }
         }
         if (!isset($data['contact_name']) || !$data['contact_name']) {
             // If no contact name, default to organizer property.
             $data['contact_name'] = $organizer;
         }
         // Store yet-unsaved values to the $data array.
         $data += array('recurrence_rules' => $rrule, 'exception_rules' => $exrule, 'recurrence_dates' => $rdate, 'exception_dates' => $exdate, 'venue' => $venue, 'address' => $address, 'cost' => $cost, 'ticket_url' => $ticket_url, 'show_map' => $do_show_map, 'ical_feed_url' => $feed->feed_url, 'ical_source_url' => $e->getProperty('url'), 'ical_organizer' => $organizer, 'ical_contact' => $contact, 'ical_uid' => $e->getProperty('uid'), 'categories' => array_keys($imported_cat), 'tags' => array_keys($imported_tags), 'feed' => $feed, 'post' => array('post_status' => 'publish', 'comment_status' => $comment_status, 'post_type' => AI1EC_POST_TYPE, 'post_author' => 1, 'post_title' => $e->getProperty('summary'), 'post_content' => stripslashes(str_replace('\\n', "\n", $e->getProperty('description')))));
         // Create event object.
         $event = new Ai1ec_Event($data);
         // TODO: when singular events change their times in an ICS feed from one
         // import to another, the matching_event_id is null, which is wrong. We
         // want to match that event that previously had a different time.
         // However, we also want the function to NOT return a matching event in
         // the case of recurring events, and different events with different
         // RECURRENCE-IDs... ponder how to solve this.. may require saving the
         // RECURRENCE-ID as another field in the database.
         $matching_event_id = $ai1ec_events_helper->get_matching_event_id($event->ical_uid, $event->ical_feed_url, $event->start, !empty($event->recurrence_rules));
         if (NULL === $matching_event_id) {
             // =================================================
             // = Event was not found, so store it and the post =
             // =================================================
             $event->save();
         } else {
             // ======================================================
             // = Event was found, let's store the new event details =
             // ======================================================
             // Update the post
             $post = get_post($matching_event_id);
             $post->post_title = $event->post->post_title;
             $post->post_content = $event->post->post_content;
             wp_update_post($post);
             // Update the event
             $event->post_id = $matching_event_id;
             $event->post = $post;
             $event->save(true);
             // Delete event's cache
             $ai1ec_events_helper->delete_event_cache($matching_event_id);
         }
         // Regenerate event's cache
         $ai1ec_events_helper->cache_event($event);
         $count++;
     }
     return $count;
 }
Example #27
0
 /**
  * Simple regex-parse of post_content for matches of <img src="foo" />; if
  * one is found, return its URL.
  *
  * @param   null       $size           (width, height) array of returned image
  *
  * @return  string|null
  */
 public function get_content_img_url(Ai1ec_Event $event, &$size = null)
 {
     preg_match('/<img([^>]+)src=["\']?([^"\'\\ >]+)([^>]*)>/i', $event->get('post')->post_content, $matches);
     // Check if we have a result, otherwise a notice is issued.
     if (empty($matches)) {
         return null;
     }
     $url = $matches[2];
     $size = array(0, 0);
     // Try to detect width and height.
     $attrs = $matches[1] . $matches[3];
     $matches = null;
     preg_match_all('/(width|height)=["\']?(\\d+)/i', $attrs, $matches, PREG_SET_ORDER);
     // Check if we have a result, otherwise a notice is issued.
     if (!empty($matches)) {
         foreach ($matches as $match) {
             $size[$match[1] === 'width' ? 0 : 1] = $match[2];
         }
     }
     return $url;
 }
 /**
  * import_the_events_calendar function
  *
  * Import events from The Events Calendar into Ai1ec.
  *
  * @return void
  **/
 function import_the_events_calendar()
 {
     global $ai1ec_view_helper, $ai1ec_events_helper;
     $args = array('post_type' => 'post', 'numberposts' => -1, 'meta_key' => '_isEvent', 'meta_value' => 'yes');
     $posts = get_posts($args);
     $imported_events = 0;
     foreach ($posts as $post) {
         $event = new Ai1ec_Event(null);
         $postmeta = get_post_custom($post->ID);
         // Need this to offset dates coming from The Events Calendar
         $gm_diff = mktime(0) - gmmktime(0);
         $event->allday = $postmeta['_EventAllDay'][0] == 'yes' || $postmeta['_EventAllDay'][0] == 1;
         $event->start = strtotime($postmeta['_EventStartDate'][0]) - $gm_diff;
         $event->end = strtotime($postmeta['_EventEndDate'][0]) - $gm_diff;
         // If all-day event, align start/end to start/end of day
         if ($event->allday) {
             $event->start = $ai1ec_events_helper->gmgetdate($event->start);
             $event->start = gmmktime(0, 0, 0, $event->start['mon'], $event->start['mday'], $event->start['year']);
             $event->end = $ai1ec_events_helper->gmgetdate($event->end);
             $event->end = gmmktime(0, 0, 0, $event->end['mon'], $event->end['mday'], $event->end['year']);
         }
         // Finally, convert to GMT storage format
         $event->start = $ai1ec_events_helper->local_to_gmt($event->start);
         $event->end = $ai1ec_events_helper->local_to_gmt($event->end);
         // Bug in The Events Calendar where some all-day events start and end at the same time
         if ($event->allday && $event->end - $event->start < 24 * 60 * 60) {
             $event->end = $event->start + 24 * 60 * 60;
         }
         $event->venue = $postmeta['_EventVenue'][0];
         $event->country = $postmeta['_EventCountry'][0];
         $event->city = $postmeta['_EventCity'][0];
         $event->province = $postmeta['_EventState'][0];
         $event->postal_code = $postmeta['_EventZip'][0];
         $event->address = array();
         if ($postmeta['$_EventAddress']) {
             $event->address[] = $postmeta['$_EventAddress'];
         }
         if ($event->city) {
             $event->address[] = $event->city;
         }
         if ($event->province) {
             $event->address[] = $event->province;
         }
         if ($event->postal_code) {
             $event->address[] = $event->postal_code;
         }
         if ($event->country) {
             $event->address[] = $event->country;
         }
         $event->address = join(', ', $event->address);
         $event->show_map = $postmeta['_EventShowMapLink'][0] == 'true' || $postmeta['_EventShowMap'][0] == 'true';
         $event->cost = $postmeta['_EventCost'][0];
         $event->contact_phone = $postmeta['_EventPhone'][0];
         $event->post = get_object_vars($post);
         $event->post["post_type"] = AI1EC_POST_TYPE;
         unset($event->post["ID"]);
         // Transfer post categories => event categories, post tags => event tags
         $terms = wp_get_post_terms($post->ID, array('category', 'post_tag'));
         $event->categories = array();
         $event->tags = array();
         foreach ($terms as $term) {
             switch ($term->taxonomy) {
                 case 'category':
                     // Ignore special "Events" category by The Events Calendar
                     if ($term->name == 'Events') {
                         break;
                     }
                     // Need to find out the category ID, if it exists.
                     $event_term = get_term_by('name', $term->name, 'events_categories');
                     // If no category exists, create it.
                     if ($event_term === false) {
                         $event_term = (object) wp_insert_term($term->name, 'events_categories', array('description' => $term->description, 'slug' => $term->slug));
                     }
                     $event->categories[] = $event_term->term_id;
                     break;
                 case 'post_tag':
                     // For some reason tag-like taxonomies are treated differently; term
                     // IDs cannot be used; instead the actual term name must be appended
                     $event->tags[] = $term->name;
                     break;
             }
         }
         $post_id = $event->save();
         $ai1ec_events_helper->cache_event($event, $post_id);
         $imported_events++;
     }
     $ai1ec_view_helper->display_admin("import.php", array('imported_events' => $imported_events));
 }
Example #29
0
 /**
  * Get the html for the exclude dates and exception rules.
  *
  * @param Ai1ec_Event $event
  * @param Ai1ec_Recurrence_Rule $rrule
  * @return string
  */
 public function get_exclude_html(Ai1ec_Event $event, Ai1ec_Recurrence_Rule $rrule)
 {
     $excludes = array();
     $exception_rules = $event->get('exception_rules');
     $exception_dates = $event->get('exception_dates');
     if ($exception_rules) {
         $excludes[] = $rrule->rrule_to_text($exception_rules);
     }
     if ($exception_dates && 0 !== strpos($exception_rules, 'EXDATE')) {
         $excludes[] = $rrule->exdate_to_text($exception_dates);
     }
     return implode(Ai1ec_I18n::__(', and '), $excludes);
 }
 /**
  * Generate and store instance entries in database for given event.
  *
  * @param Ai1ec_Event $event Instance of event to create entries for.
  *
  * @return bool Success.
  */
 public function create(Ai1ec_Event $event)
 {
     $evs = array();
     $e = array('post_id' => $event->get('post_id'), 'start' => $event->get('start')->format_to_gmt(), 'end' => $event->get('end')->format_to_gmt());
     $duration = $event->get('end')->diff_sec($event->get('start'));
     // Timestamp of today date + 3 years (94608000 seconds)
     $tif = $this->_registry->get('date.system')->current_time(true) + 94608000;
     // Always cache initial instance
     $evs[] = $e;
     $_start = $event->get('start')->format_to_gmt();
     $_end = $event->get('end')->format_to_gmt();
     if ($event->get('recurrence_rules')) {
         $_restore_default_tz = date_default_timezone_get();
         $start_timezone = $event->get('start')->get_timezone();
         date_default_timezone_set($start_timezone);
         $evs = array_merge($evs, $this->create_instances_by_recurrence($event, $e, $_start, $tif, $duration, $start_timezone));
         date_default_timezone_set($_restore_default_tz);
         unset($_restore_default_tz);
     }
     // Make entries unique (sometimes recurrence generator creates duplicates?)
     $evs_unique = array();
     foreach ($evs as $ev) {
         $evs_unique[md5(serialize($ev))] = $ev;
     }
     $search_helper = $this->_registry->get('model.search');
     foreach ($evs_unique as $e) {
         // Find out if this event instance is already accounted for by an
         // overriding 'RECURRENCE-ID' of the same iCalendar feed (by comparing the
         // UID, start date, recurrence). If so, then do not create duplicate
         // instance of event.
         $start = $e['start'];
         $matching_event_id = null;
         if ($event->get('ical_uid')) {
             $matching_event_id = $search_helper->get_matching_event_id($event->get('ical_uid'), $event->get('ical_feed_url'), $event->get('start'), false, $event->get('post_id'));
         }
         // If no other instance was found
         if (null === $matching_event_id) {
             $this->_dbi->insert('ai1ec_event_instances', $e, array('%d', '%d', '%d'));
         }
     }
     return true;
 }