Browse Source

! Update the iCal export function. Add in permissions and interface to actually use it as well. WIP

Signed-off-by: Spuds <[email protected]>
Spuds 12 years ago
parent
commit
00c470f243

+ 45 - 13
Sources/Calendar.php

@@ -148,8 +148,10 @@ function CalendarMain()
 
 /**
  * This function processes posting/editing/deleting a calendar event.
+ *
  * 	- calls Post() function if event is linked to a post.
  *  - calls insertEvent() to insert the event if not linked to post.
+ *
  * It requires the calendar_post permission to use.
  * It uses the event_post sub template in the Calendar template.
  * It is accessed with ?action=calendar;sa=post.
@@ -317,12 +319,21 @@ function CalendarPost()
 
 /**
  * This function offers up a download of an event in iCal 2.0 format.
- * @todo lol... User interface! :P
+ *
+ * follows the conventions in RFC5546 http://tools.ietf.org/html/rfc5546
+ * sets events as all day events since we don't have hourly events
+ * will honor and set multi day events
+ * sets a sequence number if the event has been modified
+ *
+ * @todo .... allow for week or month export files as well?
  */
 function iCalDownload()
 {
-	global $smcFunc, $sourcedir, $forum_version, $context, $modSettings;
+	global $smcFunc, $sourcedir, $forum_version, $context, $modSettings, $webmaster_email, $mbname;
 
+	// This requires the export permission
+	isAllowedTo('calendar_export');
+	
 	// Goes without saying that this is required.
 	if (!isset($_REQUEST['eventid']))
 		fatal_lang_error('no_access', false);
@@ -332,7 +343,7 @@ function iCalDownload()
 
 	// Load up the event in question and check it exists.
 	$event = getEventProperties($_REQUEST['eventid']);
-
+	
 	if ($event === false)
 		fatal_lang_error('no_access', false);
 
@@ -345,19 +356,39 @@ function iCalDownload()
 		$title[$id] .= "\n";
 	}
 
-	// Format the date.
-	$date = $event['year'] . '-' . ($event['month'] < 10 ? '0' . $event['month'] : $event['month']) . '-' . ($event['day'] < 10 ? '0' . $event['day'] : $event['day']) . 'T';
-	$date .= '1200:00:00Z';
+	// Format the dates.
+	$datestamp = date('Ymd\THis\Z', time());
+	$datestart = $event['year'] . ($event['month'] < 10 ? '0' . $event['month'] : $event['month']) . ($event['day'] < 10 ? '0' . $event['day'] : $event['day']);
 
-	// This is what we will be sending later.
+	// Do we have a mutli day event?
+	if ($event['span'] > 1)
+	{
+		$dateend = strtotime($event['year'] . '-' . ($event['month'] < 10 ? '0' . $event['month'] : $event['month']) . '-' . ($event['day'] < 10 ? '0' . $event['day'] : $event['day']));
+		$dateend += ($event['span'] - 1) * 86400;
+		$dateend = date('Ymd', $dateend);
+	}
+
+	// This is what we will be sending later
 	$filecontents = '';
 	$filecontents .= 'BEGIN:VCALENDAR' . "\n";
+	$filecontents .= 'METHOD:PUBLISH' . "\n";
+	$filecontents .= 'PRODID:-//SimpleMachines//SMF ' . (empty($forum_version) ? 2.0 : strtr($forum_version, array('SMF ' => ''))) . '//EN' . "\n";
 	$filecontents .= 'VERSION:2.0' . "\n";
-	$filecontents .= 'PRODID:-//SimpleMachines//SMF ' . (empty($forum_version) ? 1.0 : strtr($forum_version, array('SMF ' => ''))) . '//EN' . "\n";
 	$filecontents .= 'BEGIN:VEVENT' . "\n";
