mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 08:52:39 +01:00
Allow events from a particular import source to be bulk-deleted
Summary: Ref T10747. If you accidentally import the wrong thing, you can clean up the big mess you made. These imported events are read-only so it's OK to destroy them completely (vs disable/hide/archive). Test Plan: Destroyed some imported events. Reviewers: chad Reviewed By: chad Maniphest Tasks: T10747 Differential Revision: https://secure.phabricator.com/D16720
This commit is contained in:
parent
94a5a09d75
commit
b47a42bf55
7 changed files with 132 additions and 1 deletions
|
@ -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',
|
||||
|
|
|
@ -83,6 +83,8 @@ final class PhabricatorCalendarApplication extends PhabricatorApplication {
|
|||
=> 'PhabricatorCalendarImportViewController',
|
||||
'disable/(?P<id>[1-9]\d*)/'
|
||||
=> 'PhabricatorCalendarImportDisableController',
|
||||
'delete/(?P<id>[1-9]\d*)/'
|
||||
=> 'PhabricatorCalendarImportDeleteController',
|
||||
'log/' => array(
|
||||
$this->getQueryRoutePattern()
|
||||
=> 'PhabricatorCalendarImportLogListController',
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorCalendarImportDeleteController
|
||||
extends PhabricatorCalendarController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->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'));
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ final class PhabricatorCalendarImportLogView extends AphrontView {
|
|||
pht('Source'),
|
||||
null,
|
||||
pht('Type'),
|
||||
pht('Mesage'),
|
||||
pht('Message'),
|
||||
pht('Date'),
|
||||
))
|
||||
->setColumnVisibility(
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorCalendarImportDeleteTransaction
|
||||
extends PhabricatorCalendarImportTransactionType {
|
||||
|
||||
const TRANSACTIONTYPE = 'calendar.import.delete';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function applyExternalEffects($object, $value) {
|
||||
$events = id(new PhabricatorCalendarEventQuery())
|
||||
->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());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue