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 @@ -2773,6 +2773,7 @@ 'PhrictionDiffController' => 'applications/phriction/controller/PhrictionDiffController.php', 'PhrictionDocument' => 'applications/phriction/storage/PhrictionDocument.php', 'PhrictionDocumentController' => 'applications/phriction/controller/PhrictionDocumentController.php', + 'PhrictionDocumentHeraldAdapter' => 'applications/phriction/herald/PhrictionDocumentHeraldAdapter.php', 'PhrictionDocumentPHIDType' => 'applications/phriction/phid/PhrictionDocumentPHIDType.php', 'PhrictionDocumentPreviewController' => 'applications/phriction/controller/PhrictionDocumentPreviewController.php', 'PhrictionDocumentQuery' => 'applications/phriction/query/PhrictionDocumentQuery.php', @@ -5988,8 +5989,10 @@ 'PhabricatorFlaggableInterface', 'PhabricatorTokenReceiverInterface', 'PhabricatorDestructibleInterface', + 'PhabricatorApplicationTransactionInterface', ), 'PhrictionDocumentController' => 'PhrictionController', + 'PhrictionDocumentHeraldAdapter' => 'HeraldAdapter', 'PhrictionDocumentPHIDType' => 'PhabricatorPHIDType', 'PhrictionDocumentPreviewController' => 'PhrictionController', 'PhrictionDocumentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', diff --git a/src/applications/herald/adapter/HeraldAdapter.php b/src/applications/herald/adapter/HeraldAdapter.php --- a/src/applications/herald/adapter/HeraldAdapter.php +++ b/src/applications/herald/adapter/HeraldAdapter.php @@ -42,6 +42,7 @@ const FIELD_TASK_PRIORITY = 'taskpriority'; const FIELD_ARCANIST_PROJECT = 'arcanist-project'; const FIELD_PUSHER_IS_COMMITTER = 'pusher-is-committer'; + const FIELD_PATH = 'path'; const CONDITION_CONTAINS = 'contains'; const CONDITION_NOT_CONTAINS = '!contains'; @@ -312,6 +313,7 @@ self::FIELD_TASK_PRIORITY => pht('Task priority'), self::FIELD_ARCANIST_PROJECT => pht('Arcanist Project'), self::FIELD_PUSHER_IS_COMMITTER => pht('Pusher same as committer'), + self::FIELD_PATH => pht('Path'), ) + $this->getCustomFieldNameMap(); } @@ -353,6 +355,7 @@ case self::FIELD_BODY: case self::FIELD_COMMITTER_RAW: case self::FIELD_AUTHOR_RAW: + case self::FIELD_PATH: return array( self::CONDITION_CONTAINS, self::CONDITION_NOT_CONTAINS, diff --git a/src/applications/herald/controller/HeraldTestConsoleController.php b/src/applications/herald/controller/HeraldTestConsoleController.php --- a/src/applications/herald/controller/HeraldTestConsoleController.php +++ b/src/applications/herald/controller/HeraldTestConsoleController.php @@ -47,6 +47,9 @@ } else if ($object instanceof PholioMock) { $adapter = id(new HeraldPholioMockAdapter()) ->setMock($object); + } else if ($object instanceof PhrictionDocument) { + $adapter = id(new PhrictionDocumentHeraldAdapter()) + ->setDocument($object); } else { throw new Exception('Can not build adapter for object!'); } diff --git a/src/applications/phriction/editor/PhrictionTransactionEditor.php b/src/applications/phriction/editor/PhrictionTransactionEditor.php --- a/src/applications/phriction/editor/PhrictionTransactionEditor.php +++ b/src/applications/phriction/editor/PhrictionTransactionEditor.php @@ -10,6 +10,7 @@ private $skipAncestorCheck; private $contentVersion; private $processContentVersionError = true; + private $heraldEmailPHIDs = array(); public function setDescription($description) { $this->description = $description; @@ -359,6 +360,16 @@ ); } + protected function getMailCC(PhabricatorLiskDAO $object) { + $phids = array(); + + foreach ($this->heraldEmailPHIDs as $phid) { + $phids[] = $phid; + } + + return $phids; + } + public function getMailTagsMap() { return array( PhrictionTransaction::MAILTAG_TITLE => @@ -647,7 +658,35 @@ protected function shouldApplyHeraldRules( PhabricatorLiskDAO $object, array $xactions) { - return false; + return true; + } + + protected function buildHeraldAdapter( + PhabricatorLiskDAO $object, + array $xactions) { + + return id(new PhrictionDocumentHeraldAdapter()) + ->setDocument($object); + } + + protected function didApplyHeraldRules( + PhabricatorLiskDAO $object, + HeraldAdapter $adapter, + HeraldTranscript $transcript) { + + $xactions = array(); + + $cc_phids = $adapter->getCcPHIDs(); + if ($cc_phids) { + $value = array_fuse($cc_phids); + $xactions[] = id(new PhrictionTransaction()) + ->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS) + ->setNewValue(array('+' => $value)); + } + + $this->heraldEmailPHIDs = $adapter->getEmailPHIDs(); + + return $xactions; } private function buildNewContentTemplate( diff --git a/src/applications/phriction/herald/PhrictionDocumentHeraldAdapter.php b/src/applications/phriction/herald/PhrictionDocumentHeraldAdapter.php new file mode 100644 --- /dev/null +++ b/src/applications/phriction/herald/PhrictionDocumentHeraldAdapter.php @@ -0,0 +1,169 @@ +<?php + +final class PhrictionDocumentHeraldAdapter extends HeraldAdapter { + + private $document; + private $ccPHIDs = array(); + private $emailPHIDs = array(); + + public function getAdapterApplicationClass() { + return 'PhabricatorPhrictionApplication'; + } + + public function getAdapterContentDescription() { + return pht('React to wiki documents being created or updated.'); + } + + public function getObject() { + return $this->document; + } + + public function setDocument(PhrictionDocument $document) { + $this->document = $document; + return $this; + } + public function getDocument() { + return $this->document; + } + + private function setCcPHIDs(array $cc_phids) { + $this->ccPHIDs = $cc_phids; + return $this; + } + public function getCcPHIDs() { + return $this->ccPHIDs; + } + + public function getEmailPHIDs() { + return $this->emailPHIDs; + } + + + public function getAdapterContentName() { + return pht('Phriction Documents'); + } + + public function supportsRuleType($rule_type) { + switch ($rule_type) { + case HeraldRuleTypeConfig::RULE_TYPE_GLOBAL: + case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL: + return true; + case HeraldRuleTypeConfig::RULE_TYPE_OBJECT: + default: + return false; + } + } + + public function getFields() { + return array_merge( + array( + self::FIELD_TITLE, + self::FIELD_BODY, + self::FIELD_AUTHOR, + self::FIELD_IS_NEW_OBJECT, + self::FIELD_CC, + self::FIELD_PATH, + ), + parent::getFields()); + } + + public function getActions($rule_type) { + switch ($rule_type) { + case HeraldRuleTypeConfig::RULE_TYPE_GLOBAL: + return array_merge( + array( + self::ACTION_ADD_CC, + self::ACTION_EMAIL, + self::ACTION_NOTHING, + ), + parent::getActions($rule_type)); + case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL: + return array_merge( + array( + self::ACTION_ADD_CC, + self::ACTION_EMAIL, + self::ACTION_FLAG, + self::ACTION_NOTHING, + ), + parent::getActions($rule_type)); + } + } + + public function getPHID() { + return $this->getDocument()->getPHID(); + } + + public function getHeraldName() { + return pht('Wiki Document %d', $this->getDocument()->getID()); + } + + public function getHeraldField($field) { + switch ($field) { + case self::FIELD_TITLE: + return $this->getDocument()->getContent()->getTitle(); + case self::FIELD_BODY: + return $this->getDocument()->getContent()->getContent(); + case self::FIELD_AUTHOR: + return $this->getDocument()->getContent()->getAuthorPHID(); + case self::FIELD_CC: + return PhabricatorSubscribersQuery::loadSubscribersForPHID( + $this->getDocument()->getPHID()); + case self::FIELD_PATH: + return $this->getDocument()->getContent()->getSlug(); + } + + return parent::getHeraldField($field); + } + + public function applyHeraldEffects(array $effects) { + assert_instances_of($effects, 'HeraldEffect'); + + $result = array(); + foreach ($effects as $effect) { + $action = $effect->getAction(); + switch ($action) { + case self::ACTION_NOTHING: + $result[] = new HeraldApplyTranscript( + $effect, + true, + pht('Great success at doing nothing.')); + break; + case self::ACTION_ADD_CC: + foreach ($effect->getTarget() as $phid) { + $this->ccPHIDs[] = $phid; + } + $result[] = new HeraldApplyTranscript( + $effect, + true, + pht('Added address to cc list.')); + break; + case self::ACTION_FLAG: + $result[] = parent::applyFlagEffect( + $effect, + $this->getDocument()->getPHID()); + break; + case self::ACTION_EMAIL: + foreach ($effect->getTarget() as $phid) { + $this->emailPHIDs[] = $phid; + } + $result[] = new HeraldApplyTranscript( + $effect, + true, + pht('Added addresses to email list.')); + break; + default: + $custom_result = parent::handleCustomHeraldEffect($effect); + if ($custom_result === null) { + throw new Exception(pht( + "No rules to handle action '%s'.", + $action)); + } + + $result[] = $custom_result; + break; + } + } + return $result; + } + +} diff --git a/src/applications/phriction/storage/PhrictionDocument.php b/src/applications/phriction/storage/PhrictionDocument.php --- a/src/applications/phriction/storage/PhrictionDocument.php +++ b/src/applications/phriction/storage/PhrictionDocument.php @@ -6,7 +6,8 @@ PhabricatorSubscribableInterface, PhabricatorFlaggableInterface, PhabricatorTokenReceiverInterface, - PhabricatorDestructibleInterface { + PhabricatorDestructibleInterface, + PhabricatorApplicationTransactionInterface { protected $slug; protected $depth; @@ -200,6 +201,22 @@ return true; } +/* -( PhabricatorApplicationTransactionInterface )------------------------- */ + + + public function getApplicationTransactionEditor() { + return new PhrictionTransactionEditor(); + } + + public function getApplicationTransactionObject() { + return $this; + } + + public function getApplicationTransactionTemplate() { + return new PhrictionTransaction(); + } + + /* -( PhabricatorTokenReceiverInterface )---------------------------------- */