@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
at recaptime-dev/main 115 lines 3.6 kB view raw
1<?php 2 3final class PhabricatorProjectWatchController 4 extends PhabricatorProjectController { 5 6 public function handleRequest(AphrontRequest $request) { 7 $viewer = $request->getViewer(); 8 $id = $request->getURIData('id'); 9 $action = $request->getURIData('action'); 10 11 $project = id(new PhabricatorProjectQuery()) 12 ->setViewer($viewer) 13 ->withIDs(array($id)) 14 ->needMembers(true) 15 ->needWatchers(true) 16 ->executeOne(); 17 if (!$project) { 18 return new Aphront404Response(); 19 } 20 21 $via = $request->getStr('via'); 22 if ($via == 'profile') { 23 $done_uri = "/project/profile/{$id}/"; 24 } else { 25 $done_uri = "/project/members/{$id}/"; 26 } 27 28 $is_watcher = $project->isUserWatcher($viewer->getPHID()); 29 $is_ancestor = $project->isUserAncestorWatcher($viewer->getPHID()); 30 if ($is_ancestor && !$is_watcher) { 31 $ancestor_phid = $project->getWatchedAncestorPHID($viewer->getPHID()); 32 $handles = $viewer->loadHandles(array($ancestor_phid)); 33 $ancestor_handle = $handles[$ancestor_phid]; 34 35 return $this->newDialog() 36 ->setTitle(pht('Watching Ancestor')) 37 ->appendParagraph( 38 pht( 39 'You are already watching %s, an ancestor of this project, and '. 40 'are thus watching all of its subprojects.', 41 $ancestor_handle->renderTag()->render())) 42 ->addCancelbutton($done_uri); 43 } 44 45 if ($request->isDialogFormPost()) { 46 $edge_action = null; 47 switch ($action) { 48 case 'watch': 49 $edge_action = '+'; 50 break; 51 case 'unwatch': 52 $edge_action = '-'; 53 break; 54 } 55 56 $type_watcher = PhabricatorObjectHasWatcherEdgeType::EDGECONST; 57 $member_spec = array( 58 $edge_action => array($viewer->getPHID() => $viewer->getPHID()), 59 ); 60 61 $xactions = array(); 62 $xactions[] = id(new PhabricatorProjectTransaction()) 63 ->setTransactionType(PhabricatorTransactions::TYPE_EDGE) 64 ->setMetadataValue('edge:type', $type_watcher) 65 ->setNewValue($member_spec); 66 67 $editor = id(new PhabricatorProjectTransactionEditor()) 68 ->setActor($viewer) 69 ->setContentSourceFromRequest($request) 70 ->setContinueOnNoEffect(true) 71 ->setContinueOnMissingFields(true) 72 ->applyTransactions($project, $xactions); 73 74 return id(new AphrontRedirectResponse())->setURI($done_uri); 75 } 76 77 $dialog = null; 78 switch ($action) { 79 case 'watch': 80 $title = pht('Watch Project?'); 81 $body = array(); 82 $body[] = pht( 83 'Watching a project will let you monitor it closely. You will '. 84 'receive email and notifications about changes to every object '. 85 'tagged with projects you watch.'); 86 $body[] = pht( 87 'Watching a project also watches all subprojects and milestones of '. 88 'that project.'); 89 $submit = pht('Watch Project'); 90 break; 91 case 'unwatch': 92 $title = pht('Unwatch Project?'); 93 $body = pht( 94 'You will no longer receive email or notifications about every '. 95 'object associated with this project.'); 96 $submit = pht('Unwatch Project'); 97 break; 98 default: 99 return new Aphront404Response(); 100 } 101 102 $dialog = $this->newDialog() 103 ->setTitle($title) 104 ->addHiddenInput('via', $via) 105 ->addCancelButton($done_uri) 106 ->addSubmitButton($submit); 107 108 foreach ((array)$body as $paragraph) { 109 $dialog->appendParagraph($paragraph); 110 } 111 112 return $dialog; 113 } 114 115}