@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+156 -38
+2
src/__phutil_library_map__.php
··· 2094 2094 'PhabricatorCalendarExportViewController' => 'applications/calendar/controller/PhabricatorCalendarExportViewController.php', 2095 2095 'PhabricatorCalendarHoliday' => 'applications/calendar/storage/PhabricatorCalendarHoliday.php', 2096 2096 'PhabricatorCalendarHolidayTestCase' => 'applications/calendar/storage/__tests__/PhabricatorCalendarHolidayTestCase.php', 2097 + 'PhabricatorCalendarICSWriter' => 'applications/calendar/util/PhabricatorCalendarICSWriter.php', 2097 2098 'PhabricatorCalendarIconSet' => 'applications/calendar/icon/PhabricatorCalendarIconSet.php', 2098 2099 'PhabricatorCalendarRemarkupRule' => 'applications/calendar/remarkup/PhabricatorCalendarRemarkupRule.php', 2099 2100 'PhabricatorCalendarReplyHandler' => 'applications/calendar/mail/PhabricatorCalendarReplyHandler.php', ··· 6866 6867 'PhabricatorCalendarExportViewController' => 'PhabricatorCalendarController', 6867 6868 'PhabricatorCalendarHoliday' => 'PhabricatorCalendarDAO', 6868 6869 'PhabricatorCalendarHolidayTestCase' => 'PhabricatorTestCase', 6870 + 'PhabricatorCalendarICSWriter' => 'Phobject', 6869 6871 'PhabricatorCalendarIconSet' => 'PhabricatorIconSet', 6870 6872 'PhabricatorCalendarRemarkupRule' => 'PhabricatorObjectRemarkupRule', 6871 6873 'PhabricatorCalendarReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
+4 -27
src/applications/calendar/controller/PhabricatorCalendarController.php
··· 6 6 PhabricatorUser $viewer, 7 7 $file_name, 8 8 array $events) { 9 - $events = mpull($events, null, 'getPHID'); 10 9 11 - if ($events) { 12 - $child_map = id(new PhabricatorCalendarEventQuery()) 13 - ->setViewer($viewer) 14 - ->withParentEventPHIDs(array_keys($events)) 15 - ->execute(); 16 - $child_map = mpull($child_map, null, 'getPHID'); 17 - } else { 18 - $child_map = array(); 19 - } 20 - 21 - $all_events = $events + $child_map; 22 - $child_groups = mgroup($child_map, 'getInstanceOfEventPHID'); 23 - 24 - $document_node = new PhutilCalendarDocumentNode(); 25 - 26 - foreach ($all_events as $event) { 27 - $child_events = idx($child_groups, $event->getPHID(), array()); 28 - $event_node = $event->newIntermediateEventNode($viewer, $child_events); 29 - $document_node->appendChild($event_node); 30 - } 31 - 32 - $root_node = id(new PhutilCalendarRootNode()) 33 - ->appendChild($document_node); 34 - 35 - $ics_data = id(new PhutilICSWriter()) 36 - ->writeICSDocument($root_node); 10 + $ics_data = id(new PhabricatorCalendarICSWriter()) 11 + ->setViewer($viewer) 12 + ->setEvents($events) 13 + ->writeICSDocument(); 37 14 38 15 return id(new AphrontFileResponse()) 39 16 ->setDownload($file_name)
+4 -10
src/applications/calendar/editor/PhabricatorCalendarEventEditor.php
··· 309 309 PhabricatorCalendarEvent $event) { 310 310 $actor = $this->getActor(); 311 311 312 - $event_node = $event->newIntermediateEventNode($actor); 313 - 314 - $document_node = id(new PhutilCalendarDocumentNode()) 315 - ->appendChild($event_node); 316 - 317 - $root_node = id(new PhutilCalendarRootNode()) 318 - ->appendChild($document_node); 319 - 320 - $ics_data = id(new PhutilICSWriter()) 321 - ->writeICSDocument($root_node); 312 + $ics_data = id(new PhabricatorCalendarICSWriter()) 313 + ->setViewer($actor) 314 + ->setEvents(array($event)) 315 + ->writeICSDocument(); 322 316 323 317 $ics_attachment = new PhabricatorMetaMTAAttachment( 324 318 $ics_data,
+60
src/applications/calendar/util/PhabricatorCalendarICSWriter.php
··· 1 + <?php 2 + 3 + final class PhabricatorCalendarICSWriter extends Phobject { 4 + 5 + private $viewer; 6 + private $events = array(); 7 + 8 + public function setViewer(PhabricatorUser $viewer) { 9 + $this->viewer = $viewer; 10 + return $this; 11 + } 12 + 13 + public function getViewer() { 14 + return $this->viewer; 15 + } 16 + 17 + public function setEvents(array $events) { 18 + assert_instances_of($events, 'PhabricatorCalendarEvent'); 19 + $this->events = $events; 20 + return $this; 21 + } 22 + 23 + public function getEvents() { 24 + return $this->events; 25 + } 26 + 27 + public function writeICSDocument() { 28 + $viewer = $this->getViewer(); 29 + $events = $this->getEvents(); 30 + 31 + $events = mpull($events, null, 'getPHID'); 32 + 33 + if ($events) { 34 + $child_map = id(new PhabricatorCalendarEventQuery()) 35 + ->setViewer($viewer) 36 + ->withParentEventPHIDs(array_keys($events)) 37 + ->execute(); 38 + $child_map = mpull($child_map, null, 'getPHID'); 39 + } else { 40 + $child_map = array(); 41 + } 42 + 43 + $all_events = $events + $child_map; 44 + $child_groups = mgroup($child_map, 'getInstanceOfEventPHID'); 45 + 46 + $document_node = new PhutilCalendarDocumentNode(); 47 + 48 + foreach ($all_events as $event) { 49 + $child_events = idx($child_groups, $event->getPHID(), array()); 50 + $event_node = $event->newIntermediateEventNode($viewer, $child_events); 51 + $document_node->appendChild($event_node); 52 + } 53 + 54 + $root_node = id(new PhutilCalendarRootNode()) 55 + ->appendChild($document_node); 56 + 57 + return id(new PhutilICSWriter()) 58 + ->writeICSDocument($root_node); 59 + } 60 + }
+86 -1
src/docs/user/userguide/calendar_exports.diviner
··· 9 9 IMPORTANT: Calendar is a prototype application. See 10 10 @{article:User Guide: Prototype Applications}. 11 11 12 - Coming soon! 12 + You can export events from Phabricator to other calendar applications like 13 + **Google Calendar** or **Calendar.app**. This document will guide you through 14 + how to export event data from Phabricator. 15 + 16 + When you export events into another application, they generally will not be 17 + editable from that application. Exporting events allows you to create one 18 + calendar that shows all the events you care about in whatever application you 19 + prefer (so you can keep track of everything you need to do), but does not let 20 + you edit Phabricator events from another application. 21 + 22 + When exporting events, you can either export individual events one at a time 23 + or export an entire group of events (for example, all events you are attending). 24 + 25 + 26 + Exporting a Single Event 27 + ======================== 28 + 29 + To export a single event, visit the event detail page and click 30 + {nav Export as .ics}. This will download an `.ics` file which you can import 31 + into most other calendar applications. 32 + 33 + Mail you receive about events also has a copy of this `.ics` file attached to 34 + it. You can import this `.ics` file directly. 35 + 36 + In **Google Calendar**, use {nav Other Calendars > Import Calendar} to import 37 + the `.ics` file. 38 + 39 + In **Calendar.app**, use {nav File > Import...} to import the `.ics` file, or 40 + drag the `.ics` file onto your calendar. 41 + 42 + When you export a recurring event, the `.ics` file will contain information 43 + about the entire event series. 44 + 45 + If you want to update event information later, you can just repeat this 46 + process. Calendar applications will update the existing event if you've 47 + previously imported an older version of it. 48 + 49 + 50 + Exporting a Group of Events 51 + =========================== 52 + 53 + You can export a group of events matching an arbitrary query (like all events 54 + you are attending) to keep different calendars in sync. 55 + 56 + To export a group of events: 57 + 58 + - Run a query in Calendar which selects the events you want to export. 59 + - Example: All events you are attending. 60 + - Example: All events you are invited to. 61 + - Example: All events tagged `#meetup`. 62 + - Select the {nav Use Results... > Export Query as .ics} action to turn 63 + the query into an export. 64 + - Name the export with a descritive name. 65 + - Select a policy mode for the export (see below for discussion). 66 + - Click {nav Create New Export} to finish the process. 67 + 68 + The **policy modes** for exports are: 69 + 70 + - **Public**: Only public information (visible to logged-out users) will 71 + be exported. This mode is not available if your install does not have 72 + public information (per `policy.allow-public` in Config). 73 + - **Privileged**: All event information will be exported. This means that 74 + anyone who knows the export URI can see ALL of the related event 75 + information, as though they were logged in with your account. 76 + 77 + WARNING: Anyone who learns the URI for an export can see the data you choose 78 + to export, even if they don't have a Phabricator account! Be careful about how 79 + much data you export and treat the URI as a secret. If you accidentally share 80 + a URI, you can disable the export. 81 + 82 + After finishing the process, you'll see a screen with some details about the 83 + export and an **ICS URI**. This URI allows you to import the events which match 84 + the query into another calendar application. 85 + 86 + In **Google Calendar**, use {nav Other Calendars > Add by URL} to import the 87 + URI. 88 + 89 + In **Calendar.app**, use {nav File > New Calendar Subscription...} to subscribe 90 + to the URI. 91 + 92 + Next Steps 93 + ========== 94 + 95 + Continue by: 96 + 97 + - returning to the @{article:Calendar User Guide}.