Page MenuHomePhabricator

D13145.diff
No OneTemporary

D13145.diff

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
@@ -57,7 +57,7 @@
=> 'PhabricatorCalendarEventEditController',
'drag/(?P<id>[1-9]\d*)/'
=> 'PhabricatorCalendarEventDragController',
- 'cancel/(?P<id>[1-9]\d*)/'
+ 'cancel/(?P<id>[1-9]\d*)/(?:(?P<sequence>\d+)/)?'
=> 'PhabricatorCalendarEventCancelController',
'(?P<action>join|decline|accept)/(?P<id>[1-9]\d*)/'
=> 'PhabricatorCalendarEventJoinController',
diff --git a/src/applications/calendar/controller/PhabricatorCalendarController.php b/src/applications/calendar/controller/PhabricatorCalendarController.php
--- a/src/applications/calendar/controller/PhabricatorCalendarController.php
+++ b/src/applications/calendar/controller/PhabricatorCalendarController.php
@@ -26,4 +26,47 @@
return $crumbs;
}
+ protected function getEventAtIndexForGhostPHID($viewer, $phid, $index) {
+ $result = id(new PhabricatorCalendarEventQuery())
+ ->setViewer($viewer)
+ ->withInstanceSequencePairs(
+ array(
+ array(
+ $phid,
+ $index,
+ ),
+ ))
+ ->requireCapabilities(
+ array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
+ ))
+ ->executeOne();
+
+ return $result;
+ }
+
+ protected function createEventFromGhost($viewer, $event, $index) {
+ $invitees = $event->getInvitees();
+
+ $new_ghost = $event->generateNthGhost($index, $viewer);
+ $new_ghost->attachParentEvent($event);
+
+ $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
+ $new_ghost
+ ->setID(null)
+ ->setPHID(null)
+ ->removeViewerTimezone($viewer)
+ ->save();
+ $ghost_invitees = array();
+ foreach ($invitees as $invitee) {
+ $ghost_invitee = clone $invitee;
+ $ghost_invitee
+ ->setID(null)
+ ->setEventPHID($new_ghost->getPHID())
+ ->save();
+ }
+ unset($unguarded);
+ return $new_ghost;
+ }
}
diff --git a/src/applications/calendar/controller/PhabricatorCalendarEventCancelController.php b/src/applications/calendar/controller/PhabricatorCalendarEventCancelController.php
--- a/src/applications/calendar/controller/PhabricatorCalendarEventCancelController.php
+++ b/src/applications/calendar/controller/PhabricatorCalendarEventCancelController.php
@@ -12,8 +12,9 @@
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
+ $sequence = $request->getURIData('sequence');
- $status = id(new PhabricatorCalendarEventQuery())
+ $event = id(new PhabricatorCalendarEventQuery())
->setViewer($user)
->withIDs(array($this->id))
->requireCapabilities(
@@ -23,15 +24,40 @@
))
->executeOne();
- if (!$status) {
+ if ($sequence) {
+ $parent_event = $event;
+ $event = $parent_event->generateNthGhost($sequence, $user);
+ $event->attachParentEvent($parent_event);
+ }
+
+ if (!$event) {
return new Aphront404Response();
}
- $cancel_uri = '/E'.$status->getID();
+ if (!$sequence) {
+ $cancel_uri = '/E'.$event->getID();
+ } else {
+ $cancel_uri = '/E'.$event->getID().'/'.$sequence;
+ }
+
+ $is_cancelled = $event->getIsCancelled();
+ $is_parent_cancelled = $event->getIsParentCancelled();
+ $is_recurring = $event->getIsRecurring();
+ $instance_of = $event->getInstanceOfEventPHID();
+
$validation_exception = null;
- $is_cancelled = $status->getIsCancelled();
if ($request->isFormPost()) {
+ if ($is_cancelled && $sequence) {
+ return id(new AphrontRedirectResponse())->setURI($cancel_uri);
+ } else if ($sequence) {
+ $event = $this->createEventFromGhost(
+ $user,
+ $event,
+ $sequence);
+ $event->applyViewerTimezone($user);
+ }
+
$xactions = array();
$xaction = id(new PhabricatorCalendarEventTransaction())
@@ -46,7 +72,7 @@
->setContinueOnMissingFields(true);
try {
- $editor->applyTransactions($status, array($xaction));
+ $editor->applyTransactions($event, array($xaction));
return id(new AphrontRedirectResponse())->setURI($cancel_uri);
} catch (PhabricatorApplicationTransactionValidationException $ex) {
$validation_exception = $ex;
@@ -54,15 +80,44 @@
}
if ($is_cancelled) {
- $title = pht('Reinstate Event');
- $paragraph = pht('Reinstate this event?');
- $cancel = pht('Don\'t Reinstate Event');
- $submit = pht('Reinstate Event');
+ if ($sequence || $is_parent_cancelled) {
+ $title = pht('Cannot Reinstate Instance');
+ $paragraph = pht('Cannot reinstate an instance of a
+ cancelled recurring event.');
+ $cancel = pht('Cancel');
+ $submit = null;
+ } else if ($is_recurring && !$instance_of) {
+ $title = pht('Reinstate Recurrence');
+ $paragraph = pht('Reinstate the entire series
+ of recurring events?');
+ $cancel = pht('Don\'t Reinstate Recurrence');
+ $submit = pht('Reinstate Recurrence');
+ } else {
+ $title = pht('Reinstate Event');
+ $paragraph = pht('Reinstate this event?');
+ $cancel = pht('Don\'t Reinstate Event');
+ $submit = pht('Reinstate Event');
+ }
} else {
- $title = pht('Cancel Event');
- $paragraph = pht('You can always reinstate the event later.');
- $cancel = pht('Don\'t Cancel Event');
- $submit = pht('Cancel Event');
+ if ($sequence) {
+ $title = pht('Cancel Instance');
+ $paragraph = pht('Cancel just this instance
+ of a recurring event.');
+ $cancel = pht('Don\'t Cancel Instance');
+ $submit = pht('Cancel Instance');
+ } else if ($is_recurring && !$instance_of) {
+ $title = pht('Cancel Recurrence');
+ $paragraph = pht('Cancel the entire series
+ of recurring events?');
+ $cancel = pht('Don\'t Cancel Recurrence');
+ $submit = pht('Cancel Recurrence');
+ } else {
+ $title = pht('Cancel Event');
+ $paragraph = pht('You can always reinstate
+ the event later.');
+ $cancel = pht('Don\'t Cancel Event');
+ $submit = pht('Cancel Event');
+ }
}
return $this->newDialog()
diff --git a/src/applications/calendar/controller/PhabricatorCalendarEventEditController.php b/src/applications/calendar/controller/PhabricatorCalendarEventEditController.php
--- a/src/applications/calendar/controller/PhabricatorCalendarEventEditController.php
+++ b/src/applications/calendar/controller/PhabricatorCalendarEventEditController.php
@@ -78,14 +78,15 @@
$cancel_uri = $this->getApplicationURI();
} else {
$event = id(new PhabricatorCalendarEventQuery())
- ->setViewer($viewer)
- ->withIDs(array($this->id))
- ->requireCapabilities(
- array(
- PhabricatorPolicyCapability::CAN_VIEW,
- PhabricatorPolicyCapability::CAN_EDIT,
- ))
- ->executeOne();
+ ->setViewer($viewer)
+ ->withIDs(array($this->id))
+ ->requireCapabilities(
+ array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
+ ))
+ ->executeOne();
+
if (!$event) {
return new Aphront404Response();
}
@@ -93,47 +94,23 @@
if ($request->getURIData('sequence')) {
$index = $request->getURIData('sequence');
- $result = id(new PhabricatorCalendarEventQuery())
- ->setViewer($viewer)
- ->withInstanceSequencePairs(
- array(
- array(
- $event->getPHID(),
- $index,
- ),
- ))
- ->requireCapabilities(
- array(
- PhabricatorPolicyCapability::CAN_VIEW,
- PhabricatorPolicyCapability::CAN_EDIT,
- ))
- ->executeOne();
+ $result = $this->getEventAtIndexForGhostPHID(
+ $viewer,
+ $event->getPHID(),
+ $index);
if ($result) {
return id(new AphrontRedirectResponse())
->setURI('/calendar/event/edit/'.$result->getID().'/');
}
- $invitees = $event->getInvitees();
-
- $new_ghost = $event->generateNthGhost($index, $viewer);
- $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
- $new_ghost
- ->setID(null)
- ->setPHID(null)
- ->removeViewerTimezone($viewer)
- ->save();
- $ghost_invitees = array();
- foreach ($invitees as $invitee) {
- $ghost_invitee = clone $invitee;
- $ghost_invitee
- ->setID(null)
- ->setEventPHID($new_ghost->getPHID())
- ->save();
- }
- unset($unguarded);
+ $event = $this->createEventFromGhost(
+ $viewer,
+ $event,
+ $index);
+
return id(new AphrontRedirectResponse())
- ->setURI('/calendar/event/edit/'.$new_ghost->getID().'/');
+ ->setURI('/calendar/event/edit/'.$event->getID().'/');
}
$end_value = AphrontFormDateControlValue::newFromEpoch(
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
@@ -27,12 +27,25 @@
return new Aphront404Response();
}
- if ($sequence && $event->getIsRecurring()) {
- $parent_event = $event;
- $event = $event->generateNthGhost($sequence, $viewer);
- $event->attachParentEvent($parent_event);
- } else if ($sequence) {
- return new Aphront404Response();
+ if ($sequence) {
+ $result = $this->getEventAtIndexForGhostPHID(
+ $viewer,
+ $event->getPHID(),
+ $sequence);
+
+ if ($result) {
+ $parent_event = $event;
+ $event = $result;
+ $event->attachParentEvent($parent_event);
+ return id(new AphrontRedirectResponse())
+ ->setURI('/E'.$result->getID());
+ } else if ($sequence && $event->getIsRecurring()) {
+ $parent_event = $event;
+ $event = $event->generateNthGhost($sequence, $viewer);
+ $event->attachParentEvent($parent_event);
+ } else if ($sequence) {
+ return new Aphront404Response();
+ }
}
$title = 'E'.$event->getID();
@@ -178,21 +191,46 @@
->setWorkflow(true));
}
+ $cancel_uri = $this->getApplicationURI("event/cancel/{$id}/");
+
+ if ($event->getIsGhostEvent()) {
+ $index = $event->getSequenceIndex();
+ $can_reinstate = $event->getIsParentCancelled();
+
+ $cancel_label = pht('Cancel This Instance');
+ $reinstate_label = pht('Reinstate This Instance');
+ $cancel_disabled = (!$can_edit || $can_reinstate);
+ $cancel_uri = $this->getApplicationURI("event/cancel/{$id}/{$index}/");
+ } else if ($event->getInstanceOfEventPHID()) {
+ $can_reinstate = $event->getIsParentCancelled();
+ $cancel_label = pht('Cancel This Instance');
+ $reinstate_label = pht('Reinstate This Instance');
+ $cancel_disabled = (!$can_edit || $can_reinstate);
+ } else if ($event->getIsRecurring()) {
+ $cancel_label = pht('Cancel Recurrence');
+ $reinstate_label = pht('Reinstate Recurrence');
+ $cancel_disabled = !$can_edit;
+ } else {
+ $cancel_label = pht('Cancel Event');
+ $reinstate_label = pht('Reinstate Event');
+ $cancel_disabled = !$can_edit;
+ }
+
if ($is_cancelled) {
$actions->addAction(
id(new PhabricatorActionView())
- ->setName(pht('Reinstate Event'))
+ ->setName($reinstate_label)
->setIcon('fa-plus')
- ->setHref($this->getApplicationURI("event/cancel/{$id}/"))
- ->setDisabled(!$can_edit)
+ ->setHref($cancel_uri)
+ ->setDisabled($cancel_disabled)
->setWorkflow(true));
} else {
$actions->addAction(
id(new PhabricatorActionView())
- ->setName(pht('Cancel Event'))
+ ->setName($cancel_label)
->setIcon('fa-times')
- ->setHref($this->getApplicationURI("event/cancel/{$id}/"))
- ->setDisabled(!$can_edit)
+ ->setHref($cancel_uri)
+ ->setDisabled($cancel_disabled)
->setWorkflow(true));
}
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
@@ -348,6 +348,10 @@
}
public function getIsParentCancelled() {
+ if ($this->instanceOfEventPHID == null) {
+ return false;
+ }
+
$recurring_event = $this->getParentEvent();
if ($recurring_event->getIsCancelled()) {
return true;

File Metadata

Mime Type
text/plain
Expires
Fri, Dec 20, 3:04 AM (21 h, 14 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6909323
Default Alt Text
D13145.diff (13 KB)

Event Timeline