1<?php
2/**
3 * @package tikiwiki
4 */
5// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
6//
7// All Rights Reserved. See copyright.txt for details and a complete list of authors.
8// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
9// $Id$
10
11require_once('tiki-setup.php');
12
13$access->check_feature('feature_calendar');
14$access->check_permission('tiki_p_view_events');
15
16// Initialization
17TikiInit::appendIncludePath("lib/ical/");
18include_once('lib/ical/iCal.php');
19
20// list calendars //
21$calendarlib = TikiLib::lib('calendar');
22
23// ###trebly:B10111:[FIX-ADD-ENH]->  there are several meaning for the same var $calendarViewMode
24if (! isset($calendarViewMode)) {
25// ###trebly:B10111:[FIX-ADD-ENH]-> $calendarViewMode become an array, several bugs comes from confusion of global values and parameters by ref
26// for calendars : (main-)calendar, action_calendar, mod_calendar, mod_action_calendar the changes of values by url request is terrible
27// for the moment 01/11/2011:11:55 just one value is used with index 'default', but initialisation is done.
28// The init is actually into two places, tiki-calendar_setup.php and tiki-calendar_export.php will be grouped for clean
29// $prefs would be added when need, $_SESSION, $PARAMS too this now generates not any change in the behavior.
30	$calendarViewMode = [casedefault => 'month',calgen => 'month',calaction => 'month',modcalgen => 'month',modcalaction => 'month',trackercal => 'month'];
31
32	if (! empty($_REQUEST['viewmode'])) {
33		$calendarViewMode['casedefault'] = $_REQUEST['viewmode'];
34	} elseif (! empty($_SESSION['CalendarViewMode'])) {
35		$calendarViewMode['casedefault'] = $_SESSION['CalendarViewMode'];
36	} else {
37		$calendarViewMode['casedefault'] = $prefs['calendar_view_mode'];
38	}
39}
40
41# If specified, limit the export to the maximum number of records (events)
42# indicated in the request; otherwise, the limit is from the global preferences.
43if (isset($_REQUEST['maxRecords'])) {
44		$maxRecords = $_REQUEST['maxRecords'];
45}
46
47if (isset($_SESSION['CalendarFocusDate'])) {
48	$startTime = $_SESSION['CalendarFocusDate'];
49} else {
50// by default, export will start from yesterday's events.
51	$startDate = new TikiDate();
52	$startDate->addDays(-1);
53	$startTime = $startDate->getTime();
54}
55
56if (isset($_REQUEST['start_date_Month'])) {
57	$startTime = TikiLib::make_time(0, 0, 0, $_REQUEST['start_date_Month'], $_REQUEST['start_date_Day'], $_REQUEST['start_date_Year']);
58} elseif (isset($_REQUEST["tstart"])) {
59	$startTime = $_REQUEST["tstart"];
60}
61
62$endDate = new TikiDate();
63$endDate->setDate($startTime);
64if ($calendarViewMode['casedefault'] == 'month') {
65	 $stopTime = $endDate->addMonths(1);
66} elseif ($calendarViewMode['casedefault'] == 'quarter') {
67	$stopTime = $endDate->addMonths(3);
68} elseif ($calendarViewMode['casedefault'] == 'semester') {
69	$stopTime = $endDate->addMonths(6);
70} elseif ($calendarViewMode['casedefault'] == 'year') {
71	$stopTime = $endDate->addMonths(12);
72} else {
73	$stopTime = $endDate->addMonths(1);
74}
75$stopTime = $endDate->getTime();
76
77if (isset($_REQUEST['stop_date_Month'])) {
78	$stopTime = TikiLib::make_time(0, 0, 0, $_REQUEST['stop_date_Month'], $_REQUEST['stop_date_Day'], $_REQUEST['stop_date_Year']);
79} elseif (isset($_REQUEST["tstop"])) {
80	$stopTime = $_REQUEST["tstop"];
81}
82
83$calendarIds = [];
84if (isset($_REQUEST['calendarIds'])) {
85	$calendarIds = $_REQUEST['calendarIds'];
86	foreach ($calendarIds as $anId) {
87		$smarty->assign('individual_' . $anId, $userlib->object_has_one_permission($anId, 'calendar'));
88	}
89} else {
90	if (! isset($_REQUEST["calendarId"])) {
91		$_REQUEST["calendarId"] = 0;
92	} else {
93		 $smarty->assign('individual_' . $_REQUEST["calendarId"], $userlib->object_has_one_permission($_REQUEST["calendarId"], 'calendar'));
94	}
95}
96$sort_mode = "name";
97
98$find = "";
99$calendars = $calendarlib->list_calendars(0, -1, $sort_mode, $find);
100
101foreach (array_keys($calendars["data"]) as $i) {
102	$calendars["data"][$i]["individual"] = $userlib->object_has_one_permission($i, 'calendar');
103}
104$smarty->assign('calendars', $calendars["data"]);
105
106// export calendar //
107if (((is_array($calendarIds) && (count($calendarIds) > 0)) or isset($_REQUEST["calendarItem"]) ) && $_REQUEST["export"] == 'y') {
108	// get calendar events
109	if (! isset($_REQUEST["calendarItem"])) {
110		$events = $calendarlib->list_raw_items($calendarIds, $user, $startTime, $stopTime, -1, $maxRecords, $sort_mode = 'start_asc', $find = '');
111	} else {
112		$events[] = $calendarlib->get_item($_REQUEST["calendarItem"]);
113	}
114
115	if (isset($_REQUEST['csv'])) {
116		header('Content-type: text/csv');
117		header("Content-Disposition: inline; filename=tiki-calendar.csv");
118		$first = true;
119		$description = '';
120		foreach ($events as $event) {
121			$line = '';
122			foreach ($event as $name => $field) {
123				if ($first === true) {
124					$description .= '"' . $name . '";';
125				}
126				if (is_array($field)) {
127					$line .= '"' . str_replace(["\n","\r",'"'], ['\\n','','""'], join(',', $field)) . '";';
128				} else {
129					$line .= '"' . str_replace(["\n","\r",'"'], ['\\n','','""'], $field) . '";';
130				}
131			}
132			if ($first === true) {
133				echo (trim($description, ';')) . "\n";
134				$first = false;
135			}
136			echo trim($line, ';') . "\n";
137		}
138	} else {
139		// create ical
140
141		$userlb = TikiLib::get('Users');
142
143		$vcalendar = new Sabre\VObject\Component\VCalendar();
144
145		foreach ($events as $event) {
146			$vevent = [];
147			$vevent['SUMMARY'] = $event['name'];
148			$vevent['DTSTART'] = (new DateTime())->setTimestamp($event['start']);
149			$vevent['DTEND'] = (new DateTime())->setTimestamp($event['end']);
150
151			$vevent['DESCRIPTION'] = preg_replace(
152				'/\n/',
153				"\\n",
154				strip_tags(
155					TikiLib::lib('parser')->parse_data(
156						$event['description'],
157						['is_html' => $prefs['calendar_description_is_html'] === 'y']
158					)
159				)
160			);
161
162			$vevent['DTSTAMP'] = (new DateTime())->setTimestamp($event['created']);
163			$vevent['LAST-MODIFIED'] = (new DateTime())->setTimestamp($event['lastModif']);
164
165			$vevent['CONTACT'] = $event['user']; // Name
166
167			if (! empty($event['url'])) {
168				$vevent['URL'] = $event['url'];
169			}
170
171			$vevent['UID'] = 'tiki-' . $event['calendarId'] . '-' . $event['calitemId'];
172
173			$vcalEvent = $vcalendar->add('VEVENT', $vevent);
174
175			foreach ($event['organizers'] as $organizer) {
176				$orgEmail = $userlib->get_user_email($organizer);
177
178				if (! empty($orgEmail)) {
179					$vcalEvent->add('ORGANIZER', $orgEmail, ['CN' => $organizer]);
180				} elseif (filter_var($organizer, FILTER_VALIDATE_EMAIL) !== false) {
181					$vcalEvent->add('ORGANIZER', $organizer);
182				}
183			}
184
185			foreach ($event['participants'] as $attendee) {
186				$attendeeEmail = $userlib->get_user_email($attendee['name']);
187
188				if (! empty($attendeeEmail)) {
189					$vcalEvent->add('ATTENDEE', $attendeeEmail, ['CN' => $attendee['name']]);
190				} else {
191					if (filter_var($attendee['name'], FILTER_VALIDATE_EMAIL) !== false) {
192						$vcalEvent->add('ATTENDEE', $attendee);
193					}
194				}
195			}
196		}
197
198		$calendar_str = $vcalendar->serialize();
199		header("Content-Length: " . strlen($calendar_str));
200		header("Expires: 0");
201		// These two lines fix pb with IE and HTTPS
202		header("Cache-Control: private");
203		header("Pragma: dummy=bogus");
204		// Outlook needs iso8859 encoding
205		header("Content-Type:text/calendar; method=REQUEST; charset=iso-8859-15");
206		header("Content-Transfer-Encoding:quoted-printable");
207		$re_encode = stripos($_SERVER['HTTP_USER_AGENT'], 'windows');	// only re-encode to ISO-8859-15 if client on Windows
208		if (function_exists('recode') && $re_encode !== false) {
209			print(recode('utf-8..iso8859-15', $calendar_str));
210		} elseif (function_exists('iconv') && $re_encode !== false) {
211			print(iconv("UTF-8", "ISO-8859-15", $calendar_str));
212		} else {
213			print($calendar_str);	// UTF-8 is good for other platforms
214		}
215	}
216	die;
217}
218
219
220$smarty->assign('iCal', $iCal);
221
222// Display the template
223$smarty->assign('mid', 'tiki-calendar_export_ical.tpl');
224$smarty->display("tiki.tpl");
225