@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Raise a warning when mentioning a user in a comment on a draft revision

Summary: See PHI433. Ref T13102. Users in the wild have mixed expecations about exactly what "draft" means. Recent changes have tried to make behavior more clear. As part of clarifying messaging, make it explicit that `@mention` does not work on drafts by showing users a warning when they try to `@mention` a user.

Test Plan:
- Mentioned users on drafts, got a warning.
- Posted normal comments on drafts, no warning.
- Posted normal/mention comments on non-drafts, no warning.

Maniphest Tasks: T13102

Differential Revision: https://secure.phabricator.com/D19210

+127
+4
src/__phutil_library_map__.php
··· 2055 2055 'PhabricatorApplicationTransactionValidationResponse' => 'applications/transactions/response/PhabricatorApplicationTransactionValidationResponse.php', 2056 2056 'PhabricatorApplicationTransactionValueController' => 'applications/transactions/controller/PhabricatorApplicationTransactionValueController.php', 2057 2057 'PhabricatorApplicationTransactionView' => 'applications/transactions/view/PhabricatorApplicationTransactionView.php', 2058 + 'PhabricatorApplicationTransactionWarningException' => 'applications/transactions/exception/PhabricatorApplicationTransactionWarningException.php', 2059 + 'PhabricatorApplicationTransactionWarningResponse' => 'applications/transactions/response/PhabricatorApplicationTransactionWarningResponse.php', 2058 2060 'PhabricatorApplicationUninstallController' => 'applications/meta/controller/PhabricatorApplicationUninstallController.php', 2059 2061 'PhabricatorApplicationsApplication' => 'applications/meta/application/PhabricatorApplicationsApplication.php', 2060 2062 'PhabricatorApplicationsController' => 'applications/meta/controller/PhabricatorApplicationsController.php', ··· 7484 7486 'PhabricatorApplicationTransactionValidationResponse' => 'AphrontProxyResponse', 7485 7487 'PhabricatorApplicationTransactionValueController' => 'PhabricatorApplicationTransactionController', 7486 7488 'PhabricatorApplicationTransactionView' => 'AphrontView', 7489 + 'PhabricatorApplicationTransactionWarningException' => 'Exception', 7490 + 'PhabricatorApplicationTransactionWarningResponse' => 'AphrontProxyResponse', 7487 7491 'PhabricatorApplicationUninstallController' => 'PhabricatorApplicationsController', 7488 7492 'PhabricatorApplicationsApplication' => 'PhabricatorApplication', 7489 7493 'PhabricatorApplicationsController' => 'PhabricatorController',
+5
src/applications/transactions/editengine/PhabricatorEditEngine.php
··· 1968 1968 ->setContinueOnNoEffect($request->isContinueRequest()) 1969 1969 ->setContinueOnMissingFields(true) 1970 1970 ->setContentSourceFromRequest($request) 1971 + ->setRaiseWarnings(!$request->getBool('editEngine.warnings')) 1971 1972 ->setIsPreview($is_preview); 1972 1973 1973 1974 try { ··· 1978 1979 ->setException($ex); 1979 1980 } catch (PhabricatorApplicationTransactionNoEffectException $ex) { 1980 1981 return id(new PhabricatorApplicationTransactionNoEffectResponse()) 1982 + ->setCancelURI($view_uri) 1983 + ->setException($ex); 1984 + } catch (PhabricatorApplicationTransactionWarningException $ex) { 1985 + return id(new PhabricatorApplicationTransactionWarningResponse()) 1981 1986 ->setCancelURI($view_uri) 1982 1987 ->setException($ex); 1983 1988 }
+47
src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
··· 48 48 private $mentionedPHIDs; 49 49 private $continueOnNoEffect; 50 50 private $continueOnMissingFields; 51 + private $raiseWarnings; 51 52 private $parentMessageID; 52 53 private $heraldAdapter; 53 54 private $heraldTranscript; ··· 271 272 272 273 public function getApplicationEmail() { 273 274 return $this->applicationEmail; 275 + } 276 + 277 + public function setRaiseWarnings($raise_warnings) { 278 + $this->raiseWarnings = $raise_warnings; 279 + return $this; 280 + } 281 + 282 + public function getRaiseWarnings() { 283 + return $this->raiseWarnings; 274 284 } 275 285 276 286 public function getTransactionTypesForObject($object) { ··· 917 927 918 928 if ($errors) { 919 929 throw new PhabricatorApplicationTransactionValidationException($errors); 930 + } 931 + 932 + if ($this->raiseWarnings) { 933 + $warnings = array(); 934 + foreach ($xactions as $xaction) { 935 + if ($this->hasWarnings($object, $xaction)) { 936 + $warnings[] = $xaction; 937 + } 938 + } 939 + if ($warnings) { 940 + throw new PhabricatorApplicationTransactionWarningException( 941 + $warnings); 942 + } 920 943 } 921 944 922 945 $this->willApplyTransactions($object, $xactions); ··· 4275 4298 4276 4299 $request->queueCall(); 4277 4300 } 4301 + } 4302 + 4303 + private function hasWarnings($object, $xaction) { 4304 + // TODO: For the moment, this is a very un-modular hack to support 4305 + // exactly one type of warning (mentioning users on a draft revision) 4306 + // that we want to show. See PHI433. 4307 + 4308 + if (!($object instanceof DifferentialRevision)) { 4309 + return false; 4310 + } 4311 + 4312 + if (!$object->isDraft()) { 4313 + return false; 4314 + } 4315 + 4316 + $type = $xaction->getTransactionType(); 4317 + if ($type != PhabricatorTransactions::TYPE_SUBSCRIBERS) { 4318 + return false; 4319 + } 4320 + 4321 + // NOTE: This will currently warn even if you're only removing 4322 + // subscribers. 4323 + 4324 + return true; 4278 4325 } 4279 4326 4280 4327 }
+13
src/applications/transactions/exception/PhabricatorApplicationTransactionWarningException.php
··· 1 + <?php 2 + 3 + final class PhabricatorApplicationTransactionWarningException 4 + extends Exception { 5 + 6 + private $xactions; 7 + 8 + public function __construct(array $xactions) { 9 + $this->xactions = $xactions; 10 + parent::__construct(); 11 + } 12 + 13 + }
+58
src/applications/transactions/response/PhabricatorApplicationTransactionWarningResponse.php
··· 1 + <?php 2 + 3 + final class PhabricatorApplicationTransactionWarningResponse 4 + extends AphrontProxyResponse { 5 + 6 + private $viewer; 7 + private $exception; 8 + private $cancelURI; 9 + 10 + public function setCancelURI($cancel_uri) { 11 + $this->cancelURI = $cancel_uri; 12 + return $this; 13 + } 14 + 15 + public function setException( 16 + PhabricatorApplicationTransactionWarningException $exception) { 17 + $this->exception = $exception; 18 + return $this; 19 + } 20 + 21 + protected function buildProxy() { 22 + return new AphrontDialogResponse(); 23 + } 24 + 25 + public function reduceProxyResponse() { 26 + $request = $this->getRequest(); 27 + 28 + $title = pht('Warning: Unexpected Effects'); 29 + 30 + $head = pht( 31 + 'This is a draft revision that will not publish any notifications '. 32 + 'until the author requests review.'); 33 + $tail = pht( 34 + 'Mentioned or subscribed users will not be notified.'); 35 + 36 + $continue = pht('Tell No One'); 37 + 38 + $dialog = id(new AphrontDialogView()) 39 + ->setViewer($request->getViewer()) 40 + ->setTitle($title); 41 + 42 + $dialog->appendParagraph($head); 43 + $dialog->appendParagraph($tail); 44 + 45 + $passthrough = $request->getPassthroughRequestParameters(); 46 + foreach ($passthrough as $key => $value) { 47 + $dialog->addHiddenInput($key, $value); 48 + } 49 + 50 + $dialog 51 + ->addHiddenInput('editEngine.warnings', 1) 52 + ->addSubmitButton($continue) 53 + ->addCancelButton($this->cancelURI); 54 + 55 + return $this->getProxy()->setDialog($dialog); 56 + } 57 + 58 + }