-	$filecontents .= 'DTSTART:' . $date . "\n";
-	$filecontents .= 'DTEND:' . $date . "\n";
+	$filecontents .= 'ORGANIZER;CN="' . $event['realname'] . '":MAILTO:' . $webmaster_email . "\n";
+	$filecontents .= 'DTSTAMP:' . $datestamp . "\n";
+	$filecontents .= 'DTSTART;VALUE=DATE:' . $datestart . "\n";
+	
+	// more than one day
+	if ($event['span'] > 1)
+		$filecontents .= 'DTEND;VALUE=DATE:' . $dateend . "\n";
+	
+	// event has changed? advance the sequence for this UID
+	if ($event['sequence'] > 0)
+		$filecontents .= 'SEQUENCE:' . $event['sequence'] . "\n";
+	
 	$filecontents .= 'SUMMARY:' . implode('', $title);
+	$filecontents .= 'UID:' . $event['eventid'] . '@' . str_replace(' ', '-', $mbname) . "\n";
 	$filecontents .= 'END:VEVENT' . "\n";
 	$filecontents .= 'END:VCALENDAR';
 
@@ -367,7 +398,7 @@ function iCalDownload()
 		@ob_start('ob_gzhandler');
 	else
 		ob_start();
-
+	
 	// Send the file headers
 	header('Pragma: ');
 	header('Cache-Control: no-cache');
@@ -378,8 +409,9 @@ function iCalDownload()
 	header('Accept-Ranges: bytes');
 	header('Connection: close');
 	header('Content-Disposition: attachment; filename=' . $event['title'] . '.ics');
-	header('Content-Length: ' . $smcFunc['strlen']($filecontents));
-
+	if (empty($modSettings['enableCompressedOutput']))
+		header('Content-Length: ' . $smcFunc['strlen']($filecontents));
+	
 	// This is a calendar item!
 	header('Content-Type: text/calendar');
 

+ 2 - 0
Sources/Display.php

@@ -556,6 +556,8 @@ function Display()
 				'title' => $row['title'],
 				'can_edit' => allowedTo('calendar_edit_any') || ($row['id_member'] == $user_info['id'] && allowedTo('calendar_edit_own')),
 				'modify_href' => $scripturl . '?action=post;msg=' . $topicinfo['id_first_msg'] . ';topic=' . $topic . '.0;calendar;eventid=' . $row['id_event'] . ';' . $context['session_var'] . '=' . $context['session_id'],
+				'can_export' => allowedTo('calendar_edit_any') || ($row['id_member'] == $user_info['id'] && allowedTo('calendar_edit_own')),
+				'export_href' => $scripturl . '?action=calendar;sa=ical;eventid=' . $row['id_event'] . ';' . $context['session_var'] . '=' . $context['session_id'],
 				'start_date' => timeformat($start_date, $date_string, 'none'),
 				'start_timestamp' => $start_date,
 				'end_date' => timeformat($end_date, $date_string, 'none'),

+ 1 - 0
Sources/ManageCalendar.php

@@ -314,6 +314,7 @@ function ModifyCalendarSettings($return_config = false)
 			array('permissions', 'calendar_post'),
 			array('permissions', 'calendar_edit_own'),
 			array('permissions', 'calendar_edit_any'),
+			array('permissions', 'calendar_export'),
 		'',
 			// How many days to show on board index, and where to display events etc?
 			array('int', 'cal_days_for_index', 6, 'postinput' => $txt['days_word']),

+ 2 - 0
Sources/ManagePermissions.php

@@ -1463,6 +1463,7 @@ function loadAllPermissions($loadType = 'classic')
 			'pm_read' => array(false, 'pm', 'use_pm_system'),
 			'pm_send' => array(false, 'pm', 'use_pm_system'),
 			'calendar_view' => array(false, 'calendar', 'view_basic_info'),
+			'calendar_export' => array(false, 'calendar', 'view_basic_info'),
 			'calendar_post' => array(false, 'calendar', 'post_calendar'),
 			'calendar_edit' => array(true, 'calendar', 'post_calendar', 'moderate_general'),
 			'admin_forum' => array(false, 'maintenance', 'administrate'),
@@ -1543,6 +1544,7 @@ function loadAllPermissions($loadType = 'classic')
 		$hiddenPermissions[] = 'calendar_view';
 		$hiddenPermissions[] = 'calendar_post';
 		$hiddenPermissions[] = 'calendar_edit';
