Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14348075
D16680.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
9 KB
Referenced Files
None
Subscribers
None
D16680.diff
View Options
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -2094,6 +2094,7 @@
'PhabricatorCalendarExportViewController' => 'applications/calendar/controller/PhabricatorCalendarExportViewController.php',
'PhabricatorCalendarHoliday' => 'applications/calendar/storage/PhabricatorCalendarHoliday.php',
'PhabricatorCalendarHolidayTestCase' => 'applications/calendar/storage/__tests__/PhabricatorCalendarHolidayTestCase.php',
+ 'PhabricatorCalendarICSWriter' => 'applications/calendar/util/PhabricatorCalendarICSWriter.php',
'PhabricatorCalendarIconSet' => 'applications/calendar/icon/PhabricatorCalendarIconSet.php',
'PhabricatorCalendarRemarkupRule' => 'applications/calendar/remarkup/PhabricatorCalendarRemarkupRule.php',
'PhabricatorCalendarReplyHandler' => 'applications/calendar/mail/PhabricatorCalendarReplyHandler.php',
@@ -6866,6 +6867,7 @@
'PhabricatorCalendarExportViewController' => 'PhabricatorCalendarController',
'PhabricatorCalendarHoliday' => 'PhabricatorCalendarDAO',
'PhabricatorCalendarHolidayTestCase' => 'PhabricatorTestCase',
+ 'PhabricatorCalendarICSWriter' => 'Phobject',
'PhabricatorCalendarIconSet' => 'PhabricatorIconSet',
'PhabricatorCalendarRemarkupRule' => 'PhabricatorObjectRemarkupRule',
'PhabricatorCalendarReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
diff --git a/src/applications/calendar/controller/PhabricatorCalendarController.php b/src/applications/calendar/controller/PhabricatorCalendarController.php
--- a/src/applications/calendar/controller/PhabricatorCalendarController.php
+++ b/src/applications/calendar/controller/PhabricatorCalendarController.php
@@ -6,34 +6,11 @@
PhabricatorUser $viewer,
$file_name,
array $events) {
- $events = mpull($events, null, 'getPHID');
- if ($events) {
- $child_map = id(new PhabricatorCalendarEventQuery())
- ->setViewer($viewer)
- ->withParentEventPHIDs(array_keys($events))
- ->execute();
- $child_map = mpull($child_map, null, 'getPHID');
- } else {
- $child_map = array();
- }
-
- $all_events = $events + $child_map;
- $child_groups = mgroup($child_map, 'getInstanceOfEventPHID');
-
- $document_node = new PhutilCalendarDocumentNode();
-
- foreach ($all_events as $event) {
- $child_events = idx($child_groups, $event->getPHID(), array());
- $event_node = $event->newIntermediateEventNode($viewer, $child_events);
- $document_node->appendChild($event_node);
- }
-
- $root_node = id(new PhutilCalendarRootNode())
- ->appendChild($document_node);
-
- $ics_data = id(new PhutilICSWriter())
- ->writeICSDocument($root_node);
+ $ics_data = id(new PhabricatorCalendarICSWriter())
+ ->setViewer($viewer)
+ ->setEvents($events)
+ ->writeICSDocument();
return id(new AphrontFileResponse())
->setDownload($file_name)
diff --git a/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php b/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php
--- a/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php
+++ b/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php
@@ -309,16 +309,10 @@
PhabricatorCalendarEvent $event) {
$actor = $this->getActor();
- $event_node = $event->newIntermediateEventNode($actor);
-
- $document_node = id(new PhutilCalendarDocumentNode())
- ->appendChild($event_node);
-
- $root_node = id(new PhutilCalendarRootNode())
- ->appendChild($document_node);
-
- $ics_data = id(new PhutilICSWriter())
- ->writeICSDocument($root_node);
+ $ics_data = id(new PhabricatorCalendarICSWriter())
+ ->setViewer($actor)
+ ->setEvents(array($event))
+ ->writeICSDocument();
$ics_attachment = new PhabricatorMetaMTAAttachment(
$ics_data,
diff --git a/src/applications/calendar/controller/PhabricatorCalendarController.php b/src/applications/calendar/util/PhabricatorCalendarICSWriter.php
copy from src/applications/calendar/controller/PhabricatorCalendarController.php
copy to src/applications/calendar/util/PhabricatorCalendarICSWriter.php
--- a/src/applications/calendar/controller/PhabricatorCalendarController.php
+++ b/src/applications/calendar/util/PhabricatorCalendarICSWriter.php
@@ -1,11 +1,33 @@
<?php
-abstract class PhabricatorCalendarController extends PhabricatorController {
+final class PhabricatorCalendarICSWriter extends Phobject {
+
+ private $viewer;
+ private $events = array();
+
+ public function setViewer(PhabricatorUser $viewer) {
+ $this->viewer = $viewer;
+ return $this;
+ }
+
+ public function getViewer() {
+ return $this->viewer;
+ }
+
+ public function setEvents(array $events) {
+ assert_instances_of($events, 'PhabricatorCalendarEvent');
+ $this->events = $events;
+ return $this;
+ }
+
+ public function getEvents() {
+ return $this->events;
+ }
+
+ public function writeICSDocument() {
+ $viewer = $this->getViewer();
+ $events = $this->getEvents();
- protected function newICSResponse(
- PhabricatorUser $viewer,
- $file_name,
- array $events) {
$events = mpull($events, null, 'getPHID');
if ($events) {
@@ -32,13 +54,7 @@
$root_node = id(new PhutilCalendarRootNode())
->appendChild($document_node);
- $ics_data = id(new PhutilICSWriter())
+ return id(new PhutilICSWriter())
->writeICSDocument($root_node);
-
- return id(new AphrontFileResponse())
- ->setDownload($file_name)
- ->setMimeType('text/calendar')
- ->setContent($ics_data);
}
-
}
diff --git a/src/docs/user/userguide/calendar_exports.diviner b/src/docs/user/userguide/calendar_exports.diviner
--- a/src/docs/user/userguide/calendar_exports.diviner
+++ b/src/docs/user/userguide/calendar_exports.diviner
@@ -9,4 +9,89 @@
IMPORTANT: Calendar is a prototype application. See
@{article:User Guide: Prototype Applications}.
-Coming soon!
+You can export events from Phabricator to other calendar applications like
+**Google Calendar** or **Calendar.app**. This document will guide you through
+how to export event data from Phabricator.
+
+When you export events into another application, they generally will not be
+editable from that application. Exporting events allows you to create one
+calendar that shows all the events you care about in whatever application you
+prefer (so you can keep track of everything you need to do), but does not let
+you edit Phabricator events from another application.
+
+When exporting events, you can either export individual events one at a time
+or export an entire group of events (for example, all events you are attending).
+
+
+Exporting a Single Event
+========================
+
+To export a single event, visit the event detail page and click
+{nav Export as .ics}. This will download an `.ics` file which you can import
+into most other calendar applications.
+
+Mail you receive about events also has a copy of this `.ics` file attached to
+it. You can import this `.ics` file directly.
+
+In **Google Calendar**, use {nav Other Calendars > Import Calendar} to import
+the `.ics` file.
+
+In **Calendar.app**, use {nav File > Import...} to import the `.ics` file, or
+drag the `.ics` file onto your calendar.
+
+When you export a recurring event, the `.ics` file will contain information
+about the entire event series.
+
+If you want to update event information later, you can just repeat this
+process. Calendar applications will update the existing event if you've
+previously imported an older version of it.
+
+
+Exporting a Group of Events
+===========================
+
+You can export a group of events matching an arbitrary query (like all events
+you are attending) to keep different calendars in sync.
+
+To export a group of events:
+
+ - Run a query in Calendar which selects the events you want to export.
+ - Example: All events you are attending.
+ - Example: All events you are invited to.
+ - Example: All events tagged `#meetup`.
+ - Select the {nav Use Results... > Export Query as .ics} action to turn
+ the query into an export.
+ - Name the export with a descritive name.
+ - Select a policy mode for the export (see below for discussion).
+ - Click {nav Create New Export} to finish the process.
+
+The **policy modes** for exports are:
+
+ - **Public**: Only public information (visible to logged-out users) will
+ be exported. This mode is not available if your install does not have
+ public information (per `policy.allow-public` in Config).
+ - **Privileged**: All event information will be exported. This means that
+ anyone who knows the export URI can see ALL of the related event
+ information, as though they were logged in with your account.
+
+WARNING: Anyone who learns the URI for an export can see the data you choose
+to export, even if they don't have a Phabricator account! Be careful about how
+much data you export and treat the URI as a secret. If you accidentally share
+a URI, you can disable the export.
+
+After finishing the process, you'll see a screen with some details about the
+export and an **ICS URI**. This URI allows you to import the events which match
+the query into another calendar application.
+
+In **Google Calendar**, use {nav Other Calendars > Add by URL} to import the
+URI.
+
+In **Calendar.app**, use {nav File > New Calendar Subscription...} to subscribe
+to the URI.
+
+Next Steps
+==========
+
+Continue by:
+
+ - returning to the @{article:Calendar User Guide}.
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Dec 20, 5:44 AM (20 h, 52 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6909596
Default Alt Text
D16680.diff (9 KB)
Attached To
Mode
D16680: Document how to export Calendar events
Attached
Detach File
Event Timeline
Log In to Comment