Begin navigating the mess that is edits to recurring events
Summary:
Ref T11804. This puts us on a path toward some kind of reasonable behavior here.
Currently, cancelling recurring events makes approximately zero sense ever in any situation.
Instead, give users the choice to cancel just the instance, or all future events. This is similar to Calendar.app. (Google Calendar has a third option, "All Events", which I may implement).
When the user picks something, basically do that.
The particulars of "do that" are messy. We have to split the series into two different series, stop the first series early, then edit the second series. Then we need to update any concrete events that are now part of the second series.
This code will get less junk in the next couple of diffs (I hope?) since I need to make it apply to edits, too, but this was a little easier to get started with.
Test Plan:
Cancelled an instance of an event; cancelled "All future events".
Both of them more or less worked in a reasonble way.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T11804
Differential Revision: https://secure.phabricator.com/D16778
2016-10-31 20:47:39 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
final class PhabricatorCalendarEventForkTransaction
|
|
|
|
extends PhabricatorCalendarEventTransactionType {
|
|
|
|
|
|
|
|
const TRANSACTIONTYPE = 'calendar.fork';
|
|
|
|
|
|
|
|
public function generateOldValue($object) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function shouldHide() {
|
|
|
|
// This transaction is purely an internal implementation detail which
|
|
|
|
// supports editing groups of events like "All Future Events".
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function applyInternalEffects($object, $value) {
|
|
|
|
$parent = $object->getParentEvent();
|
|
|
|
|
|
|
|
$object->setInstanceOfEventPHID(null);
|
|
|
|
$object->attachParentEvent(null);
|
|
|
|
|
|
|
|
$rrule = $parent->newRecurrenceRule();
|
|
|
|
$object->setRecurrenceRule($rrule);
|
|
|
|
|
|
|
|
$until = $parent->newUntilDateTime();
|
|
|
|
if ($until) {
|
|
|
|
$object->setUntilDateTime($until);
|
|
|
|
}
|
|
|
|
|
|
|
|
$old_sequence_index = $object->getSequenceIndex();
|
|
|
|
$object->setSequenceIndex(0);
|
|
|
|
|
|
|
|
// Stop the parent event from recurring after the start date of this event.
|
2016-10-31 22:56:10 +01:00
|
|
|
// Since the "until" time is inclusive, rewind it by one second. We could
|
|
|
|
// figure out the previous instance's time instead or use a COUNT, but this
|
|
|
|
// seems simpler as long as it doesn't cause any issues.
|
|
|
|
$until_cutoff = $object->newStartDateTime()
|
|
|
|
->newRelativeDateTime('-PT1S')
|
|
|
|
->newAbsoluteDateTime();
|
|
|
|
|
|
|
|
$parent->setUntilDateTime($until_cutoff);
|
Begin navigating the mess that is edits to recurring events
Summary:
Ref T11804. This puts us on a path toward some kind of reasonable behavior here.
Currently, cancelling recurring events makes approximately zero sense ever in any situation.
Instead, give users the choice to cancel just the instance, or all future events. This is similar to Calendar.app. (Google Calendar has a third option, "All Events", which I may implement).
When the user picks something, basically do that.
The particulars of "do that" are messy. We have to split the series into two different series, stop the first series early, then edit the second series. Then we need to update any concrete events that are now part of the second series.
This code will get less junk in the next couple of diffs (I hope?) since I need to make it apply to edits, too, but this was a little easier to get started with.
Test Plan:
Cancelled an instance of an event; cancelled "All future events".
Both of them more or less worked in a reasonble way.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T11804
Differential Revision: https://secure.phabricator.com/D16778
2016-10-31 20:47:39 +01:00
|
|
|
$parent->save();
|
|
|
|
|
|
|
|
// NOTE: If we implement "COUNT" on editable events, we need to adjust
|
|
|
|
// the "COUNT" here and divide it up between the parent and the fork.
|
|
|
|
|
|
|
|
// Make all following children of the old parent children of this node
|
|
|
|
// instead.
|
|
|
|
$conn = $object->establishConnection('w');
|
|
|
|
queryfx(
|
|
|
|
$conn,
|
|
|
|
'UPDATE %T SET
|
|
|
|
instanceOfEventPHID = %s,
|
|
|
|
sequenceIndex = (sequenceIndex - %d)
|
|
|
|
WHERE instanceOfEventPHID = %s
|
|
|
|
AND utcInstanceEpoch > %d',
|
|
|
|
$object->getTableName(),
|
|
|
|
$object->getPHID(),
|
|
|
|
$old_sequence_index,
|
|
|
|
$parent->getPHID(),
|
|
|
|
$object->getUTCInstanceEpoch());
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|