mirror of
https://we.phorge.it/source/phorge.git
synced 2025-01-02 10:51:01 +01:00
Users should be able to rsvp to event via email
Summary: Closes T7957, Users should be able to rsvp to event via email. Test Plan: Create event, open invitee email, reply to email w/ !rsvp yes, refresh event, invitee should show as attending. Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley, #blessed_reviewers Subscribers: Korvin, epriestley Maniphest Tasks: T7957 Differential Revision: https://secure.phabricator.com/D12651
This commit is contained in:
parent
7aac1effac
commit
46a1b816ed
6 changed files with 148 additions and 14 deletions
|
@ -1498,6 +1498,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorCalendarEventCommentController' => 'applications/calendar/controller/PhabricatorCalendarEventCommentController.php',
|
||||
'PhabricatorCalendarEventEditController' => 'applications/calendar/controller/PhabricatorCalendarEventEditController.php',
|
||||
'PhabricatorCalendarEventEditor' => 'applications/calendar/editor/PhabricatorCalendarEventEditor.php',
|
||||
'PhabricatorCalendarEventEmailCommand' => 'applications/calendar/command/PhabricatorCalendarEventEmailCommand.php',
|
||||
'PhabricatorCalendarEventInvalidEpochException' => 'applications/calendar/exception/PhabricatorCalendarEventInvalidEpochException.php',
|
||||
'PhabricatorCalendarEventInvitee' => 'applications/calendar/storage/PhabricatorCalendarEventInvitee.php',
|
||||
'PhabricatorCalendarEventInviteeQuery' => 'applications/calendar/query/PhabricatorCalendarEventInviteeQuery.php',
|
||||
|
@ -1506,6 +1507,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorCalendarEventMailReceiver' => 'applications/calendar/mail/PhabricatorCalendarEventMailReceiver.php',
|
||||
'PhabricatorCalendarEventPHIDType' => 'applications/calendar/phid/PhabricatorCalendarEventPHIDType.php',
|
||||
'PhabricatorCalendarEventQuery' => 'applications/calendar/query/PhabricatorCalendarEventQuery.php',
|
||||
'PhabricatorCalendarEventRSVPEmailCommand' => 'applications/calendar/command/PhabricatorCalendarEventRSVPEmailCommand.php',
|
||||
'PhabricatorCalendarEventSearchEngine' => 'applications/calendar/query/PhabricatorCalendarEventSearchEngine.php',
|
||||
'PhabricatorCalendarEventSearchIndexer' => 'applications/calendar/search/PhabricatorCalendarEventSearchIndexer.php',
|
||||
'PhabricatorCalendarEventTransaction' => 'applications/calendar/storage/PhabricatorCalendarEventTransaction.php',
|
||||
|
@ -4848,6 +4850,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorCalendarEventCommentController' => 'PhabricatorCalendarController',
|
||||
'PhabricatorCalendarEventEditController' => 'PhabricatorCalendarController',
|
||||
'PhabricatorCalendarEventEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhabricatorCalendarEventEmailCommand' => 'MetaMTAEmailTransactionCommand',
|
||||
'PhabricatorCalendarEventInvalidEpochException' => 'Exception',
|
||||
'PhabricatorCalendarEventInvitee' => array(
|
||||
'PhabricatorCalendarDAO',
|
||||
|
@ -4859,6 +4862,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorCalendarEventMailReceiver' => 'PhabricatorObjectMailReceiver',
|
||||
'PhabricatorCalendarEventPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhabricatorCalendarEventQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhabricatorCalendarEventRSVPEmailCommand' => 'PhabricatorCalendarEventEmailCommand',
|
||||
'PhabricatorCalendarEventSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PhabricatorCalendarEventSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
|
||||
'PhabricatorCalendarEventTransaction' => 'PhabricatorApplicationTransaction',
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
abstract class PhabricatorCalendarEventEmailCommand
|
||||
extends MetaMTAEmailTransactionCommand {
|
||||
|
||||
public function isCommandSupportedForObject(
|
||||
PhabricatorApplicationTransactionInterface $object) {
|
||||
return ($object instanceof PhabricatorCalendarEvent);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorCalendarEventRSVPEmailCommand
|
||||
extends PhabricatorCalendarEventEmailCommand {
|
||||
|
||||
public function getCommand() {
|
||||
return 'rsvp';
|
||||
}
|
||||
|
||||
public function getCommandSyntax() {
|
||||
return '**!rsvp** //rsvp//';
|
||||
}
|
||||
|
||||
public function getCommandSummary() {
|
||||
return pht('RSVP to event.');
|
||||
}
|
||||
|
||||
public function getCommandDescription() {
|
||||
$status_attending = PhabricatorCalendarEventInvitee::STATUS_ATTENDING;
|
||||
$status_declined = PhabricatorCalendarEventInvitee::STATUS_DECLINED;
|
||||
|
||||
$yes_values = implode(', ', $this->getYesValues());
|
||||
$no_values = implode(', ', $this->getNoValues());
|
||||
|
||||
$table = array();
|
||||
$table[] = '| '.pht('RSVP').' | '.pht('Keywords');
|
||||
$table[] = '|---|---|';
|
||||
$table[] = '| '.$status_attending.' | '.$yes_values;
|
||||
$table[] = '| '.$status_declined.' | '.$no_values;
|
||||
$table = implode("\n", $table);
|
||||
|
||||
return pht(
|
||||
'To RSVP to the event, specify the desired RSVP, like '.
|
||||
'`!rsvp yes`. This table shows the configured names for rsvp\'s.'.
|
||||
"\n\n%s\n\n".
|
||||
'If you specify an invalid rsvp, the command is ignored. This '.
|
||||
'command has no effect if you do not specify an rsvp.',
|
||||
$table);
|
||||
}
|
||||
|
||||
public function buildTransactions(
|
||||
PhabricatorUser $viewer,
|
||||
PhabricatorApplicationTransactionInterface $object,
|
||||
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;
|
||||
} else if (in_array($target, $no_values)) {
|
||||
$rsvp = $status_declined;
|
||||
} else {
|
||||
$rsvp = null;
|
||||
}
|
||||
|
||||
if ($rsvp === null) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$xactions[] = $object->getApplicationTransactionTemplate()
|
||||
->setTransactionType(PhabricatorCalendarEventTransaction::TYPE_INVITE)
|
||||
->setNewValue(array($viewer->getPHID() => $rsvp));
|
||||
|
||||
return $xactions;
|
||||
}
|
||||
|
||||
private function getYesValues() {
|
||||
return array(
|
||||
'yes',
|
||||
'yep',
|
||||
'sounds good',
|
||||
'going',
|
||||
'attending',
|
||||
'will be there',
|
||||
'sure',
|
||||
'accept',
|
||||
'ya',
|
||||
'yeah',
|
||||
'yuh',
|
||||
'uhuh',
|
||||
'ok',
|
||||
'okay',
|
||||
'yiss',
|
||||
'aww yiss',
|
||||
'attend',
|
||||
'intend to attend',
|
||||
'confirm',
|
||||
'confirmed',
|
||||
'bringing dessert',
|
||||
'bringing desert',
|
||||
'time2business',
|
||||
'time4business',
|
||||
);
|
||||
}
|
||||
|
||||
private function getNoValues() {
|
||||
return array(
|
||||
'no',
|
||||
'nope',
|
||||
'no thank you',
|
||||
'next time',
|
||||
'nah',
|
||||
'nuh',
|
||||
'huh',
|
||||
'wut',
|
||||
'no way',
|
||||
'nuhuh',
|
||||
'decline',
|
||||
'declined',
|
||||
'leave',
|
||||
'cancel',
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -147,16 +147,8 @@ final class PhabricatorCalendarEventEditor
|
|||
case PhabricatorCalendarEventTransaction::TYPE_INVITE:
|
||||
$map = $xaction->getNewValue();
|
||||
$phids = array_keys($map);
|
||||
$invitees = array();
|
||||
|
||||
if ($map) {
|
||||
$invitees = id(new PhabricatorCalendarEventInviteeQuery())
|
||||
->setViewer($this->getActor())
|
||||
->withEventPHIDs(array($object->getPHID()))
|
||||
->withInviteePHIDs($phids)
|
||||
->execute();
|
||||
$invitees = mpull($invitees, null, 'getInviteePHID');
|
||||
}
|
||||
$invitees = $object->getInvitees();
|
||||
$invitees = mpull($invitees, null, 'getInviteePHID');
|
||||
|
||||
foreach ($phids as $phid) {
|
||||
$invitee = idx($invitees, $phid);
|
||||
|
@ -165,10 +157,12 @@ final class PhabricatorCalendarEventEditor
|
|||
->setEventPHID($object->getPHID())
|
||||
->setInviteePHID($phid)
|
||||
->setInviterPHID($this->getActingAsPHID());
|
||||
$invitees[] = $invitee;
|
||||
}
|
||||
$invitee->setStatus($map[$phid])
|
||||
->save();
|
||||
}
|
||||
$object->attachInvitees($invitees);
|
||||
return;
|
||||
case PhabricatorTransactions::TYPE_COMMENT:
|
||||
case PhabricatorTransactions::TYPE_VIEW_POLICY:
|
||||
|
@ -254,14 +248,16 @@ final class PhabricatorCalendarEventEditor
|
|||
$phids[] = $this->getActingAsPHID();
|
||||
|
||||
$invitees = $object->getInvitees();
|
||||
foreach ($invitees as $phid => $status) {
|
||||
foreach ($invitees as $invitee) {
|
||||
$status = $invitee->getStatus();
|
||||
if ($status === PhabricatorCalendarEventInvitee::STATUS_ATTENDING
|
||||
|| $status === PhabricatorCalendarEventInvitee::STATUS_INVITED) {
|
||||
$phids[] = $phid;
|
||||
$phids[] = $invitee->getInviteePHID();
|
||||
}
|
||||
}
|
||||
|
||||
$phids = array_unique($phids);
|
||||
|
||||
return $phids;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ final class PhabricatorCalendarEvent extends PhabricatorCalendarDAO
|
|||
}
|
||||
|
||||
public function save() {
|
||||
if ($this->getDateTo() <= $this->getDateFrom()) {
|
||||
if ($this->getDateTo() < $this->getDateFrom()) {
|
||||
throw new PhabricatorCalendarEventInvalidEpochException();
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ final class PhabricatorCalendarEventTransaction
|
|||
const TYPE_CANCEL = 'calendar.cancel';
|
||||
const TYPE_INVITE = 'calendar.invite';
|
||||
|
||||
|
||||
const MAILTAG_RESCHEDULE = 'calendar-reschedule';
|
||||
const MAILTAG_CONTENT = 'calendar-content';
|
||||
const MAILTAG_OTHER = 'calendar-other';
|
||||
|
|
Loading…
Reference in a new issue