Index: src/__phutil_library_map__.php =================================================================== --- src/__phutil_library_map__.php +++ src/__phutil_library_map__.php @@ -464,6 +464,7 @@ 'DifferentialRevisionViewController' => 'applications/differential/controller/DifferentialRevisionViewController.php', 'DifferentialSearchIndexer' => 'applications/differential/search/DifferentialSearchIndexer.php', 'DifferentialSubscribeController' => 'applications/differential/controller/DifferentialSubscribeController.php', + 'DifferentialSubscribersField' => 'applications/differential/customfield/DifferentialSubscribersField.php', 'DifferentialSummaryField' => 'applications/differential/customfield/DifferentialSummaryField.php', 'DifferentialSummaryFieldSpecification' => 'applications/differential/field/specification/DifferentialSummaryFieldSpecification.php', 'DifferentialTasksAttacher' => 'applications/differential/DifferentialTasksAttacher.php', @@ -3012,6 +3013,7 @@ 'DifferentialRevisionViewController' => 'DifferentialController', 'DifferentialSearchIndexer' => 'PhabricatorSearchDocumentIndexer', 'DifferentialSubscribeController' => 'DifferentialController', + 'DifferentialSubscribersField' => 'DifferentialCoreCustomField', 'DifferentialSummaryField' => 'DifferentialCoreCustomField', 'DifferentialSummaryFieldSpecification' => 'DifferentialFreeformFieldSpecification', 'DifferentialTestPlanField' => 'DifferentialCoreCustomField', Index: src/applications/differential/customfield/DifferentialCoreCustomField.php =================================================================== --- src/applications/differential/customfield/DifferentialCoreCustomField.php +++ src/applications/differential/customfield/DifferentialCoreCustomField.php @@ -14,9 +14,11 @@ abstract protected function readValueFromRevision( DifferentialRevision $revision); - abstract protected function writeValueToRevision( + protected function writeValueToRevision( DifferentialRevision $revision, - $value); + $value) { + throw new PhabricatorCustomFieldImplementationIncompleteException($this); + } protected function isCoreFieldRequired() { return false; Index: src/applications/differential/customfield/DifferentialEditPolicyField.php =================================================================== --- src/applications/differential/customfield/DifferentialEditPolicyField.php +++ src/applications/differential/customfield/DifferentialEditPolicyField.php @@ -20,12 +20,6 @@ return $revision->getEditPolicy(); } - protected function writeValueToRevision( - DifferentialRevision $revision, - $value) { - $revision->setEditPolicy($value); - } - public function readValueFromRequest(AphrontRequest $request) { $this->setValue($request->getStr($this->getFieldKey())); } Index: src/applications/differential/customfield/DifferentialRepositoryField.php =================================================================== --- src/applications/differential/customfield/DifferentialRepositoryField.php +++ src/applications/differential/customfield/DifferentialRepositoryField.php @@ -29,7 +29,7 @@ public function readValueFromRequest(AphrontRequest $request) { $phids = $request->getArr($this->getFieldKey()); $first = head($phids); - $this->setValue(coalesce($first, null)); + $this->setValue(nonempty($first, null)); } public function getRequiredHandlePHIDsForEdit() { @@ -41,7 +41,6 @@ } public function renderEditControl(array $handles) { - if ($this->getValue()) { $control_value = array_select_keys($handles, array($this->getValue())); } else { @@ -97,7 +96,6 @@ $xaction->renderHandleLink($author_phid), $xaction->renderHandleLink($old)); } - } public function getApplicationTransactionTitleForFeed( Index: src/applications/differential/customfield/DifferentialSubscribersField.php =================================================================== --- /dev/null +++ src/applications/differential/customfield/DifferentialSubscribersField.php @@ -0,0 +1,49 @@ +getPHID()); + } + + public function getNewValueForApplicationTransactions() { + return array('=' => $this->getValue()); + } + + public function readValueFromRequest(AphrontRequest $request) { + $this->setValue($request->getArr($this->getFieldKey())); + } + + public function getRequiredHandlePHIDsForEdit() { + return $this->getValue(); + } + + public function renderEditControl(array $handles) { + return id(new AphrontFormTokenizerControl()) + ->setName($this->getFieldKey()) + ->setDatasource('/typeahead/common/mailable/') + ->setValue($handles) + ->setError($this->getFieldError()) + ->setLabel($this->getFieldName()); + } + + public function getApplicationTransactionType() { + return PhabricatorTransactions::TYPE_SUBSCRIBERS; + } + +} Index: src/applications/differential/customfield/DifferentialViewPolicyField.php =================================================================== --- src/applications/differential/customfield/DifferentialViewPolicyField.php +++ src/applications/differential/customfield/DifferentialViewPolicyField.php @@ -20,12 +20,6 @@ return $revision->getViewPolicy(); } - protected function writeValueToRevision( - DifferentialRevision $revision, - $value) { - $revision->setViewPolicy($value); - } - public function readValueFromRequest(AphrontRequest $request) { $this->setValue($request->getStr($this->getFieldKey())); } Index: src/applications/differential/editor/DifferentialTransactionEditor.php =================================================================== --- src/applications/differential/editor/DifferentialTransactionEditor.php +++ src/applications/differential/editor/DifferentialTransactionEditor.php @@ -58,6 +58,8 @@ case PhabricatorTransactions::TYPE_EDIT_POLICY: $object->setEditPolicy($xaction->getNewValue()); return; + case PhabricatorTransactions::TYPE_SUBSCRIBERS: + return; } return parent::applyCustomInternalTransaction($object, $xaction); @@ -71,6 +73,8 @@ case PhabricatorTransactions::TYPE_VIEW_POLICY: case PhabricatorTransactions::TYPE_EDIT_POLICY: return; + case PhabricatorTransactions::TYPE_SUBSCRIBERS: + return; } return parent::applyCustomExternalTransaction($object, $xaction); Index: src/applications/differential/storage/DifferentialRevision.php =================================================================== --- src/applications/differential/storage/DifferentialRevision.php +++ src/applications/differential/storage/DifferentialRevision.php @@ -469,6 +469,7 @@ new DifferentialTitleField(), new DifferentialSummaryField(), new DifferentialTestPlanField(), + new DifferentialSubscribersField(), new DifferentialRepositoryField(), new DifferentialViewPolicyField(), new DifferentialEditPolicyField(), Index: src/applications/transactions/storage/PhabricatorApplicationTransaction.php =================================================================== --- src/applications/transactions/storage/PhabricatorApplicationTransaction.php +++ src/applications/transactions/storage/PhabricatorApplicationTransaction.php @@ -186,7 +186,11 @@ public function getHandle($phid) { if (empty($this->handles[$phid])) { throw new Exception( - "Transaction requires a handle ('{$phid}') it did not load."); + pht( + 'Transaction ("%s") requires a handle ("%s") that it did not '. + 'load.', + $this->getPHID(), + $phid)); } return $this->handles[$phid]; }