Page MenuHomePhabricator

D12868.id30952.diff
No OneTemporary

D12868.id30952.diff

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
@@ -3101,6 +3101,7 @@
'ProjectQueryConduitAPIMethod' => 'applications/project/conduit/ProjectQueryConduitAPIMethod.php',
'ProjectRemarkupRule' => 'applications/project/remarkup/ProjectRemarkupRule.php',
'ProjectRemarkupRuleTestCase' => 'applications/project/remarkup/__tests__/ProjectRemarkupRuleTestCase.php',
+ 'ProjectReplyHandler' => 'applications/project/mail/ProjectReplyHandler.php',
'QueryFormattingTestCase' => 'infrastructure/storage/__tests__/QueryFormattingTestCase.php',
'ReleephAuthorFieldSpecification' => 'applications/releeph/field/specification/ReleephAuthorFieldSpecification.php',
'ReleephBranch' => 'applications/releeph/storage/ReleephBranch.php',
@@ -6670,6 +6671,7 @@
'ProjectQueryConduitAPIMethod' => 'ProjectConduitAPIMethod',
'ProjectRemarkupRule' => 'PhabricatorObjectRemarkupRule',
'ProjectRemarkupRuleTestCase' => 'PhabricatorTestCase',
+ 'ProjectReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
'QueryFormattingTestCase' => 'PhabricatorTestCase',
'ReleephAuthorFieldSpecification' => 'ReleephFieldSpecification',
'ReleephBranch' => array(
diff --git a/src/applications/project/editor/PhabricatorProjectTransactionEditor.php b/src/applications/project/editor/PhabricatorProjectTransactionEditor.php
--- a/src/applications/project/editor/PhabricatorProjectTransactionEditor.php
+++ b/src/applications/project/editor/PhabricatorProjectTransactionEditor.php
@@ -41,7 +41,7 @@
$slugs = $object->getSlugs();
$slugs = mpull($slugs, 'getSlug', 'getSlug');
unset($slugs[$object->getPrimarySlug()]);
- return $slugs;
+ return array_keys($slugs);
case PhabricatorProjectTransaction::TYPE_STATUS:
return $object->getStatus();
case PhabricatorProjectTransaction::TYPE_IMAGE:
@@ -403,11 +403,74 @@
return parent::requireCapabilities($object, $xaction);
}
- /**
- * Note: this is implemented for Feed purposes.
- */
+ protected function loadEdges(
+ PhabricatorLiskDAO $object,
+ array $xactions) {
+
+ $member_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
+ $object->getPHID(),
+ PhabricatorProjectProjectHasMemberEdgeType::EDGECONST);
+ $object->attachMemberPHIDs($member_phids);
+ }
+
+ protected function shouldSendMail(
+ PhabricatorLiskDAO $object,
+ array $xactions) {
+ return true;
+ }
+
+ protected function getMailSubjectPrefix() {
+ return pht('[Project]');
+ }
+
protected function getMailTo(PhabricatorLiskDAO $object) {
- return array();
+ return $object->getMemberPHIDs();
+ }
+
+ protected function getMailCC(PhabricatorLiskDAO $object) {
+ $all = parent::getMailCC($object);
+ return array_diff($all, $object->getMemberPHIDs());
+ }
+
+ public function getMailTagsMap() {
+ return array(
+ PhabricatorProjectTransaction::MAILTAG_METADATA =>
+ pht('Project name, hashtags, icon, image, or color changes.'),
+ PhabricatorProjectTransaction::MAILTAG_MEMBERS =>
+ pht('Project membership changes.'),
+ PhabricatorProjectTransaction::MAILTAG_WATCHERS =>
+ pht('Project watcher list changes.'),
+ PhabricatorProjectTransaction::MAILTAG_OTHER =>
+ pht('Other project activity not listed above occurs.'),
+ );
+ }
+
+ protected function buildReplyHandler(PhabricatorLiskDAO $object) {
+ return id(new ProjectReplyHandler())
+ ->setMailReceiver($object);
+ }
+
+ protected function buildMailTemplate(PhabricatorLiskDAO $object) {
+ $id = $object->getID();
+ $name = $object->getName();
+
+ return id(new PhabricatorMetaMTAMail())
+ ->setSubject("{$name}")
+ ->addHeader('Thread-Topic', "Project {$id}");
+ }
+
+ protected function buildMailBody(
+ PhabricatorLiskDAO $object,
+ array $xactions) {
+
+ $body = parent::buildMailBody($object, $xactions);
+
+ $uri = '/project/profile/'.$object->getID().'/';
+ $body->addLinkSection(
+ pht('PROJECT DETAIL'),
+ PhabricatorEnv::getProductionURI($uri));
+
+ return $body;
}
protected function shouldPublishFeedStory(
diff --git a/src/applications/project/mail/ProjectReplyHandler.php b/src/applications/project/mail/ProjectReplyHandler.php
new file mode 100644
--- /dev/null
+++ b/src/applications/project/mail/ProjectReplyHandler.php
@@ -0,0 +1,20 @@
+<?php
+
+final class ProjectReplyHandler
+ extends PhabricatorApplicationTransactionReplyHandler {
+
+ public function validateMailReceiver($mail_receiver) {
+ if (!($mail_receiver instanceof PhabricatorProject)) {
+ throw new Exception('Mail receiver is not a PhabricatorProject.');
+ }
+ }
+
+ public function getObjectPrefix() {
+ return PhabricatorProjectProjectPHIDType::TYPECONST;
+ }
+
+ protected function shouldCreateCommentFromMailBody() {
+ return false;
+ }
+
+}
diff --git a/src/applications/project/storage/PhabricatorProjectTransaction.php b/src/applications/project/storage/PhabricatorProjectTransaction.php
--- a/src/applications/project/storage/PhabricatorProjectTransaction.php
+++ b/src/applications/project/storage/PhabricatorProjectTransaction.php
@@ -14,6 +14,11 @@
// NOTE: This is deprecated, members are just a normal edge now.
const TYPE_MEMBERS = 'project:members';
+ const MAILTAG_METADATA = 'project-metadata';
+ const MAILTAG_MEMBERS = 'project-members';
+ const MAILTAG_WATCHERS = 'project-watchers';
+ const MAILTAG_OTHER = 'project-other';
+
public function getApplicationName() {
return 'project';
}
@@ -106,6 +111,8 @@
$old,
$new);
}
+ break;
+
case self::TYPE_STATUS:
if ($old == 0) {
return pht(
@@ -116,6 +123,8 @@
'%s activated this project.',
$author_handle);
}
+ break;
+
case self::TYPE_IMAGE:
// TODO: Some day, it would be nice to show the images.
if (!$old) {
@@ -134,18 +143,21 @@
$this->renderHandleLink($old),
$this->renderHandleLink($new));
}
+ break;
case self::TYPE_ICON:
return pht(
'%s set this project\'s icon to %s.',
$author_handle,
PhabricatorProjectIcon::getLabel($new));
+ break;
case self::TYPE_COLOR:
return pht(
'%s set this project\'s color to %s.',
$author_handle,
PHUITagView::getShadeName($new));
+ break;
case self::TYPE_LOCKED:
if ($new) {
@@ -157,6 +169,7 @@
'%s unlocked this project\'s membership.',
$author_handle);
}
+ break;
case self::TYPE_SLUGS:
$add = array_diff($new, $old);
@@ -183,6 +196,7 @@
count($rem),
$this->renderSlugList($rem));
}
+ break;
case self::TYPE_MEMBERS:
$add = array_diff($new, $old);
@@ -221,6 +235,7 @@
$this->renderHandleList($rem));
}
}
+ break;
}
return parent::getTitle();
@@ -339,12 +354,43 @@
$object_handle,
$this->renderSlugList($rem));
}
-
}
return parent::getTitleForFeed();
}
+ public function getMailTags() {
+ $tags = array();
+ switch ($this->getTransactionType()) {
+ case self::TYPE_NAME:
+ case self::TYPE_SLUGS:
+ case self::TYPE_IMAGE:
+ case self::TYPE_ICON:
+ case self::TYPE_COLOR:
+ $tags[] = self::MAILTAG_METADATA;
+ break;
+ case PhabricatorTransactions::TYPE_EDGE:
+ $type = $this->getMetadata('edge:type');
+ $type = head($type);
+ $type_member = PhabricatorProjectProjectHasMemberEdgeType::EDGECONST;
+ $type_watcher = PhabricatorObjectHasWatcherEdgeType::EDGECONST;
+ if ($type == $type_member) {
+ $tags[] = self::MAILTAG_MEMBERS;
+ } else if ($type == $type_watcher) {
+ $tags[] = self::MAILTAG_WATCHERS;
+ } else {
+ $tags[] = self::MAILTAG_OTHER;
+ }
+ break;
+ case self::TYPE_STATUS:
+ case self::TYPE_LOCKED:
+ default:
+ $tags[] = self::MAILTAG_OTHER;
+ break;
+ }
+ return $tags;
+ }
+
private function renderSlugList($slugs) {
return implode(', ', $slugs);
}
diff --git a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
--- a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
+++ b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
@@ -840,6 +840,8 @@
// subscribers to pick up changes caused by Herald (or by other side effects
// in various transaction phases).
$this->loadSubscribers($object);
+ // Hook for other edges that may need (re-)loading
+ $this->loadEdges($object, $xactions);
$this->loadHandles($xactions);
@@ -965,6 +967,12 @@
}
}
+ protected function loadEdges(
+ PhabricatorLiskDAO $object,
+ array $xactions) {
+ return;
+ }
+
private function validateEditParameters(
PhabricatorLiskDAO $object,
array $xactions) {

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 2, 12:47 PM (5 d, 20 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7711939
Default Alt Text
D12868.id30952.diff (9 KB)

Event Timeline