Example #1
0
/**
 * Detect calendar matches in a time period, in user-time.
 *
 * @param  MEMBER			The member to detect conflicts for
 * @param  boolean		Whether to restrict only to viewable events for the current member
 * @param  ?TIME			The timestamp that found times must exceed. In user-time (NULL: use find_periods_recurrence default)
 * @param  ?TIME			The timestamp that found times must not exceed. In user-time (NULL: use find_periods_recurrence default)
 * @param  ?array			The type filter (NULL: none)
 * @param  boolean		Whether to include RSS events in the results
 * @return array			A list of events happening, with time details
 */
function calendar_matches($member_id, $restrict, $period_start, $period_end, $filter = NULL, $do_rss = true)
{
    if (is_null($period_start)) {
        $period_start = utctime_to_usertime(time());
    }
    if (is_null($period_end)) {
        $period_end = utctime_to_usertime(time() + 60 * 60 * 24 * 360 * 20);
    }
    $matches = array();
    $where = '';
    if ($restrict) {
        if ($where != '') {
            $where .= ' AND ';
        }
        $where .= '(e_submitter=' . strval((int) $member_id) . ' OR e_is_public=1)';
    }
    if (!is_null($filter)) {
        foreach ($filter as $a => $b) {
            if ($b == 0) {
                if ($where != '') {
                    $where .= ' AND ';
                }
                $where .= 'e_type<>' . strval((int) substr($a, 4));
            }
        }
    }
    if ($where != '') {
        $where .= ' AND ';
    }
    $where .= '(validated=1 OR e_is_public=0)';
    if (addon_installed('syndication_blocks')) {
        // Determine what feeds to overlay
        $feed_urls_todo = array();
        for ($i = 0; $i < 10; $i++) {
            $feed_url = post_param('feed_' . strval($i), ocp_admirecookie('feed_' . strval($i), ''));
            require_code('users_active_actions');
            ocp_setcookie('feed_' . strval($i), $feed_url);
            if ($feed_url != '' && preg_match('#^[\\w\\d\\-\\_]*$#', $feed_url) == 0) {
                $feed_urls_todo[$feed_url] = NULL;
            }
        }
        $_event_types = list_to_map('id', $GLOBALS['SITE_DB']->query_select('calendar_types', array('id', 't_title', 't_logo', 't_external_feed')));
        foreach ($_event_types as $j => $_event_type) {
            if ($_event_type['t_external_feed'] != '' && (is_null($filter) || !array_key_exists($_event_type['id'], $filter) || $filter[$_event_type['id']] == 1) && has_category_access(get_member(), 'calendar', strval($_event_type['id']))) {
                $feed_urls_todo[$_event_type['t_external_feed']] = $_event_type['id'];
            }
            $_event_types[$j]['text_original'] = get_translated_text($_event_type['t_title']);
        }
        $event_types = collapse_2d_complexity('text_original', 't_logo', $_event_types);
        // Overlay it
        foreach ($feed_urls_todo as $feed_url => $event_type) {
            $temp_file_path = ocp_tempnam('feed');
            require_code('files');
            $write_to_file = fopen($temp_file_path, 'wb');
            http_download_file($feed_url, 1024 * 512, false, false, 'ocPortal', NULL, NULL, NULL, NULL, NULL, $write_to_file);
            if ($GLOBALS['HTTP_DOWNLOAD_MIME_TYPE'] == 'text/calendar' || $GLOBALS['HTTP_DOWNLOAD_MIME_TYPE'] == 'application/octet-stream') {
                $data = file_get_contents($temp_file_path);
                require_code('calendar_ical');
                $whole = end(explode('BEGIN:VCALENDAR', $data));
                $events = explode('BEGIN:VEVENT', $whole);
                $calendar_nodes = array();
                foreach ($events as $key => $items) {
                    $items = preg_replace('#(.+)\\n +(.*)\\n#', '${1}${2}' . "\n", $items);
                    // Merge split lines
                    $nodes = explode("\n", $items);
                    foreach ($nodes as $_child) {
                        if (strpos($_child, ':') === false) {
                            continue;
                        }
                        $child = array('', '');
                        $in_quotes = false;
                        $j = 0;
                        for ($i = 0; $i < strlen($_child); $i++) {
                            $char = $_child[$i];
                            if ($char == '"') {
                                $in_quotes = !$in_quotes;
                            }
                            if ($j != 1 && !$in_quotes && $char == ':') {
                                $j++;
                            } else {
                                $child[$j] .= $char;
                            }
                        }
                        $matches2 = array();
                        if (preg_match('#;TZID=(.*)#', $child[0], $matches2)) {
                            $calendar_nodes[$key]['TZID'] = $matches2[1];
                        }
                        $child[0] = preg_replace('#;.*#', '', $child[0]);
                        if (array_key_exists("1", $child) && $child[0] !== 'PRODID' && $child[0] !== 'VERSION' && $child[0] !== 'END') {
                            $calendar_nodes[$key][$child[0]] = str_replace(array('\\n', '\\,'), array("\n", ','), trim($child[1]));
                        }
                    }
                    if ($key != 0) {
                        list($full_url, $type_id, $type, $recurrence, $recurrences, $seg_recurrences, $title, $content, $priority, $is_public, $start_year, $start_month, $start_day, $start_hour, $start_minute, $end_year, $end_month, $end_day, $end_hour, $end_minute, $timezone, $validated, $allow_rating, $allow_comments, $allow_trackbacks, $notes) = get_event_data_ical($calendar_nodes[$key]);
                        $is_public = 1;
                        $event = array('e_recurrence' => $recurrence, 'e_content' => $content, 'e_title' => $title, 'e_id' => $feed_url, 'e_priority' => $priority, 't_logo' => 'calendar/rss', 'e_recurrences' => $recurrences, 'e_seg_recurrences' => $seg_recurrences, 'e_is_public' => $is_public, 'e_start_year' => $start_year, 'e_start_month' => $start_month, 'e_start_day' => $start_day, 'e_start_hour' => $start_hour, 'e_start_minute' => $start_minute, 'e_end_year' => $end_year, 'e_end_month' => $end_month, 'e_end_day' => $end_day, 'e_end_hour' => $end_hour, 'e_end_minute' => $end_minute, 'e_timezone' => $timezone);
                        if (!is_null($event_type)) {
                            $event['t_logo'] = $_event_types[$event_type]['t_logo'];
                        }
                        if (!is_null($type)) {
                            $event['t_title'] = $type;
                            if (array_key_exists($type, $event_types)) {
                                $event['t_logo'] = $event_types[$type];
                            }
                        }
                        $their_times = find_periods_recurrence($timezone, 0, $start_year, $start_month, $start_day, $start_hour, $start_minute, $end_year, $end_month, $end_day, $end_hour, $end_minute, $recurrence, $recurrences, $period_start, $period_end);
                        // Now search every combination to see if we can get a hit
                        foreach ($their_times as $their) {
                            $matches[] = array($full_url, $event, $their[0], $their[1], $their[2], $their[3], $their[4], $their[5]);
                        }
                    }
                }
            } else {
                require_code('rss');
                $rss = new rss($temp_file_path, true);
                $content = new ocp_tempcode();
                foreach ($rss->gleamed_items as $item) {
                    if (array_key_exists('guid', $item)) {
                        $full_url = $item['guid'];
                    } elseif (array_key_exists('comment_url', $item)) {
                        $full_url = $item['comment_url'];
                    } elseif (array_key_exists('full_url', $item)) {
                        $full_url = $item['full_url'];
                    } else {
                        $full_url = '';
                    }
                    if (array_key_exists('title', $item) && array_key_exists('clean_add_date', $item) && $full_url != '') {
                        $event = array('e_recurrence' => 'none', 'e_content' => array_key_exists('news', $item) ? $item['news'] : '', 'e_title' => $item['title'], 'e_id' => $full_url, 'e_priority' => 'na', 't_logo' => 'calendar/rss', 'e_recurrences' => 1, 'e_seg_recurrences' => '', 'e_is_public' => 1, 'e_timezone' => get_users_timezone());
                        if (!is_null($event_type)) {
                            $event['t_logo'] = $_event_types[$event_type]['t_logo'];
                        }
                        if (array_key_exists('category', $item)) {
                            $event['t_title'] = $item['category'];
                            if (array_key_exists($item['category'], $event_types)) {
                                $event['t_logo'] = $event_types[$item['category']];
                            }
                        }
                        $from = utctime_to_usertime($item['clean_add_date']);
                        if ($from >= $period_start && $from < $period_end) {
                            $event += array('e_start_year' => date('Y', $from), 'e_start_month' => date('m', $from), 'e_start_day' => date('D', $from), 'e_start_hour' => date('H', $from), 'e_start_minute' => date('i', $from), 'e_end_year' => NULL, 'e_end_month' => NULL, 'e_end_day' => NULL, 'e_end_hour' => NULL, 'e_end_minute' => NULL);
                            $matches[] = array($full_url, $event, $from, NULL, $from, NULL, $from, NULL);
                        }
                    }
                }
            }
            @unlink($temp_file_path);
        }
    }
    if ($where != '') {
        $where .= ' AND ';
    }
    $where .= '(((e_start_month>=' . strval(intval(date('m', $period_start)) - 1) . ' AND e_start_year=' . date('Y', $period_start) . ' OR e_start_year>' . date('Y', $period_start) . ') AND (e_start_month<=' . strval(intval(date('m', $period_end)) + 1) . ' AND e_start_year=' . date('Y', $period_end) . ' OR e_start_year<' . date('Y', $period_end) . ')) OR ' . db_string_not_equal_to('e_recurrence', 'none') . ')';
    $where = ' WHERE ' . $where;
    $event_count = $GLOBALS['SITE_DB']->query_value_null_ok_full('SELECT COUNT(*) FROM ' . $GLOBALS['SITE_DB']->get_table_prefix() . 'calendar_events e LEFT JOIN ' . $GLOBALS['SITE_DB']->get_table_prefix() . 'calendar_types t ON e.e_type=t.id' . $where);
    if ($event_count > 2000) {
        attach_message(do_lang_tempcode('TOO_MANY_TO_CHOOSE_FROM'), 'inform');
        return array();
    }
    $events = $GLOBALS['SITE_DB']->query('SELECT *,e.id AS e_id FROM ' . $GLOBALS['SITE_DB']->get_table_prefix() . 'calendar_events e LEFT JOIN ' . $GLOBALS['SITE_DB']->get_table_prefix() . 'calendar_types t ON e.e_type=t.id' . $where);
    foreach ($events as $event) {
        if (!has_category_access(get_member(), 'calendar', strval($event['e_type']))) {
            continue;
        }
        $their_times = find_periods_recurrence($event['e_timezone'], $event['e_do_timezone_conv'], $event['e_start_year'], $event['e_start_month'], $event['e_start_day'], $event['e_start_hour'], $event['e_start_minute'], $event['e_end_year'], $event['e_end_month'], $event['e_end_day'], $event['e_end_hour'], $event['e_end_minute'], $event['e_recurrence'], $event['e_recurrences'], $period_start, $period_end);
        // Now search every combination to see if we can get a hit
        foreach ($their_times as $their) {
            $matches[] = array($event['e_id'], $event, $their[0], $their[1], $their[2], $their[3], $their[4], $their[5]);
        }
    }
    global $M_SORT_KEY;
    $M_SORT_KEY = 2;
    usort($matches, 'multi_sort');
    return $matches;
}
Example #2
0
/**
 * Import ical events to members's event calendar.
 *
 * @param  PATH		File path
*/
function ical_import($file_name)
{
    $data = unixify_line_format(file_get_contents($file_name));
    $whole = end(explode('BEGIN:VCALENDAR', $data));
    $events = explode('BEGIN:VEVENT', $whole);
    $calendar_nodes = array();
    foreach ($events as $key => $items) {
        $items = preg_replace('#(.+)\\n +(.*)\\n#', '${1}${2}' . "\n", $items);
        // Merge split lines
        $nodes = explode("\n", $items);
        foreach ($nodes as $_child) {
            if (strpos($_child, ':') === false) {
                continue;
            }
            $child = array('', '');
            $in_quotes = false;
            $j = 0;
            for ($i = 0; $i < strlen($_child); $i++) {
                $char = $_child[$i];
                if ($char == '"') {
                    $in_quotes = !$in_quotes;
                }
                if ($j != 1 && !$in_quotes && $char == ':') {
                    $j++;
                } else {
                    $child[$j] .= $char;
                }
            }
            $matches = array();
            if (preg_match('#;TZID=(.*)#', $child[0], $matches)) {
                $calendar_nodes[$key]['TZID'] = $matches[1];
            }
            $child[0] = preg_replace('#;.*#', '', $child[0]);
            if (array_key_exists(1, $child) && $child[0] !== 'PRODID' && $child[0] !== 'VERSION' && $child[0] !== 'END') {
                $calendar_nodes[$key][$child[0]] = trim($child[1]);
            }
        }
        if ($key != 0) {
            list(, $type_id, $type, $recurrence, $recurrences, $seg_recurrences, $title, $content, $priority, $is_public, $start_year, $start_month, $start_day, $start_hour, $start_minute, $end_year, $end_month, $end_day, $end_hour, $end_minute, $timezone, $validated, $allow_rating, $allow_comments, $allow_trackbacks, $notes) = get_event_data_ical($calendar_nodes[$key]);
            if (is_null($type_id)) {
                require_code('calendar2');
                $type_id = add_event_type(ucfirst($type), 'calendar/general');
            }
            $id = add_calendar_event($type, $recurrence, $recurrences, $seg_recurrences, $title, $content, $priority, $is_public, $start_year, $start_month, $start_day, $start_hour, $start_minute, $end_year, $end_month, $end_day, $end_hour, $end_minute, $timezone, 1, $validated, $allow_rating, $allow_comments, $allow_trackbacks, $notes);
        }
    }
}