Example #1
0
/**
 * Show bookings ical feed (NB: the event type for this is admins only, unless edited).
 */
function bookings_ical_script()
{
    $pass_ok = get_param('pass', '') == md5('booking_salt_' . $GLOBALS['SITE_INFO']['admin_password']);
    if (!$pass_ok && !$GLOBALS['FORUM_DRIVER']->is_super_admin(get_member())) {
        access_denied('I_ERROR');
    }
    require_code('calendar_ical');
    require_code('booking');
    @ini_set('ocproducts.xss_detect', '0');
    if ($pass_ok) {
        header('Content-Type: text/calendar');
        header('Content-Disposition: filename="bookings_export.ics"');
    }
    // If not, it's an admin testing, so just display contents
    if (function_exists('set_time_limit')) {
        @set_time_limit(0);
    }
    $time = get_param_integer('from', time());
    if ($time < 0) {
        $time = time() + 60 * 60 * 24 * $time;
    }
    require_lang('booking');
    $id = get_param_integer('id');
    $where = 'bookable_id=' . strval($id) . ' AND (b_year>' . date('Y', $time) . ' OR (b_year=' . date('Y', $time) . ' AND b_month>' . date('m', $time) . ') OR (b_year=' . date('Y', $time) . ' AND b_month=' . date('m', $time) . ' AND b_day>=' . date('d', $time) . '))';
    $members_with_bookings = $GLOBALS['SITE_DB']->query('SELECT DISTINCT member_id FROM ' . get_table_prefix() . 'booking WHERE ' . $where . ' ORDER BY booked_at DESC', 10000);
    echo "BEGIN:VCALENDAR\n";
    echo "VERSION:2.0\n";
    echo "PRODID:-//ocProducts/ocPortal//NONSGML v1.0//EN\n";
    echo "CALSCALE:GREGORIAN\n";
    $bookable_category = get_translated_text($GLOBALS['SITE_DB']->query_value('bookable', 'title', array('id' => $id)));
    echo "X-WR-CALNAME:" . ical_escape(get_site_name() . ': ' . do_lang('BOOKINGS') . ': ' . $bookable_category) . "\n";
    require_code('booking2');
    require_lang('booking');
    $max_time = time();
    foreach ($members_with_bookings as $member_with_booking) {
        $bookings = $GLOBALS['SITE_DB']->query('SELECT id FROM ' . get_table_prefix() . 'booking WHERE (' . $where . ') AND member_id=' . strval($member_with_booking['member_id']) . ' ORDER BY booked_at DESC', 10000);
        $request = get_booking_request_from_db(collapse_1d_complexity('id', $bookings));
        foreach ($request as $i => $r) {
            $booking = $r['_rows'][0];
            $codes = '';
            foreach ($r['_rows'] as $row) {
                if ($codes != '') {
                    $codes .= ', ';
                }
                $codes .= $row['code_allocation'];
            }
            $supplements = $GLOBALS['SITE_DB']->query_select('booking_supplement a JOIN ' . get_table_prefix() . 'bookable_supplement b ON a.supplement_id=b.id', array('quantity', 'notes', 'title'), array('booking_id' => $booking['id']));
            $_url = build_url(array('page' => 'cms_booking', 'type' => '_eb', 'id' => find_booking_under($booking['member_id'], $booking['id'])), get_module_zone('cms_booking'), NULL, false, false, true);
            $url = $_url->evaluate();
            $time_start = mktime(0, 0, 0, $r['start_month'], $r['start_day'], $r['start_year']);
            $time_end = mktime(0, 0, 0, $r['end_month'], $r['end_day'] + 1, $r['end_year']);
            if ($time_end > $max_time) {
                $max_time = $time_end;
            }
            $description = $booking['notes'];
            foreach ($supplements as $supplement) {
                $description .= "\n\n+ " . get_translated_text($supplement['title']) . 'x' . integer_format($supplement['quantity']);
                if ($supplement['notes'] != '') {
                    $description .= ' (' . $supplement['notes'] . ')';
                }
            }
            for ($j = 0; $j < $r['quantity']; $j++) {
                echo "BEGIN:VEVENT\n";
                echo "DTSTAMP:" . date('Ymd', $booking['booked_at']) . "T" . date('His', $booking['booked_at']) . "\n";
                echo "CREATED:" . date('Ymd', $booking['booked_at']) . "T" . date('His', $booking['booked_at']) . "\n";
                echo "SUMMARY:" . ical_escape($bookable_category) . "\n";
                echo "DESCRIPTION:" . ical_escape($description) . "\n";
                if (!is_guest($booking['member_id'])) {
                    echo "ORGANIZER;CN=" . ical_escape($GLOBALS['FORUM_DRIVER']->get_username($booking['member_id'])) . ";DIR=" . ical_escape($GLOBALS['FORUM_DRIVER']->member_profile_url($booking['member_id'])) . ":MAILTO:" . ical_escape($GLOBALS['FORUM_DRIVER']->get_member_email_address($booking['member_id'])) . "\n";
                }
                echo "CATEGORIES:" . ical_escape($bookable_category) . "\n";
                echo "CLASS:PRIVATE\n";
                echo "STATUS:" . ($booking['paid_at'] !== NULL ? 'CONFIRMED' : 'TENTATIVE') . "\n";
                echo "UID:" . ical_escape(strval($booking['id']) . '-booking@' . get_base_url()) . "\n";
                echo "URL:" . ical_escape($url) . "\n";
                echo "DTSTART:" . str_pad($r['start_year'], 4, '0', STR_PAD_LEFT) . str_pad($r['start_month'], 2, '0', STR_PAD_LEFT) . str_pad($r['start_day'], 2, '0', STR_PAD_LEFT) . "\n";
                echo "DTEND:" . str_pad($r['end_year'], 4, '0', STR_PAD_LEFT) . str_pad($r['end_month'], 2, '0', STR_PAD_LEFT) . str_pad($r['end_day'], 2, '0', STR_PAD_LEFT) . "\n";
                echo 'TZID:' . get_site_timezone() . "\n";
                echo "END:VEVENT\n";
            }
        }
    }
    // Show free slots
    if (get_param_integer('free', 0) == 1) {
        $codes_in_total = collapse_1d_complexity('code', $GLOBALS['SITE_DB']->query_select('bookable_codes', array('code'), array('bookable_id' => $id)));
        $i = $time;
        $up_to = strtotime('+2 days', $max_time);
        do {
            $day = intval(date('d', $i));
            $month = intval(date('m', $i));
            $year = intval(date('Y', $i));
            $codes_taken_already = collapse_1d_complexity('code_allocation', $GLOBALS['SITE_DB']->query_select('booking', array('code_allocation'), array('b_day' => $day, 'b_month' => $month, 'b_year' => $year)));
            foreach (array_diff($codes_in_total, $codes_taken_already) as $code) {
                echo "BEGIN:VEVENT\n";
                echo "DTSTAMP:" . date('Ymd', time()) . "T" . date('His', time()) . "\n";
                echo "CREATED:" . date('Ymd', time()) . "T" . date('His', time()) . "\n";
                echo "SUMMARY:" . ical_escape(do_lang('NOT_TAKEN', $code)) . "\n";
                echo "CATEGORIES:" . ical_escape($bookable_category) . "\n";
                echo "CLASS:PUBLIC\n";
                echo "STATUS:TENTATIVE\n";
                echo "UID:" . ical_escape(strval($day) . '/' . strval($month) . '/' . strval($year) . '-' . $code . '-booking@' . get_base_url()) . "\n";
                $_url = build_url(array('page' => 'cms_booking', 'type' => 'ab', 'bookable_id' => $id, 'day' => $day, 'month' => $month, 'year' => $year, 'code' => $code), get_module_zone('cms_booking'), NULL, false, false, true);
                $url = $_url->evaluate();
                echo "URL:" . ical_escape($url) . "\n";
                $time = mktime(0, 0, 0, $month, $day, $year);
                if ($time > $max_time) {
                    $max_time = $time;
                }
                echo "DTSTART:" . date('Ymd', $time) . "\n";
                echo "END:VEVENT\n";
            }
            $i = strtotime('+1 day', $i);
        } while ($i <= $up_to);
    }
    echo "END:VCALENDAR\n";
    exit;
}
Example #2
0
/**
 * Outputs the logged-in member's calendar view to ical.
 */
