mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-18 19:40:55 +01:00
Convert Calendar to Modular Transactions
Summary: Ref T9275. Swaps Calendar over to modular transactions. Theoretically, this has almost no effect on anything. Ref T10633. I didn't actually do anything here yet, but this gets us ready to put timestamps in email. Test Plan: Created and edited a bunch of events, nothing seemed catastrophically broken. Reviewers: chad Reviewed By: chad Maniphest Tasks: T9275, T10633 Differential Revision: https://secure.phabricator.com/D16286
This commit is contained in:
parent
63fec9b97d
commit
7b09f5698f
28 changed files with 942 additions and 953 deletions
|
@ -2021,24 +2021,40 @@ phutil_register_library_map(array(
|
|||
'PhabricatorCalendarDAO' => 'applications/calendar/storage/PhabricatorCalendarDAO.php',
|
||||
'PhabricatorCalendarEditEngine' => 'applications/calendar/editor/PhabricatorCalendarEditEngine.php',
|
||||
'PhabricatorCalendarEvent' => 'applications/calendar/storage/PhabricatorCalendarEvent.php',
|
||||
'PhabricatorCalendarEventAcceptTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventAcceptTransaction.php',
|
||||
'PhabricatorCalendarEventAllDayTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventAllDayTransaction.php',
|
||||
'PhabricatorCalendarEventCancelController' => 'applications/calendar/controller/PhabricatorCalendarEventCancelController.php',
|
||||
'PhabricatorCalendarEventCancelTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventCancelTransaction.php',
|
||||
'PhabricatorCalendarEventDateTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventDateTransaction.php',
|
||||
'PhabricatorCalendarEventDeclineTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventDeclineTransaction.php',
|
||||
'PhabricatorCalendarEventDescriptionTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventDescriptionTransaction.php',
|
||||
'PhabricatorCalendarEventDragController' => 'applications/calendar/controller/PhabricatorCalendarEventDragController.php',
|
||||
'PhabricatorCalendarEventEditController' => 'applications/calendar/controller/PhabricatorCalendarEventEditController.php',
|
||||
'PhabricatorCalendarEventEditor' => 'applications/calendar/editor/PhabricatorCalendarEventEditor.php',
|
||||
'PhabricatorCalendarEventEmailCommand' => 'applications/calendar/command/PhabricatorCalendarEventEmailCommand.php',
|
||||
'PhabricatorCalendarEventEndDateTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventEndDateTransaction.php',
|
||||
'PhabricatorCalendarEventFrequencyTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventFrequencyTransaction.php',
|
||||
'PhabricatorCalendarEventFulltextEngine' => 'applications/calendar/search/PhabricatorCalendarEventFulltextEngine.php',
|
||||
'PhabricatorCalendarEventIconTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventIconTransaction.php',
|
||||
'PhabricatorCalendarEventInviteTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventInviteTransaction.php',
|
||||
'PhabricatorCalendarEventInvitee' => 'applications/calendar/storage/PhabricatorCalendarEventInvitee.php',
|
||||
'PhabricatorCalendarEventInviteeQuery' => 'applications/calendar/query/PhabricatorCalendarEventInviteeQuery.php',
|
||||
'PhabricatorCalendarEventJoinController' => 'applications/calendar/controller/PhabricatorCalendarEventJoinController.php',
|
||||
'PhabricatorCalendarEventListController' => 'applications/calendar/controller/PhabricatorCalendarEventListController.php',
|
||||
'PhabricatorCalendarEventMailReceiver' => 'applications/calendar/mail/PhabricatorCalendarEventMailReceiver.php',
|
||||
'PhabricatorCalendarEventNameTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventNameTransaction.php',
|
||||
'PhabricatorCalendarEventPHIDType' => 'applications/calendar/phid/PhabricatorCalendarEventPHIDType.php',
|
||||
'PhabricatorCalendarEventQuery' => 'applications/calendar/query/PhabricatorCalendarEventQuery.php',
|
||||
'PhabricatorCalendarEventRSVPEmailCommand' => 'applications/calendar/command/PhabricatorCalendarEventRSVPEmailCommand.php',
|
||||
'PhabricatorCalendarEventRecurringTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventRecurringTransaction.php',
|
||||
'PhabricatorCalendarEventReplyTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventReplyTransaction.php',
|
||||
'PhabricatorCalendarEventSearchEngine' => 'applications/calendar/query/PhabricatorCalendarEventSearchEngine.php',
|
||||
'PhabricatorCalendarEventStartDateTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventStartDateTransaction.php',
|
||||
'PhabricatorCalendarEventTransaction' => 'applications/calendar/storage/PhabricatorCalendarEventTransaction.php',
|
||||
'PhabricatorCalendarEventTransactionComment' => 'applications/calendar/storage/PhabricatorCalendarEventTransactionComment.php',
|
||||
'PhabricatorCalendarEventTransactionQuery' => 'applications/calendar/query/PhabricatorCalendarEventTransactionQuery.php',
|
||||
'PhabricatorCalendarEventTransactionType' => 'applications/calendar/xaction/PhabricatorCalendarEventTransactionType.php',
|
||||
'PhabricatorCalendarEventUntilDateTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventUntilDateTransaction.php',
|
||||
'PhabricatorCalendarEventViewController' => 'applications/calendar/controller/PhabricatorCalendarEventViewController.php',
|
||||
'PhabricatorCalendarHoliday' => 'applications/calendar/storage/PhabricatorCalendarHoliday.php',
|
||||
'PhabricatorCalendarHolidayTestCase' => 'applications/calendar/storage/__tests__/PhabricatorCalendarHolidayTestCase.php',
|
||||
|
@ -6629,12 +6645,22 @@ phutil_register_library_map(array(
|
|||
'PhabricatorSpacesInterface',
|
||||
'PhabricatorFulltextInterface',
|
||||
),
|
||||
'PhabricatorCalendarEventAcceptTransaction' => 'PhabricatorCalendarEventReplyTransaction',
|
||||
'PhabricatorCalendarEventAllDayTransaction' => 'PhabricatorCalendarEventTransactionType',
|
||||
'PhabricatorCalendarEventCancelController' => 'PhabricatorCalendarController',
|
||||
'PhabricatorCalendarEventCancelTransaction' => 'PhabricatorCalendarEventTransactionType',
|
||||
'PhabricatorCalendarEventDateTransaction' => 'PhabricatorCalendarEventTransactionType',
|
||||
'PhabricatorCalendarEventDeclineTransaction' => 'PhabricatorCalendarEventReplyTransaction',
|
||||
'PhabricatorCalendarEventDescriptionTransaction' => 'PhabricatorCalendarEventTransactionType',
|
||||
'PhabricatorCalendarEventDragController' => 'PhabricatorCalendarController',
|
||||
'PhabricatorCalendarEventEditController' => 'PhabricatorCalendarController',
|
||||
'PhabricatorCalendarEventEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhabricatorCalendarEventEmailCommand' => 'MetaMTAEmailTransactionCommand',
|
||||
'PhabricatorCalendarEventEndDateTransaction' => 'PhabricatorCalendarEventDateTransaction',
|
||||
'PhabricatorCalendarEventFrequencyTransaction' => 'PhabricatorCalendarEventTransactionType',
|
||||
'PhabricatorCalendarEventFulltextEngine' => 'PhabricatorFulltextEngine',
|
||||
'PhabricatorCalendarEventIconTransaction' => 'PhabricatorCalendarEventTransactionType',
|
||||
'PhabricatorCalendarEventInviteTransaction' => 'PhabricatorCalendarEventTransactionType',
|
||||
'PhabricatorCalendarEventInvitee' => array(
|
||||
'PhabricatorCalendarDAO',
|
||||
'PhabricatorPolicyInterface',
|
||||
|
@ -6643,13 +6669,19 @@ phutil_register_library_map(array(
|
|||
'PhabricatorCalendarEventJoinController' => 'PhabricatorCalendarController',
|
||||
'PhabricatorCalendarEventListController' => 'PhabricatorCalendarController',
|
||||
'PhabricatorCalendarEventMailReceiver' => 'PhabricatorObjectMailReceiver',
|
||||
'PhabricatorCalendarEventNameTransaction' => 'PhabricatorCalendarEventTransactionType',
|
||||
'PhabricatorCalendarEventPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhabricatorCalendarEventQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhabricatorCalendarEventRSVPEmailCommand' => 'PhabricatorCalendarEventEmailCommand',
|
||||
'PhabricatorCalendarEventRecurringTransaction' => 'PhabricatorCalendarEventTransactionType',
|
||||
'PhabricatorCalendarEventReplyTransaction' => 'PhabricatorCalendarEventTransactionType',
|
||||
'PhabricatorCalendarEventSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PhabricatorCalendarEventTransaction' => 'PhabricatorApplicationTransaction',
|
||||
'PhabricatorCalendarEventStartDateTransaction' => 'PhabricatorCalendarEventDateTransaction',
|
||||
'PhabricatorCalendarEventTransaction' => 'PhabricatorModularTransaction',
|
||||
'PhabricatorCalendarEventTransactionComment' => 'PhabricatorApplicationTransactionComment',
|
||||
'PhabricatorCalendarEventTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhabricatorCalendarEventTransactionType' => 'PhabricatorModularTransactionType',
|
||||
'PhabricatorCalendarEventUntilDateTransaction' => 'PhabricatorCalendarEventDateTransaction',
|
||||
'PhabricatorCalendarEventViewController' => 'PhabricatorCalendarController',
|
||||
'PhabricatorCalendarHoliday' => 'PhabricatorCalendarDAO',
|
||||
'PhabricatorCalendarHolidayTestCase' => 'PhabricatorTestCase',
|
||||
|
|
|
@ -44,32 +44,24 @@ final class PhabricatorCalendarEventRSVPEmailCommand
|
|||
PhabricatorMetaMTAReceivedMail $mail,
|
||||
$command,
|
||||
array $argv) {
|
||||
$status_attending = PhabricatorCalendarEventInvitee::STATUS_ATTENDING;
|
||||
$status_declined = PhabricatorCalendarEventInvitee::STATUS_DECLINED;
|
||||
$xactions = array();
|
||||
|
||||
$target = phutil_utf8_strtolower(implode(' ', $argv));
|
||||
$rsvp = null;
|
||||
|
||||
$yes_values = $this->getYesValues();
|
||||
$no_values = $this->getNoValues();
|
||||
|
||||
if (in_array($target, $yes_values)) {
|
||||
$rsvp = $status_attending;
|
||||
$rsvp = PhabricatorCalendarEventAcceptTransaction::TRANSACTIONTYPE;
|
||||
} else if (in_array($target, $no_values)) {
|
||||
$rsvp = $status_declined;
|
||||
$rsvp = PhabricatorCalendarEventDeclineTransaction::TRANSACTIONTYPE;
|
||||
} else {
|
||||
$rsvp = null;
|
||||
}
|
||||
|
||||
if ($rsvp === null) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$xactions = array();
|
||||
$xactions[] = $object->getApplicationTransactionTemplate()
|
||||
->setTransactionType(PhabricatorCalendarEventTransaction::TYPE_INVITE)
|
||||
->setNewValue(array($viewer->getPHID() => $rsvp));
|
||||
|
||||
->setTransactionType($rsvp)
|
||||
->setNewValue(true);
|
||||
return $xactions;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ final class PhabricatorCalendarEventCancelController
|
|||
|
||||
$xaction = id(new PhabricatorCalendarEventTransaction())
|
||||
->setTransactionType(
|
||||
PhabricatorCalendarEventTransaction::TYPE_CANCEL)
|
||||
PhabricatorCalendarEventCancelTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue(!$is_cancelled);
|
||||
|
||||
$editor = id(new PhabricatorCalendarEventEditor())
|
||||
|
|
|
@ -41,13 +41,14 @@ final class PhabricatorCalendarEventDragController
|
|||
$viewer,
|
||||
$end));
|
||||
|
||||
|
||||
$xactions[] = id(new PhabricatorCalendarEventTransaction())
|
||||
->setTransactionType(PhabricatorCalendarEventTransaction::TYPE_START_DATE)
|
||||
->setTransactionType(
|
||||
PhabricatorCalendarEventStartDateTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($start_value);
|
||||
|
||||
$xactions[] = id(new PhabricatorCalendarEventTransaction())
|
||||
->setTransactionType(PhabricatorCalendarEventTransaction::TYPE_END_DATE)
|
||||
->setTransactionType(
|
||||
PhabricatorCalendarEventEndDateTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($end_value);
|
||||
|
||||
$editor = id(new PhabricatorCalendarEventEditor())
|
||||
|
|
|
@ -33,9 +33,11 @@ final class PhabricatorCalendarEventJoinController
|
|||
$validation_exception = null;
|
||||
if ($request->isFormPost()) {
|
||||
if ($is_join) {
|
||||
$xaction_type = PhabricatorCalendarEventTransaction::TYPE_ACCEPT;
|
||||
$xaction_type =
|
||||
PhabricatorCalendarEventAcceptTransaction::TRANSACTIONTYPE;
|
||||
} else {
|
||||
$xaction_type = PhabricatorCalendarEventTransaction::TYPE_DECLINE;
|
||||
$xaction_type =
|
||||
PhabricatorCalendarEventDeclineTransaction::TRANSACTIONTYPE;
|
||||
}
|
||||
|
||||
$xaction = id(new PhabricatorCalendarEventTransaction())
|
||||
|
|
|
@ -120,7 +120,7 @@ final class PhabricatorCalendarEventViewController
|
|||
if ($event->isChildEvent()) {
|
||||
$edit_label = pht('Edit This Instance');
|
||||
} else {
|
||||
$edit_label = pht('Edit');
|
||||
$edit_label = pht('Edit Event');
|
||||
}
|
||||
|
||||
$curtain = $this->newCurtainView($event);
|
||||
|
|
|
@ -81,7 +81,8 @@ final class PhabricatorCalendarEditEngine
|
|||
->setLabel(pht('Name'))
|
||||
->setDescription(pht('Name of the event.'))
|
||||
->setIsRequired(true)
|
||||
->setTransactionType(PhabricatorCalendarEventTransaction::TYPE_NAME)
|
||||
->setTransactionType(
|
||||
PhabricatorCalendarEventNameTransaction::TRANSACTIONTYPE)
|
||||
->setConduitDescription(pht('Rename the event.'))
|
||||
->setConduitTypeDescription(pht('New event name.'))
|
||||
->setValue($object->getName()),
|
||||
|
@ -90,7 +91,7 @@ final class PhabricatorCalendarEditEngine
|
|||
->setLabel(pht('Description'))
|
||||
->setDescription(pht('Description of the event.'))
|
||||
->setTransactionType(
|
||||
PhabricatorCalendarEventTransaction::TYPE_DESCRIPTION)
|
||||
PhabricatorCalendarEventDescriptionTransaction::TRANSACTIONTYPE)
|
||||
->setConduitDescription(pht('Update the event description.'))
|
||||
->setConduitTypeDescription(pht('New event description.'))
|
||||
->setValue($object->getDescription()),
|
||||
|
@ -100,7 +101,7 @@ final class PhabricatorCalendarEditEngine
|
|||
->setLabel(pht('Cancelled'))
|
||||
->setDescription(pht('Cancel the event.'))
|
||||
->setTransactionType(
|
||||
PhabricatorCalendarEventTransaction::TYPE_CANCEL)
|
||||
PhabricatorCalendarEventCancelTransaction::TRANSACTIONTYPE)
|
||||
->setIsConduitOnly(true)
|
||||
->setConduitDescription(pht('Cancel or restore the event.'))
|
||||
->setConduitTypeDescription(pht('True to cancel the event.'))
|
||||
|
@ -110,7 +111,8 @@ final class PhabricatorCalendarEditEngine
|
|||
->setAliases(array('invite', 'invitee', 'invitees', 'inviteePHID'))
|
||||
->setLabel(pht('Invitees'))
|
||||
->setDatasource(new PhabricatorMetaMTAMailableDatasource())
|
||||
->setTransactionType(PhabricatorCalendarEventTransaction::TYPE_INVITE)
|
||||
->setTransactionType(
|
||||
PhabricatorCalendarEventInviteTransaction::TRANSACTIONTYPE)
|
||||
->setDescription(pht('Users invited to the event.'))
|
||||
->setConduitDescription(pht('Change invited users.'))
|
||||
->setConduitTypeDescription(pht('New event invitees.'))
|
||||
|
@ -124,7 +126,7 @@ final class PhabricatorCalendarEditEngine
|
|||
->setLabel(pht('Recurring'))
|
||||
->setOptions(pht('One-Time Event'), pht('Recurring Event'))
|
||||
->setTransactionType(
|
||||
PhabricatorCalendarEventTransaction::TYPE_RECURRING)
|
||||
PhabricatorCalendarEventRecurringTransaction::TRANSACTIONTYPE)
|
||||
->setDescription(pht('One time or recurring event.'))
|
||||
->setConduitDescription(pht('Make the event recurring.'))
|
||||
->setConduitTypeDescription(pht('Mark the event as a recurring event.'))
|
||||
|
@ -135,7 +137,7 @@ final class PhabricatorCalendarEditEngine
|
|||
->setLabel(pht('Frequency'))
|
||||
->setOptions($frequency_options)
|
||||
->setTransactionType(
|
||||
PhabricatorCalendarEventTransaction::TYPE_FREQUENCY)
|
||||
PhabricatorCalendarEventFrequencyTransaction::TRANSACTIONTYPE)
|
||||
->setDescription(pht('Recurring event frequency.'))
|
||||
->setConduitDescription(pht('Change the event frequency.'))
|
||||
->setConduitTypeDescription(pht('New event frequency.'))
|
||||
|
@ -148,7 +150,7 @@ final class PhabricatorCalendarEditEngine
|
|||
->setKey('until')
|
||||
->setLabel(pht('Repeat Until'))
|
||||
->setTransactionType(
|
||||
PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE)
|
||||
PhabricatorCalendarEventUntilDateTransaction::TRANSACTIONTYPE)
|
||||
->setDescription(pht('Last instance of the event.'))
|
||||
->setConduitDescription(pht('Change when the event repeats until.'))
|
||||
->setConduitTypeDescription(pht('New final event time.'))
|
||||
|
@ -159,7 +161,8 @@ final class PhabricatorCalendarEditEngine
|
|||
->setKey('isAllDay')
|
||||
->setLabel(pht('All Day'))
|
||||
->setOptions(pht('Normal Event'), pht('All Day Event'))
|
||||
->setTransactionType(PhabricatorCalendarEventTransaction::TYPE_ALL_DAY)
|
||||
->setTransactionType(
|
||||
PhabricatorCalendarEventAllDayTransaction::TRANSACTIONTYPE)
|
||||
->setDescription(pht('Marks this as an all day event.'))
|
||||
->setConduitDescription(pht('Make the event an all day event.'))
|
||||
->setConduitTypeDescription(pht('Mark the event as an all day event.'))
|
||||
|
@ -169,7 +172,7 @@ final class PhabricatorCalendarEditEngine
|
|||
->setKey('start')
|
||||
->setLabel(pht('Start'))
|
||||
->setTransactionType(
|
||||
PhabricatorCalendarEventTransaction::TYPE_START_DATE)
|
||||
PhabricatorCalendarEventStartDateTransaction::TRANSACTIONTYPE)
|
||||
->setDescription(pht('Start time of the event.'))
|
||||
->setConduitDescription(pht('Change the start time of the event.'))
|
||||
->setConduitTypeDescription(pht('New event start time.'))
|
||||
|
@ -179,7 +182,7 @@ final class PhabricatorCalendarEditEngine
|
|||
->setKey('end')
|
||||
->setLabel(pht('End'))
|
||||
->setTransactionType(
|
||||
PhabricatorCalendarEventTransaction::TYPE_END_DATE)
|
||||
PhabricatorCalendarEventEndDateTransaction::TRANSACTIONTYPE)
|
||||
->setDescription(pht('End time of the event.'))
|
||||
->setConduitDescription(pht('Change the end time of the event.'))
|
||||
->setConduitTypeDescription(pht('New event end time.'))
|
||||
|
@ -189,7 +192,8 @@ final class PhabricatorCalendarEditEngine
|
|||
->setKey('icon')
|
||||
->setLabel(pht('Icon'))
|
||||
->setIconSet(new PhabricatorCalendarIconSet())
|
||||
->setTransactionType(PhabricatorCalendarEventTransaction::TYPE_ICON)
|
||||
->setTransactionType(
|
||||
PhabricatorCalendarEventIconTransaction::TRANSACTIONTYPE)
|
||||
->setDescription(pht('Event icon.'))
|
||||
->setConduitDescription(pht('Change the event icon.'))
|
||||
->setConduitTypeDescription(pht('New event icon.'))
|
||||
|
|
|
@ -58,21 +58,6 @@ final class PhabricatorCalendarEventEditor
|
|||
public function getTransactionTypes() {
|
||||
$types = parent::getTransactionTypes();
|
||||
|
||||
$types[] = PhabricatorCalendarEventTransaction::TYPE_NAME;
|
||||
$types[] = PhabricatorCalendarEventTransaction::TYPE_START_DATE;
|
||||
$types[] = PhabricatorCalendarEventTransaction::TYPE_END_DATE;
|
||||
$types[] = PhabricatorCalendarEventTransaction::TYPE_DESCRIPTION;
|
||||
$types[] = PhabricatorCalendarEventTransaction::TYPE_CANCEL;
|
||||
$types[] = PhabricatorCalendarEventTransaction::TYPE_INVITE;
|
||||
$types[] = PhabricatorCalendarEventTransaction::TYPE_ALL_DAY;
|
||||
$types[] = PhabricatorCalendarEventTransaction::TYPE_ICON;
|
||||
$types[] = PhabricatorCalendarEventTransaction::TYPE_ACCEPT;
|
||||
$types[] = PhabricatorCalendarEventTransaction::TYPE_DECLINE;
|
||||
|
||||
$types[] = PhabricatorCalendarEventTransaction::TYPE_RECURRING;
|
||||
$types[] = PhabricatorCalendarEventTransaction::TYPE_FREQUENCY;
|
||||
$types[] = PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE;
|
||||
|
||||
$types[] = PhabricatorTransactions::TYPE_COMMENT;
|
||||
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
|
||||
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
|
||||
|
@ -80,217 +65,6 @@ final class PhabricatorCalendarEventEditor
|
|||
return $types;
|
||||
}
|
||||
|
||||
protected function getCustomTransactionOldValue(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhabricatorCalendarEventTransaction::TYPE_RECURRING:
|
||||
return (int)$object->getIsRecurring();
|
||||
case PhabricatorCalendarEventTransaction::TYPE_FREQUENCY:
|
||||
return $object->getFrequencyUnit();
|
||||
case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE:
|
||||
return $object->getRecurrenceEndDate();
|
||||
case PhabricatorCalendarEventTransaction::TYPE_NAME:
|
||||
return $object->getName();
|
||||
case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
|
||||
return $object->getDateFrom();
|
||||
case PhabricatorCalendarEventTransaction::TYPE_END_DATE:
|
||||
return $object->getDateTo();
|
||||
case PhabricatorCalendarEventTransaction::TYPE_DESCRIPTION:
|
||||
return $object->getDescription();
|
||||
case PhabricatorCalendarEventTransaction::TYPE_CANCEL:
|
||||
return $object->getIsCancelled();
|
||||
case PhabricatorCalendarEventTransaction::TYPE_ALL_DAY:
|
||||
return (int)$object->getIsAllDay();
|
||||
case PhabricatorCalendarEventTransaction::TYPE_ICON:
|
||||
return $object->getIcon();
|
||||
case PhabricatorCalendarEventTransaction::TYPE_ACCEPT:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_DECLINE:
|
||||
$actor_phid = $this->getActingAsPHID();
|
||||
return $object->getUserInviteStatus($actor_phid);
|
||||
case PhabricatorCalendarEventTransaction::TYPE_INVITE:
|
||||
$invitees = $object->getInvitees();
|
||||
return mpull($invitees, 'getStatus', 'getInviteePHID');
|
||||
}
|
||||
|
||||
return parent::getCustomTransactionOldValue($object, $xaction);
|
||||
}
|
||||
|
||||
protected function getCustomTransactionNewValue(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhabricatorCalendarEventTransaction::TYPE_FREQUENCY:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_NAME:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_DESCRIPTION:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_CANCEL:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_ICON:
|
||||
return $xaction->getNewValue();
|
||||
case PhabricatorCalendarEventTransaction::TYPE_ACCEPT:
|
||||
return PhabricatorCalendarEventInvitee::STATUS_ATTENDING;
|
||||
case PhabricatorCalendarEventTransaction::TYPE_DECLINE:
|
||||
return PhabricatorCalendarEventInvitee::STATUS_DECLINED;
|
||||
case PhabricatorCalendarEventTransaction::TYPE_ALL_DAY:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_RECURRING:
|
||||
return (int)$xaction->getNewValue();
|
||||
case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_END_DATE:
|
||||
return $xaction->getNewValue()->getEpoch();
|
||||
case PhabricatorCalendarEventTransaction::TYPE_INVITE:
|
||||
$status_invited = PhabricatorCalendarEventInvitee::STATUS_INVITED;
|
||||
$status_uninvited = PhabricatorCalendarEventInvitee::STATUS_UNINVITED;
|
||||
$status_attending = PhabricatorCalendarEventInvitee::STATUS_ATTENDING;
|
||||
|
||||
$invitees = $object->getInvitees();
|
||||
foreach ($invitees as $key => $invitee) {
|
||||
if ($invitee->getStatus() == $status_uninvited) {
|
||||
unset($invitees[$key]);
|
||||
}
|
||||
}
|
||||
$invitees = mpull($invitees, null, 'getInviteePHID');
|
||||
|
||||
$new = $xaction->getNewValue();
|
||||
$new = array_fuse($new);
|
||||
|
||||
$all = array_keys($invitees + $new);
|
||||
$map = array();
|
||||
foreach ($all as $phid) {
|
||||
$is_old = isset($invitees[$phid]);
|
||||
$is_new = isset($new[$phid]);
|
||||
|
||||
if ($is_old && !$is_new) {
|
||||
$map[$phid] = $status_uninvited;
|
||||
} else if (!$is_old && $is_new) {
|
||||
$map[$phid] = $status_invited;
|
||||
} else {
|
||||
$map[$phid] = $invitees[$phid]->getStatus();
|
||||
}
|
||||
}
|
||||
|
||||
// If we're creating this event and the actor is inviting themselves,
|
||||
// mark them as attending.
|
||||
if ($this->getIsNewObject()) {
|
||||
$acting_phid = $this->getActingAsPHID();
|
||||
if (isset($map[$acting_phid])) {
|
||||
$map[$acting_phid] = $status_attending;
|
||||
}
|
||||
}
|
||||
|
||||
return $map;
|
||||
}
|
||||
|
||||
return parent::getCustomTransactionNewValue($object, $xaction);
|
||||
}
|
||||
|
||||
protected function applyCustomInternalTransaction(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhabricatorCalendarEventTransaction::TYPE_RECURRING:
|
||||
return $object->setIsRecurring((int)$xaction->getNewValue());
|
||||
case PhabricatorCalendarEventTransaction::TYPE_FREQUENCY:
|
||||
return $object->setRecurrenceFrequency(
|
||||
array(
|
||||
'rule' => $xaction->getNewValue(),
|
||||
));
|
||||
case PhabricatorCalendarEventTransaction::TYPE_NAME:
|
||||
$object->setName($xaction->getNewValue());
|
||||
return;
|
||||
case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
|
||||
$object->setDateFrom($xaction->getNewValue());
|
||||
return;
|
||||
case PhabricatorCalendarEventTransaction::TYPE_END_DATE:
|
||||
$object->setDateTo($xaction->getNewValue());
|
||||
return;
|
||||
case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE:
|
||||
$object->setRecurrenceEndDate($xaction->getNewValue());
|
||||
return;
|
||||
case PhabricatorCalendarEventTransaction::TYPE_DESCRIPTION:
|
||||
$object->setDescription($xaction->getNewValue());
|
||||
return;
|
||||
case PhabricatorCalendarEventTransaction::TYPE_CANCEL:
|
||||
$object->setIsCancelled((int)$xaction->getNewValue());
|
||||
return;
|
||||
case PhabricatorCalendarEventTransaction::TYPE_ALL_DAY:
|
||||
$object->setIsAllDay((int)$xaction->getNewValue());
|
||||
return;
|
||||
case PhabricatorCalendarEventTransaction::TYPE_ICON:
|
||||
$object->setIcon($xaction->getNewValue());
|
||||
return;
|
||||
case PhabricatorCalendarEventTransaction::TYPE_INVITE:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_ACCEPT:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_DECLINE:
|
||||
return;
|
||||
}
|
||||
|
||||
return parent::applyCustomInternalTransaction($object, $xaction);
|
||||
}
|
||||
|
||||
protected function applyCustomExternalTransaction(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhabricatorCalendarEventTransaction::TYPE_RECURRING:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_FREQUENCY:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_NAME:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_END_DATE:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_DESCRIPTION:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_CANCEL:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_ALL_DAY:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_ICON:
|
||||
return;
|
||||
case PhabricatorCalendarEventTransaction::TYPE_INVITE:
|
||||
$map = $xaction->getNewValue();
|
||||
$phids = array_keys($map);
|
||||
$invitees = $object->getInvitees();
|
||||
$invitees = mpull($invitees, null, 'getInviteePHID');
|
||||
|
||||
foreach ($phids as $phid) {
|
||||
$invitee = idx($invitees, $phid);
|
||||
if (!$invitee) {
|
||||
$invitee = id(new PhabricatorCalendarEventInvitee())
|
||||
->setEventPHID($object->getPHID())
|
||||
->setInviteePHID($phid)
|
||||
->setInviterPHID($this->getActingAsPHID());
|
||||
$invitees[] = $invitee;
|
||||
}
|
||||
$invitee->setStatus($map[$phid])
|
||||
->save();
|
||||
}
|
||||
$object->attachInvitees($invitees);
|
||||
return;
|
||||
case PhabricatorCalendarEventTransaction::TYPE_ACCEPT:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_DECLINE:
|
||||
$acting_phid = $this->getActingAsPHID();
|
||||
|
||||
$invitees = $object->getInvitees();
|
||||
$invitees = mpull($invitees, null, 'getInviteePHID');
|
||||
|
||||
$invitee = idx($invitees, $acting_phid);
|
||||
if (!$invitee) {
|
||||
$invitee = id(new PhabricatorCalendarEventInvitee())
|
||||
->setEventPHID($object->getPHID())
|
||||
->setInviteePHID($acting_phid)
|
||||
->setInviterPHID($acting_phid);
|
||||
$invitees[$acting_phid] = $invitee;
|
||||
}
|
||||
|
||||
$invitee
|
||||
->setStatus($xaction->getNewValue())
|
||||
->save();
|
||||
|
||||
$object->attachInvitees($invitees);
|
||||
return;
|
||||
}
|
||||
|
||||
return parent::applyCustomExternalTransaction($object, $xaction);
|
||||
}
|
||||
|
||||
protected function applyFinalEffects(
|
||||
PhabricatorLiskDAO $object,
|
||||
array $xactions) {
|
||||
|
@ -302,26 +76,21 @@ final class PhabricatorCalendarEventEditor
|
|||
$invalidate_phids = array();
|
||||
foreach ($xactions as $xaction) {
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhabricatorCalendarEventTransaction::TYPE_ICON:
|
||||
break;
|
||||
case PhabricatorCalendarEventTransaction::TYPE_RECURRING:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_FREQUENCY:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_END_DATE:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_CANCEL:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_ALL_DAY:
|
||||
case PhabricatorCalendarEventUntilDateTransaction::TRANSACTIONTYPE:
|
||||
case PhabricatorCalendarEventStartDateTransaction::TRANSACTIONTYPE:
|
||||
case PhabricatorCalendarEventEndDateTransaction::TRANSACTIONTYPE:
|
||||
case PhabricatorCalendarEventCancelTransaction::TRANSACTIONTYPE:
|
||||
case PhabricatorCalendarEventAllDayTransaction::TRANSACTIONTYPE:
|
||||
// For these kinds of changes, we need to invalidate the availabilty
|
||||
// caches for all attendees.
|
||||
$invalidate_all = true;
|
||||
break;
|
||||
|
||||
case PhabricatorCalendarEventTransaction::TYPE_ACCEPT:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_DECLINE:
|
||||
case PhabricatorCalendarEventAcceptTransaction::TRANSACTIONTYPE:
|
||||
case PhabricatorCalendarEventDeclineTransaction::TRANSACTIONTYPE:
|
||||
$acting_phid = $this->getActingAsPHID();
|
||||
$invalidate_phids[$acting_phid] = $acting_phid;
|
||||
break;
|
||||
case PhabricatorCalendarEventTransaction::TYPE_INVITE:
|
||||
case PhabricatorCalendarEventInviteTransaction::TRANSACTIONTYPE:
|
||||
foreach ($xaction->getNewValue() as $phid => $ignored) {
|
||||
$invalidate_phids[$phid] = $phid;
|
||||
}
|
||||
|
@ -357,14 +126,15 @@ final class PhabricatorCalendarEventEditor
|
|||
protected function validateAllTransactions(
|
||||
PhabricatorLiskDAO $object,
|
||||
array $xactions) {
|
||||
|
||||
$start_date_xaction =
|
||||
PhabricatorCalendarEventTransaction::TYPE_START_DATE;
|
||||
PhabricatorCalendarEventStartDateTransaction::TRANSACTIONTYPE;
|
||||
$end_date_xaction =
|
||||
PhabricatorCalendarEventTransaction::TYPE_END_DATE;
|
||||
PhabricatorCalendarEventEndDateTransaction::TRANSACTIONTYPE;
|
||||
$is_recurrence_xaction =
|
||||
PhabricatorCalendarEventTransaction::TYPE_RECURRING;
|
||||
PhabricatorCalendarEventRecurringTransaction::TRANSACTIONTYPE;
|
||||
$recurrence_end_xaction =
|
||||
PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE;
|
||||
PhabricatorCalendarEventUntilDateTransaction::TRANSACTIONTYPE;
|
||||
|
||||
$start_date = $object->getDateFrom();
|
||||
$end_date = $object->getDateTo();
|
||||
|
@ -386,19 +156,16 @@ final class PhabricatorCalendarEventEditor
|
|||
}
|
||||
|
||||
if ($start_date > $end_date) {
|
||||
$type = PhabricatorCalendarEventTransaction::TYPE_END_DATE;
|
||||
$errors[] = new PhabricatorApplicationTransactionValidationError(
|
||||
$type,
|
||||
$end_date_xaction,
|
||||
pht('Invalid'),
|
||||
pht('End date must be after start date.'),
|
||||
null);
|
||||
}
|
||||
|
||||
if ($recurrence_end && !$is_recurring) {
|
||||
$type =
|
||||
PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE;
|
||||
$errors[] = new PhabricatorApplicationTransactionValidationError(
|
||||
$type,
|
||||
$recurrence_end_xaction,
|
||||
pht('Invalid'),
|
||||
pht('Event must be recurring to have a recurrence end date.').
|
||||
null);
|
||||
|
@ -407,97 +174,6 @@ final class PhabricatorCalendarEventEditor
|
|||
return $errors;
|
||||
}
|
||||
|
||||
protected function validateTransaction(
|
||||
PhabricatorLiskDAO $object,
|
||||
$type,
|
||||
array $xactions) {
|
||||
|
||||
$errors = parent::validateTransaction($object, $type, $xactions);
|
||||
|
||||
switch ($type) {
|
||||
case PhabricatorCalendarEventTransaction::TYPE_NAME:
|
||||
$missing = $this->validateIsEmptyTextField(
|
||||
$object->getName(),
|
||||
$xactions);
|
||||
|
||||
if ($missing) {
|
||||
$error = new PhabricatorApplicationTransactionValidationError(
|
||||
$type,
|
||||
pht('Required'),
|
||||
pht('Event name is required.'),
|
||||
nonempty(last($xactions), null));
|
||||
|
||||
$error->setIsMissingFieldError(true);
|
||||
$errors[] = $error;
|
||||
}
|
||||
break;
|
||||
case PhabricatorCalendarEventTransaction::TYPE_INVITE:
|
||||
$old = $object->getInvitees();
|
||||
$old = mpull($old, null, 'getInviteePHID');
|
||||
foreach ($xactions as $xaction) {
|
||||
$new = $xaction->getNewValue();
|
||||
$new = array_fuse($new);
|
||||
$add = array_diff_key($new, $old);
|
||||
if (!$add) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// In the UI, we only allow you to invite mailable objects, but there
|
||||
// is no definitive marker for "invitable object" today. Just allow
|
||||
// any valid object to be invited.
|
||||
$objects = id(new PhabricatorObjectQuery())
|
||||
->setViewer($this->getActor())
|
||||
->withPHIDs($add)
|
||||
->execute();
|
||||
$objects = mpull($objects, null, 'getPHID');
|
||||
foreach ($add as $phid) {
|
||||
if (isset($objects[$phid])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$errors[] = new PhabricatorApplicationTransactionValidationError(
|
||||
$type,
|
||||
pht('Invalid'),
|
||||
pht(
|
||||
'Invitee "%s" identifies an object that does not exist or '.
|
||||
'which you do not have permission to view.',
|
||||
$phid));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_END_DATE:
|
||||
case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE:
|
||||
foreach ($xactions as $xaction) {
|
||||
if ($xaction->getNewValue()->isValid()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
|
||||
$message = pht('Start date is invalid.');
|
||||
break;
|
||||
case PhabricatorCalendarEventTransaction::TYPE_END_DATE:
|
||||
$message = pht('End date is invalid.');
|
||||
break;
|
||||
case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE:
|
||||
$message = pht('Repeat until date is invalid.');
|
||||
break;
|
||||
}
|
||||
|
||||
$errors[] = new PhabricatorApplicationTransactionValidationError(
|
||||
$type,
|
||||
pht('Invalid'),
|
||||
$message,
|
||||
$xaction);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
protected function shouldPublishFeedStory(
|
||||
PhabricatorLiskDAO $object,
|
||||
array $xactions) {
|
||||
|
|
|
@ -1,22 +1,7 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorCalendarEventTransaction
|
||||
extends PhabricatorApplicationTransaction {
|
||||
|
||||
const TYPE_NAME = 'calendar.name';
|
||||
const TYPE_START_DATE = 'calendar.startdate';
|
||||
const TYPE_END_DATE = 'calendar.enddate';
|
||||
const TYPE_DESCRIPTION = 'calendar.description';
|
||||
const TYPE_CANCEL = 'calendar.cancel';
|
||||
const TYPE_ALL_DAY = 'calendar.allday';
|
||||
const TYPE_ICON = 'calendar.icon';
|
||||
const TYPE_INVITE = 'calendar.invite';
|
||||
const TYPE_ACCEPT = 'calendar.accept';
|
||||
const TYPE_DECLINE = 'calendar.decline';
|
||||
|
||||
const TYPE_RECURRING = 'calendar.recurring';
|
||||
const TYPE_FREQUENCY = 'calendar.frequency';
|
||||
const TYPE_RECURRENCE_END_DATE = 'calendar.recurrenceenddate';
|
||||
extends PhabricatorModularTransaction {
|
||||
|
||||
const MAILTAG_RESCHEDULE = 'calendar-reschedule';
|
||||
const MAILTAG_CONTENT = 'calendar-content';
|
||||
|
@ -34,580 +19,25 @@ final class PhabricatorCalendarEventTransaction
|
|||
return new PhabricatorCalendarEventTransactionComment();
|
||||
}
|
||||
|
||||
public function getRequiredHandlePHIDs() {
|
||||
$phids = parent::getRequiredHandlePHIDs();
|
||||
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_NAME:
|
||||
case self::TYPE_START_DATE:
|
||||
case self::TYPE_END_DATE:
|
||||
case self::TYPE_DESCRIPTION:
|
||||
case self::TYPE_CANCEL:
|
||||
case self::TYPE_ALL_DAY:
|
||||
case self::TYPE_RECURRING:
|
||||
case self::TYPE_FREQUENCY:
|
||||
case self::TYPE_RECURRENCE_END_DATE:
|
||||
$phids[] = $this->getObjectPHID();
|
||||
break;
|
||||
case self::TYPE_INVITE:
|
||||
$new = $this->getNewValue();
|
||||
foreach ($new as $phid => $status) {
|
||||
$phids[] = $phid;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $phids;
|
||||
}
|
||||
|
||||
public function shouldHide() {
|
||||
$old = $this->getOldValue();
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_START_DATE:
|
||||
case self::TYPE_END_DATE:
|
||||
case self::TYPE_DESCRIPTION:
|
||||
case self::TYPE_CANCEL:
|
||||
case self::TYPE_ALL_DAY:
|
||||
case self::TYPE_INVITE:
|
||||
case self::TYPE_RECURRING:
|
||||
case self::TYPE_FREQUENCY:
|
||||
case self::TYPE_RECURRENCE_END_DATE:
|
||||
return ($old === null);
|
||||
}
|
||||
return parent::shouldHide();
|
||||
}
|
||||
|
||||
public function getIcon() {
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_ICON:
|
||||
return $this->getNewValue();
|
||||
case self::TYPE_NAME:
|
||||
case self::TYPE_START_DATE:
|
||||
case self::TYPE_END_DATE:
|
||||
case self::TYPE_DESCRIPTION:
|
||||
case self::TYPE_ALL_DAY:
|
||||
case self::TYPE_CANCEL:
|
||||
case self::TYPE_RECURRING:
|
||||
case self::TYPE_FREQUENCY:
|
||||
case self::TYPE_RECURRENCE_END_DATE:
|
||||
return 'fa-pencil';
|
||||
break;
|
||||
case self::TYPE_INVITE:
|
||||
return 'fa-user-plus';
|
||||
break;
|
||||
}
|
||||
return parent::getIcon();
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
$author_phid = $this->getAuthorPHID();
|
||||
$object_phid = $this->getObjectPHID();
|
||||
|
||||
$old = $this->getOldValue();
|
||||
$new = $this->getNewValue();
|
||||
|
||||
$type = $this->getTransactionType();
|
||||
switch ($type) {
|
||||
case self::TYPE_NAME:
|
||||
if ($old === null) {
|
||||
return pht(
|
||||
'%s created this event.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
} else {
|
||||
return pht(
|
||||
'%s changed the name of this event from %s to %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$old,
|
||||
$new);
|
||||
}
|
||||
case self::TYPE_START_DATE:
|
||||
if ($old) {
|
||||
return pht(
|
||||
'%s edited the start date of this event.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
}
|
||||
break;
|
||||
case self::TYPE_END_DATE:
|
||||
if ($old) {
|
||||
return pht(
|
||||
'%s edited the end date of this event.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
}
|
||||
break;
|
||||
case self::TYPE_DESCRIPTION:
|
||||
return pht(
|
||||
"%s updated the event's description.",
|
||||
$this->renderHandleLink($author_phid));
|
||||
case self::TYPE_ALL_DAY:
|
||||
if ($new) {
|
||||
return pht(
|
||||
'%s made this an all day event.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
} else {
|
||||
return pht(
|
||||
'%s converted this from an all day event.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
}
|
||||
case self::TYPE_ICON:
|
||||
$set = new PhabricatorCalendarIconSet();
|
||||
return pht(
|
||||
'%s set this event\'s icon to %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$set->getIconLabel($new));
|
||||
break;
|
||||
case self::TYPE_CANCEL:
|
||||
if ($new) {
|
||||
return pht(
|
||||
'%s cancelled this event.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
} else {
|
||||
return pht(
|
||||
'%s reinstated this event.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
}
|
||||
case self::TYPE_ACCEPT:
|
||||
return pht(
|
||||
'%s is attending this event.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
case self::TYPE_DECLINE:
|
||||
return pht(
|
||||
'%s declined this event.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
case self::TYPE_INVITE:
|
||||
$text = null;
|
||||
|
||||
list($old, $new) = $this->getSimpleInvites($old, $new);
|
||||
|
||||
if (count($old) === 1
|
||||
&& count($new) === 1
|
||||
&& isset($old[$author_phid])) {
|
||||
// user joined/declined/accepted event themself
|
||||
$old_status = $old[$author_phid];
|
||||
$new_status = $new[$author_phid];
|
||||
|
||||
if ($old_status !== $new_status) {
|
||||
switch ($new_status) {
|
||||
case PhabricatorCalendarEventInvitee::STATUS_INVITED:
|
||||
$text = pht(
|
||||
'%s has joined this event.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
break;
|
||||
case PhabricatorCalendarEventInvitee::STATUS_ATTENDING:
|
||||
$text = pht(
|
||||
'%s is attending this event.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
break;
|
||||
case PhabricatorCalendarEventInvitee::STATUS_DECLINED:
|
||||
case PhabricatorCalendarEventInvitee::STATUS_UNINVITED:
|
||||
$text = pht(
|
||||
'%s has declined this event.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
break;
|
||||
default:
|
||||
$text = pht(
|
||||
'%s has changed their status for this event.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// user changed status for many users
|
||||
$self_joined = null;
|
||||
$self_declined = null;
|
||||
$added = array();
|
||||
$uninvited = array();
|
||||
|
||||
foreach ($new as $phid => $status) {
|
||||
if ($status == PhabricatorCalendarEventInvitee::STATUS_INVITED
|
||||
|| $status == PhabricatorCalendarEventInvitee::STATUS_ATTENDING) {
|
||||
// added users
|
||||
$added[] = $phid;
|
||||
} else if (
|
||||
$status == PhabricatorCalendarEventInvitee::STATUS_DECLINED
|
||||
|| $status == PhabricatorCalendarEventInvitee::STATUS_UNINVITED) {
|
||||
$uninvited[] = $phid;
|
||||
}
|
||||
}
|
||||
|
||||
$count_added = count($added);
|
||||
$count_uninvited = count($uninvited);
|
||||
$added_text = null;
|
||||
$uninvited_text = null;
|
||||
|
||||
if ($count_added > 0 && $count_uninvited == 0) {
|
||||
$added_text = $this->renderHandleList($added);
|
||||
$text = pht('%s invited %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$added_text);
|
||||
} else if ($count_added > 0 && $count_uninvited > 0) {
|
||||
$added_text = $this->renderHandleList($added);
|
||||
$uninvited_text = $this->renderHandleList($uninvited);
|
||||
$text = pht('%s invited %s and uninvited %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$added_text,
|
||||
$uninvited_text);
|
||||
} else if ($count_added == 0 && $count_uninvited > 0) {
|
||||
$uninvited_text = $this->renderHandleList($uninvited);
|
||||
$text = pht('%s uninvited %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$uninvited_text);
|
||||
} else {
|
||||
$text = pht('%s updated the invitee list.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
}
|
||||
}
|
||||
return $text;
|
||||
case self::TYPE_RECURRING:
|
||||
$text = pht('%s made this event recurring.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
return $text;
|
||||
case self::TYPE_FREQUENCY:
|
||||
$rule = $new;
|
||||
if (is_array($rule)) {
|
||||
$rule = idx($rule, 'rule');
|
||||
}
|
||||
|
||||
$text = '';
|
||||
switch ($rule) {
|
||||
case PhabricatorCalendarEvent::FREQUENCY_DAILY:
|
||||
$text = pht('%s set this event to repeat daily.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
break;
|
||||
case PhabricatorCalendarEvent::FREQUENCY_WEEKLY:
|
||||
$text = pht('%s set this event to repeat weekly.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
break;
|
||||
case PhabricatorCalendarEvent::FREQUENCY_MONTHLY:
|
||||
$text = pht('%s set this event to repeat monthly.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
break;
|
||||
case PhabricatorCalendarEvent::FREQUENCY_YEARLY:
|
||||
$text = pht('%s set this event to repeat yearly.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
break;
|
||||
}
|
||||
return $text;
|
||||
case self::TYPE_RECURRENCE_END_DATE:
|
||||
$text = pht('%s has changed the recurrence end date of this event.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
return $text;
|
||||
}
|
||||
return parent::getTitle();
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
$author_phid = $this->getAuthorPHID();
|
||||
$object_phid = $this->getObjectPHID();
|
||||
|
||||
$old = $this->getOldValue();
|
||||
$new = $this->getNewValue();
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$type = $this->getTransactionType();
|
||||
switch ($type) {
|
||||
case self::TYPE_NAME:
|
||||
if ($old === null) {
|
||||
return pht(
|
||||
'%s created %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
} else {
|
||||
return pht(
|
||||
'%s changed the name of %s from %s to %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid),
|
||||
$old,
|
||||
$new);
|
||||
}
|
||||
case self::TYPE_START_DATE:
|
||||
if ($old) {
|
||||
$old = phabricator_datetime($old, $viewer);
|
||||
$new = phabricator_datetime($new, $viewer);
|
||||
return pht(
|
||||
'%s changed the start date of %s from %s to %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid),
|
||||
$old,
|
||||
$new);
|
||||
}
|
||||
break;
|
||||
case self::TYPE_END_DATE:
|
||||
if ($old) {
|
||||
$old = phabricator_datetime($old, $viewer);
|
||||
$new = phabricator_datetime($new, $viewer);
|
||||
return pht(
|
||||
'%s edited the end date of %s from %s to %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid),
|
||||
$old,
|
||||
$new);
|
||||
}
|
||||
break;
|
||||
case self::TYPE_DESCRIPTION:
|
||||
return pht(
|
||||
'%s updated the description of %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
case self::TYPE_ALL_DAY:
|
||||
if ($new) {
|
||||
return pht(
|
||||
'%s made %s an all day event.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
} else {
|
||||
return pht(
|
||||
'%s converted %s from an all day event.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
}
|
||||
case self::TYPE_ICON:
|
||||
$set = new PhabricatorCalendarIconSet();
|
||||
return pht(
|
||||
'%s set the icon for %s to %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid),
|
||||
$set->getIconLabel($new));
|
||||
case self::TYPE_CANCEL:
|
||||
if ($new) {
|
||||
return pht(
|
||||
'%s cancelled %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
} else {
|
||||
return pht(
|
||||
'%s reinstated %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
}
|
||||
case self::TYPE_ACCEPT:
|
||||
return pht(
|
||||
'%s is attending %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
case self::TYPE_DECLINE:
|
||||
return pht(
|
||||
'%s declined %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
case self::TYPE_INVITE:
|
||||
$text = null;
|
||||
|
||||
list($old, $new) = $this->getSimpleInvites($old, $new);
|
||||
|
||||
if (count($old) === 1
|
||||
&& count($new) === 1
|
||||
&& isset($old[$author_phid])) {
|
||||
// user joined/declined/accepted event themself
|
||||
$old_status = $old[$author_phid];
|
||||
$new_status = $new[$author_phid];
|
||||
|
||||
if ($old_status !== $new_status) {
|
||||
switch ($new_status) {
|
||||
case PhabricatorCalendarEventInvitee::STATUS_INVITED:
|
||||
$text = pht(
|
||||
'%s has joined %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
break;
|
||||
case PhabricatorCalendarEventInvitee::STATUS_ATTENDING:
|
||||
$text = pht(
|
||||
'%s is attending %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
break;
|
||||
case PhabricatorCalendarEventInvitee::STATUS_DECLINED:
|
||||
case PhabricatorCalendarEventInvitee::STATUS_UNINVITED:
|
||||
$text = pht(
|
||||
'%s has declined %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
break;
|
||||
default:
|
||||
$text = pht(
|
||||
'%s has changed their status of %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// user changed status for many users
|
||||
$self_joined = null;
|
||||
$self_declined = null;
|
||||
$added = array();
|
||||
$uninvited = array();
|
||||
|
||||
foreach ($new as $phid => $status) {
|
||||
if ($status == PhabricatorCalendarEventInvitee::STATUS_INVITED
|
||||
|| $status == PhabricatorCalendarEventInvitee::STATUS_ATTENDING) {
|
||||
// added users
|
||||
$added[] = $phid;
|
||||
} else if (
|
||||
$status == PhabricatorCalendarEventInvitee::STATUS_DECLINED
|
||||
|| $status == PhabricatorCalendarEventInvitee::STATUS_UNINVITED) {
|
||||
$uninvited[] = $phid;
|
||||
}
|
||||
}
|
||||
|
||||
$count_added = count($added);
|
||||
$count_uninvited = count($uninvited);
|
||||
$added_text = null;
|
||||
$uninvited_text = null;
|
||||
|
||||
if ($count_added > 0 && $count_uninvited == 0) {
|
||||
$added_text = $this->renderHandleList($added);
|
||||
$text = pht('%s invited %s to %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$added_text,
|
||||
$this->renderHandleLink($object_phid));
|
||||
} else if ($count_added > 0 && $count_uninvited > 0) {
|
||||
$added_text = $this->renderHandleList($added);
|
||||
$uninvited_text = $this->renderHandleList($uninvited);
|
||||
$text = pht('%s invited %s and uninvited %s to %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$added_text,
|
||||
$uninvited_text,
|
||||
$this->renderHandleLink($object_phid));
|
||||
} else if ($count_added == 0 && $count_uninvited > 0) {
|
||||
$uninvited_text = $this->renderHandleList($uninvited);
|
||||
$text = pht('%s uninvited %s to %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$uninvited_text,
|
||||
$this->renderHandleLink($object_phid));
|
||||
} else {
|
||||
$text = pht('%s updated the invitee list of %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
}
|
||||
}
|
||||
return $text;
|
||||
case self::TYPE_RECURRING:
|
||||
$text = pht('%s made %s a recurring event.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
return $text;
|
||||
case self::TYPE_FREQUENCY:
|
||||
$rule = $new;
|
||||
if (is_array($rule)) {
|
||||
$rule = idx($rule, 'rule');
|
||||
}
|
||||
|
||||
$text = '';
|
||||
switch ($rule) {
|
||||
case PhabricatorCalendarEvent::FREQUENCY_DAILY:
|
||||
$text = pht('%s set %s to repeat daily.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
break;
|
||||
case PhabricatorCalendarEvent::FREQUENCY_WEEKLY:
|
||||
$text = pht('%s set %s to repeat weekly.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
break;
|
||||
case PhabricatorCalendarEvent::FREQUENCY_MONTHLY:
|
||||
$text = pht('%s set %s to repeat monthly.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
break;
|
||||
case PhabricatorCalendarEvent::FREQUENCY_YEARLY:
|
||||
$text = pht('%s set %s to repeat yearly.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
break;
|
||||
}
|
||||
return $text;
|
||||
case self::TYPE_RECURRENCE_END_DATE:
|
||||
$text = pht('%s set the recurrence end date of %s to %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid),
|
||||
$new);
|
||||
return $text;
|
||||
}
|
||||
|
||||
return parent::getTitleForFeed();
|
||||
}
|
||||
|
||||
public function getColor() {
|
||||
$old = $this->getOldValue();
|
||||
$new = $this->getNewValue();
|
||||
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_NAME:
|
||||
case self::TYPE_START_DATE:
|
||||
case self::TYPE_END_DATE:
|
||||
case self::TYPE_DESCRIPTION:
|
||||
case self::TYPE_CANCEL:
|
||||
case self::TYPE_INVITE:
|
||||
return PhabricatorTransactions::COLOR_GREEN;
|
||||
}
|
||||
|
||||
return parent::getColor();
|
||||
}
|
||||
|
||||
|
||||
public function hasChangeDetails() {
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_DESCRIPTION:
|
||||
return ($this->getOldValue() !== null);
|
||||
}
|
||||
|
||||
return parent::hasChangeDetails();
|
||||
}
|
||||
|
||||
public function renderChangeDetails(PhabricatorUser $viewer) {
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_DESCRIPTION:
|
||||
$old = $this->getOldValue();
|
||||
$new = $this->getNewValue();
|
||||
|
||||
return $this->renderTextCorpusChangeDetails(
|
||||
$viewer,
|
||||
$old,
|
||||
$new);
|
||||
}
|
||||
|
||||
return parent::renderChangeDetails($viewer);
|
||||
public function getBaseTransactionClass() {
|
||||
return 'PhabricatorCalendarEventTransactionType';
|
||||
}
|
||||
|
||||
public function getMailTags() {
|
||||
$tags = array();
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_NAME:
|
||||
case self::TYPE_DESCRIPTION:
|
||||
case self::TYPE_INVITE:
|
||||
case self::TYPE_ICON:
|
||||
case PhabricatorCalendarEventNameTransaction::TRANSACTIONTYPE:
|
||||
case PhabricatorCalendarEventDescriptionTransaction::TRANSACTIONTYPE:
|
||||
case PhabricatorCalendarEventInviteTransaction::TRANSACTIONTYPE:
|
||||
$tags[] = self::MAILTAG_CONTENT;
|
||||
break;
|
||||
case self::TYPE_START_DATE:
|
||||
case self::TYPE_END_DATE:
|
||||
case self::TYPE_CANCEL:
|
||||
case PhabricatorCalendarEventStartDateTransaction::TRANSACTIONTYPE:
|
||||
case PhabricatorCalendarEventEndDateTransaction::TRANSACTIONTYPE:
|
||||
case PhabricatorCalendarEventCancelTransaction::TRANSACTIONTYPE:
|
||||
$tags[] = self::MAILTAG_RESCHEDULE;
|
||||
break;
|
||||
}
|
||||
return $tags;
|
||||
}
|
||||
|
||||
private function getSimpleInvites(array $old, array $new) {
|
||||
// Fill in any new invitees as "uninvited" in the old data, to make
|
||||
// some of the rendering logic a little easier.
|
||||
$status_uninvited = PhabricatorCalendarEventInvitee::STATUS_UNINVITED;
|
||||
$old = $old + array_fill_keys(array_keys($new), $status_uninvited);
|
||||
|
||||
$all = $old + $new;
|
||||
foreach (array_keys($all) as $key) {
|
||||
// If the invitee exists in both the old and new lists with the same
|
||||
// value, remove it from both.
|
||||
if (isset($old[$key]) && isset($new[$key])) {
|
||||
if ($old[$key] == $new[$key]) {
|
||||
unset($old[$key]);
|
||||
unset($new[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array($old, $new);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorCalendarEventAcceptTransaction
|
||||
extends PhabricatorCalendarEventReplyTransaction {
|
||||
|
||||
const TRANSACTIONTYPE = 'calendar.accept';
|
||||
|
||||
public function generateNewValue($object, $value) {
|
||||
return PhabricatorCalendarEventInvitee::STATUS_ATTENDING;
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
return pht(
|
||||
'%s is attending this event.',
|
||||
$this->renderAuthor());
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
return pht(
|
||||
'%s is attending %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorCalendarEventAllDayTransaction
|
||||
extends PhabricatorCalendarEventTransactionType {
|
||||
|
||||
const TRANSACTIONTYPE = 'calendar.allday';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
return (int)$object->getIsAllDay();
|
||||
}
|
||||
|
||||
public function generateNewValue($object, $value) {
|
||||
return (int)$value;
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
$object->setIsAllDay($value);
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
if ($this->getNewValue()) {
|
||||
return pht(
|
||||
'%s changed this as an all day event.',
|
||||
$this->renderAuthor());
|
||||
} else {
|
||||
return pht(
|
||||
'%s conveted this from an all day event.',
|
||||
$this->renderAuthor());
|
||||
}
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
if ($this->getNewValue()) {
|
||||
return pht(
|
||||
'%s changed %s to an all day event.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject());
|
||||
} else {
|
||||
return pht(
|
||||
'%s converted %s from an all day event.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorCalendarEventCancelTransaction
|
||||
extends PhabricatorCalendarEventTransactionType {
|
||||
|
||||
const TRANSACTIONTYPE = 'calendar.cancel';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
return (int)$object->getIsCancelled();
|
||||
}
|
||||
|
||||
public function generateNewValue($object, $value) {
|
||||
return (int)$value;
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
$object->setIsCancelled($value);
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
if ($this->getNewValue()) {
|
||||
return pht(
|
||||
'%s cancelled this event.',
|
||||
$this->renderAuthor());
|
||||
} else {
|
||||
return pht(
|
||||
'%s reinstated this event.',
|
||||
$this->renderAuthor());
|
||||
}
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
if ($this->getNewValue()) {
|
||||
return pht(
|
||||
'%s cancelled %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject());
|
||||
} else {
|
||||
return pht(
|
||||
'%s reinstated %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
abstract class PhabricatorCalendarEventDateTransaction
|
||||
extends PhabricatorCalendarEventTransactionType {
|
||||
|
||||
abstract protected function getInvalidDateMessage();
|
||||
|
||||
public function generateNewValue($object, $value) {
|
||||
return $value->getEpoch();
|
||||
}
|
||||
|
||||
public function validateTransactions($object, array $xactions) {
|
||||
$errors = array();
|
||||
|
||||
foreach ($xactions as $xaction) {
|
||||
if ($xaction->getNewValue()->isValid()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$message = $this->getInvalidDateMessage();
|
||||
$errors[] = $this->newInvalidError($message, $xaction);
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorCalendarEventDeclineTransaction
|
||||
extends PhabricatorCalendarEventReplyTransaction {
|
||||
|
||||
const TRANSACTIONTYPE = 'calendar.decline';
|
||||
|
||||
public function generateNewValue($object, $value) {
|
||||
return PhabricatorCalendarEventInvitee::STATUS_DECLINED;
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
return pht(
|
||||
'%s declined this event.',
|
||||
$this->renderAuthor());
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
return pht(
|
||||
'%s declined %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorCalendarEventDescriptionTransaction
|
||||
extends PhabricatorCalendarEventTransactionType {
|
||||
|
||||
const TRANSACTIONTYPE = 'calendar.description';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
return $object->getDescription();
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
$object->setDescription($value);
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
return pht(
|
||||
'%s updated the event description.',
|
||||
$this->renderAuthor());
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
return pht(
|
||||
'%s updated the event description for %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject());
|
||||
}
|
||||
|
||||
public function hasChangeDetailView() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function newChangeDetailView() {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
return id(new PhabricatorApplicationTransactionTextDiffDetailView())
|
||||
->setViewer($viewer)
|
||||
->setOldText($this->getOldValue())
|
||||
->setNewText($this->getNewValue());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorCalendarEventEndDateTransaction
|
||||
extends PhabricatorCalendarEventDateTransaction {
|
||||
|
||||
const TRANSACTIONTYPE = 'calendar.enddate';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
return $object->getDateTo();
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
$object->setDateTo($value);
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
return pht(
|
||||
'%s changed the end date for this event from %s to %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderOldDate(),
|
||||
$this->renderNewDate());
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
return pht(
|
||||
'%s changed the end date for %s from %s to %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject(),
|
||||
$this->renderOldDate(),
|
||||
$this->renderNewDate());
|
||||
}
|
||||
|
||||
protected function getInvalidDateMessage() {
|
||||
return pht('End date is invalid.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorCalendarEventFrequencyTransaction
|
||||
extends PhabricatorCalendarEventTransactionType {
|
||||
|
||||
const TRANSACTIONTYPE = 'calendar.frequency';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
return $object->getFrequencyUnit();
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
$object->setRecurrenceFrequency(
|
||||
array(
|
||||
'rule' => $value,
|
||||
));
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
$frequency = $this->getFrequencyUnit($this->getNewValue());
|
||||
switch ($frequency) {
|
||||
case PhabricatorCalendarEvent::FREQUENCY_DAILY:
|
||||
return pht(
|
||||
'%s set this event to repeat daily.',
|
||||
$this->renderAuthor());
|
||||
case PhabricatorCalendarEvent::FREQUENCY_WEEKLY:
|
||||
return pht(
|
||||
'%s set this event to repeat weekly.',
|
||||
$this->renderAuthor());
|
||||
case PhabricatorCalendarEvent::FREQUENCY_MONTHLY:
|
||||
return pht(
|
||||
'%s set this event to repeat monthly.',
|
||||
$this->renderAuthor());
|
||||
case PhabricatorCalendarEvent::FREQUENCY_YEARLY:
|
||||
return pht(
|
||||
'%s set this event to repeat yearly.',
|
||||
$this->renderAuthor());
|
||||
}
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
$frequency = $this->getFrequencyUnit($this->getNewValue());
|
||||
switch ($frequency) {
|
||||
case PhabricatorCalendarEvent::FREQUENCY_DAILY:
|
||||
return pht(
|
||||
'%s set %s to repeat daily.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject());
|
||||
case PhabricatorCalendarEvent::FREQUENCY_WEEKLY:
|
||||
return pht(
|
||||
'%s set %s to repeat weekly.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject());
|
||||
case PhabricatorCalendarEvent::FREQUENCY_MONTHLY:
|
||||
return pht(
|
||||
'%s set %s to repeat monthly.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject());
|
||||
case PhabricatorCalendarEvent::FREQUENCY_YEARLY:
|
||||
return pht(
|
||||
'%s set %s to repeat yearly.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject());
|
||||
}
|
||||
}
|
||||
|
||||
private function getFrequencyUnit($value) {
|
||||
if (is_array($value)) {
|
||||
$value = idx($value, 'rule');
|
||||
} else {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorCalendarEventIconTransaction
|
||||
extends PhabricatorCalendarEventTransactionType {
|
||||
|
||||
const TRANSACTIONTYPE = 'calendar.icon';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
return $object->getIcon();
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
$object->setIcon($value);
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
$old = $this->getIconLabel($this->getOldValue());
|
||||
$new = $this->getIconLabel($this->getNewValue());
|
||||
|
||||
return pht(
|
||||
'%s changed the event icon from %s to %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderValue($old),
|
||||
$this->renderValue($new));
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
$old = $this->getIconLabel($this->getOldValue());
|
||||
$new = $this->getIconLabel($this->getNewValue());
|
||||
|
||||
return pht(
|
||||
'%s changed the icon for %s from %s to %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject(),
|
||||
$this->renderValue($old),
|
||||
$this->renderValue($new));
|
||||
}
|
||||
|
||||
private function getIconLabel($icon) {
|
||||
$set = new PhabricatorCalendarIconSet();
|
||||
return $set->getIconLabel($icon);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,191 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorCalendarEventInviteTransaction
|
||||
extends PhabricatorCalendarEventTransactionType {
|
||||
|
||||
const TRANSACTIONTYPE = 'calendar.invite';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
$status_uninvited = PhabricatorCalendarEventInvitee::STATUS_UNINVITED;
|
||||
|
||||
$invitees = $object->getInvitees();
|
||||
foreach ($invitees as $key => $invitee) {
|
||||
if ($invitee->getStatus() == $status_uninvited) {
|
||||
unset($invitees[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
return mpull($invitees, 'getStatus', 'getInviteePHID');
|
||||
}
|
||||
|
||||
public function generateNewValue($object, $value) {
|
||||
$status_invited = PhabricatorCalendarEventInvitee::STATUS_INVITED;
|
||||
$status_uninvited = PhabricatorCalendarEventInvitee::STATUS_UNINVITED;
|
||||
$status_attending = PhabricatorCalendarEventInvitee::STATUS_ATTENDING;
|
||||
|
||||
$invitees = $this->generateOldValue($object);
|
||||
|
||||
$new = array_fuse($value);
|
||||
|
||||
$all = array_keys($invitees + $new);
|
||||
$map = array();
|
||||
foreach ($all as $phid) {
|
||||
$is_old = isset($invitees[$phid]);
|
||||
$is_new = isset($new[$phid]);
|
||||
|
||||
if ($is_old && !$is_new) {
|
||||
$map[$phid] = $status_uninvited;
|
||||
} else if (!$is_old && $is_new) {
|
||||
$map[$phid] = $status_invited;
|
||||
} else {
|
||||
$map[$phid] = $invitees[$phid];
|
||||
}
|
||||
}
|
||||
|
||||
// If we're creating this event and the actor is inviting themselves,
|
||||
// mark them as attending.
|
||||
if ($this->isNewObject()) {
|
||||
$acting_phid = $this->getActingAsPHID();
|
||||
if (isset($map[$acting_phid])) {
|
||||
$map[$acting_phid] = $status_attending;
|
||||
}
|
||||
}
|
||||
|
||||
return $map;
|
||||
}
|
||||
|
||||
public function applyExternalEffects($object, $value) {
|
||||
$phids = array_keys($value);
|
||||
$invitees = $object->getInvitees();
|
||||
$invitees = mpull($invitees, null, 'getInviteePHID');
|
||||
|
||||
foreach ($phids as $phid) {
|
||||
$invitee = idx($invitees, $phid);
|
||||
if (!$invitee) {
|
||||
$invitee = id(new PhabricatorCalendarEventInvitee())
|
||||
->setEventPHID($object->getPHID())
|
||||
->setInviteePHID($phid)
|
||||
->setInviterPHID($this->getActingAsPHID());
|
||||
$invitees[] = $invitee;
|
||||
}
|
||||
$invitee->setStatus($value[$phid])
|
||||
->save();
|
||||
}
|
||||
|
||||
$object->attachInvitees($invitees);
|
||||
}
|
||||
|
||||
public function validateTransactions($object, array $xactions) {
|
||||
$actor = $this->getActor();
|
||||
|
||||
$errors = array();
|
||||
|
||||
$old = $object->getInvitees();
|
||||
$old = mpull($old, null, 'getInviteePHID');
|
||||
foreach ($xactions as $xaction) {
|
||||
$new = $xaction->getNewValue();
|
||||
$new = array_fuse($new);
|
||||
$add = array_diff_key($new, $old);
|
||||
if (!$add) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// In the UI, we only allow you to invite mailable objects, but there
|
||||
// is no definitive marker for "invitable object" today. Just allow
|
||||
// any valid object to be invited.
|
||||
$objects = id(new PhabricatorObjectQuery())
|
||||
->setViewer($actor)
|
||||
->withPHIDs($add)
|
||||
->execute();
|
||||
$objects = mpull($objects, null, 'getPHID');
|
||||
foreach ($add as $phid) {
|
||||
if (isset($objects[$phid])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$errors[] = $this->newInvalidError(
|
||||
pht(
|
||||
'Invitee "%s" identifies an object that does not exist or '.
|
||||
'which you do not have permission to view.',
|
||||
$phid),
|
||||
$xaction);
|
||||
}
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
public function getIcon() {
|
||||
return 'fa-user-plus';
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
list($add, $rem) = $this->getChanges();
|
||||
|
||||
if ($add && !$rem) {
|
||||
return pht(
|
||||
'%s invited %s attendee(s): %s.',
|
||||
$this->renderAuthor(),
|
||||
phutil_count($add),
|
||||
$this->renderHandleList($add));
|
||||
} else if (!$add && $rem) {
|
||||
return pht(
|
||||
'%s uninvited %s attendee(s): %s.',
|
||||
$this->renderAuthor(),
|
||||
phutil_count($rem),
|
||||
$this->renderHandleList($rem));
|
||||
} else {
|
||||
return pht(
|
||||
'%s invited %s attendee(s): %s; uninvinted %s attendee(s): %s.',
|
||||
$this->renderAuthor(),
|
||||
phutil_count($add),
|
||||
$this->renderHandleList($add),
|
||||
phutil_count($rem),
|
||||
$this->renderHandleList($rem));
|
||||
}
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
list($add, $rem) = $this->getChanges();
|
||||
|
||||
if ($add && !$rem) {
|
||||
return pht(
|
||||
'%s invited %s attendee(s) to %s: %s.',
|
||||
$this->renderAuthor(),
|
||||
phutil_count($add),
|
||||
$this->renderObject(),
|
||||
$this->renderHandleList($add));
|
||||
} else if (!$add && $rem) {
|
||||
return pht(
|
||||
'%s uninvited %s attendee(s) to %s: %s.',
|
||||
$this->renderAuthor(),
|
||||
phutil_count($rem),
|
||||
$this->renderObject(),
|
||||
$this->renderHandleList($rem));
|
||||
} else {
|
||||
return pht(
|
||||
'%s updated the invite list for %s, invited %s: %s; '.
|
||||
'uninvinted %s: %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject(),
|
||||
phutil_count($add),
|
||||
$this->renderHandleList($add),
|
||||
phutil_count($rem),
|
||||
$this->renderHandleList($rem));
|
||||
}
|
||||
}
|
||||
|
||||
private function getChanges() {
|
||||
$old = $this->getOldValue();
|
||||
$new = $this->getNewValue();
|
||||
|
||||
$add = array_diff_key($new, $old);
|
||||
$rem = array_diff_key($old, $new);
|
||||
|
||||
$add = array_keys($add);
|
||||
$rem = array_keys($rem);
|
||||
|
||||
return array(array_fuse($add), array_fuse($rem));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorCalendarEventNameTransaction
|
||||
extends PhabricatorCalendarEventTransactionType {
|
||||
|
||||
const TRANSACTIONTYPE = 'calendar.name';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
return $object->getName();
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
$object->setName($value);
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
return pht(
|
||||
'%s renamed this event from %s to %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderOldValue(),
|
||||
$this->renderNewValue());
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
return pht(
|
||||
'%s renamed %s from %s to %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject(),
|
||||
$this->renderOldValue(),
|
||||
$this->renderNewValue());
|
||||
}
|
||||
|
||||
public function validateTransactions($object, array $xactions) {
|
||||
$errors = array();
|
||||
|
||||
if ($this->isEmptyTextTransaction($object->getName(), $xactions)) {
|
||||
$errors[] = $this->newRequiredError(
|
||||
pht('Events must have a name.'));
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorCalendarEventRecurringTransaction
|
||||
extends PhabricatorCalendarEventTransactionType {
|
||||
|
||||
const TRANSACTIONTYPE = 'calendar.recurring';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
return (int)$object->getIsRecurring();
|
||||
}
|
||||
|
||||
public function generateNewValue($object, $value) {
|
||||
return (int)$value;
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
$object->setIsRecurring($value);
|
||||
}
|
||||
|
||||
public function validateTransactions($object, array $xactions) {
|
||||
$errors = array();
|
||||
|
||||
$old = $object->getIsRecurring();
|
||||
foreach ($xactions as $xaction) {
|
||||
if ($this->getIsNewObject()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($xaction->getNewValue() == $old) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$errors[] = $this->newInvalidError(
|
||||
pht(
|
||||
'An event can only be made recurring when it is created. '.
|
||||
'You can not convert an existing event into a recurring '.
|
||||
'event or vice versa.'),
|
||||
$xaction);
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
abstract class PhabricatorCalendarEventReplyTransaction
|
||||
extends PhabricatorCalendarEventTransactionType {
|
||||
|
||||
public function generateOldValue($object) {
|
||||
$actor_phid = $this->getActingAsPHID();
|
||||
return $object->getUserInviteStatus($actor_phid);
|
||||
}
|
||||
|
||||
public function applyExternalEffects($object, $value) {
|
||||
$acting_phid = $this->getActingAsPHID();
|
||||
|
||||
$invitees = $object->getInvitees();
|
||||
$invitees = mpull($invitees, null, 'getInviteePHID');
|
||||
|
||||
$invitee = idx($invitees, $acting_phid);
|
||||
if (!$invitee) {
|
||||
$invitee = id(new PhabricatorCalendarEventInvitee())
|
||||
->setEventPHID($object->getPHID())
|
||||
->setInviteePHID($acting_phid)
|
||||
->setInviterPHID($acting_phid);
|
||||
$invitees[$acting_phid] = $invitee;
|
||||
}
|
||||
|
||||
$invitee
|
||||
->setStatus($value)
|
||||
->save();
|
||||
|
||||
$object->attachInvitees($invitees);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorCalendarEventStartDateTransaction
|
||||
extends PhabricatorCalendarEventDateTransaction {
|
||||
|
||||
const TRANSACTIONTYPE = 'calendar.startdate';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
return $object->getDateFrom();
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
$object->setDateFrom($value);
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
return pht(
|
||||
'%s changed the start date for this event from %s to %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderOldDate(),
|
||||
$this->renderNewDate());
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
return pht(
|
||||
'%s changed the start date for %s from %s to %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject(),
|
||||
$this->renderOldDate(),
|
||||
$this->renderNewDate());
|
||||
}
|
||||
|
||||
protected function getInvalidDateMessage() {
|
||||
return pht('Start date is invalid.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
|
||||
abstract class PhabricatorCalendarEventTransactionType
|
||||
extends PhabricatorModularTransactionType {}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorCalendarEventUntilDateTransaction
|
||||
extends PhabricatorCalendarEventDateTransaction {
|
||||
|
||||
const TRANSACTIONTYPE = 'calendar.recurrenceenddate';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
return $object->getRecurrenceEndDate();
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
$object->setRecurrenceEndDate($value);
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
return pht(
|
||||
'%s changed this event to repeat until %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderNewDate());
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
return pht(
|
||||
'%s changed %s to repeat until %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject(),
|
||||
$this->renderNewDate());
|
||||
}
|
||||
|
||||
protected function getInvalidDateMessage() {
|
||||
return pht('Repeat until date is invalid.');
|
||||
}
|
||||
|
||||
}
|
|
@ -12,6 +12,7 @@ final class PHUIHandleListView
|
|||
|
||||
private $handleList;
|
||||
private $asInline;
|
||||
private $asText;
|
||||
|
||||
public function setHandleList(PhabricatorHandleList $list) {
|
||||
$this->handleList = $list;
|
||||
|
@ -27,6 +28,15 @@ final class PHUIHandleListView
|
|||
return $this->asInline;
|
||||
}
|
||||
|
||||
public function setAsText($as_text) {
|
||||
$this->asText = $as_text;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAsText() {
|
||||
return $this->asText;
|
||||
}
|
||||
|
||||
protected function getTagName() {
|
||||
// TODO: It would be nice to render this with a proper <ul />, at least in
|
||||
// block mode, but don't stir the waters up too much for now.
|
||||
|
@ -37,9 +47,9 @@ final class PHUIHandleListView
|
|||
$list = $this->handleList;
|
||||
$items = array();
|
||||
foreach ($list as $handle) {
|
||||
$view = $list->renderHandle($handle->getPHID());
|
||||
|
||||
$view->setShowHovercard(true);
|
||||
$view = $list->renderHandle($handle->getPHID())
|
||||
->setShowHovercard(true)
|
||||
->setAsText($this->getAsText());
|
||||
|
||||
$items[] = $view;
|
||||
}
|
||||
|
|
|
@ -86,6 +86,14 @@ abstract class PhabricatorModularTransactionType
|
|||
return $this->viewer;
|
||||
}
|
||||
|
||||
final public function getActor() {
|
||||
return $this->getEditor()->getActor();
|
||||
}
|
||||
|
||||
final public function getActingAsPHID() {
|
||||
return $this->getEditor()->getActingAsPHID();
|
||||
}
|
||||
|
||||
final public function setEditor(
|
||||
PhabricatorApplicationTransactionEditor $editor) {
|
||||
$this->editor = $editor;
|
||||
|
@ -141,6 +149,19 @@ abstract class PhabricatorModularTransactionType
|
|||
return $display;
|
||||
}
|
||||
|
||||
final protected function renderHandleList(array $phids) {
|
||||
$viewer = $this->getViewer();
|
||||
$display = $viewer->renderHandleList($phids)
|
||||
->setAsInline(true);
|
||||
|
||||
$rendering_target = $this->getStorage()->getRenderingTarget();
|
||||
if ($rendering_target == PhabricatorApplicationTransaction::TARGET_TEXT) {
|
||||
$display->setAsText(true);
|
||||
}
|
||||
|
||||
return $display;
|
||||
}
|
||||
|
||||
final protected function renderValue($value) {
|
||||
$rendering_target = $this->getStorage()->getRenderingTarget();
|
||||
if ($rendering_target == PhabricatorApplicationTransaction::TARGET_TEXT) {
|
||||
|
@ -155,6 +176,32 @@ abstract class PhabricatorModularTransactionType
|
|||
$value);
|
||||
}
|
||||
|
||||
final protected function renderOldValue() {
|
||||
return $this->renderValue($this->getOldValue());
|
||||
}
|
||||
|
||||
final protected function renderNewValue() {
|
||||
return $this->renderValue($this->getNewValue());
|
||||
}
|
||||
|
||||
final protected function renderDate($epoch) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$display = phabricator_datetime($epoch, $viewer);
|
||||
|
||||
// TODO: When rendering for email, include the UTC offset. See T10633.
|
||||
|
||||
return $this->renderValue($display);
|
||||
}
|
||||
|
||||
final protected function renderOldDate() {
|
||||
return $this->renderDate($this->getOldValue());
|
||||
}
|
||||
|
||||
final protected function renderNewDate() {
|
||||
return $this->renderDate($this->getNewValue());
|
||||
}
|
||||
|
||||
final protected function newError($title, $message, $xaction = null) {
|
||||
return new PhabricatorApplicationTransactionValidationError(
|
||||
$this->getTransactionTypeConstant(),
|
||||
|
@ -163,4 +210,26 @@ abstract class PhabricatorModularTransactionType
|
|||
$xaction);
|
||||
}
|
||||
|
||||
final protected function newRequiredError($message, $xaction = null) {
|
||||
return $this->newError(pht('Required'), $message, $xaction)
|
||||
->setIsMissingFieldError(true);
|
||||
}
|
||||
|
||||
final protected function newInvalidError($message, $xaction = null) {
|
||||
return $this->newError(pht('Invalid'), $message, $xaction);
|
||||
}
|
||||
|
||||
final protected function isNewObject() {
|
||||
return $this->getEditor()->getIsNewObject();
|
||||
}
|
||||
|
||||
final protected function isEmptyTextTransaction($value, array $xactions) {
|
||||
foreach ($xactions as $xaction) {
|
||||
$value = $xaction->getNewValue();
|
||||
}
|
||||
|
||||
return !strlen($value);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1560,6 +1560,24 @@ final class PhabricatorUSEnglishTranslation
|
|||
),
|
||||
),
|
||||
),
|
||||
|
||||
'%s invited %s attendee(s): %s.' =>
|
||||
'%s invited: %3$s.',
|
||||
|
||||
'%s uninvited %s attendee(s): %s.' =>
|
||||
'%s uninvited: %3$s.',
|
||||
|
||||
'%s invited %s attendee(s): %s; uninvinted %s attendee(s): %s.' =>
|
||||
'%s invited: %3$s; uninvited: %5$s.',
|
||||
|
||||
'%s invited %s attendee(s) to %s: %s.' =>
|
||||
'%s added invites for %3$s: %4$s.',
|
||||
|
||||
'%s uninvited %s attendee(s) to %s: %s.' =>
|
||||
'%s removed invites for %3$s: %4$s.',
|
||||
|
||||
'%s updated the invite list for %s, invited %s: %s; uninvinted %s: %s.' =>
|
||||
'%s updated the invite list for %s, invited: %4$s; uninvited: %6$s.',
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue