Page MenuHomePhabricator

D16680.id40161.diff
No OneTemporary

D16680.id40161.diff

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

Mime Type
text/plain
Expires
Thu, Oct 24, 10:20 PM (3 w, 3 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6720525
Default Alt Text
D16680.id40161.diff (9 KB)

Event Timeline