+		$hiddenPermissions[] = 'calendar_export';
 	}
 	if (!in_array('w', $context['admin_features']))
 		$hiddenPermissions[] = 'issue_warning';

+ 26 - 19
Sources/Subs-Calendar.php

@@ -102,11 +102,13 @@ function getBirthdayRange($low_date, $high_date)
 }
 
 /**
- * Get all events within the given time range.
- * finds all the posted calendar events within a date range.
- * both the earliest_date and latest_date should be in the standard YYYY-MM-DD format.
- * censors the posted event titles.
- * uses the current user's permissions if use_permissions is true, otherwise it does nothing "permission specific"
+ * Get all calendar events within the given time range.
+ *
+ * - finds all the posted calendar events within a date range.
+ * - both the earliest_date and latest_date should be in the standard YYYY-MM-DD format.
+ * - censors the posted event titles.
+ * - uses the current user's permissions if use_permissions is true, otherwise it does nothing "permission specific"
+ *
  * @param string $earliest_date
  * @param string $latest_date
  * @param bool $use_permissions = true
@@ -142,7 +144,6 @@ function getEventRange($low_date, $high_date, $use_permissions = true)
 	while ($row = $smcFunc['db_fetch_assoc']($result))
 	{
 		// If the attached topic is not approved then for the moment pretend it doesn't exist
-		// @todo This should be fixed to show them all and then sort by approval state later?
 		if (!empty($row['id_first_msg']) && $modSettings['postmod_active'] && !$row['approved'])
 			continue;
 
@@ -168,31 +169,34 @@ function getEventRange($low_date, $high_date, $use_permissions = true)
 				$events[strftime('%Y-%m-%d', $date)][] = array(
 					'id' => $row['id_event'],
 					'title' => $row['title'],
-					'can_edit' => allowedTo('calendar_edit_any') || ($row['id_member'] == $user_info['id'] && allowedTo('calendar_edit_own')),
-					'modify_href' => $scripturl . '?action=' . ($row['id_board'] == 0 ? 'calendar;sa=post;' : 'post;msg=' . $row['id_first_msg'] . ';topic=' . $row['id_topic'] . '.0;calendar;') . 'eventid=' . $row['id_event'] . ';' . $context['session_var'] . '=' . $context['session_id'],
-					'href' => $row['id_board'] == 0 ? '' : $scripturl . '?topic=' . $row['id_topic'] . '.0',
-					'link' => $row['id_board'] == 0 ? $row['title'] : '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0">' . $row['title'] . '</a>',
 					'start_date' => $row['start_date'],
 					'end_date' => $row['end_date'],
 					'is_last' => false,
-					'id_board' => $row['id_board'],
+					'id_board' => $row['id_board'],	
+					'href' => $row['id_board'] == 0 ? '' : $scripturl . '?topic=' . $row['id_topic'] . '.0',
+					'link' => $row['id_board'] == 0 ? $row['title'] : '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0">' . $row['title'] . '</a>',
+					'can_edit' => allowedTo('calendar_edit_any') || ($row['id_member'] == $user_info['id'] && allowedTo('calendar_edit_own')),
+					'modify_href' => $scripturl . '?action=' . ($row['id_board'] == 0 ? 'calendar;sa=post;' : 'post;msg=' . $row['id_first_msg'] . ';topic=' . $row['id_topic'] . '.0;calendar;') . 'eventid=' . $row['id_event'] . ';' . $context['session_var'] . '=' . $context['session_id'],
+					'can_export' => allowedTo('calendar_export'),
+					'export_href' => $scripturl . '?action=calendar;sa=ical;eventid=' . $row['id_event'] . ';' . $context['session_var'] . '=' . $context['session_id'],
 				);
 			// Otherwise, this is going to be cached and the VIEWER'S permissions should apply... just put together some info.
 			else
 				$events[strftime('%Y-%m-%d', $date)][] = array(
 					'id' => $row['id_event'],
 					'title' => $row['title'],
-					'topic' => $row['id_topic'],
-					'msg' => $row['id_first_msg'],
-					'poster' => $row['id_member'],
 					'start_date' => $row['start_date'],
 					'end_date' => $row['end_date'],
 					'is_last' => false,
-					'allowed_groups' => explode(',', $row['member_groups']),
 					'id_board' => $row['id_board'],
 					'href' => $row['id_topic'] == 0 ? '' : $scripturl . '?topic=' . $row['id_topic'] . '.0',
 					'link' => $row['id_topic'] == 0 ? $row['title'] : '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0">' . $row['title'] . '</a>',
 					'can_edit' => false,
+					'can_export' => false,
+					'topic' => $row['id_topic'],
+					'msg' => $row['id_first_msg'],
+					'poster' => $row['id_member'],
+					'allowed_groups' => explode(',', $row['member_groups']),
 				);
 		}
 	}
@@ -898,9 +902,8 @@ function modifyEvent($event_id, &$eventOptions)
 
 	// Properly sanitize the title.
 	$eventOptions['title'] = $smcFunc['htmlspecialchars']($eventOptions['title'], ENT_QUOTES);
-
+	
 	// Scan the start date for validity and get its components.
-	// @todo $year, $month, and $day are not set
 	if (($num_results = sscanf($eventOptions['start_date'], '%d-%d-%d', $year, $month, $day)) !== 3)
 		trigger_error('modifyEvent(): invalid start date format given', E_USER_ERROR);
 
@@ -909,7 +912,6 @@ function modifyEvent($event_id, &$eventOptions)
 
 	// Set the end date to the start date + span (if the end date wasn't already given).
 	if (!isset($eventOptions['end_date']))
-		// @todo $year, $month, and $day are not set
 		$eventOptions['end_date'] = strftime('%Y-%m-%d', mktime(0, 0, 0, $month, $day, $year) + $eventOptions['span'] * 86400);
 
 	$smcFunc['db_query']('', '
@@ -970,9 +972,12 @@ function getEventProperties($event_id)
 			c.id_event, c.id_board, c.id_topic, MONTH(c.start_date) AS month,
 			DAYOFMONTH(c.start_date) AS day, YEAR(c.start_date) AS year,
 			(TO_DAYS(c.end_date) - TO_DAYS(c.start_date)) AS span, c.id_member, c.title,
-			t.id_first_msg, t.id_member_started
+			t.id_first_msg, t.id_member_started,
+			mb.real_name, m.modified_time
 		FROM {db_prefix}calendar AS c
 			LEFT JOIN {db_prefix}topics AS t ON (t.id_topic = c.id_topic)
+			LEFT JOIN {db_prefix}members AS mb ON (mb.id_member = t.id_member_started)
+			LEFT JOIN {db_prefix}messages AS m ON (m.id_msg  = t.id_first_msg)
 		WHERE c.id_event = {int:id_event}',
 		array(
 			'id_event' => $event_id,
@@ -997,6 +1002,8 @@ function getEventProperties($event_id)
 		'title' => $row['title'],
 		'span' => 1 + $row['span'],
 		'member' => $row['id_member'],
+		'realname' => $row['real_name'],
+		'sequence' => $row['modified_time'],
 		'topic' => array(
 			'id' => $row['id_topic'],
 			'member_started' => $row['id_member_started'],

+ 1 - 1
Themes/default/BoardIndex.template.php

@@ -378,7 +378,7 @@ function template_info_center()
 			//		title, href, is_last, can_edit (are they allowed?), modify_href, and is_today.
 			foreach ($context['calendar_events'] as $event)
 				echo '
-					', $event['can_edit'] ? '<a href="' . $event['modify_href'] . '" title="' . $txt['calendar_edit'] . '"><img src="' . $settings['images_url'] . '/icons/modify_small.png" alt="*" /></a> ' : '', $event['href'] == '' ? '' : '<a href="' . $event['href'] . '">', $event['is_today'] ? '<strong>' . $event['title'] . '</strong>' : $event['title'], $event['href'] == '' ? '' : '</a>', $event['is_last'] ? '<br />' : ', ';
+					', $event['can_edit'] ? '<a href="' . $event['modify_href'] . '" title="' . $txt['calendar_edit'] . '"><img src="' . $settings['images_url'] . '/icons/calendar_modify.png" alt="*" /></a> ' : '', $event['href'] == '' ? '' : '<a href="' . $event['href'] . '">', $event['is_today'] ? '<strong>' . $event['title'] . '</strong>' : $event['title'], $event['href'] == '' ? '' : '</a>', $event['is_last'] ? '<br />' : ', ';
 		}
 		
 		echo '

+ 16 - 13
Themes/default/Calendar.template.php

@@ -101,7 +101,7 @@ function template_event_post()
 
 	// Start the main table.
 	echo '
-			<div id="post_event">
+		<div id="post_event">
 			<div class="cat_bar">
 				<h3 class="catbg">
 					', $context['page_title'], '
@@ -130,7 +130,7 @@ function template_event_post()
 					<fieldset id="event_main">
 						<legend><span', isset($context['post_error']['no_event']) ? ' class="error"' : '', '>', $txt['calendar_event_title'], '</span></legend>
 						<input type="text" name="evtitle" maxlength="255" size="70" value="', $context['event']['title'], '" class="input_text" />
-						<div class="smalltext">
+						<div class="smalltext" style="white-space: nowrap;">
 							<input type="hidden" name="calendar" value="1" />', $txt['calendar_year'], '
 							<select name="year" id="year" onchange="generateDays();">';
 
@@ -221,7 +221,6 @@ function template_event_post()
 					</fieldset>';
 
 	echo '
-					<div class="righttext">
 						<input type="submit" value="', empty($context['event']['new']) ? $txt['save'] : $txt['post'], '" class="button_submit" />';
 	// Delete button?
 	if (empty($context['event']['new']))
@@ -231,13 +230,12 @@ function template_event_post()
 	echo '
 						<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" />
 						<input type="hidden" name="eventid" value="', $context['event']['eventid'], '" />
-					</div>
+						<br class="clear" />
 				</div>
 				<span class="lowerframe"><span></span></span>
 			</div>
-			</div>
-		</form>
-		<br class="clear" />';
+		</div>
+		</form>';
 }
 
 // Display a monthly calendar grid.
@@ -375,20 +373,25 @@ function template_show_month_grid($grid_name)
 				if (!empty($day['events']))
 				{
 					echo '
-							<div class="smalltext">
-								<span class="event">', $txt['events'], '</span>';
+							<div class="smalltext lefttext">
+								<span class="event">', $txt['events'], '</span><br />';
 
 					/* The events are made up of:
 						title, href, is_last, can_edit (are they allowed to?), and modify_href. */
 					foreach ($day['events'] as $event)
 					{
-						// If they can edit the event, show a star they can click on....
+						// If they can edit the event, show an icon they can click on....
 						if ($event['can_edit'])
 							echo '
-								<a class="modify_event" href="', $event['modify_href'], '"><img src="' . $settings['images_url'] . '/icons/modify_small.png" alt="*" /></a>';
+								<a class="modify_event" href="', $event['modify_href'], '"><img src="' . $settings['images_url'] . '/icons/calendar_modify.png" alt="*" title="' . $txt['modify'] . '" /></a>';
+						
+						if ($event['can_export'])
+							echo '
+								<a class="modify_event" href="', $event['export_href'], '"><img src="' . $settings['images_url'] . '/icons/calendar_export.png" alt=">" title="' . $txt['save'] . '"/></a>';
 
+								
 						echo '
-								', $event['link'], $event['is_last'] ? '' : ', ';
+								', $event['link'], $event['is_last'] ? '' : '<br />';
 					}
 
 					echo '
