1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-27 01:02:42 +01:00

Document how to export Calendar events

Summary:
Ref T10747. This explains how exports work.

Also make mail exports use the same logic as other stuff.

Test Plan: Read documentation. Did some exports.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10747

Differential Revision: https://secure.phabricator.com/D16680
This commit is contained in:
epriestley 2016-10-06 14:46:50 -07:00
parent 4819446fe5
commit ff97ed2195
5 changed files with 156 additions and 38 deletions

View file

@ -2094,6 +2094,7 @@ phutil_register_library_map(array(
'PhabricatorCalendarExportViewController' => 'applications/calendar/controller/PhabricatorCalendarExportViewController.php', 'PhabricatorCalendarExportViewController' => 'applications/calendar/controller/PhabricatorCalendarExportViewController.php',
'PhabricatorCalendarHoliday' => 'applications/calendar/storage/PhabricatorCalendarHoliday.php', 'PhabricatorCalendarHoliday' => 'applications/calendar/storage/PhabricatorCalendarHoliday.php',
'PhabricatorCalendarHolidayTestCase' => 'applications/calendar/storage/__tests__/PhabricatorCalendarHolidayTestCase.php', 'PhabricatorCalendarHolidayTestCase' => 'applications/calendar/storage/__tests__/PhabricatorCalendarHolidayTestCase.php',
'PhabricatorCalendarICSWriter' => 'applications/calendar/util/PhabricatorCalendarICSWriter.php',
'PhabricatorCalendarIconSet' => 'applications/calendar/icon/PhabricatorCalendarIconSet.php', 'PhabricatorCalendarIconSet' => 'applications/calendar/icon/PhabricatorCalendarIconSet.php',
'PhabricatorCalendarRemarkupRule' => 'applications/calendar/remarkup/PhabricatorCalendarRemarkupRule.php', 'PhabricatorCalendarRemarkupRule' => 'applications/calendar/remarkup/PhabricatorCalendarRemarkupRule.php',
'PhabricatorCalendarReplyHandler' => 'applications/calendar/mail/PhabricatorCalendarReplyHandler.php', 'PhabricatorCalendarReplyHandler' => 'applications/calendar/mail/PhabricatorCalendarReplyHandler.php',
@ -6866,6 +6867,7 @@ phutil_register_library_map(array(
'PhabricatorCalendarExportViewController' => 'PhabricatorCalendarController', 'PhabricatorCalendarExportViewController' => 'PhabricatorCalendarController',
'PhabricatorCalendarHoliday' => 'PhabricatorCalendarDAO', 'PhabricatorCalendarHoliday' => 'PhabricatorCalendarDAO',
'PhabricatorCalendarHolidayTestCase' => 'PhabricatorTestCase', 'PhabricatorCalendarHolidayTestCase' => 'PhabricatorTestCase',
'PhabricatorCalendarICSWriter' => 'Phobject',
'PhabricatorCalendarIconSet' => 'PhabricatorIconSet', 'PhabricatorCalendarIconSet' => 'PhabricatorIconSet',
'PhabricatorCalendarRemarkupRule' => 'PhabricatorObjectRemarkupRule', 'PhabricatorCalendarRemarkupRule' => 'PhabricatorObjectRemarkupRule',
'PhabricatorCalendarReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler', 'PhabricatorCalendarReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',

View file

@ -6,34 +6,11 @@ abstract class PhabricatorCalendarController extends PhabricatorController {
PhabricatorUser $viewer, PhabricatorUser $viewer,
$file_name, $file_name,
array $events) { array $events) {
$events = mpull($events, null, 'getPHID');
if ($events) { $ics_data = id(new PhabricatorCalendarICSWriter())
$child_map = id(new PhabricatorCalendarEventQuery()) ->setViewer($viewer)
->setViewer($viewer) ->setEvents($events)
->withParentEventPHIDs(array_keys($events)) ->writeICSDocument();
->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);
return id(new AphrontFileResponse()) return id(new AphrontFileResponse())
->setDownload($file_name) ->setDownload($file_name)

View file

@ -309,16 +309,10 @@ final class PhabricatorCalendarEventEditor
PhabricatorCalendarEvent $event) { PhabricatorCalendarEvent $event) {
$actor = $this->getActor(); $actor = $this->getActor();
$event_node = $event->newIntermediateEventNode($actor); $ics_data = id(new PhabricatorCalendarICSWriter())
->setViewer($actor)
$document_node = id(new PhutilCalendarDocumentNode()) ->setEvents(array($event))
->appendChild($event_node); ->writeICSDocument();
$root_node = id(new PhutilCalendarRootNode())
->appendChild($document_node);
$ics_data = id(new PhutilICSWriter())
->writeICSDocument($root_node);
$ics_attachment = new PhabricatorMetaMTAAttachment( $ics_attachment = new PhabricatorMetaMTAAttachment(
$ics_data, $ics_data,

View file

@ -0,0 +1,60 @@
<?php
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();
$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);
return id(new PhutilICSWriter())
->writeICSDocument($root_node);
}
}

View file

@ -9,4 +9,89 @@ Overview
IMPORTANT: Calendar is a prototype application. See IMPORTANT: Calendar is a prototype application. See
@{article:User Guide: Prototype Applications}. @{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}.