@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.

Use standard rendering and controller for Differential subscriptions

Summary:
Ref T2222. Differential has custom code for managing subscriptions, but no longer requires it.

The one trick is that we don't have a hook for loading related data on the subscriptions workflow right now. Just glue that in for the moment; it's relatively harmless, and once Diffusion converts we'll have more context on how to best surface it properly.

Test Plan: Subscribed and unsubscribed from a revision. Viewed different revisions and saw correct subscription state.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T2222

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

+32 -119
-2
src/__phutil_library_map__.php
··· 464 464 'DifferentialRevisionUpdateHistoryView' => 'applications/differential/view/DifferentialRevisionUpdateHistoryView.php', 465 465 'DifferentialRevisionViewController' => 'applications/differential/controller/DifferentialRevisionViewController.php', 466 466 'DifferentialSearchIndexer' => 'applications/differential/search/DifferentialSearchIndexer.php', 467 - 'DifferentialSubscribeController' => 'applications/differential/controller/DifferentialSubscribeController.php', 468 467 'DifferentialSubscribersField' => 'applications/differential/customfield/DifferentialSubscribersField.php', 469 468 'DifferentialSummaryField' => 'applications/differential/customfield/DifferentialSummaryField.php', 470 469 'DifferentialSummaryFieldSpecification' => 'applications/differential/field/specification/DifferentialSummaryFieldSpecification.php', ··· 3014 3013 'DifferentialRevisionUpdateHistoryView' => 'AphrontView', 3015 3014 'DifferentialRevisionViewController' => 'DifferentialController', 3016 3015 'DifferentialSearchIndexer' => 'PhabricatorSearchDocumentIndexer', 3017 - 'DifferentialSubscribeController' => 'DifferentialController', 3018 3016 'DifferentialSubscribersField' => 'DifferentialCoreCustomField', 3019 3017 'DifferentialSummaryField' => 'DifferentialCoreCustomField', 3020 3018 'DifferentialSummaryFieldSpecification' => 'DifferentialFreeformFieldSpecification',
-2
src/applications/differential/application/PhabricatorApplicationDifferential.php
··· 63 63 => 'DifferentialInlineCommentEditController', 64 64 ), 65 65 ), 66 - 'subscribe/(?P<action>add|rem)/(?P<id>[1-9]\d*)/' 67 - => 'DifferentialSubscribeController', 68 66 'preview/' => 'PhabricatorMarkupPreviewController', 69 67 ), 70 68 );
+4 -28
src/applications/differential/controller/DifferentialRevisionViewController.php
··· 459 459 } 460 460 461 461 private function getRevisionActions(DifferentialRevision $revision) { 462 - $user = $this->getRequest()->getUser(); 463 - $viewer_phid = $user->getPHID(); 464 - $viewer_is_owner = ($revision->getAuthorPHID() == $viewer_phid); 465 - $viewer_is_reviewer = in_array($viewer_phid, $revision->getReviewers()); 466 - $viewer_is_cc = in_array($viewer_phid, $revision->getCCPHIDs()); 467 - $logged_in = $this->getRequest()->getUser()->isLoggedIn(); 468 - $status = $revision->getStatus(); 462 + $viewer = $this->getRequest()->getUser(); 469 463 $revision_id = $revision->getID(); 470 464 $revision_phid = $revision->getPHID(); 471 465 472 - $links = array(); 473 - 474 466 $can_edit = PhabricatorPolicyFilter::hasCapability( 475 - $user, 467 + $viewer, 476 468 $revision, 477 469 PhabricatorPolicyCapability::CAN_EDIT); 470 + 471 + $links = array(); 478 472 479 473 $links[] = array( 480 474 'icon' => 'edit', ··· 483 477 'disabled' => !$can_edit, 484 478 'sigil' => $can_edit ? null : 'workflow', 485 479 ); 486 - 487 - if (!$viewer_is_owner && !$viewer_is_reviewer) { 488 - $action = $viewer_is_cc ? 'rem' : 'add'; 489 - $links[] = array( 490 - 'icon' => $viewer_is_cc ? 'disable' : 'check', 491 - 'href' => "/differential/subscribe/{$action}/{$revision_id}/", 492 - 'name' => $viewer_is_cc ? pht('Unsubscribe') : pht('Subscribe'), 493 - 'instant' => $logged_in, 494 - 'disabled' => !$logged_in, 495 - 'sigil' => $can_edit ? null : 'workflow', 496 - ); 497 - } else { 498 - $links[] = array( 499 - 'icon' => 'enable', 500 - 'name' => pht('Automatically Subscribed'), 501 - 'disabled' => true, 502 - ); 503 - } 504 480 505 481 $this->requireResource('phabricator-object-selector-css'); 506 482 $this->requireResource('javelin-behavior-phabricator-object-selector');
-80
src/applications/differential/controller/DifferentialSubscribeController.php
··· 1 - <?php 2 - 3 - final class DifferentialSubscribeController extends DifferentialController { 4 - 5 - private $id; 6 - private $action; 7 - 8 - public function willProcessRequest(array $data) { 9 - $this->id = $data['id']; 10 - $this->action = $data['action']; 11 - } 12 - 13 - public function processRequest() { 14 - 15 - $request = $this->getRequest(); 16 - $user = $request->getUser(); 17 - 18 - $revision = id(new DifferentialRevisionQuery()) 19 - ->withIDs(array($this->id)) 20 - ->setViewer($request->getUser()) 21 - ->needRelationships(true) 22 - ->needReviewerStatus(true) 23 - ->executeOne(); 24 - if (!$revision) { 25 - return new Aphront404Response(); 26 - } 27 - 28 - if (!$request->isFormPost()) { 29 - $dialog = new AphrontDialogView(); 30 - 31 - switch ($this->action) { 32 - case 'add': 33 - $button = pht('Subscribe'); 34 - $title = pht('Subscribe to Revision'); 35 - $prompt = pht('Really subscribe to this revision?'); 36 - break; 37 - case 'rem': 38 - $button = pht('Unsubscribe'); 39 - $title = pht('Unsubscribe from Revision'); 40 - $prompt = pht('Really unsubscribe from this revision? Herald will '. 41 - 'not resubscribe you to a revision you unsubscribe '. 42 - 'from.'); 43 - break; 44 - default: 45 - return new Aphront400Response(); 46 - } 47 - 48 - $dialog 49 - ->setUser($user) 50 - ->setTitle($title) 51 - ->appendChild(phutil_tag('p', array(), $prompt)) 52 - ->setSubmitURI($request->getRequestURI()) 53 - ->addSubmitButton($button) 54 - ->addCancelButton('/D'.$revision->getID()); 55 - 56 - return id(new AphrontDialogResponse())->setDialog($dialog); 57 - } 58 - 59 - $phid = $user->getPHID(); 60 - 61 - switch ($this->action) { 62 - case 'add': 63 - DifferentialRevisionEditor::addCCAndUpdateRevision( 64 - $revision, 65 - $phid, 66 - $user); 67 - break; 68 - case 'rem': 69 - DifferentialRevisionEditor::removeCCAndUpdateRevision( 70 - $revision, 71 - $phid, 72 - $user); 73 - break; 74 - default: 75 - return new Aphront400Response(); 76 - } 77 - 78 - return id(new AphrontRedirectResponse())->setURI('/D'.$revision->getID()); 79 - } 80 - }
+28 -7
src/applications/differential/storage/DifferentialRevision.php
··· 444 444 445 445 446 446 public function isAutomaticallySubscribed($phid) { 447 - // TODO: Reviewers are also automatically subscribed, but that data may 448 - // not always be loaded, so be conservative for now. All the editing code 449 - // has checks around this already. 450 - return ($phid == $this->getAuthorPHID()); 447 + if ($phid == $this->getAuthorPHID()) { 448 + return true; 449 + } 450 + 451 + // TODO: This only happens when adding or removing CCs, and is safe from a 452 + // policy perspective, but the subscription pathway should have some 453 + // opportunity to load this data properly. For now, this is the only case 454 + // where implicit subscription is not an intrinsic property of the object. 455 + if ($this->reviewerStatus == self::ATTACHABLE) { 456 + $reviewers = id(new DifferentialRevisionQuery()) 457 + ->setViewer(PhabricatorUser::getOmnipotentUser()) 458 + ->withPHIDs(array($this->getPHID())) 459 + ->needReviewerStatus(true) 460 + ->executeOne() 461 + ->getReviewerStatus(); 462 + } else { 463 + $reviewers = $this->getReviewerStatus(); 464 + } 465 + 466 + foreach ($reviewers as $reviewer) { 467 + if ($reviewer->getReviewerPHID() == $phid) { 468 + return true; 469 + } 470 + } 471 + 472 + return false; 451 473 } 452 474 453 475 public function shouldShowSubscribersProperty() { 454 - // TODO: For now, Differential has its own stuff. 476 + // TODO: Differential does its own thing for now. 455 477 return false; 456 478 } 457 479 458 480 public function shouldAllowSubscription($phid) { 459 - // TODO: For now, Differential has its own stuff. 460 - return false; 481 + return true; 461 482 } 462 483 463 484