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

Add a "documents I've signed" view to Legalpad

Summary:
Ref T3116. Allow documents to be queried for ones the viewer has signed, and make this the default view.

This also relaxes the versioning stuff a little bit, and stops invalidating signatures on older versions of documents. While I think we should do that eventually, it should be more explicit and have better coordination in the UI. For now, we'll track and show older signatures, but not invalidate them.

I imagine eventually differentiating between "minor edits" (typo / link fixes, for example) and major edits which actually require re-signature.

Test Plan: {F171650}

Reviewers: chad

Reviewed By: chad

Subscribers: epriestley

Maniphest Tasks: T3116

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

+85 -69
+1 -9
src/applications/legalpad/controller/LegalpadDocumentEditController.php
··· 31 31 $document = id(new LegalpadDocumentQuery()) 32 32 ->setViewer($user) 33 33 ->needDocumentBodies(true) 34 - ->needSignatures(true) 35 34 ->requireCapabilities( 36 35 array( 37 36 PhabricatorPolicyCapability::CAN_VIEW, ··· 154 153 $this->getApplicationURI('view/'.$document->getID())); 155 154 $title = pht('Update Document'); 156 155 $short = pht('Update'); 157 - $signatures = $document->getSignatures(); 158 - if ($signatures) { 159 - $form->appendInstructions(pht( 160 - 'Warning: there are %d signature(s) already for this document. '. 161 - 'Updating the title or text will invalidate these signatures and '. 162 - 'users will need to sign again. Proceed carefully.', 163 - count($signatures))); 164 - } 156 + 165 157 $crumbs->addTextCrumb( 166 158 $document->getMonogram(), 167 159 $this->getApplicationURI('view/'.$document->getID()));
+32 -41
src/applications/legalpad/query/LegalpadDocumentQuery.php
··· 77 77 78 78 $data = queryfx_all( 79 79 $conn_r, 80 - 'SELECT d.* FROM %T d %Q %Q %Q %Q', 80 + 'SELECT d.* FROM %T d %Q %Q %Q %Q %Q', 81 81 $table->getTableName(), 82 82 $this->buildJoinClause($conn_r), 83 83 $this->buildWhereClause($conn_r), 84 + $this->buildGroupClause($conn_r), 84 85 $this->buildOrderClause($conn_r), 85 86 $this->buildLimitClause($conn_r)); 86 87 ··· 90 91 } 91 92 92 93 protected function willFilterPage(array $documents) { 93 - if ($this->signerPHIDs) { 94 - $document_map = mpull($documents, null, 'getPHID'); 95 - $signatures = id(new LegalpadDocumentSignatureQuery()) 96 - ->setViewer($this->getViewer()) 97 - ->withDocumentPHIDs(array_keys($document_map)) 98 - ->withSignerPHIDs($this->signerPHIDs) 99 - ->execute(); 100 - $signatures = mgroup($signatures, 'getDocumentPHID'); 101 - foreach ($document_map as $document_phid => $document) { 102 - $sigs = idx($signatures, $document_phid, array()); 103 - foreach ($sigs as $index => $sig) { 104 - if ($sig->getDocumentVersion() != $document->getVersions()) { 105 - unset($sigs[$index]); 106 - } 107 - } 108 - $signer_phids = mpull($sigs, 'getSignerPHID'); 109 - if (array_diff($this->signerPHIDs, $signer_phids)) { 110 - unset($documents[$document->getID()]); 111 - } 112 - } 113 - } 114 - 115 94 if ($this->needDocumentBodies) { 116 95 $documents = $this->loadDocumentBodies($documents); 117 96 } ··· 126 105 127 106 if ($this->needViewerSignatures) { 128 107 if ($documents) { 129 - 130 108 if ($this->getViewer()->getPHID()) { 131 109 $signatures = id(new LegalpadDocumentSignatureQuery()) 132 110 ->setViewer($this->getViewer()) ··· 153 131 private function buildJoinClause($conn_r) { 154 132 $joins = array(); 155 133 156 - if ($this->contributorPHIDs) { 134 + if ($this->contributorPHIDs !== null) { 135 + $joins[] = qsprintf( 136 + $conn_r, 137 + 'JOIN edge contributor ON contributor.src = d.phid 138 + AND contributor.type = %d', 139 + PhabricatorEdgeConfig::TYPE_OBJECT_HAS_CONTRIBUTOR); 140 + } 141 + 142 + if ($this->signerPHIDs !== null) { 157 143 $joins[] = qsprintf( 158 144 $conn_r, 159 - 'JOIN edge e ON e.src = d.phid'); 145 + 'JOIN %T signer ON signer.documentPHID = d.phid 146 + AND signer.signerPHID IN (%Ls)', 147 + id(new LegalpadDocumentSignature())->getTableName(), 148 + $this->signerPHIDs); 160 149 } 161 150 162 151 return implode(' ', $joins); 163 152 } 164 153 154 + private function buildGroupClause(AphrontDatabaseConnection $conn_r) { 155 + if ($this->contributorPHIDs || $this->signerPHIDs) { 156 + return 'GROUP BY d.id'; 157 + } else { 158 + return ''; 159 + } 160 + } 161 + 165 162 protected function buildWhereClause($conn_r) { 166 163 $where = array(); 167 164 168 - $where[] = $this->buildPagingClause($conn_r); 169 - 170 - if ($this->ids) { 165 + if ($this->ids !== null) { 171 166 $where[] = qsprintf( 172 167 $conn_r, 173 168 'd.id IN (%Ld)', 174 169 $this->ids); 175 170 } 176 171 177 - if ($this->phids) { 172 + if ($this->phids !== null) { 178 173 $where[] = qsprintf( 179 174 $conn_r, 180 175 'd.phid IN (%Ls)', 181 176 $this->phids); 182 177 } 183 178 184 - if ($this->creatorPHIDs) { 179 + if ($this->creatorPHIDs !== null) { 185 180 $where[] = qsprintf( 186 181 $conn_r, 187 182 'd.creatorPHID IN (%Ls)', 188 183 $this->creatorPHIDs); 189 184 } 190 185 191 - if ($this->dateCreatedAfter) { 186 + if ($this->dateCreatedAfter !== null) { 192 187 $where[] = qsprintf( 193 188 $conn_r, 194 189 'd.dateCreated >= %d', 195 190 $this->dateCreatedAfter); 196 191 } 197 192 198 - if ($this->dateCreatedBefore) { 193 + if ($this->dateCreatedBefore !== null) { 199 194 $where[] = qsprintf( 200 195 $conn_r, 201 196 'd.dateCreated <= %d', 202 197 $this->dateCreatedBefore); 203 198 } 204 199 205 - if ($this->contributorPHIDs) { 200 + if ($this->contributorPHIDs !== null) { 206 201 $where[] = qsprintf( 207 202 $conn_r, 208 - 'e.type = %s AND e.dst IN (%Ls)', 209 - PhabricatorEdgeConfig::TYPE_OBJECT_HAS_CONTRIBUTOR, 203 + 'contributor.dst IN (%Ls)', 210 204 $this->contributorPHIDs); 211 205 } 206 + 207 + $where[] = $this->buildPagingClause($conn_r); 212 208 213 209 return $this->formatWhereClause($where); 214 210 } ··· 256 252 257 253 foreach ($documents as $document) { 258 254 $sigs = idx($signatures, $document->getPHID(), array()); 259 - foreach ($sigs as $index => $sig) { 260 - if ($sig->getDocumentVersion() != $document->getVersions()) { 261 - unset($sigs[$index]); 262 - } 263 - } 264 255 $document->attachSignatures($sigs); 265 256 } 266 257
+45 -6
src/applications/legalpad/query/LegalpadDocumentSearchEngine.php
··· 21 21 'contributorPHIDs', 22 22 $this->readUsersFromRequest($request, 'contributors')); 23 23 24 + $saved->setParameter( 25 + 'withViewerSignature', 26 + $request->getBool('withViewerSignature')); 27 + 24 28 $saved->setParameter('createdStart', $request->getStr('createdStart')); 25 29 $saved->setParameter('createdEnd', $request->getStr('createdEnd')); 26 30 ··· 29 33 30 34 public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { 31 35 $query = id(new LegalpadDocumentQuery()) 32 - ->needViewerSignatures(true) 33 - ->withCreatorPHIDs($saved->getParameter('creatorPHIDs', array())) 34 - ->withContributorPHIDs($saved->getParameter('contributorPHIDs', array())); 36 + ->needViewerSignatures(true); 37 + 38 + $creator_phids = $saved->getParameter('creatorPHIDs', array()); 39 + if ($creator_phids) { 40 + $query->withCreatorPHIDs($creator_phids); 41 + } 42 + 43 + $contributor_phids = $saved->getParameter('contributorPHIDs', array()); 44 + if ($contributor_phids) { 45 + $query->withContributorPHIDs($contributor_phids); 46 + } 47 + 48 + if ($saved->getParameter('withViewerSignature')) { 49 + $viewer_phid = $this->requireViewer()->getPHID(); 50 + if ($viewer_phid) { 51 + $query->withSignerPHIDs(array($viewer_phid)); 52 + } 53 + } 35 54 36 55 $start = $this->parseDateTime($saved->getParameter('createdStart')); 37 56 $end = $this->parseDateTime($saved->getParameter('createdEnd')); ··· 60 79 ->withPHIDs($phids) 61 80 ->execute(); 62 81 82 + $viewer_signature = $saved_query->getParameter('withViewerSignature'); 83 + if (!$this->requireViewer()->getPHID()) { 84 + $viewer_signature = false; 85 + } 86 + 63 87 $form 88 + ->appendChild( 89 + id(new AphrontFormCheckboxControl()) 90 + ->addCheckbox( 91 + 'withViewerSignature', 92 + 1, 93 + pht('Show only documents I have signed.'), 94 + $viewer_signature) 95 + ->setDisabled(!$this->requireViewer()->getPHID())) 64 96 ->appendChild( 65 97 id(new AphrontFormTokenizerControl()) 66 98 ->setDatasource('/typeahead/common/users/') ··· 89 121 } 90 122 91 123 public function getBuiltinQueryNames() { 92 - $names = array( 93 - 'all' => pht('All Documents'), 94 - ); 124 + $names = array(); 125 + 126 + if ($this->requireViewer()->isLoggedIn()) { 127 + $names['signed'] = pht('Signed Documents'); 128 + } 129 + 130 + $names['all'] = pht('All Documents'); 95 131 96 132 return $names; 97 133 } ··· 102 138 $query->setQueryKey($query_key); 103 139 104 140 switch ($query_key) { 141 + case 'signed': 142 + return $query 143 + ->setParameter('withViewerSignature', true); 105 144 case 'all': 106 145 return $query; 107 146 }
+4 -2
src/applications/policy/__tests__/PhabricatorPolicyDataTestCase.php
··· 14 14 $proj_a = id(new PhabricatorProject()) 15 15 ->setName('A') 16 16 ->setAuthorPHID($author->getPHID()) 17 - ->setIcon('fa-briefcase') 17 + ->setIcon(PhabricatorProject::DEFAULT_ICON) 18 + ->setColor(PhabricatorProject::DEFAULT_COLOR) 18 19 ->save(); 19 20 $proj_b = id(new PhabricatorProject()) 20 21 ->setName('B') 21 22 ->setAuthorPHID($author->getPHID()) 22 - ->setIcon('fa-briefcase') 23 + ->setIcon(PhabricatorProject::DEFAULT_ICON) 24 + ->setColor(PhabricatorProject::DEFAULT_COLOR) 23 25 ->save(); 24 26 25 27 $proj_a->setViewPolicy($proj_b->getPHID())->save();
+3
src/applications/policy/rule/PhabricatorPolicyRuleLegalpadSignature.php
··· 15 15 return; 16 16 } 17 17 18 + // TODO: This accepts signature of any version of the document, even an 19 + // older version. 20 + 18 21 $documents = id(new LegalpadDocumentQuery()) 19 22 ->setViewer(PhabricatorUser::getOmnipotentUser()) 20 23 ->withPHIDs($values)
-11
src/infrastructure/internationalization/translation/PhabricatorBaseEnglishTranslation.php
··· 890 890 '%d Users Need Approval', 891 891 ), 892 892 893 - 'Warning: there are %d signature(s) already for this document. '. 894 - 'Updating the title or text will invalidate these signatures and users '. 895 - 'will need to sign again. Proceed carefully.' => array( 896 - 'Warning: there is %d signature already for this document. '. 897 - 'Updating the title or text will invalidate this signature and the '. 898 - 'user will need to sign again. Proceed carefully.', 899 - 'Warning: there are %d signatures already for this document. '. 900 - 'Updating the title or text will invalidate these signatures and '. 901 - 'users will need to sign again. Proceed carefully.', 902 - ), 903 - 904 893 '%s older changes(s) are hidden.' => array( 905 894 '%d older change is hidden.', 906 895 '%d older changes are hidden.',