@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.

Make .ics export less scary and attach .ics files to event mail

Summary:
Ref T10747.

- Remove the warning dialog since these files don't seem to do anything confusing/problematic in Calendar.app or Google Calendar. Those importers generally need to be defensive about how they handle random ".ics" files from arbitrary third parties anyway, and this makes testing imports easier since we have a GET-table ".ics" URI for public events.
- Attach ".ics" files to email.

Test Plan:
- Clicked "Export as .ics", got an ICS file.
- Used "bin/mail show-outbound" to review an ICS attachment, although I don't actually have real mail set up locally so this may still be a little funky.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10747

Differential Revision: https://secure.phabricator.com/D16559

+43 -30
+1 -1
src/applications/calendar/application/PhabricatorCalendarApplication.php
··· 59 59 => 'PhabricatorCalendarEventCancelController', 60 60 '(?P<action>join|decline|accept)/(?P<id>[1-9]\d*)/' 61 61 => 'PhabricatorCalendarEventJoinController', 62 - 'export/(?P<id>[1-9]\d*)/' 62 + 'export/(?P<id>[1-9]\d*)/(?P<filename>[^/]*)' 63 63 => 'PhabricatorCalendarEventExportController', 64 64 ), 65 65 ),
+12 -26
src/applications/calendar/controller/PhabricatorCalendarEventExportController.php
··· 19 19 return new Aphront404Response(); 20 20 } 21 21 22 - if ($request->isFormPost()) { 23 - $file_name = $event->getMonogram().'.ics'; 24 - 25 - $event_node = $event->newIntermediateEventNode($viewer); 22 + $file_name = $event->getICSFilename(); 23 + $event_node = $event->newIntermediateEventNode($viewer); 26 24 27 - $document_node = id(new PhutilCalendarDocumentNode()) 28 - ->appendChild($event_node); 25 + $document_node = id(new PhutilCalendarDocumentNode()) 26 + ->appendChild($event_node); 29 27 30 - $root_node = id(new PhutilCalendarRootNode()) 31 - ->appendChild($document_node); 32 - 33 - $ics_data = id(new PhutilICSWriter()) 34 - ->writeICSDocument($root_node); 35 - 36 - return id(new AphrontFileResponse()) 37 - ->setDownload($file_name) 38 - ->setMimeType('text/calendar') 39 - ->setContent($ics_data); 40 - } 28 + $root_node = id(new PhutilCalendarRootNode()) 29 + ->appendChild($document_node); 41 30 42 - return $this->newDialog() 43 - ->setDisableWorkflowOnSubmit(true) 44 - ->setTitle(pht('Export as .ics')) 45 - ->appendParagraph( 46 - pht( 47 - 'WARNING: This feature is a prototype and only supports a limited '. 48 - 'set of features. Keep your expectations low!')) 49 - ->addSubmitButton(pht('Download .ics')) 50 - ->addCancelButton($event->getURI(), pht('Close')); 31 + $ics_data = id(new PhutilICSWriter()) 32 + ->writeICSDocument($root_node); 51 33 34 + return id(new AphrontFileResponse()) 35 + ->setDownload($file_name) 36 + ->setMimeType('text/calendar') 37 + ->setContent($ics_data); 52 38 } 53 39 54 40 }
+3 -3
src/applications/calendar/controller/PhabricatorCalendarEventViewController.php
··· 193 193 ->setWorkflow(true)); 194 194 } 195 195 196 - $export_uri = $this->getApplicationURI("event/export/{$id}/"); 196 + $ics_name = $event->getICSFilename(); 197 + $export_uri = $this->getApplicationURI("event/export/{$id}/{$ics_name}"); 197 198 198 199 $curtain->addAction( 199 200 id(new PhabricatorActionView()) 200 201 ->setName(pht('Export as .ics')) 201 202 ->setIcon('fa-download') 202 - ->setHref($export_uri) 203 - ->setWorkflow(true)); 203 + ->setHref($export_uri)); 204 204 205 205 return $curtain; 206 206 }
+24
src/applications/calendar/editor/PhabricatorCalendarEventEditor.php
··· 285 285 pht('EVENT DETAIL'), 286 286 PhabricatorEnv::getProductionURI('/E'.$object->getID())); 287 287 288 + $ics_attachment = $this->newICSAttachment($object); 289 + $body->addAttachment($ics_attachment); 288 290 289 291 return $body; 290 292 } ··· 303 305 ->setObject($object); 304 306 } 305 307 308 + private function newICSAttachment( 309 + PhabricatorCalendarEvent $event) { 310 + $actor = $this->getActor(); 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); 322 + 323 + $ics_attachment = new PhabricatorMetaMTAAttachment( 324 + $ics_data, 325 + $event->getICSFilename(), 326 + 'text/calendar'); 327 + 328 + return $ics_attachment; 329 + } 306 330 307 331 }
+3
src/applications/calendar/storage/PhabricatorCalendarEvent.php
··· 625 625 return null; 626 626 } 627 627 628 + public function getICSFilename() { 629 + return $this->getMonogram().'.ics'; 630 + } 628 631 629 632 public function newIntermediateEventNode(PhabricatorUser $viewer) { 630 633 $base_uri = new PhutilURI(PhabricatorEnv::getProductionURI('/'));