diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 1733b447eb..bf92e734b1 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2105,6 +2105,8 @@ phutil_register_library_map(array( 'PhabricatorCalendarIconSet' => 'applications/calendar/icon/PhabricatorCalendarIconSet.php', 'PhabricatorCalendarImport' => 'applications/calendar/storage/PhabricatorCalendarImport.php', 'PhabricatorCalendarImportDefaultLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportDefaultLogType.php', + 'PhabricatorCalendarImportDeleteController' => 'applications/calendar/controller/PhabricatorCalendarImportDeleteController.php', + 'PhabricatorCalendarImportDeleteTransaction' => 'applications/calendar/xaction/PhabricatorCalendarImportDeleteTransaction.php', 'PhabricatorCalendarImportDisableController' => 'applications/calendar/controller/PhabricatorCalendarImportDisableController.php', 'PhabricatorCalendarImportDisableTransaction' => 'applications/calendar/xaction/PhabricatorCalendarImportDisableTransaction.php', 'PhabricatorCalendarImportDuplicateLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportDuplicateLogType.php', @@ -6937,6 +6939,8 @@ phutil_register_library_map(array( 'PhabricatorDestructibleInterface', ), 'PhabricatorCalendarImportDefaultLogType' => 'PhabricatorCalendarImportLogType', + 'PhabricatorCalendarImportDeleteController' => 'PhabricatorCalendarController', + 'PhabricatorCalendarImportDeleteTransaction' => 'PhabricatorCalendarImportTransactionType', 'PhabricatorCalendarImportDisableController' => 'PhabricatorCalendarController', 'PhabricatorCalendarImportDisableTransaction' => 'PhabricatorCalendarImportTransactionType', 'PhabricatorCalendarImportDuplicateLogType' => 'PhabricatorCalendarImportLogType', diff --git a/src/applications/calendar/application/PhabricatorCalendarApplication.php b/src/applications/calendar/application/PhabricatorCalendarApplication.php index ebd0dde088..807e2b9956 100644 --- a/src/applications/calendar/application/PhabricatorCalendarApplication.php +++ b/src/applications/calendar/application/PhabricatorCalendarApplication.php @@ -83,6 +83,8 @@ final class PhabricatorCalendarApplication extends PhabricatorApplication { => 'PhabricatorCalendarImportViewController', 'disable/(?P[1-9]\d*)/' => 'PhabricatorCalendarImportDisableController', + 'delete/(?P[1-9]\d*)/' + => 'PhabricatorCalendarImportDeleteController', 'log/' => array( $this->getQueryRoutePattern() => 'PhabricatorCalendarImportLogListController', diff --git a/src/applications/calendar/controller/PhabricatorCalendarImportDeleteController.php b/src/applications/calendar/controller/PhabricatorCalendarImportDeleteController.php new file mode 100644 index 0000000000..fd65777515 --- /dev/null +++ b/src/applications/calendar/controller/PhabricatorCalendarImportDeleteController.php @@ -0,0 +1,64 @@ +getViewer(); + + $import = id(new PhabricatorCalendarImportQuery()) + ->setViewer($viewer) + ->withIDs(array($request->getURIData('id'))) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->executeOne(); + if (!$import) { + return new Aphront404Response(); + } + + $import_uri = $import->getURI(); + + $engine = $import->getEngine(); + if (!$engine->canDeleteAnyEvents($viewer, $import)) { + return $this->newDialog() + ->setTitle(pht('No Imported Events')) + ->appendParagraph( + pht( + 'No events from this source currently exist. They may have '. + 'failed to import, have been updated by another source, or '. + 'already have been deleted.')) + ->addCancelButton($import_uri, pht('Done')); + } + + if ($request->isFormPost()) { + $xactions = array(); + $xactions[] = id(new PhabricatorCalendarImportTransaction()) + ->setTransactionType( + PhabricatorCalendarImportDeleteTransaction::TRANSACTIONTYPE) + ->setNewValue(true); + + $editor = id(new PhabricatorCalendarImportEditor()) + ->setActor($viewer) + ->setContinueOnNoEffect(true) + ->setContinueOnMissingFields(true) + ->setContentSourceFromRequest($request); + + $editor->applyTransactions($import, $xactions); + + return id(new AphrontRedirectResponse())->setURI($import_uri); + } + + return $this->newDialog() + ->setTitle(pht('Delete Imported Events')) + ->appendParagraph( + pht( + 'Delete all the events that were imported from this source? '. + 'This action can not be undone.')) + ->addCancelButton($import_uri) + ->addSubmitButton(pht('Delete Events')); + } + +} diff --git a/src/applications/calendar/controller/PhabricatorCalendarImportViewController.php b/src/applications/calendar/controller/PhabricatorCalendarImportViewController.php index 2333dab45c..0ecd5787cb 100644 --- a/src/applications/calendar/controller/PhabricatorCalendarImportViewController.php +++ b/src/applications/calendar/controller/PhabricatorCalendarImportViewController.php @@ -123,6 +123,24 @@ final class PhabricatorCalendarImportViewController ->setWorkflow(true) ->setHref($disable_uri)); + + if ($can_edit) { + $can_delete = $engine->canDeleteAnyEvents($viewer, $import); + } else { + $can_delete = false; + } + + $delete_uri = "import/delete/{$id}/"; + $delete_uri = $this->getApplicationURI($delete_uri); + + $curtain->addAction( + id(new PhabricatorActionView()) + ->setName(pht('Delete Imported Events')) + ->setIcon('fa-times') + ->setDisabled(!$can_delete) + ->setWorkflow(true) + ->setHref($delete_uri)); + return $curtain; } diff --git a/src/applications/calendar/import/PhabricatorCalendarImportEngine.php b/src/applications/calendar/import/PhabricatorCalendarImportEngine.php index 6555b693e7..6e1b466cc0 100644 --- a/src/applications/calendar/import/PhabricatorCalendarImportEngine.php +++ b/src/applications/calendar/import/PhabricatorCalendarImportEngine.php @@ -398,4 +398,17 @@ abstract class PhabricatorCalendarImportEngine return $event; } + public function canDeleteAnyEvents( + PhabricatorUser $viewer, + PhabricatorCalendarImport $import) { + + $any_event = id(new PhabricatorCalendarEventQuery()) + ->setViewer($viewer) + ->withImportSourcePHIDs(array($import->getPHID())) + ->setLimit(1) + ->execute(); + + return (bool)$any_event; + } + } diff --git a/src/applications/calendar/view/PhabricatorCalendarImportLogView.php b/src/applications/calendar/view/PhabricatorCalendarImportLogView.php index abf40b3cd7..d33a8fdd38 100644 --- a/src/applications/calendar/view/PhabricatorCalendarImportLogView.php +++ b/src/applications/calendar/view/PhabricatorCalendarImportLogView.php @@ -60,7 +60,7 @@ final class PhabricatorCalendarImportLogView extends AphrontView { pht('Source'), null, pht('Type'), - pht('Mesage'), + pht('Message'), pht('Date'), )) ->setColumnVisibility( diff --git a/src/applications/calendar/xaction/PhabricatorCalendarImportDeleteTransaction.php b/src/applications/calendar/xaction/PhabricatorCalendarImportDeleteTransaction.php new file mode 100644 index 0000000000..83bf78169f --- /dev/null +++ b/src/applications/calendar/xaction/PhabricatorCalendarImportDeleteTransaction.php @@ -0,0 +1,30 @@ +setViewer($this->getActor()) + ->withImportSourcePHIDs(array($object->getPHID())) + ->execute(); + + $engine = new PhabricatorDestructionEngine(); + foreach ($events as $event) { + $engine->destroyObject($event); + } + } + + public function getTitle() { + return pht( + '%s deleted imported events from this source.', + $this->renderAuthor()); + } + +}