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 @@ -2044,6 +2044,7 @@ 'PhabricatorCalendarEventEditor' => 'applications/calendar/editor/PhabricatorCalendarEventEditor.php', 'PhabricatorCalendarEventEmailCommand' => 'applications/calendar/command/PhabricatorCalendarEventEmailCommand.php', 'PhabricatorCalendarEventEndDateTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventEndDateTransaction.php', + 'PhabricatorCalendarEventExportController' => 'applications/calendar/controller/PhabricatorCalendarEventExportController.php', 'PhabricatorCalendarEventFrequencyTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventFrequencyTransaction.php', 'PhabricatorCalendarEventFulltextEngine' => 'applications/calendar/search/PhabricatorCalendarEventFulltextEngine.php', 'PhabricatorCalendarEventHeraldAdapter' => 'applications/calendar/herald/PhabricatorCalendarEventHeraldAdapter.php', @@ -6781,6 +6782,7 @@ 'PhabricatorCalendarEventEditor' => 'PhabricatorApplicationTransactionEditor', 'PhabricatorCalendarEventEmailCommand' => 'MetaMTAEmailTransactionCommand', 'PhabricatorCalendarEventEndDateTransaction' => 'PhabricatorCalendarEventDateTransaction', + 'PhabricatorCalendarEventExportController' => 'PhabricatorCalendarController', 'PhabricatorCalendarEventFrequencyTransaction' => 'PhabricatorCalendarEventTransactionType', 'PhabricatorCalendarEventFulltextEngine' => 'PhabricatorFulltextEngine', 'PhabricatorCalendarEventHeraldAdapter' => 'HeraldAdapter', diff --git a/src/applications/calendar/application/PhabricatorCalendarApplication.php b/src/applications/calendar/application/PhabricatorCalendarApplication.php --- a/src/applications/calendar/application/PhabricatorCalendarApplication.php +++ b/src/applications/calendar/application/PhabricatorCalendarApplication.php @@ -59,6 +59,8 @@ => 'PhabricatorCalendarEventCancelController', '(?Pjoin|decline|accept)/(?P[1-9]\d*)/' => 'PhabricatorCalendarEventJoinController', + 'export/(?P[1-9]\d*)/' + => 'PhabricatorCalendarEventExportController', ), ), ); diff --git a/src/applications/calendar/controller/PhabricatorCalendarEventExportController.php b/src/applications/calendar/controller/PhabricatorCalendarEventExportController.php new file mode 100644 --- /dev/null +++ b/src/applications/calendar/controller/PhabricatorCalendarEventExportController.php @@ -0,0 +1,54 @@ +getViewer(); + $id = $request->getURIData('id'); + + $event = id(new PhabricatorCalendarEventQuery()) + ->setViewer($viewer) + ->withIDs(array($id)) + ->executeOne(); + if (!$event) { + return new Aphront404Response(); + } + + if ($request->isFormPost()) { + $file_name = $event->getMonogram().'.ics'; + + $event_node = $event->newIntermediateEventNode(); + + $document_node = id(new PhutilCalendarDocumentNode()) + ->appendChild($event_node); + + $root_node = id(new PhutilCalendarRootNode()) + ->appendChild($document_node); + + $ics_data = id(new PhutilICSWriter()) + ->writeICSDocument($root_node); + + return id(new AphrontFileResponse()) + ->setDownload($file_name) + ->setMimeType('text/calendar') + ->setContent($ics_data); + } + + return $this->newDialog() + ->setDisableWorkflowOnSubmit(true) + ->setTitle(pht('Export as .ics')) + ->appendParagraph( + pht( + 'WARNING: This feature is a prototype and only supports a limited '. + 'set of features. Keep your expectations low!')) + ->addSubmitButton(pht('Download .ics')) + ->addCancelButton($event->getURI(), pht('Close')); + + } + +} diff --git a/src/applications/calendar/controller/PhabricatorCalendarEventViewController.php b/src/applications/calendar/controller/PhabricatorCalendarEventViewController.php --- a/src/applications/calendar/controller/PhabricatorCalendarEventViewController.php +++ b/src/applications/calendar/controller/PhabricatorCalendarEventViewController.php @@ -193,6 +193,15 @@ ->setWorkflow(true)); } + $export_uri = $this->getApplicationURI("event/export/{$id}/"); + + $curtain->addAction( + id(new PhabricatorActionView()) + ->setName(pht('Export as .ics')) + ->setIcon('fa-download') + ->setHref($export_uri) + ->setWorkflow(true)); + return $curtain; } diff --git a/src/applications/calendar/storage/PhabricatorCalendarEvent.php b/src/applications/calendar/storage/PhabricatorCalendarEvent.php --- a/src/applications/calendar/storage/PhabricatorCalendarEvent.php +++ b/src/applications/calendar/storage/PhabricatorCalendarEvent.php @@ -626,6 +626,43 @@ } + public function newIntermediateEventNode() { + $base_uri = new PhutilURI(PhabricatorEnv::getProductionURI('/')); + $domain = $base_uri->getDomain(); + + $uid = $this->getPHID().'@'.$domain; + + $created = $this->getDateCreated(); + $created = PhutilCalendarAbsoluteDateTime::newFromEpoch($created); + + $modified = $this->getDateModified(); + $modified = PhutilCalendarAbsoluteDateTime::newFromEpoch($modified); + + $date_start = $this->getDateFrom(); + $date_start = PhutilCalendarAbsoluteDateTime::newFromEpoch($date_start); + + $date_end = $this->getDateTo(); + $date_end = PhutilCalendarAbsoluteDateTime::newFromEpoch($date_end); + + if ($this->getIsAllDay()) { + $date_start->setIsAllDay(true); + $date_end->setIsAllDay(true); + } + + $node = id(new PhutilCalendarEventNode()) + ->setUID($uid) + ->setName($this->getName()) + ->setDescription($this->getDescription()) + ->setCreatedDateTime($created) + ->setModifiedDateTime($modified) + ->setStartDateTime($date_start) + ->setEndDateTime($date_end); + + return $node; + } + + + /* -( Markup Interface )--------------------------------------------------- */