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

Legalpad - add a view signatures page

Summary: ...needs to add a LegalpadDocumentSignatureQuery class to get this done, which is also re-deployed everywhere we were issuing raw queries. Ref T3116.

Test Plan: viewed some signatures. Verified color and footer icons showed up how I wanted them to.

Reviewers: epriestley

Reviewed By: epriestley

CC: Korvin, epriestley, aran

Maniphest Tasks: T3116

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

+295 -30
+9 -1
src/__phutil_library_map__.php
··· 842 842 'LegalpadDocumentSearchEngine' => 'applications/legalpad/query/LegalpadDocumentSearchEngine.php', 843 843 'LegalpadDocumentSignController' => 'applications/legalpad/controller/LegalpadDocumentSignController.php', 844 844 'LegalpadDocumentSignature' => 'applications/legalpad/storage/LegalpadDocumentSignature.php', 845 + 'LegalpadDocumentSignatureListController' => 'applications/legalpad/controller/LegalpadDocumentSignatureListController.php', 846 + 'LegalpadDocumentSignatureQuery' => 'applications/legalpad/query/LegalpadDocumentSignatureQuery.php', 845 847 'LegalpadDocumentSignatureVerificationController' => 'applications/legalpad/controller/LegalpadDocumentSignatureVerificationController.php', 846 848 'LegalpadDocumentViewController' => 'applications/legalpad/controller/LegalpadDocumentViewController.php', 847 849 'LegalpadMockMailReceiver' => 'applications/legalpad/mail/LegalpadMockMailReceiver.php', ··· 3374 3376 'LegalpadDocumentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 3375 3377 'LegalpadDocumentSearchEngine' => 'PhabricatorApplicationSearchEngine', 3376 3378 'LegalpadDocumentSignController' => 'LegalpadController', 3377 - 'LegalpadDocumentSignature' => 'LegalpadDAO', 3379 + 'LegalpadDocumentSignature' => 3380 + array( 3381 + 0 => 'LegalpadDAO', 3382 + 1 => 'PhabricatorPolicyInterface', 3383 + ), 3384 + 'LegalpadDocumentSignatureListController' => 'LegalpadController', 3385 + 'LegalpadDocumentSignatureQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 3378 3386 'LegalpadDocumentSignatureVerificationController' => 'LegalpadController', 3379 3387 'LegalpadDocumentViewController' => 'LegalpadController', 3380 3388 'LegalpadMockMailReceiver' => 'PhabricatorObjectMailReceiver',
+2 -1
src/applications/legalpad/application/PhabricatorApplicationLegalpad.php
··· 49 49 'comment/(?P<id>\d+)/' => 'LegalpadDocumentCommentController', 50 50 'view/(?P<id>\d+)/' => 'LegalpadDocumentViewController', 51 51 'verify/(?P<code>[^/]+)/' => 52 - 'LegalpadDocumentSignatureVerificationController', 52 + 'LegalpadDocumentSignatureVerificationController', 53 + 'signatures/(?P<id>\d+)/' => 'LegalpadDocumentSignatureListController', 53 54 'document/' => array( 54 55 'preview/' => 'PhabricatorMarkupPreviewController'), 55 56 ));
+6 -9
src/applications/legalpad/controller/LegalpadDocumentSignController.php
··· 1 1 <?php 2 2 3 - /** 4 - * @group legalpad 5 - */ 6 3 final class LegalpadDocumentSignController extends LegalpadController { 7 4 8 5 private $id; ··· 56 53 } 57 54 58 55 if ($signer_phid) { 59 - $signature = id(new LegalpadDocumentSignature()) 60 - ->loadOneWhere( 61 - 'documentPHID = %s AND signerPHID = %s AND documentVersion = %d', 62 - $document->getPHID(), 63 - $signer_phid, 64 - $document->getVersions()); 56 + $signature = id(new LegalpadDocumentSignatureQuery()) 57 + ->setViewer($user) 58 + ->withDocumentPHIDs(array($document->getPHID())) 59 + ->withSignerPHIDs(array($signer_phid)) 60 + ->withDocumentVersions(array($document->getVersions())) 61 + ->executeOne(); 65 62 } 66 63 67 64 if (!$signature) {
+122
src/applications/legalpad/controller/LegalpadDocumentSignatureListController.php
··· 1 + <?php 2 + 3 + final class LegalpadDocumentSignatureListController extends LegalpadController { 4 + 5 + private $documentId; 6 + 7 + public function willProcessRequest(array $data) { 8 + $this->documentId = $data['id']; 9 + } 10 + 11 + public function processRequest() { 12 + $request = $this->getRequest(); 13 + $user = $request->getUser(); 14 + 15 + $document = id(new LegalpadDocumentQuery()) 16 + ->setViewer($user) 17 + ->withIDs(array($this->documentId)) 18 + ->executeOne(); 19 + 20 + if (!$document) { 21 + return new Aphront404Response(); 22 + } 23 + 24 + $title = pht('Signatures for %s', $document->getMonogram()); 25 + 26 + $pager = id(new AphrontCursorPagerView()) 27 + ->readFromRequest($request); 28 + $signatures = id(new LegalpadDocumentSignatureQuery()) 29 + ->setViewer($user) 30 + ->withDocumentPHIDs(array($document->getPHID())) 31 + ->executeWithCursorPager($pager); 32 + 33 + $crumbs = $this->buildApplicationCrumbs($this->buildSideNav()); 34 + $crumbs->addTextCrumb( 35 + $document->getMonogram(), 36 + $this->getApplicationURI('view/'.$document->getID())); 37 + 38 + $crumbs->addTextCrumb( 39 + pht('Signatures')); 40 + $list = $this->renderResultsList($document, $signatures); 41 + $list->setPager($pager); 42 + 43 + return $this->buildApplicationPage( 44 + array( 45 + $crumbs, 46 + $list, 47 + ), 48 + array( 49 + 'title' => $title, 50 + 'device' => true, 51 + )); 52 + } 53 + 54 + private function renderResultsList( 55 + LegalpadDocument $document, 56 + array $signatures) { 57 + assert_instances_of($signatures, 'LegalpadDocumentSignature'); 58 + 59 + $user = $this->getRequest()->getUser(); 60 + 61 + $list = new PHUIObjectItemListView(); 62 + $list->setUser($user); 63 + 64 + foreach ($signatures as $signature) { 65 + $created = phabricator_date($signature->getDateCreated(), $user); 66 + 67 + $data = $signature->getSignatureData(); 68 + 69 + $sig_data = phutil_tag( 70 + 'div', 71 + array(), 72 + array( 73 + phutil_tag( 74 + 'div', 75 + array(), 76 + phutil_tag( 77 + 'a', 78 + array( 79 + 'href' => 'mailto:'.$data['email'], 80 + ), 81 + $data['email'])), 82 + phutil_tag( 83 + 'div', 84 + array(), 85 + $data['address_1']), 86 + phutil_tag( 87 + 'div', 88 + array(), 89 + $data['address_2']), 90 + phutil_tag( 91 + 'div', 92 + array(), 93 + $data['phone']) 94 + )); 95 + 96 + $item = id(new PHUIObjectItemView()) 97 + ->setObject($signature) 98 + ->setHeader($data['name']) 99 + ->setSubhead($sig_data) 100 + ->addIcon('none', pht('Signed %s', $created)); 101 + 102 + $good_sig = true; 103 + if (!$signature->isVerified()) { 104 + $item->addFootIcon('disable', 'Unverified Email'); 105 + $good_sig = false; 106 + } 107 + if ($signature->getDocumentVersion() != $document->getVersions()) { 108 + $item->addFootIcon('delete', 'Stale Signature'); 109 + $good_sig = false; 110 + } 111 + 112 + if ($good_sig) { 113 + $item->setBarColor('green'); 114 + } 115 + 116 + $list->addItem($item); 117 + } 118 + 119 + return $list; 120 + } 121 + 122 + }
+12 -2
src/applications/legalpad/controller/LegalpadDocumentSignatureVerificationController.php
··· 21 21 $request = $this->getRequest(); 22 22 $user = $request->getUser(); 23 23 24 - $signature = id(new LegalpadDocumentSignature()) 25 - ->loadOneWhere('secretKey = %s', $this->code); 24 + // this page can be accessed by not logged in users to valid their 25 + // signatures. use the omnipotent user for these cases. 26 + if (!$user->isLoggedIn()) { 27 + $viewer = PhabricatorUser::getOmnipotentUser(); 28 + } else { 29 + $viewer = $user; 30 + } 31 + 32 + $signature = id(new LegalpadDocumentSignatureQuery()) 33 + ->setViewer($viewer) 34 + ->withSecretKeys(array($this->code)) 35 + ->executeOne(); 26 36 27 37 if (!$signature) { 28 38 $title = pht('Unable to Verify Signature');
+9 -1
src/applications/legalpad/controller/LegalpadDocumentViewController.php
··· 132 132 $document, 133 133 PhabricatorPolicyCapability::CAN_EDIT); 134 134 135 + $doc_id = $document->getID(); 136 + 135 137 $actions->addAction( 136 138 id(new PhabricatorActionView()) 137 139 ->setIcon('edit') 138 140 ->setName(pht('Edit Document')) 139 - ->setHref($this->getApplicationURI('/edit/'.$document->getID().'/')) 141 + ->setHref($this->getApplicationURI('/edit/'.$doc_id.'/')) 140 142 ->setDisabled(!$can_edit) 141 143 ->setWorkflow(!$can_edit)); 142 144 ··· 145 147 ->setIcon('like') 146 148 ->setName(pht('Sign Document')) 147 149 ->setHref('/'.$document->getMonogram())); 150 + 151 + $actions->addAction( 152 + id(new PhabricatorActionView()) 153 + ->setIcon('transcript') 154 + ->setName(pht('View Signatures')) 155 + ->setHref($this->getApplicationURI('/signatures/'.$doc_id.'/'))); 148 156 149 157 return $actions; 150 158 }
+9 -12
src/applications/legalpad/query/LegalpadDocumentQuery.php
··· 1 1 <?php 2 2 3 - /** 4 - * @group legalpad 5 - */ 6 3 final class LegalpadDocumentQuery 7 4 extends PhabricatorCursorPagedPolicyAwareQuery { 8 5 ··· 89 86 protected function willFilterPage(array $documents) { 90 87 if ($this->signerPHIDs) { 91 88 $document_map = mpull($documents, null, 'getPHID'); 92 - $signatures = id(new LegalpadDocumentSignature()) 93 - ->loadAllWhere( 94 - 'documentPHID IN (%Ls) AND signerPHID IN (%Ls)', 95 - array_keys($document_map), 96 - $this->signerPHIDs); 89 + $signatures = id(new LegalpadDocumentSignatureQuery()) 90 + ->setViewer($this->getViewer()) 91 + ->withDocumentPHIDs(array_keys($document_map)) 92 + ->wtihSignerPHIDs($this->signerPHIDs) 93 + ->execute(); 97 94 $signatures = mgroup($signatures, 'getDocumentPHID'); 98 95 foreach ($document_map as $document_phid => $document) { 99 96 $sigs = idx($signatures, $document_phid, array()); ··· 222 219 private function loadSignatures(array $documents) { 223 220 $document_map = mpull($documents, null, 'getPHID'); 224 221 225 - $signatures = id(new LegalpadDocumentSignature()) 226 - ->loadAllWhere( 227 - 'documentPHID IN (%Ls)', 228 - array_keys($document_map)); 222 + $signatures = id(new LegalpadDocumentSignatureQuery()) 223 + ->setViewer($this->getViewer()) 224 + ->withDocumentPHIDs(array_keys($document_map)) 225 + ->execute(); 229 226 $signatures = mgroup($signatures, 'getDocumentPHID'); 230 227 231 228 foreach ($documents as $document) {
+101
src/applications/legalpad/query/LegalpadDocumentSignatureQuery.php
··· 1 + <?php 2 + 3 + final class LegalpadDocumentSignatureQuery 4 + extends PhabricatorCursorPagedPolicyAwareQuery { 5 + 6 + private $ids; 7 + private $documentPHIDs; 8 + private $signerPHIDs; 9 + private $documentVersions; 10 + private $secretKeys; 11 + 12 + public function withIDs(array $ids) { 13 + $this->ids = $ids; 14 + return $this; 15 + } 16 + 17 + public function withDocumentPHIDs(array $phids) { 18 + $this->documentPHIDs = $phids; 19 + return $this; 20 + } 21 + 22 + public function withSignerPHIDs(array $phids) { 23 + $this->signerPHIDs = $phids; 24 + return $this; 25 + } 26 + 27 + public function withDocumentVersions(array $versions) { 28 + $this->documentVersions = $versions; 29 + return $this; 30 + } 31 + 32 + public function withSecretKeys(array $keys) { 33 + $this->secretKeys = $keys; 34 + return $this; 35 + } 36 + 37 + protected function loadPage() { 38 + $table = new LegalpadDocumentSignature(); 39 + $conn_r = $table->establishConnection('r'); 40 + 41 + $data = queryfx_all( 42 + $conn_r, 43 + 'SELECT * FROM %T %Q %Q %Q', 44 + $table->getTableName(), 45 + $this->buildWhereClause($conn_r), 46 + $this->buildOrderClause($conn_r), 47 + $this->buildLimitClause($conn_r)); 48 + 49 + $documents = $table->loadAllFromArray($data); 50 + 51 + return $documents; 52 + } 53 + 54 + protected function buildWhereClause($conn_r) { 55 + $where = array(); 56 + 57 + $where[] = $this->buildPagingClause($conn_r); 58 + 59 + if ($this->ids) { 60 + $where[] = qsprintf( 61 + $conn_r, 62 + 'id IN (%Ld)', 63 + $this->ids); 64 + } 65 + 66 + if ($this->documentPHIDs) { 67 + $where[] = qsprintf( 68 + $conn_r, 69 + 'documentPHID IN (%Ls)', 70 + $this->documentPHIDs); 71 + } 72 + 73 + if ($this->signerPHIDs) { 74 + $where[] = qsprintf( 75 + $conn_r, 76 + 'signerPHID IN (%Ls)', 77 + $this->signerPHIDs); 78 + } 79 + 80 + if ($this->documentVersions) { 81 + $where[] = qsprintf( 82 + $conn_r, 83 + 'documentVersion IN (%Ld)', 84 + $this->documentVersions); 85 + } 86 + 87 + if ($this->secretKeys) { 88 + $where[] = qsprintf( 89 + $conn_r, 90 + 'secretKey IN (%Ls)', 91 + $this->secretKeys); 92 + } 93 + 94 + return $this->formatWhereClause($where); 95 + } 96 + 97 + public function getQueryApplicationClass() { 98 + return 'PhabricatorApplicationLegalpad'; 99 + } 100 + 101 + }
+25 -4
src/applications/legalpad/storage/LegalpadDocumentSignature.php
··· 1 1 <?php 2 2 3 - /** 4 - * @group legalpad 5 - */ 6 - final class LegalpadDocumentSignature extends LegalpadDAO { 3 + final class LegalpadDocumentSignature 4 + extends LegalpadDAO 5 + implements PhabricatorPolicyInterface { 7 6 8 7 const VERIFIED = 0; 9 8 const UNVERIFIED = 1; ··· 32 31 33 32 public function isVerified() { 34 33 return $this->getVerified() != self::UNVERIFIED; 34 + } 35 + /* -( PhabricatorPolicyInterface )----------------------------------------- */ 36 + 37 + public function getCapabilities() { 38 + return array( 39 + PhabricatorPolicyCapability::CAN_VIEW, 40 + ); 41 + } 42 + 43 + public function getPolicy($capability) { 44 + switch ($capability) { 45 + case PhabricatorPolicyCapability::CAN_VIEW: 46 + return PhabricatorPolicies::POLICY_USER; 47 + } 48 + } 49 + 50 + public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { 51 + return false; 52 + } 53 + 54 + public function describeAutomaticCapability($capability) { 55 + return null; 35 56 } 36 57 37 58 }