function output_ical()
{
    @ini_set('ocproducts.xss_detect', '0');
    header('Content-Type: text/calendar');
    header('Content-Disposition: filename="export.ics"');
    if (function_exists('set_time_limit')) {
        @set_time_limit(0);
    }
    $filter = get_param_integer('type_filter', NULL);
    if ($filter === 0) {
        $filter = NULL;
    }
    $where = '(e_submitter=' . strval(get_member()) . ' OR e_is_public=1)';
    if (!is_null($filter)) {
        $where .= ' AND e_type=' . strval($filter);
    }
    $events = $GLOBALS['SITE_DB']->query('SELECT e_is_public,e_submitter,e_add_date,e_edit_date,e_title,e_content,e_type,validated,id,e_recurrence,e_recurrences,e_start_hour,e_start_minute,e_start_month,e_start_day,e_start_year,e_end_hour,e_end_minute,e_end_month,e_end_day,e_end_year FROM ' . get_table_prefix() . 'calendar_events WHERE ' . $where . ' ORDER BY e_add_date DESC', 10000);
    echo "BEGIN:VCALENDAR\n";
    echo "VERSION:2.0\n";
    echo "PRODID:-//ocProducts/ocPortal//NONSGML v1.0//EN\n";
    echo "CALSCALE:GREGORIAN\n";
    $categories = array();
    $_categories = $GLOBALS['SITE_DB']->query_select('calendar_types', array('*'));
    foreach ($_categories as $category) {
        $categories[$category['id']] = get_translated_text($category['t_title']);
    }
    if (is_null($filter) || !array_key_exists($filter, $categories)) {
        echo "X-WR-CALNAME:" . ical_escape(get_site_name()) . "\n";
    } else {
        echo "X-WR-CALNAME:" . ical_escape(get_site_name() . ": " . $categories[$filter]) . "\n";
    }
    foreach ($events as $event) {
        if (!has_category_access(get_member(), 'calendar', strval($event['e_type']))) {
            continue;
        }
        if ($event['e_is_public'] == 1 || $event['e_submitter'] == get_member()) {
            echo "BEGIN:VEVENT\n";
            echo "DTSTAMP:" . date('Ymd', $event['e_add_date']) . "T" . date('His', $event['e_add_date']) . "\n";
            echo "CREATED:" . date('Ymd', $event['e_add_date']) . "T" . date('His', $event['e_add_date']) . "\n";
            if (!is_null($event['e_edit_date'])) {
                echo "LAST-MODIFIED:" . date('Ymd', $event['e_edit_date']) . "T" . date('His', $event['e_edit_date']) . "\n";
            }
            echo "SUMMARY:" . ical_escape(get_translated_text($event['e_title'])) . "\n";
            $description = get_translated_text($event['e_content']);
            $matches = array();
            $num_matches = preg_match_all('#\\[attachment[^\\]]*\\](\\d+)\\[/attachment\\]#', $description, $matches);
            for ($i = 0; $i < $num_matches; $i++) {
                $description = str_replace($matches[0], '', $description);
                $attachments = $GLOBALS['SITE_DB']->query_select('attachments', array('*'), array('id' => intval($matches[1])));
                if (array_key_exists(0, $attachments)) {
                    $attachment = $attachments[0];
                    require_code('mime_types');
                    echo "ATTACH;FMTTYPE=" . ical_escape(get_mime_type($attachment['a_original_filename'])) . ":" . ical_escape(find_script('attachments') . '?id=' . strval($attachment['id'])) . "\n";
                }
            }
            echo "DESCRIPTION:" . ical_escape(strip_comcode($description)) . "\n";
            if (!is_guest($event['e_submitter'])) {
                echo "ORGANIZER;CN=" . ical_escape($GLOBALS['FORUM_DRIVER']->get_username($event['e_submitter'])) . ";DIR=" . ical_escape($GLOBALS['FORUM_DRIVER']->member_profile_url($event['e_submitter'])) . ":MAILTO:" . ical_escape($GLOBALS['FORUM_DRIVER']->get_member_email_address($event['e_submitter'])) . "\n";
            }
            echo "CATEGORIES:" . ical_escape($categories[$event['e_type']]) . "\n";
            echo "CLASS:" . ($event['e_is_public'] == 1 ? 'PUBLIC' : 'PRIVATE') . "\n";
            echo "STATUS:" . ($event['validated'] == 1 ? 'CONFIRMED' : 'TENTATIVE') . "\n";
            echo "UID:" . ical_escape(strval($event['id']) . '@' . get_base_url()) . "\n";
            $_url = build_url(array('page' => 'calendar', 'type' => 'view', 'id' => $event['id']), get_module_zone('calendar'), NULL, false, false, true);
            $url = $_url->evaluate();
            echo "URL:" . ical_escape($url) . "\n";
            $forum = get_value('comment_forum__calendar');
            if (is_null($forum)) {
                $forum = get_option('comments_forum_name');
            }
            $start = 0;
            do {
                $count = 0;
                $_comments = $GLOBALS['FORUM_DRIVER']->get_forum_topic_posts($GLOBALS['FORUM_DRIVER']->find_topic_id_for_topic_identifier($forum, 'events_' . strval($event['id'])), $count, 1000, $start);
                if (is_array($_comments)) {
                    foreach ($_comments as $comment) {
                        if ($comment['title'] != '') {
                            $comment['message'] = $comment['title'] . ': ' . $comment['message'];
                        }
                        echo "COMMENT:" . ical_escape(strip_comcode(is_object($comment['message']) ? $comment['message'] : $comment['message']) . ' - ' . $GLOBALS['FORUM_DRIVER']->get_username($comment['user']) . ' (' . get_timezoned_date($comment['date']) . ')') . "\n";
                    }
                }
                $start += 1000;
            } while (count($_comments) == 1000);
            $time = mktime(is_null($event['e_start_hour']) ? 12 : $event['e_start_hour'], is_null($event['e_start_minute']) ? 0 : $event['e_start_minute'], 0, $event['e_start_month'], $event['e_start_day'], $event['e_start_year']);
            $time2 = mixed();
            $time2 = is_null($event['e_end_year']) || is_null($event['e_end_month']) || is_null($event['e_end_day']) ? NULL : mktime(is_null($event['e_end_hour']) ? 12 : $event['e_end_hour'], is_null($event['e_end_minute']) ? 0 : $event['e_end_minute'], 0, $event['e_end_month'], $event['e_end_day'], $event['e_end_year']);
            if ($event['e_recurrence'] != 'none') {
                $parts = explode(' ', $event['e_recurrence']);
                if (count($parts) == 1) {
                    echo "DTSTART;TZ=" . $event['e_timezone'] . ":" . date('Ymd', $time) . (is_null($event['e_start_hour']) ? "" : "T" . date('His', $time)) . "\n";
                    if (!is_null($time2)) {
                        echo "DTEND:" . date('Ymd', $time2) . "T" . (is_null($event['e_end_hour']) ? "" : "T" . date('His', $time2)) . "\n";
                    }
                    $recurrence_code = 'FREQ=' . strtoupper($parts[0]);
                    echo "RRULE:" . $recurrence_code . (is_null($event['e_recurrences']) ? '' : ";COUNT=" . strval($event['e_recurrences'])) . "\n";
                } else {
                    for ($i = 0; $i < strlen($parts[1]); $i++) {
                        switch ($parts[0]) {
                            case 'daily':
                                $time += 60 * 60 * 24;
                                if (!is_null($time2)) {
                                    $time2 += 60 * 60 * 24;
                                }
                                break;
                            case 'weekly':
                                $time += 60 * 60 * 24 * 7;
                                if (!is_null($time2)) {
                                    $time2 += 60 * 60 * 24 * 7;
                                }
                                break;
                            case 'monthly':
                                $days_in_month = intval(date('D', mktime(0, 0, 0, intval(date('m', $time)) + 1, 0, intval(date('Y', $time)))));
                                $time += 60 * 60 * $days_in_month;
                                if (!is_null($time2)) {
                                    $time2 += 60 * 60 * $days_in_month;
                                }
                                break;
                            case 'yearly':
                                $days_in_year = intval(date('Y', mktime(0, 0, 0, 0, 0, intval(date('Y', $time)) + 1)));
                                $time += 60 * 60 * 24 * $days_in_year;
                                if (!is_null($time2)) {
                                    $time2 += 60 * 60 * 24 * $days_in_year;
                                }
                                break;
                        }
                        if ($parts[1][$i] != '0') {
                            echo "DTSTART:" . date('Ymd', $time) . "T" . date('His', $time) . "\n";
                            if (!is_null($time2)) {
                                echo "DTEND:" . date('Ymd', $time2) . (is_null($event['e_start_hour']) ? "" : "T" . date('His', $time2)) . "\n";
                            }
                            $recurrence_code = 'FREQ=' . strtoupper($parts[0]);
                            echo "RRULE:" . $recurrence_code . ";INTERVAL=" . strval(strlen($parts[1])) . ";COUNT=1\n";
                        }
                    }
                }
            } else {
                echo "DTSTART:" . date('Ymd', $time) . "T" . date('His', $time) . "\n";
                if (!is_null($time2)) {
                    echo "DTEND:" . date('Ymd', $time2) . (is_null($event['e_start_hour']) ? "" : "T" . date('His', $time2)) . "\n";
                }
            }
            $attendees = $GLOBALS['SITE_DB']->query_select('calendar_reminders', array('*'), array('e_id' => $event['id']), '', 5000);
            if (count($attendees) == 5000) {
                $attendees = array();
            }
            foreach ($attendees as $attendee) {
                if ($attendee['n_member_id'] != get_member()) {
                    if (!is_guest($event['n_member_id'])) {
                        echo "ATTENDEE;CN=" . ical_escape($GLOBALS['FORUM_DRIVER']->get_username($attendee['n_member_id'])) . ";DIR=" . ical_escape($GLOBALS['FORUM_DRIVER']->member_profile_url($attendee['n_member_id'])) . ":MAILTO:" . ical_escape($GLOBALS['FORUM_DRIVER']->get_member_email_address($attendee['n_member_id'])) . "\n";
                    }
                } else {
                    echo "BEGIN:VALARM\n";
                    echo "X-WR-ALARMUID:alarm" . ical_escape(strval($event['id']) . '@' . get_base_url()) . "\n";
                    echo "ACTION:AUDIO\n";
                    echo "TRIGGER:-PT" . strval($attendee['n_seconds_before']) . "S\n";
                    echo "ATTACH;VALUE=URI:Basso\n";
                    echo "END:VALARM\n";
                }
            }
            echo "END:VEVENT\n";
        }
    }
    echo "END:VCALENDAR\n";
    exit;
}