@@ -503,7 +506,7 @@ function template_show_week_grid($grid_name)
 					// If they can edit the event, show a star they can click on....
 					if ($event['can_edit'])
 						echo '
-								<a href="', $event['modify_href'], '"><img src="' . $settings['images_url'] . '/icons/modify_small.png" alt="*" /></a> ';
+								<a href="', $event['modify_href'], '"><img src="' . $settings['images_url'] . '/icons/calendar_modify.png" alt="*" /></a> ';
 
 					echo '
 								', $event['link'], $event['is_last'] ? '' : ', ';

+ 1 - 1
Themes/default/Display.template.php

@@ -146,7 +146,7 @@ function template_main()
 		foreach ($context['linked_calendar_events'] as $event)
 			echo '
 							<li>
-								', ($event['can_edit'] ? '<a href="' . $event['modify_href'] . '"> <img src="' . $settings['images_url'] . '/icons/modify_small.png" alt="" title="' . $txt['modify'] . '" class="edit_event" /></a> ' : ''), '<strong>', $event['title'], '</strong>: ', $event['start_date'], ($event['start_date'] != $event['end_date'] ? ' - ' . $event['end_date'] : ''), '
+								', ($event['can_edit'] ? '<a href="' . $event['modify_href'] . '"> <img src="' . $settings['images_url'] . '/icons/calendar_modify.png" alt="" title="' . $txt['modify'] . '" class="edit_event" /></a> ' : ''), '<strong>', $event['title'], '</strong>: ', $event['start_date'], ($event['start_date'] != $event['end_date'] ? ' - ' . $event['end_date'] : ''), '
 							</li>';
 
 		echo '

