Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14871729
D12645.id30377.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
12 KB
Referenced Files
None
Subscribers
None
D12645.id30377.diff
View Options
diff --git a/resources/sql/autopatches/20150501.calendar.1.reply.sql b/resources/sql/autopatches/20150501.calendar.1.reply.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20150501.calendar.1.reply.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_calendar.calendar_event
+ ADD mailKey binary(20) NOT NULL;
diff --git a/resources/sql/autopatches/20150501.calendar.2.reply.php b/resources/sql/autopatches/20150501.calendar.2.reply.php
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20150501.calendar.2.reply.php
@@ -0,0 +1,21 @@
+<?php
+
+echo "Adding mailkeys to events.\n";
+
+$table = new PhabricatorCalendarEvent();
+$conn_w = $table->establishConnection('w');
+$iterator = new LiskMigrationIterator($table);
+foreach ($iterator as $event) {
+ $id = $event->getID();
+
+ echo "Populating event {$id}...\n";
+
+ queryfx(
+ $conn_w,
+ 'UPDATE %T SET mailKey = %s WHERE id = %d',
+ $table->getTableName(),
+ Filesystem::readRandomCharacters(20),
+ $id);
+}
+
+echo "Done.\n";
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1491,6 +1491,7 @@
'PhabricatorCalendarEventInviteeQuery' => 'applications/calendar/query/PhabricatorCalendarEventInviteeQuery.php',
'PhabricatorCalendarEventJoinController' => 'applications/calendar/controller/PhabricatorCalendarEventJoinController.php',
'PhabricatorCalendarEventListController' => 'applications/calendar/controller/PhabricatorCalendarEventListController.php',
+ 'PhabricatorCalendarEventMailReceiver' => 'applications/calendar/mail/PhabricatorCalendarEventMailReceiver.php',
'PhabricatorCalendarEventPHIDType' => 'applications/calendar/phid/PhabricatorCalendarEventPHIDType.php',
'PhabricatorCalendarEventQuery' => 'applications/calendar/query/PhabricatorCalendarEventQuery.php',
'PhabricatorCalendarEventSearchEngine' => 'applications/calendar/query/PhabricatorCalendarEventSearchEngine.php',
@@ -1502,6 +1503,7 @@
'PhabricatorCalendarHoliday' => 'applications/calendar/storage/PhabricatorCalendarHoliday.php',
'PhabricatorCalendarHolidayTestCase' => 'applications/calendar/storage/__tests__/PhabricatorCalendarHolidayTestCase.php',
'PhabricatorCalendarRemarkupRule' => 'applications/calendar/remarkup/PhabricatorCalendarRemarkupRule.php',
+ 'PhabricatorCalendarReplyHandler' => 'applications/calendar/mail/PhabricatorCalendarReplyHandler.php',
'PhabricatorCalendarSchemaSpec' => 'applications/calendar/storage/PhabricatorCalendarSchemaSpec.php',
'PhabricatorCalendarViewController' => 'applications/calendar/controller/PhabricatorCalendarViewController.php',
'PhabricatorCampfireProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorCampfireProtocolAdapter.php',
@@ -4830,6 +4832,7 @@
'PhabricatorCalendarEventInviteeQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorCalendarEventJoinController' => 'PhabricatorCalendarController',
'PhabricatorCalendarEventListController' => 'PhabricatorCalendarController',
+ 'PhabricatorCalendarEventMailReceiver' => 'PhabricatorObjectMailReceiver',
'PhabricatorCalendarEventPHIDType' => 'PhabricatorPHIDType',
'PhabricatorCalendarEventQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorCalendarEventSearchEngine' => 'PhabricatorApplicationSearchEngine',
@@ -4841,6 +4844,7 @@
'PhabricatorCalendarHoliday' => 'PhabricatorCalendarDAO',
'PhabricatorCalendarHolidayTestCase' => 'PhabricatorTestCase',
'PhabricatorCalendarRemarkupRule' => 'PhabricatorObjectRemarkupRule',
+ 'PhabricatorCalendarReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
'PhabricatorCalendarSchemaSpec' => 'PhabricatorConfigSchemaSpec',
'PhabricatorCalendarViewController' => 'PhabricatorCalendarController',
'PhabricatorCampfireProtocolAdapter' => 'PhabricatorBotBaseStreamingProtocolAdapter',
diff --git a/src/applications/calendar/application/PhabricatorCalendarApplication.php b/src/applications/calendar/application/PhabricatorCalendarApplication.php
--- a/src/applications/calendar/application/PhabricatorCalendarApplication.php
+++ b/src/applications/calendar/application/PhabricatorCalendarApplication.php
@@ -74,4 +74,18 @@
return $items;
}
+ public function getMailCommandObjects() {
+ return array(
+ 'event' => array(
+ 'name' => pht('Email Commands: Events'),
+ 'header' => pht('Interacting with Calendar Events'),
+ 'object' => new PhabricatorCalendarEvent(),
+ 'summary' => pht(
+ 'This page documents the commands you can use to interact with '.
+ 'events in Calendar. These commands work when creating new tasks '.
+ 'via email and when replying to existing tasks.'),
+ ),
+ );
+ }
+
}
diff --git a/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php b/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php
--- a/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php
+++ b/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php
@@ -209,10 +209,6 @@
return $errors;
}
- protected function getMailTo(PhabricatorLiskDAO $object) {
- return array($object->getUserPHID());
- }
-
protected function shouldPublishFeedStory(
PhabricatorLiskDAO $object,
array $xactions) {
@@ -222,4 +218,86 @@
protected function supportsSearch() {
return true;
}
+
+ protected function shouldSendMail(
+ PhabricatorLiskDAO $object,
+ array $xactions) {
+
+ $xactions = mfilter($xactions, 'shouldHide', true);
+ return $xactions;
+ }
+
+ protected function getMailSubjectPrefix() {
+ return pht('[Calendar]');
+ }
+
+ protected function getMailTo(PhabricatorLiskDAO $object) {
+ $phids = array();
+
+ if ($object->getUserPHID()) {
+ $phids[] = $object->getUserPHID();
+ }
+ $phids[] = $this->getActingAsPHID();
+
+ $invitees = $object->getInvitees();
+ foreach ($invitees as $phid => $status) {
+ if ($status === PhabricatorCalendarEventInvitee::STATUS_ATTENDING
+ || $status === PhabricatorCalendarEventInvitee::STATUS_INVITED) {
+ $phids[] = $phid;
+ }
+ }
+
+ $phids = array_unique($phids);
+ return $phids;
+ }
+
+ public function getMailTagsMap() {
+ return array(
+ PhabricatorCalendarEventTransaction::MAILTAG_CONTENT =>
+ pht("An event's name, status, invite list, and description
+ changes."),
+ PhabricatorCalendarEventTransaction::MAILTAG_RESCHEDULE =>
+ pht("An event's start and end date and cancellation status
+ changes."),
+ PhabricatorCalendarEventTransaction::MAILTAG_OTHER =>
+ pht('Other event activity not listed above occurs.'),
+ );
+ }
+
+ protected function buildReplyHandler(PhabricatorLiskDAO $object) {
+ return id(new PhabricatorCalendarReplyHandler())
+ ->setMailReceiver($object);
+ }
+
+ protected function buildMailTemplate(PhabricatorLiskDAO $object) {
+ $id = $object->getID();
+ $name = $object->getName();
+
+ return id(new PhabricatorMetaMTAMail())
+ ->setSubject("E{$id}: {$name}")
+ ->addHeader('Thread-Topic', "E{$id}: ".$object->getName());
+ }
+
+ protected function buildMailBody(
+ PhabricatorLiskDAO $object,
+ array $xactions) {
+
+ $description = $object->getDescription();
+ $body = parent::buildMailBody($object, $xactions);
+
+ if (strlen($description)) {
+ $body->addTextSection(
+ pht('EVENT DESCRIPTION'),
+ $object->getDescription());
+ }
+
+ $body->addLinkSection(
+ pht('EVENT DETAIL'),
+ PhabricatorEnv::getProductionURI('/E'.$object->getID()));
+
+
+ return $body;
+ }
+
+
}
diff --git a/src/applications/calendar/mail/PhabricatorCalendarEventMailReceiver.php b/src/applications/calendar/mail/PhabricatorCalendarEventMailReceiver.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/mail/PhabricatorCalendarEventMailReceiver.php
@@ -0,0 +1,28 @@
+<?php
+
+final class PhabricatorCalendarEventMailReceiver
+ extends PhabricatorObjectMailReceiver {
+
+ public function isEnabled() {
+ $app_class = 'PhabricatorCalendarApplication';
+ return PhabricatorApplication::isClassInstalled($app_class);
+ }
+
+ protected function getObjectPattern() {
+ return 'E[1-9]\d*';
+ }
+
+ protected function loadObject($pattern, PhabricatorUser $viewer) {
+ $id = (int)trim($pattern, 'E');
+
+ return id(new PhabricatorCalendarEventQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($id))
+ ->executeOne();
+ }
+
+ protected function getTransactionReplyHandler() {
+ return new PhabricatorCalendarReplyHandler();
+ }
+
+}
diff --git a/src/applications/calendar/mail/PhabricatorCalendarReplyHandler.php b/src/applications/calendar/mail/PhabricatorCalendarReplyHandler.php
new file mode 100644
--- /dev/null
+++ b/src/applications/calendar/mail/PhabricatorCalendarReplyHandler.php
@@ -0,0 +1,15 @@
+<?php
+
+final class PhabricatorCalendarReplyHandler
+ extends PhabricatorApplicationTransactionReplyHandler {
+
+ public function validateMailReceiver($mail_receiver) {
+ if (!($mail_receiver instanceof PhabricatorCalendarEvent)) {
+ throw new Exception('Mail receiver is not a PhabricatorCalendarEvent!');
+ }
+ }
+
+ public function getObjectPrefix() {
+ return 'E';
+ }
+}
diff --git a/src/applications/calendar/storage/PhabricatorCalendarEvent.php b/src/applications/calendar/storage/PhabricatorCalendarEvent.php
--- a/src/applications/calendar/storage/PhabricatorCalendarEvent.php
+++ b/src/applications/calendar/storage/PhabricatorCalendarEvent.php
@@ -17,6 +17,7 @@
protected $status;
protected $description;
protected $isCancelled;
+ protected $mailKey;
protected $viewPolicy;
protected $editPolicy;
@@ -40,6 +41,17 @@
->attachInvitees(array());
}
+ public function save() {
+ if ($this->getDateTo() <= $this->getDateFrom()) {
+ throw new PhabricatorCalendarEventInvalidEpochException();
+ }
+
+ if (!$this->mailKey) {
+ $this->mailKey = Filesystem::readRandomCharacters(20);
+ }
+ return parent::save();
+ }
+
private static $statusTexts = array(
self::STATUS_AWAY => 'away',
self::STATUS_SPORADIC => 'sporadic',
@@ -76,6 +88,7 @@
'status' => 'uint32',
'description' => 'text',
'isCancelled' => 'bool',
+ 'mailKey' => 'bytes20',
),
self::CONFIG_KEY_SCHEMA => array(
'userPHID_dateFrom' => array(
@@ -156,19 +169,6 @@
return $is_attending;
}
- /**
- * Validates data and throws exceptions for non-sensical status
- * windows
- */
- public function save() {
-
- if ($this->getDateTo() <= $this->getDateFrom()) {
- throw new PhabricatorCalendarEventInvalidEpochException();
- }
-
- return parent::save();
- }
-
/* -( Markup Interface )--------------------------------------------------- */
diff --git a/src/applications/calendar/storage/PhabricatorCalendarEventTransaction.php b/src/applications/calendar/storage/PhabricatorCalendarEventTransaction.php
--- a/src/applications/calendar/storage/PhabricatorCalendarEventTransaction.php
+++ b/src/applications/calendar/storage/PhabricatorCalendarEventTransaction.php
@@ -11,6 +11,8 @@
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';
@@ -442,25 +444,15 @@
$tags = array();
switch ($this->getTransactionType()) {
case self::TYPE_NAME:
- $tags[] = self::MAILTAG_CONTENT;
- break;
- case self::TYPE_START_DATE:
- $tags[] = self::MAILTAG_CONTENT;
- break;
- case self::TYPE_END_DATE:
- $tags[] = self::MAILTAG_CONTENT;
- break;
case self::TYPE_STATUS:
- $tags[] = self::MAILTAG_OTHER;
- break;
case self::TYPE_DESCRIPTION:
+ case self::TYPE_INVITE:
$tags[] = self::MAILTAG_CONTENT;
break;
+ case self::TYPE_START_DATE:
+ case self::TYPE_END_DATE:
case self::TYPE_CANCEL:
- $tags[] = self::MAILTAG_CONTENT;
- break;
- case self::TYPE_INVITE:
- $tags[] = self::MAILTAG_CONTENT;
+ $tags[] = self::MAILTAG_RESCHEDULE;
break;
}
return $tags;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Feb 9, 4:10 AM (3 h, 19 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7105403
Default Alt Text
D12645.id30377.diff (12 KB)
Attached To
Mode
D12645: Calendar event transaction emails without reply handling
Attached
Detach File
Event Timeline
Log In to Comment