/** * get_matching_events function * * Get events that match with the arguments provided. * * @param int | bool $start Events start before this (GMT) time * @param int | bool $end Events end before this (GMT) time * @param array $filter Array of filters for the events returned. * ['cat_ids'] => non-associatative array of category IDs * ['tag_ids'] => non-associatative array of tag IDs * ['post_ids'] => non-associatative array of post IDs * * @return array Matching events #' **/ function get_matching_events($start = false, $end = false, $filter = array()) { global $wpdb, $ai1ec_calendar_helper, $ai1ec_localization_helper; // holds event_categories sql $c_sql = ''; $c_where_sql = ''; // holds event_tags sql $t_sql = ''; $t_where_sql = ''; // holds posts sql $p_where_sql = ''; // holds start sql $start_where_sql = ''; // holds end sql $end_where_sql = ''; // hold escape values $args = array(); // ============================= // = Generating start date sql = // ============================= if ($start !== false) { $start_where_sql = "AND (e.start >= %s OR e.recurrence_rules != '')"; $args[] = Ai1ec_Time_Utility::to_mysql_date($start); } // =========================== // = Generating end date sql = // =========================== if ($end !== false) { $end_where_sql = "AND (e.end <= %s OR e.recurrence_rules != '')"; $args[] = Ai1ec_Time_Utility::to_mysql_date($end); } $wpml_join_particle = $ai1ec_localization_helper->get_wpml_table_join(); $wpml_where_particle = $ai1ec_localization_helper->get_wpml_table_where(); // Get the Join (filter_join) and Where (filter_where) statements based on $filter elements specified $ai1ec_calendar_helper->_get_filter_sql($filter); $query = $wpdb->prepare("SELECT *, e.post_id, e.start as start, e.end as end, e.allday, e.recurrence_rules, e.exception_rules,\n\t\t\t\te.recurrence_dates, e.exception_dates, e.venue, e.country, e.address, e.city, e.province, e.postal_code,\n\t\t\t\te.show_map, e.contact_name, e.contact_phone, e.contact_email, e.cost, e.ical_feed_url, e.ical_source_url,\n\t\t\t\te.ical_organizer, e.ical_contact, e.ical_uid " . "FROM {$wpdb->posts} " . "INNER JOIN {$wpdb->prefix}ai1ec_events AS e ON e.post_id = ID " . $wpml_join_particle . $filter['filter_join'] . "WHERE post_type = '" . AI1EC_POST_TYPE . "' " . "AND post_status = 'publish' " . $wpml_where_particle . $filter['filter_where'] . $start_where_sql . $end_where_sql, $args); $events = $wpdb->get_results($query, ARRAY_A); foreach ($events as &$event) { $event['start'] = Ai1ec_Time_Utility::from_mysql_date($event['start']); $event['end'] = Ai1ec_Time_Utility::from_mysql_date($event['end']); try { $event = new Ai1ec_Event($event); } catch (Ai1ec_Event_Not_Found $n) { unset($event); // The event is not found, continue to the next event continue; } // if there are recurrence rules, include the event, else... if (empty($event->recurrence_rules)) { // if start time is set, and event start time is before the range // it, continue to the next event if ($start !== false && $event->start < $start) { unset($event); continue; } // if end time is set, and event end time is after // it, continue to the next event if ($end !== false && $ev->end < $end) { unset($event); continue; } } } return $events; }
/** * save function * * Saves the current event data to the database. If $this->post_id exists, * but $update is false, creates a new record in the ai1ec_events table of * this event data, but does not try to create a new post. Else if $update * is true, updates existing event record. If $this->post_id is empty, * creates a new post AND record in the ai1ec_events table for this event. * * @param bool $update Whether to update an existing event or create a * new one * @return int The post_id of the new or existing event. **/ function save($update = false) { global $wpdb, $ai1ec_events_helper, $ai1ec_exporter_controller; // =========================== // = Insert events meta data = // =========================== // Set facebook user and eid to 0 if they are not set, otherwise they will be set to '' since we use %s for big ints $facebook_eid = isset($this->facebook_eid) ? $this->facebook_eid : 0; $facebook_user = isset($this->facebook_user) ? $this->facebook_user : 0; $columns = array('post_id' => $this->post_id, 'start' => Ai1ec_Time_Utility::to_mysql_date($this->start), 'end' => Ai1ec_Time_Utility::to_mysql_date($this->end), 'allday' => $this->allday, 'instant_event' => $this->instant_event, 'recurrence_rules' => $this->recurrence_rules, 'exception_rules' => $this->exception_rules, 'recurrence_dates' => $this->recurrence_dates, 'exception_dates' => $this->exception_dates, 'venue' => $this->venue, 'country' => $this->country, 'address' => $this->address, 'city' => $this->city, 'province' => $this->province, 'postal_code' => $this->postal_code, 'show_map' => $this->show_map, 'contact_name' => $this->contact_name, 'contact_phone' => $this->contact_phone, 'contact_email' => $this->contact_email, 'contact_url' => $this->contact_url, 'cost' => $this->cost, 'ticket_url' => $this->ticket_url, 'ical_feed_url' => $this->ical_feed_url, 'ical_source_url' => $this->ical_source_url, 'ical_uid' => $this->ical_uid, 'show_coordinates' => $this->show_coordinates, 'latitude' => $this->latitude, 'longitude' => $this->longitude, 'facebook_eid' => $facebook_eid, 'facebook_user' => $facebook_user, 'facebook_status' => $this->facebook_status); $format = array('%d', '%s', '%s', '%d', '%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%d', '%f', '%f', '%s', '%s', '%s'); $table_name = $wpdb->prefix . 'ai1ec_events'; if ($this->post_id) { if (!$update) { // ========================= // = Insert new event data = // ========================= $wpdb->query($wpdb->prepare("INSERT INTO {$table_name} ( " . join(', ', array_keys($columns)) . " ) VALUES ( " . join(', ', $format) . " )", $columns)); $ai1ec_exporter_controller->export_location($columns, false); } else { // ============================== // = Update existing event data = // ============================== $where = array('post_id' => $this->post_id); $where_escape = array('%d'); $wpdb->update($table_name, $columns, $where, $format, $where_escape); $ai1ec_exporter_controller->export_location($columns, true); } } else { // =================== // = Insert new post = // =================== $this->post_id = wp_insert_post($this->post); $columns['post_id'] = $this->post_id; wp_set_post_terms($this->post_id, $this->categories, 'events_categories'); wp_set_post_terms($this->post_id, $this->tags, 'events_tags'); if (isset($this->feed) && isset($this->feed->feed_id)) { $feed_name = $this->feed->feed_url; // If the feed is not from an imported file, parse the url. if (!isset($this->feed->feed_imported_file)) { $url_components = parse_url($this->feed->feed_url); $feed_name = $url_components["host"]; } $term = term_exists($feed_name, 'events_feeds'); if (!$term) { // term doesn't exist, create it $term = wp_insert_term($feed_name, 'events_feeds', array('description' => $this->feed->feed_url)); } // term_exists returns object, wp_insert_term returns array $term = (object) $term; if (isset($term->term_id)) { // associate the event with the feed only if we have term id set $a = wp_set_object_terms($this->post_id, (int) $term->term_id, 'events_feeds', false); } } // ========================= // = Insert new event data = // ========================= $wpdb->query($wpdb->prepare("INSERT INTO {$table_name} ( " . join(', ', array_keys($columns)) . " ) VALUES ( " . join(', ', $format) . " )", $columns)); $ai1ec_exporter_controller->export_location($columns, false); } return $this->post_id; }
/** * get_events_relative_to function * * Return all events starting after the given reference time, limiting the * result set to a maximum of $limit items, offset by $page_offset. A * negative $page_offset can be provided, which will return events *before* * the reference time, as expected. * * @param int $time limit to events starting after this (local) UNIX time * @param int $limit return a maximum of this number of items * @param int $page_offset offset the result set by $limit times this number * @param array $filter Array of filters for the events returned. * ['cat_ids'] => non-associatative array of category IDs * ['tag_ids'] => non-associatative array of tag IDs * ['post_ids'] => non-associatative array of post IDs * @param int $last_day Last day (time), that was displayed. * NOTE FROM NICOLA: be careful, if you want a query with events * that have a start date which is greater than today, pass 0 as * this parameter. If you pass false ( or pass nothing ) you end up with a query * with events that finish before today. I don't know the rationale * behind this but that's how it works * * @return array five-element array: * ['events'] an array of matching event objects * ['prev'] true if more previous events * ['next'] true if more next events * ['date_first'] UNIX timestamp (date part) of first event * ['date_last'] UNIX timestamp (date part) of last event */ function get_events_relative_to($time, $limit = 0, $page_offset = 0, $filter = array(), $last_day = false) { global $wpdb, $ai1ec_events_helper, $ai1ec_localization_helper, $ai1ec_settings; // Figure out what the beginning of the day is to properly query all-day // events; then convert to GMT time $bits = $ai1ec_events_helper->gmgetdate($time); // Even if there ARE more than 5 times the limit results - we shall not // try to fetch and display these, as it would crash system $upper_boundary = $limit; if ($ai1ec_settings->agenda_include_entire_last_day && false !== $last_day) { $upper_boundary *= 5; } // Convert timestamp to GMT time $time = $ai1ec_events_helper->local_to_gmt($time); // Query arguments $args = array(Ai1ec_Time_Utility::to_mysql_date($time)); if ($page_offset >= 0) { $first_record = $page_offset * $limit; } else { $first_record = (-$page_offset - 1) * $limit; } // Get post status Where snippet and associated SQL arguments $this->_get_post_status_sql($post_status_where, $args); // Get the Join (filter_join) and Where (filter_where) statements based on // $filter elements specified $this->_get_filter_sql($filter); $wpml_join_particle = $ai1ec_localization_helper->get_wpml_table_join('p.ID'); $wpml_where_particle = $ai1ec_localization_helper->get_wpml_table_where(); $filter_date_clause = $page_offset >= 0 ? 'i.end >= %s ' : 'i.start < %s '; $order_direction = $page_offset >= 0 ? 'ASC' : 'DESC'; if (false !== $last_day) { if (0 == $last_day) { $last_day = (int) $_SERVER['REQUEST_TIME']; } $filter_date_clause = ' i.start '; if ($page_offset < 0) { $filter_date_clause .= '<'; $order_direction = 'DESC'; } else { $filter_date_clause .= '>'; $order_direction = 'ASC'; } $filter_date_clause .= ' %s '; $args[0] = Ai1ec_Time_Utility::to_mysql_date($last_day); $first_record = 0; } $query = $wpdb->prepare('SELECT DISTINCT SQL_CALC_FOUND_ROWS p.*, e.post_id, i.id AS instance_id, ' . 'i.start AS start, ' . 'i.end AS end, ' . 'IF( e.allday, e.allday, i.end = DATE_ADD( i.start, INTERVAL 1 DAY ) ) AS allday, ' . 'e.recurrence_rules, e.exception_rules, e.instant_event, e.recurrence_dates, e.exception_dates, ' . 'e.venue, e.country, e.address, e.city, e.province, e.postal_code, ' . 'e.show_map, e.contact_name, e.contact_phone, e.contact_email, e.cost, ' . 'e.ical_feed_url, e.ical_source_url, e.ical_organizer, e.ical_contact, e.ical_uid ' . 'FROM ' . $wpdb->prefix . 'ai1ec_events e ' . 'INNER JOIN ' . $wpdb->posts . ' p ON e.post_id = p.ID ' . $wpml_join_particle . 'INNER JOIN ' . $wpdb->prefix . 'ai1ec_event_instances i ON e.post_id = i.post_id ' . $filter['filter_join'] . "WHERE post_type = '" . AI1EC_POST_TYPE . "' " . 'AND ' . $filter_date_clause . $wpml_where_particle . $filter['filter_where'] . $post_status_where . 'ORDER BY i.start ' . $order_direction . ', post_title ' . $order_direction . ' LIMIT ' . $first_record . ', ' . $upper_boundary, $args); $events = $wpdb->get_results($query, ARRAY_A); // Limit the number of records to convert to data-object $events = $this->_limit_result_set($events, $limit, false !== $last_day); // Reorder records if in negative page offset if ($page_offset < 0) { $events = array_reverse($events); } $date_first = $date_last = NULL; foreach ($events as &$event) { $event['start'] = Ai1ec_Time_Utility::from_mysql_date($event['start']); $event['end'] = Ai1ec_Time_Utility::from_mysql_date($event['end']); if (NULL === $date_first) { $date_first = $event['start']; } $date_last = $event['start']; $event = new Ai1ec_Event($event); } // Find out if there are more records in the current nav direction $more = $wpdb->get_var('SELECT FOUND_ROWS()') > $first_record + $limit; // Navigating in the future if ($page_offset > 0) { $prev = true; $next = $more; } elseif ($page_offset < 0) { $prev = $more; $next = true; } else { $query = $wpdb->prepare("SELECT COUNT(*) " . "FROM {$wpdb->prefix}ai1ec_events e " . "INNER JOIN {$wpdb->prefix}ai1ec_event_instances i ON e.post_id = i.post_id " . "INNER JOIN {$wpdb->posts} p ON e.post_id = p.ID " . $wpml_join_particle . $filter['filter_join'] . "WHERE post_type = '" . AI1EC_POST_TYPE . "' " . "AND i.start < %s " . $wpml_where_particle . $filter['filter_where'] . $post_status_where, $args); $prev = $wpdb->get_var($query); $next = $more; } return array('events' => $events, 'prev' => $prev, 'next' => $next, 'date_first' => $date_first, 'date_last' => $date_last); }