+ 2 - 2
Themes/default/css/index.css

@@ -1868,8 +1868,8 @@ div.table_frame .table_list
 }
 .edit_event
 {
-	margin: 0 1em;
-	vertical-align: middle;
+	margin: 0 .8em;
+	vertical-align: top;
 }
 /* Poll question */
 #poll

BIN
Themes/default/images/icons/calendar_export.png


BIN
Themes/default/images/icons/calendar_modify.png


+ 1 - 0
Themes/default/languages/Errors.english.php

@@ -64,6 +64,7 @@ $txt['cannot_post_unapproved_replies_own'] = 'You do not have permission to post
 $txt['cannot_post_unapproved_replies_any'] = 'You do not have permission to post unapproved replies to other users\' topics.';
 $txt['cannot_calendar_edit_any'] = 'You cannot edit calendar events.';
 $txt['cannot_calendar_edit_own'] = 'You don\'t have the privileges necessary to edit your own events.';
+$txt['cannot_calendar_export'] = 'Sorry, You cannot export calendar events.';
 $txt['cannot_calendar_post'] = 'Event posting isn\'t allowed - sorry.';
 $txt['cannot_calendar_view'] = 'Sorry, but you are not allowed to view the calendar.';
 $txt['cannot_remove_any'] = 'Sorry, but you don\'t have the privilege to remove just any topic.  Check to make sure this topic wasn\'t just moved to another board.';

