1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-23 14:00:56 +01:00

Update Legalpad to use modular transactions

Summary: Update Legalpad for modular transactions

Test Plan:
- New Document (no sign)
- New Document (individual)
- New Document (corp)
- Require Signature - get prompted to sign before I can do anything.
- Edit Documents
- Sign Documents
- Comment on Documents

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin

Differential Revision: https://secure.phabricator.com/D17826
This commit is contained in:
Chad Little 2017-05-04 11:53:52 -07:00
parent 06eae5578b
commit 705fd11ba1
10 changed files with 308 additions and 197 deletions

View file

@ -1400,8 +1400,10 @@ phutil_register_library_map(array(
'LegalpadDocumentEditor' => 'applications/legalpad/editor/LegalpadDocumentEditor.php',
'LegalpadDocumentListController' => 'applications/legalpad/controller/LegalpadDocumentListController.php',
'LegalpadDocumentManageController' => 'applications/legalpad/controller/LegalpadDocumentManageController.php',
'LegalpadDocumentPreambleTransaction' => 'applications/legalpad/xaction/LegalpadDocumentPreambleTransaction.php',
'LegalpadDocumentQuery' => 'applications/legalpad/query/LegalpadDocumentQuery.php',
'LegalpadDocumentRemarkupRule' => 'applications/legalpad/remarkup/LegalpadDocumentRemarkupRule.php',
'LegalpadDocumentRequireSignatureTransaction' => 'applications/legalpad/xaction/LegalpadDocumentRequireSignatureTransaction.php',
'LegalpadDocumentSearchEngine' => 'applications/legalpad/query/LegalpadDocumentSearchEngine.php',
'LegalpadDocumentSignController' => 'applications/legalpad/controller/LegalpadDocumentSignController.php',
'LegalpadDocumentSignature' => 'applications/legalpad/storage/LegalpadDocumentSignature.php',
@ -1409,8 +1411,12 @@ phutil_register_library_map(array(
'LegalpadDocumentSignatureListController' => 'applications/legalpad/controller/LegalpadDocumentSignatureListController.php',
'LegalpadDocumentSignatureQuery' => 'applications/legalpad/query/LegalpadDocumentSignatureQuery.php',
'LegalpadDocumentSignatureSearchEngine' => 'applications/legalpad/query/LegalpadDocumentSignatureSearchEngine.php',
'LegalpadDocumentSignatureTypeTransaction' => 'applications/legalpad/xaction/LegalpadDocumentSignatureTypeTransaction.php',
'LegalpadDocumentSignatureVerificationController' => 'applications/legalpad/controller/LegalpadDocumentSignatureVerificationController.php',
'LegalpadDocumentSignatureViewController' => 'applications/legalpad/controller/LegalpadDocumentSignatureViewController.php',
'LegalpadDocumentTextTransaction' => 'applications/legalpad/xaction/LegalpadDocumentTextTransaction.php',
'LegalpadDocumentTitleTransaction' => 'applications/legalpad/xaction/LegalpadDocumentTitleTransaction.php',
'LegalpadDocumentTransactionType' => 'applications/legalpad/xaction/LegalpadDocumentTransactionType.php',
'LegalpadMailReceiver' => 'applications/legalpad/mail/LegalpadMailReceiver.php',
'LegalpadObjectNeedsSignatureEdgeType' => 'applications/legalpad/edge/LegalpadObjectNeedsSignatureEdgeType.php',
'LegalpadReplyHandler' => 'applications/legalpad/mail/LegalpadReplyHandler.php',
@ -6395,8 +6401,10 @@ phutil_register_library_map(array(
'LegalpadDocumentEditor' => 'PhabricatorApplicationTransactionEditor',
'LegalpadDocumentListController' => 'LegalpadController',
'LegalpadDocumentManageController' => 'LegalpadController',
'LegalpadDocumentPreambleTransaction' => 'LegalpadDocumentTransactionType',
'LegalpadDocumentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'LegalpadDocumentRemarkupRule' => 'PhabricatorObjectRemarkupRule',
'LegalpadDocumentRequireSignatureTransaction' => 'LegalpadDocumentTransactionType',
'LegalpadDocumentSearchEngine' => 'PhabricatorApplicationSearchEngine',
'LegalpadDocumentSignController' => 'LegalpadController',
'LegalpadDocumentSignature' => array(
@ -6407,15 +6415,19 @@ phutil_register_library_map(array(
'LegalpadDocumentSignatureListController' => 'LegalpadController',
'LegalpadDocumentSignatureQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'LegalpadDocumentSignatureSearchEngine' => 'PhabricatorApplicationSearchEngine',
'LegalpadDocumentSignatureTypeTransaction' => 'LegalpadDocumentTransactionType',
'LegalpadDocumentSignatureVerificationController' => 'LegalpadController',
'LegalpadDocumentSignatureViewController' => 'LegalpadController',
'LegalpadDocumentTextTransaction' => 'LegalpadDocumentTransactionType',
'LegalpadDocumentTitleTransaction' => 'LegalpadDocumentTransactionType',
'LegalpadDocumentTransactionType' => 'PhabricatorModularTransactionType',
'LegalpadMailReceiver' => 'PhabricatorObjectMailReceiver',
'LegalpadObjectNeedsSignatureEdgeType' => 'PhabricatorEdgeType',
'LegalpadReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
'LegalpadRequireSignatureHeraldAction' => 'HeraldAction',
'LegalpadSchemaSpec' => 'PhabricatorConfigSchemaSpec',
'LegalpadSignatureNeededByObjectEdgeType' => 'PhabricatorEdgeType',
'LegalpadTransaction' => 'PhabricatorApplicationTransaction',
'LegalpadTransaction' => 'PhabricatorModularTransaction',
'LegalpadTransactionComment' => 'PhabricatorApplicationTransactionComment',
'LegalpadTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'LegalpadTransactionView' => 'PhabricatorApplicationTransactionView',

View file

@ -57,7 +57,8 @@ final class LegalpadDocumentEditController extends LegalpadController {
$errors[] = pht('The document title may not be blank.');
} else {
$xactions[] = id(new LegalpadTransaction())
->setTransactionType(LegalpadTransaction::TYPE_TITLE)
->setTransactionType(
LegalpadDocumentTitleTransaction::TRANSACTIONTYPE)
->setNewValue($title);
}
@ -67,7 +68,8 @@ final class LegalpadDocumentEditController extends LegalpadController {
$errors[] = pht('The document may not be blank.');
} else {
$xactions[] = id(new LegalpadTransaction())
->setTransactionType(LegalpadTransaction::TYPE_TEXT)
->setTransactionType(
LegalpadDocumentTextTransaction::TRANSACTIONTYPE)
->setNewValue($text);
}
@ -83,13 +85,15 @@ final class LegalpadDocumentEditController extends LegalpadController {
if ($is_create) {
$v_signature_type = $request->getStr('signatureType');
$xactions[] = id(new LegalpadTransaction())
->setTransactionType(LegalpadTransaction::TYPE_SIGNATURE_TYPE)
->setTransactionType(
LegalpadDocumentSignatureTypeTransaction::TRANSACTIONTYPE)
->setNewValue($v_signature_type);
}
$v_preamble = $request->getStr('preamble');
$xactions[] = id(new LegalpadTransaction())
->setTransactionType(LegalpadTransaction::TYPE_PREAMBLE)
->setTransactionType(
LegalpadDocumentPreambleTransaction::TRANSACTIONTYPE)
->setNewValue($v_preamble);
$v_require_signature = $request->getBool('requireSignature', 0);
@ -106,7 +110,8 @@ final class LegalpadDocumentEditController extends LegalpadController {
}
if ($viewer->getIsAdmin()) {
$xactions[] = id(new LegalpadTransaction())
->setTransactionType(LegalpadTransaction::TYPE_REQUIRE_SIGNATURE)
->setTransactionType(
LegalpadDocumentRequireSignatureTransaction::TRANSACTIONTYPE)
->setNewValue($v_require_signature);
}

View file

@ -3,8 +3,6 @@
final class LegalpadDocumentEditor
extends PhabricatorApplicationTransactionEditor {
private $isContribution = false;
public function getEditorApplicationClass() {
return 'PhabricatorLegalpadApplication';
}
@ -13,15 +11,6 @@ final class LegalpadDocumentEditor
return pht('Legalpad Documents');
}
private function setIsContribution($is_contribution) {
$this->isContribution = $is_contribution;
return $this;
}
private function isContribution() {
return $this->isContribution;
}
public function getTransactionTypes() {
$types = parent::getTransactionTypes();
@ -29,99 +18,25 @@ final class LegalpadDocumentEditor
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
$types[] = LegalpadTransaction::TYPE_TITLE;
$types[] = LegalpadTransaction::TYPE_TEXT;
$types[] = LegalpadTransaction::TYPE_SIGNATURE_TYPE;
$types[] = LegalpadTransaction::TYPE_PREAMBLE;
$types[] = LegalpadTransaction::TYPE_REQUIRE_SIGNATURE;
return $types;
}
protected function getCustomTransactionOldValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case LegalpadTransaction::TYPE_TITLE:
return $object->getDocumentBody()->getTitle();
case LegalpadTransaction::TYPE_TEXT:
return $object->getDocumentBody()->getText();
case LegalpadTransaction::TYPE_SIGNATURE_TYPE:
return $object->getSignatureType();
case LegalpadTransaction::TYPE_PREAMBLE:
return $object->getPreamble();
case LegalpadTransaction::TYPE_REQUIRE_SIGNATURE:
return (bool)$object->getRequireSignature();
}
}
protected function getCustomTransactionNewValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case LegalpadTransaction::TYPE_TITLE:
case LegalpadTransaction::TYPE_TEXT:
case LegalpadTransaction::TYPE_SIGNATURE_TYPE:
case LegalpadTransaction::TYPE_PREAMBLE:
return $xaction->getNewValue();
case LegalpadTransaction::TYPE_REQUIRE_SIGNATURE:
return (bool)$xaction->getNewValue();
}
}
protected function applyCustomInternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case LegalpadTransaction::TYPE_TITLE:
$object->setTitle($xaction->getNewValue());
$body = $object->getDocumentBody();
$body->setTitle($xaction->getNewValue());
$this->setIsContribution(true);
break;
case LegalpadTransaction::TYPE_TEXT:
$body = $object->getDocumentBody();
$body->setText($xaction->getNewValue());
$this->setIsContribution(true);
break;
case LegalpadTransaction::TYPE_SIGNATURE_TYPE:
$object->setSignatureType($xaction->getNewValue());
break;
case LegalpadTransaction::TYPE_PREAMBLE:
$object->setPreamble($xaction->getNewValue());
break;
case LegalpadTransaction::TYPE_REQUIRE_SIGNATURE:
$object->setRequireSignature((int)$xaction->getNewValue());
break;
}
}
protected function applyCustomExternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case LegalpadTransaction::TYPE_REQUIRE_SIGNATURE:
if ($xaction->getNewValue()) {
$session = new PhabricatorAuthSession();
queryfx(
$session->establishConnection('w'),
'UPDATE %T SET signedLegalpadDocuments = 0',
$session->getTableName());
}
break;
}
return;
}
protected function applyFinalEffects(
PhabricatorLiskDAO $object,
array $xactions) {
if ($this->isContribution()) {
$is_contribution = false;
foreach ($xactions as $xaction) {
switch ($xaction->getTransactionType()) {
case LegalpadDocumentTitleTransaction::TRANSACTIONTYPE:
case LegalpadDocumentTextTransaction::TRANSACTIONTYPE:
$is_contribution = true;
break;
}
}
if ($is_contribution) {
$object->setVersions($object->getVersions() + 1);
$body = $object->getDocumentBody();
$body->setVersion($object->getVersions());
@ -149,22 +64,6 @@ final class LegalpadDocumentEditor
return $xactions;
}
protected function mergeTransactions(
PhabricatorApplicationTransaction $u,
PhabricatorApplicationTransaction $v) {
$type = $u->getTransactionType();
switch ($type) {
case LegalpadTransaction::TYPE_TITLE:
case LegalpadTransaction::TYPE_TEXT:
case LegalpadTransaction::TYPE_SIGNATURE_TYPE:
case LegalpadTransaction::TYPE_PREAMBLE:
case LegalpadTransaction::TYPE_REQUIRE_SIGNATURE:
return $v;
}
return parent::mergeTransactions($u, $v);
}
/* -( Sending Mail )------------------------------------------------------- */
@ -201,10 +100,10 @@ final class LegalpadDocumentEditor
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case LegalpadTransaction::TYPE_TEXT:
case LegalpadTransaction::TYPE_TITLE:
case LegalpadTransaction::TYPE_PREAMBLE:
case LegalpadTransaction::TYPE_REQUIRE_SIGNATURE:
case LegalpadDocumentTextTransaction::TRANSACTIONTYPE:
case LegalpadDocumentTitleTransaction::TRANSACTIONTYPE:
case LegalpadDocumentPreambleTransaction::TRANSACTIONTYPE:
case LegalpadDocumentRequireSignatureTransaction::TRANSACTIONTYPE:
return true;
}

View file

@ -1,12 +1,6 @@
<?php
final class LegalpadTransaction extends PhabricatorApplicationTransaction {
const TYPE_TITLE = 'title';
const TYPE_TEXT = 'text';
const TYPE_SIGNATURE_TYPE = 'legalpad:signature-type';
const TYPE_PREAMBLE = 'legalpad:premable';
const TYPE_REQUIRE_SIGNATURE = 'legalpad:require-signature';
final class LegalpadTransaction extends PhabricatorModularTransaction {
public function getApplicationName() {
return 'legalpad';
@ -24,73 +18,8 @@ final class LegalpadTransaction extends PhabricatorApplicationTransaction {
return new LegalpadTransactionView();
}
public function shouldHide() {
$old = $this->getOldValue();
switch ($this->getTransactionType()) {
case self::TYPE_TITLE:
case self::TYPE_TEXT:
return ($old === null);
case self::TYPE_SIGNATURE_TYPE:
return true;
}
return parent::shouldHide();
}
public function getTitle() {
$author_phid = $this->getAuthorPHID();
$old = $this->getOldValue();
$new = $this->getNewValue();
$type = $this->getTransactionType();
switch ($type) {
case self::TYPE_TITLE:
return pht(
'%s renamed this document from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old,
$new);
case self::TYPE_TEXT:
return pht(
"%s updated the document's text.",
$this->renderHandleLink($author_phid));
case self::TYPE_PREAMBLE:
return pht(
'%s updated the preamble.',
$this->renderHandleLink($author_phid));
case self::TYPE_REQUIRE_SIGNATURE:
if ($new) {
$text = pht(
'%s set the document to require signatures.',
$this->renderHandleLink($author_phid));
} else {
$text = pht(
'%s set the document to not require signatures.',
$this->renderHandleLink($author_phid));
}
return $text;
}
return parent::getTitle();
}
public function hasChangeDetails() {
switch ($this->getTransactionType()) {
case self::TYPE_TITLE:
case self::TYPE_TEXT:
case self::TYPE_PREAMBLE:
return true;
}
return parent::hasChangeDetails();
}
public function renderChangeDetails(PhabricatorUser $viewer) {
return $this->renderTextCorpusChangeDetails(
$viewer,
$this->getOldValue(),
$this->getNewValue());
public function getBaseTransactionClass() {
return 'LegalpadDocumentTransactionType';
}
}

View file

@ -0,0 +1,57 @@
<?php
final class LegalpadDocumentPreambleTransaction
extends LegalpadDocumentTransactionType {
const TRANSACTIONTYPE = 'legalpad:premable';
public function generateOldValue($object) {
return $object->getPreamble();
}
public function applyInternalEffects($object, $value) {
$object->setPreamble($value);
}
public function getTitle() {
return pht(
'%s updated the document preamble.',
$this->renderAuthor());
}
public function getTitleForFeed() {
return pht(
'%s updated the document preamble for %s.',
$this->renderAuthor(),
$this->renderObject());
}
public function hasChangeDetailView() {
return true;
}
public function getMailDiffSectionHeader() {
return pht('CHANGES TO DOCUMENT PREAMBLE');
}
public function newChangeDetailView() {
$viewer = $this->getViewer();
return id(new PhabricatorApplicationTransactionTextDiffDetailView())
->setViewer($viewer)
->setOldText($this->getOldValue())
->setNewText($this->getNewValue());
}
public function newRemarkupChanges() {
$changes = array();
$changes[] = $this->newRemarkupChange()
->setOldValue($this->getOldValue())
->setNewValue($this->getNewValue());
return $changes;
}
}

View file

@ -0,0 +1,58 @@
<?php
final class LegalpadDocumentRequireSignatureTransaction
extends LegalpadDocumentTransactionType {
const TRANSACTIONTYPE = 'legalpad:require-signature';
public function generateOldValue($object) {
return $object->getRequireSignature();
}
public function applyInternalEffects($object, $value) {
$object->setRequireSignature($value);
}
public function applyExternalEffects($object, $value) {
if (strlen($value)) {
$session = new PhabricatorAuthSession();
queryfx(
$session->establishConnection('w'),
'UPDATE %T SET signedLegalpadDocuments = 0',
$session->getTableName());
}
}
public function getTitle() {
$new = $this->getNewValue();
if ($new) {
return pht(
'%s set the document to require signatures.',
$this->renderAuthor());
} else {
return pht(
'%s set the document to not require signatures.',
$this->renderAuthor());
}
}
public function getTitleForFeed() {
$new = $this->getNewValue();
if ($new) {
return pht(
'%s set the document %s to require signatures.',
$this->renderAuthor(),
$this->renderObject());
} else {
return pht(
'%s set the document %s to not require signatures.',
$this->renderAuthor(),
$this->renderObject());
}
}
public function getIcon() {
return 'fa-pencil-square';
}
}

View file

@ -0,0 +1,29 @@
<?php
final class LegalpadDocumentSignatureTypeTransaction
extends LegalpadDocumentTransactionType {
const TRANSACTIONTYPE = 'legalpad:signature-type';
public function generateOldValue($object) {
return $object->getSignatureType();
}
public function applyInternalEffects($object, $value) {
$object->setSignatureType($value);
}
public function getTitle() {
return pht(
'%s set the document signature type.',
$this->renderAuthor());
}
public function getTitleForFeed() {
return pht(
'%s set the document signature type for %s.',
$this->renderAuthor(),
$this->renderObject());
}
}

View file

@ -0,0 +1,60 @@
<?php
final class LegalpadDocumentTextTransaction
extends LegalpadDocumentTransactionType {
const TRANSACTIONTYPE = 'text';
public function generateOldValue($object) {
$body = $object->getDocumentBody();
return $body->getText();
}
public function applyInternalEffects($object, $value) {
$body = $object->getDocumentBody();
$body->setText($value);
$object->attachDocumentBody($body);
}
public function getTitle() {
return pht(
'%s updated the document text.',
$this->renderAuthor());
}
public function getTitleForFeed() {
return pht(
'%s updated the document text for %s.',
$this->renderAuthor(),
$this->renderObject());
}
public function hasChangeDetailView() {
return true;
}
public function getMailDiffSectionHeader() {
return pht('CHANGES TO DOCUMENT TEXT');
}
public function newChangeDetailView() {
$viewer = $this->getViewer();
return id(new PhabricatorApplicationTransactionTextDiffDetailView())
->setViewer($viewer)
->setOldText($this->getOldValue())
->setNewText($this->getNewValue());
}
public function newRemarkupChanges() {
$changes = array();
$changes[] = $this->newRemarkupChange()
->setOldValue($this->getOldValue())
->setNewValue($this->getNewValue());
return $changes;
}
}

View file

@ -0,0 +1,58 @@
<?php
final class LegalpadDocumentTitleTransaction
extends LegalpadDocumentTransactionType {
const TRANSACTIONTYPE = 'title';
public function generateOldValue($object) {
return $object->getTitle();
}
public function applyInternalEffects($object, $value) {
$object->setTitle($value);
$body = $object->getDocumentBody();
$body->setTitle($value);
$object->attachDocumentBody($body);
}
public function getTitle() {
return pht(
'%s renamed this document from %s to %s.',
$this->renderAuthor(),
$this->renderOldValue(),
$this->renderNewValue());
}
public function getTitleForFeed() {
return pht(
'%s renamed document %s from %s to %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderOldValue(),
$this->renderNewValue());
}
public function validateTransactions($object, array $xactions) {
$errors = array();
if ($this->isEmptyTextTransaction($object->getTitle(), $xactions)) {
$errors[] = $this->newRequiredError(
pht('Documents must have a title.'));
}
$max_length = $object->getColumnMaximumByteLength('title');
foreach ($xactions as $xaction) {
$new_value = $xaction->getNewValue();
$new_length = strlen($new_value);
if ($new_length > $max_length) {
$errors[] = $this->newInvalidError(
pht('The title can be no longer than %s characters.',
new PhutilNumber($max_length)));
}
}
return $errors;
}
}

View file

@ -0,0 +1,4 @@
<?php
abstract class LegalpadDocumentTransactionType
extends PhabricatorModularTransactionType {}