@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 upstream/main 215 lines 6.3 kB view raw
1<?php 2 3final class DifferentialDiffViewController extends DifferentialController { 4 5 public function shouldAllowPublic() { 6 return true; 7 } 8 9 public function handleRequest(AphrontRequest $request) { 10 $viewer = $this->getViewer(); 11 $id = $request->getURIData('id'); 12 13 $diff = id(new DifferentialDiffQuery()) 14 ->setViewer($viewer) 15 ->withIDs(array($id)) 16 ->executeOne(); 17 if (!$diff) { 18 return new Aphront404Response(); 19 } 20 21 if ($diff->getRevisionID()) { 22 return id(new AphrontRedirectResponse()) 23 ->setURI('/D'.$diff->getRevisionID().'?id='.$diff->getID()); 24 } 25 26 if ($request->isFormPost()) { 27 $diff_id = $diff->getID(); 28 $revision_id = $request->getInt('revisionID'); 29 if ($revision_id) { 30 $attach_uri = "/revision/attach/{$diff_id}/to/{$revision_id}/"; 31 } else { 32 $attach_uri = "/revision/attach/{$diff_id}/to/"; 33 } 34 $attach_uri = $this->getApplicationURI($attach_uri); 35 36 return id(new AphrontRedirectResponse()) 37 ->setURI($attach_uri); 38 } 39 40 $diff_phid = $diff->getPHID(); 41 $buildables = id(new HarbormasterBuildableQuery()) 42 ->setViewer($viewer) 43 ->withBuildablePHIDs(array($diff_phid)) 44 ->withManualBuildables(false) 45 ->needBuilds(true) 46 ->needTargets(true) 47 ->execute(); 48 $buildables = mpull($buildables, null, 'getBuildablePHID'); 49 $diff->attachBuildable(idx($buildables, $diff_phid)); 50 51 // TODO: implement optgroup support in AphrontFormSelectControl? 52 $select = array(); 53 $select[] = hsprintf('<optgroup label="%s">', pht('Create New Revision')); 54 $select[] = phutil_tag( 55 'option', 56 array('value' => ''), 57 pht('Create a new Revision...')); 58 $select[] = hsprintf('</optgroup>'); 59 60 $selected_id = $request->getInt('revisionID'); 61 62 $revisions = $this->loadSelectableRevisions($viewer, $selected_id); 63 64 if ($revisions) { 65 $select[] = hsprintf( 66 '<optgroup label="%s">', 67 pht('Update Existing Revision')); 68 foreach ($revisions as $revision) { 69 if ($selected_id == $revision->getID()) { 70 $selected = 'selected'; 71 } else { 72 $selected = null; 73 } 74 75 $select[] = phutil_tag( 76 'option', 77 array( 78 'value' => $revision->getID(), 79 'selected' => $selected, 80 ), 81 id(new PhutilUTF8StringTruncator()) 82 ->setMaximumGlyphs(128) 83 ->truncateString( 84 'D'.$revision->getID().' '.$revision->getTitle())); 85 } 86 $select[] = hsprintf('</optgroup>'); 87 } 88 89 $select = phutil_tag( 90 'select', 91 array('name' => 'revisionID'), 92 $select); 93 94 $form = id(new AphrontFormView()) 95 ->setViewer($viewer) 96 ->appendRemarkupInstructions( 97 pht( 98 'Review the diff for correctness. When you are satisfied, either '. 99 '**create a new revision** or **update an existing revision**.')) 100 ->appendChild( 101 id(new AphrontFormMarkupControl()) 102 ->setLabel(pht('Attach To')) 103 ->setValue($select)) 104 ->appendChild( 105 id(new AphrontFormSubmitControl()) 106 ->setValue(pht('Continue'))); 107 108 $props = id(new DifferentialDiffProperty())->loadAllWhere( 109 'diffID = %d', 110 $diff->getID()); 111 $props = mpull($props, 'getData', 'getName'); 112 113 $property_head = id(new PHUIHeaderView()) 114 ->setHeader(pht('Properties')); 115 116 $property_view = new PHUIPropertyListView(); 117 118 $changesets = $diff->loadChangesets(); 119 $changesets = msort($changesets, 'getSortKey'); 120 121 $this->buildPackageMaps($changesets); 122 123 $table_of_contents = $this->buildTableOfContents( 124 $changesets, 125 $changesets, 126 $diff->loadCoverageMap($viewer)); 127 128 $refs = array(); 129 foreach ($changesets as $changeset) { 130 $refs[$changeset->getID()] = $changeset->getID(); 131 } 132 133 $details = id(new DifferentialChangesetListView()) 134 ->setChangesets($changesets) 135 ->setVisibleChangesets($changesets) 136 ->setRenderingReferences($refs) 137 ->setStandaloneURI('/differential/changeset/') 138 ->setDiff($diff) 139 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 140 ->setTitle(pht('Diff %d', $diff->getID())) 141 ->setUser($request->getUser()); 142 143 $title = pht('Diff %d', $diff->getID()); 144 $crumbs = $this->buildApplicationCrumbs(); 145 $crumbs->addTextCrumb($title); 146 $crumbs->setBorder(true); 147 148 $header = id(new PHUIHeaderView()) 149 ->setHeader($title); 150 151 $prop_box = id(new PHUIObjectBoxView()) 152 ->setHeader($property_head) 153 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 154 ->addPropertyList($property_view) 155 ->setForm($form); 156 157 $view = id(new PHUITwoColumnView()) 158 ->setHeader($header) 159 ->setMainColumn(array( 160 161 )) 162 ->setFooter(array( 163 $prop_box, 164 $table_of_contents, 165 $details, 166 )); 167 168 $page = $this->newPage() 169 ->setTitle(pht('Diff View')) 170 ->setCrumbs($crumbs) 171 ->appendChild($view); 172 return $page; 173 } 174 175 private function loadSelectableRevisions( 176 PhabricatorUser $viewer, 177 $selected_id) { 178 179 $revisions = id(new DifferentialRevisionQuery()) 180 ->setViewer($viewer) 181 ->withAuthors(array($viewer->getPHID())) 182 ->withIsOpen(true) 183 ->requireCapabilities( 184 array( 185 PhabricatorPolicyCapability::CAN_VIEW, 186 PhabricatorPolicyCapability::CAN_EDIT, 187 )) 188 ->execute(); 189 $revisions = mpull($revisions, null, 'getID'); 190 191 // If a specific revision is selected (for example, because the user is 192 // following the "Update Diff" workflow), but not present in the dropdown, 193 // try to add it to the dropdown even if it is closed. This allows the 194 // workflow to be used to update abandoned revisions. 195 196 if ($selected_id) { 197 if (empty($revisions[$selected_id])) { 198 $selected = id(new DifferentialRevisionQuery()) 199 ->setViewer($viewer) 200 ->withIDs(array($selected_id)) 201 ->requireCapabilities( 202 array( 203 PhabricatorPolicyCapability::CAN_VIEW, 204 PhabricatorPolicyCapability::CAN_EDIT, 205 )) 206 ->execute(); 207 $revisions = mpull($selected, null, 'getID') + $revisions; 208 } 209 } 210 211 return $revisions; 212 } 213 214 215}