+ 1 - 0
Themes/default/languages/ManageCalendar.english.php

@@ -7,6 +7,7 @@ $txt['calendar_desc'] = 'From here you can modify all aspects of the calendar.';
 $txt['calendar_settings_desc'] = 'Here you can enable the calendar, and determine the settings that it should use.';
 $txt['save_settings'] = 'Save Settings';
 $txt['groups_calendar_view'] = 'Membergroups allowed to view the calendar';
+$txt['groups_calendar_export'] = 'Membergroups allowed to export calendar events';
 $txt['groups_calendar_post'] = 'Membergroups allowed to create events';
 $txt['groups_calendar_edit_own'] = 'Membergroups allowed to edit their own events';
 $txt['groups_calendar_edit_any'] = 'Membergroups allowed to edit any events';

+ 2 - 0
Themes/default/languages/ManagePermissions.english.php

@@ -104,6 +104,8 @@ $txt['permissionname_calendar_edit'] = 'Edit events in the calendar';
 $txt['permissionhelp_calendar_edit'] = 'An Event is a topic linked to a certain date or date range. The event can be edited by clicking the red asterisk (*) next to the event in the calendar view. In order to be able to edit an event, a user must have sufficient permissions to edit the first message of the topic that is linked to the event.';
 $txt['permissionname_calendar_edit_own'] = 'Own events';
 $txt['permissionname_calendar_edit_any'] = 'Any events';
+$txt['permissionname_calendar_export'] = 'Export events from the calendar';
+$txt['permissionhelp_calendar_export'] = 'Exports a text file in the iCal format for importing in to other calendar applications';
 
 $txt['permissiongroup_maintenance'] = 'Forum administration';
 $txt['permissionname_admin_forum'] = 'Administrate forum and database';