mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-18 21:02:41 +01:00
Allow Legalpad documents to designate corporate signers
Summary: Ref T5532. This adds: - Documents can designate that they should be signed by "Corporations" or "Individuals". - Corporate documents get different fields and a different exemption process. - Basically everything works the same but this is like a zillion lines of form code. Test Plan: See screenshots. Reviewers: btrahan, chad Reviewed By: chad Subscribers: epriestley Maniphest Tasks: T5532 Differential Revision: https://secure.phabricator.com/D9812
This commit is contained in:
parent
04d5402e2f
commit
e8d217b8bd
17 changed files with 728 additions and 292 deletions
2
resources/sql/autopatches/20140703.legalcorp.1.sql
Normal file
2
resources/sql/autopatches/20140703.legalcorp.1.sql
Normal file
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE {$NAMESPACE}_legalpad.legalpad_document
|
||||
ADD signatureType VARCHAR(4) NOT NULL COLLATE utf8_bin;
|
2
resources/sql/autopatches/20140703.legalcorp.2.sql
Normal file
2
resources/sql/autopatches/20140703.legalcorp.2.sql
Normal file
|
@ -0,0 +1,2 @@
|
|||
UPDATE {$NAMESPACE}_legalpad.legalpad_document
|
||||
SET signatureType = 'user' WHERE signatureType = '';
|
2
resources/sql/autopatches/20140703.legalcorp.3.sql
Normal file
2
resources/sql/autopatches/20140703.legalcorp.3.sql
Normal file
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE {$NAMESPACE}_legalpad.legalpad_documentsignature
|
||||
ADD signatureType VARCHAR(4) NOT NULL COLLATE utf8_bin AFTER documentVersion;
|
2
resources/sql/autopatches/20140703.legalcorp.4.sql
Normal file
2
resources/sql/autopatches/20140703.legalcorp.4.sql
Normal file
|
@ -0,0 +1,2 @@
|
|||
UPDATE {$NAMESPACE}_legalpad.legalpad_documentsignature
|
||||
SET signatureType = 'user' WHERE signatureType = '';
|
2
resources/sql/autopatches/20140703.legalcorp.5.sql
Normal file
2
resources/sql/autopatches/20140703.legalcorp.5.sql
Normal file
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE {$NAMESPACE}_legalpad.legalpad_documentsignature
|
||||
CHANGE signerPHID signerPHID VARCHAR(64) COLLATE utf8_bin;
|
|
@ -1,11 +1,9 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @group legalpad
|
||||
*/
|
||||
final class LegalpadTransactionType extends LegalpadConstants {
|
||||
|
||||
const TYPE_TITLE = 'title';
|
||||
const TYPE_TEXT = 'text';
|
||||
const TYPE_SIGNATURE_TYPE = 'legalpad:signature-type';
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @group legalpad
|
||||
*/
|
||||
final class LegalpadDocumentEditController extends LegalpadController {
|
||||
|
||||
private $id;
|
||||
|
@ -26,8 +23,6 @@ final class LegalpadDocumentEditController extends LegalpadController {
|
|||
->setCreatorPHID($user->getPHID());
|
||||
$document->attachDocumentBody($body);
|
||||
$document->setDocumentBodyPHID(PhabricatorPHIDConstants::PHID_VOID);
|
||||
$title = null;
|
||||
$text = null;
|
||||
} else {
|
||||
$is_create = false;
|
||||
|
||||
|
@ -44,12 +39,15 @@ final class LegalpadDocumentEditController extends LegalpadController {
|
|||
if (!$document) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$title = $document->getDocumentBody()->getTitle();
|
||||
$text = $document->getDocumentBody()->getText();
|
||||
}
|
||||
|
||||
$e_title = true;
|
||||
$e_text = true;
|
||||
|
||||
$title = $document->getDocumentBody()->getTitle();
|
||||
$text = $document->getDocumentBody()->getText();
|
||||
$v_signature_type = $document->getSignatureType();
|
||||
|
||||
$errors = array();
|
||||
$can_view = null;
|
||||
$can_edit = null;
|
||||
|
@ -86,6 +84,13 @@ final class LegalpadDocumentEditController extends LegalpadController {
|
|||
->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY)
|
||||
->setNewValue($can_edit);
|
||||
|
||||
if ($is_create) {
|
||||
$v_signature_type = $request->getStr('signatureType');
|
||||
$xactions[] = id(new LegalpadTransaction())
|
||||
->setTransactionType(LegalpadTransactionType::TYPE_SIGNATURE_TYPE)
|
||||
->setNewValue($v_signature_type);
|
||||
}
|
||||
|
||||
if (!$errors) {
|
||||
$editor = id(new LegalpadDocumentEditor())
|
||||
->setContentSourceFromRequest($request)
|
||||
|
@ -113,7 +118,23 @@ final class LegalpadDocumentEditController extends LegalpadController {
|
|||
->setLabel(pht('Title'))
|
||||
->setError($e_title)
|
||||
->setValue($title)
|
||||
->setName('title'))
|
||||
->setName('title'));
|
||||
|
||||
if ($is_create) {
|
||||
$form->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setLabel(pht('Who Should Sign?'))
|
||||
->setName(pht('signatureType'))
|
||||
->setValue($v_signature_type)
|
||||
->setOptions(LegalpadDocument::getSignatureTypeMap()));
|
||||
} else {
|
||||
$form->appendChild(
|
||||
id(new AphrontFormMarkupControl())
|
||||
->setLabel(pht('Who Should Sign?'))
|
||||
->setValue($document->getSignatureTypeName()));
|
||||
}
|
||||
|
||||
$form
|
||||
->appendChild(
|
||||
id(new PhabricatorRemarkupControl())
|
||||
->setID('document-text')
|
||||
|
|
|
@ -173,6 +173,10 @@ final class LegalpadDocumentManageController extends LegalpadController {
|
|||
->setObject($document)
|
||||
->setActionList($actions);
|
||||
|
||||
$properties->addProperty(
|
||||
pht('Signature Type'),
|
||||
$document->getSignatureTypeName());
|
||||
|
||||
$properties->addProperty(
|
||||
pht('Last Updated'),
|
||||
phabricator_datetime($document->getDateModified(), $user));
|
||||
|
|
|
@ -25,107 +25,116 @@ final class LegalpadDocumentSignController extends LegalpadController {
|
|||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$signer_phid = null;
|
||||
$signature_data = array();
|
||||
if ($viewer->isLoggedIn()) {
|
||||
$signer_phid = $viewer->getPHID();
|
||||
$signature_data = array(
|
||||
'name' => $viewer->getRealName(),
|
||||
'email' => $viewer->loadPrimaryEmailAddress(),
|
||||
);
|
||||
} else if ($request->isFormPost()) {
|
||||
$email = new PhutilEmailAddress($request->getStr('email'));
|
||||
if (strlen($email->getDomainName())) {
|
||||
$email_obj = id(new PhabricatorUserEmail())
|
||||
->loadOneWhere('address = %s', $email->getAddress());
|
||||
if ($email_obj) {
|
||||
return $this->signInResponse();
|
||||
}
|
||||
$external_account = id(new PhabricatorExternalAccountQuery())
|
||||
->setViewer($viewer)
|
||||
->withAccountTypes(array('email'))
|
||||
->withAccountDomains(array($email->getDomainName()))
|
||||
->withAccountIDs(array($email->getAddress()))
|
||||
->loadOneOrCreate();
|
||||
if ($external_account->getUserPHID()) {
|
||||
return $this->signInResponse();
|
||||
}
|
||||
$signer_phid = $external_account->getPHID();
|
||||
}
|
||||
}
|
||||
list($signer_phid, $signature_data) = $this->readSignerInformation(
|
||||
$document,
|
||||
$request);
|
||||
|
||||
$signature = null;
|
||||
if ($signer_phid) {
|
||||
// TODO: This is odd and should probably be adjusted after grey/external
|
||||
// accounts work better, but use the omnipotent viewer to check for a
|
||||
// signature so we can pick up anonymous/grey signatures.
|
||||
|
||||
$signature = id(new LegalpadDocumentSignatureQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withDocumentPHIDs(array($document->getPHID()))
|
||||
->withSignerPHIDs(array($signer_phid))
|
||||
->executeOne();
|
||||
$type_individual = LegalpadDocument::SIGNATURE_TYPE_INDIVIDUAL;
|
||||
$is_individual = ($document->getSignatureType() == $type_individual);
|
||||
if ($is_individual) {
|
||||
if ($signer_phid) {
|
||||
// TODO: This is odd and should probably be adjusted after grey/external
|
||||
// accounts work better, but use the omnipotent viewer to check for a
|
||||
// signature so we can pick up anonymous/grey signatures.
|
||||
|
||||
if ($signature && !$viewer->isLoggedIn()) {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Already Signed'))
|
||||
->appendParagraph(pht('You have already signed this document!'))
|
||||
->addCancelButton('/'.$document->getMonogram(), pht('Okay'));
|
||||
$signature = id(new LegalpadDocumentSignatureQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withDocumentPHIDs(array($document->getPHID()))
|
||||
->withSignerPHIDs(array($signer_phid))
|
||||
->executeOne();
|
||||
|
||||
if ($signature && !$viewer->isLoggedIn()) {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Already Signed'))
|
||||
->appendParagraph(pht('You have already signed this document!'))
|
||||
->addCancelButton('/'.$document->getMonogram(), pht('Okay'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$signed_status = null;
|
||||
if (!$signature) {
|
||||
$has_signed = false;
|
||||
$signed_status = null;
|
||||
if (!$signature) {
|
||||
$has_signed = false;
|
||||
$signature = id(new LegalpadDocumentSignature())
|
||||
->setSignerPHID($signer_phid)
|
||||
->setDocumentPHID($document->getPHID())
|
||||
->setDocumentVersion($document->getVersions());
|
||||
|
||||
// If the user is logged in, show a notice that they haven't signed.
|
||||
// If they aren't logged in, we can't be as sure, so don't show
|
||||
// anything.
|
||||
if ($viewer->isLoggedIn()) {
|
||||
$signed_status = id(new AphrontErrorView())
|
||||
->setSeverity(AphrontErrorView::SEVERITY_WARNING)
|
||||
->setErrors(
|
||||
array(
|
||||
pht('You have not signed this document yet.'),
|
||||
));
|
||||
}
|
||||
} else {
|
||||
$has_signed = true;
|
||||
$signature_data = $signature->getSignatureData();
|
||||
|
||||
// In this case, we know they've signed.
|
||||
$signed_at = $signature->getDateCreated();
|
||||
|
||||
if ($signature->getIsExemption()) {
|
||||
$exemption_phid = $signature->getExemptionPHID();
|
||||
$handles = $this->loadViewerHandles(array($exemption_phid));
|
||||
$exemption_handle = $handles[$exemption_phid];
|
||||
|
||||
$signed_text = pht(
|
||||
'You do not need to sign this document. '.
|
||||
'%s added a signature exemption for you on %s.',
|
||||
$exemption_handle->renderLink(),
|
||||
phabricator_datetime($signed_at, $viewer));
|
||||
} else {
|
||||
$signed_text = pht(
|
||||
'You signed this document on %s.',
|
||||
phabricator_datetime($signed_at, $viewer));
|
||||
}
|
||||
|
||||
$signed_status = id(new AphrontErrorView())
|
||||
->setSeverity(AphrontErrorView::SEVERITY_NOTICE)
|
||||
->setErrors(array($signed_text));
|
||||
}
|
||||
|
||||
$field_errors = array(
|
||||
'name' => true,
|
||||
'email' => true,
|
||||
'agree' => true,
|
||||
);
|
||||
} else {
|
||||
$signature = id(new LegalpadDocumentSignature())
|
||||
->setSignerPHID($signer_phid)
|
||||
->setDocumentPHID($document->getPHID())
|
||||
->setDocumentVersion($document->getVersions())
|
||||
->setSignerName((string)idx($signature_data, 'name'))
|
||||
->setSignerEmail((string)idx($signature_data, 'email'))
|
||||
->setSignatureData($signature_data);
|
||||
->setDocumentVersion($document->getVersions());
|
||||
|
||||
// If the user is logged in, show a notice that they haven't signed.
|
||||
// If they aren't logged in, we can't be as sure, so don't show anything.
|
||||
if ($viewer->isLoggedIn()) {
|
||||
$has_signed = false;
|
||||
|
||||
$signed_status = null;
|
||||
} else {
|
||||
// This just hides the form.
|
||||
$has_signed = true;
|
||||
|
||||
$login_text = pht(
|
||||
'This document requires a corporate signatory. You must log in to '.
|
||||
'accept this document on behalf of a company you represent.');
|
||||
$signed_status = id(new AphrontErrorView())
|
||||
->setSeverity(AphrontErrorView::SEVERITY_WARNING)
|
||||
->setErrors(
|
||||
array(
|
||||
pht('You have not signed this document yet.'),
|
||||
));
|
||||
}
|
||||
} else {
|
||||
$has_signed = true;
|
||||
$signature_data = $signature->getSignatureData();
|
||||
|
||||
// In this case, we know they've signed.
|
||||
$signed_at = $signature->getDateCreated();
|
||||
|
||||
if ($signature->getIsExemption()) {
|
||||
$exemption_phid = $signature->getExemptionPHID();
|
||||
$handles = $this->loadViewerHandles(array($exemption_phid));
|
||||
$exemption_handle = $handles[$exemption_phid];
|
||||
|
||||
$signed_text = pht(
|
||||
'You do not need to sign this document. '.
|
||||
'%s added a signature exemption for you on %s.',
|
||||
$exemption_handle->renderLink(),
|
||||
phabricator_datetime($signed_at, $viewer));
|
||||
} else {
|
||||
$signed_text = pht(
|
||||
'You signed this document on %s.',
|
||||
phabricator_datetime($signed_at, $viewer));
|
||||
->setErrors(array($login_text));
|
||||
}
|
||||
|
||||
$signed_status = id(new AphrontErrorView())
|
||||
->setSeverity(AphrontErrorView::SEVERITY_NOTICE)
|
||||
->setErrors(array($signed_text));
|
||||
$field_errors = array(
|
||||
'name' => true,
|
||||
'address' => true,
|
||||
'contact.name' => true,
|
||||
'email' => true,
|
||||
);
|
||||
}
|
||||
|
||||
$e_name = true;
|
||||
$e_email = true;
|
||||
$e_agree = null;
|
||||
$signature->setSignatureData($signature_data);
|
||||
|
||||
$errors = array();
|
||||
if ($request->isFormOrHisecPost() && !$has_signed) {
|
||||
|
@ -139,50 +148,25 @@ final class LegalpadDocumentSignController extends LegalpadController {
|
|||
'/'.$document->getMonogram());
|
||||
}
|
||||
|
||||
$name = $request->getStr('name');
|
||||
$agree = $request->getExists('agree');
|
||||
list($form_data, $errors, $field_errors) = $this->readSignatureForm(
|
||||
$document,
|
||||
$request);
|
||||
|
||||
if (!strlen($name)) {
|
||||
$e_name = pht('Required');
|
||||
$errors[] = pht('Name field is required.');
|
||||
} else {
|
||||
$e_name = null;
|
||||
}
|
||||
$signature_data['name'] = $name;
|
||||
|
||||
if ($viewer->isLoggedIn()) {
|
||||
$email = $viewer->loadPrimaryEmailAddress();
|
||||
} else {
|
||||
$email = $request->getStr('email');
|
||||
|
||||
$addr_obj = null;
|
||||
if (!strlen($email)) {
|
||||
$e_email = pht('Required');
|
||||
$errors[] = pht('Email field is required.');
|
||||
} else {
|
||||
$addr_obj = new PhutilEmailAddress($email);
|
||||
$domain = $addr_obj->getDomainName();
|
||||
if (!$domain) {
|
||||
$e_email = pht('Invalid');
|
||||
$errors[] = pht('A valid email is required.');
|
||||
} else {
|
||||
$e_email = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
$signature_data['email'] = $email;
|
||||
$signature_data = $form_data + $signature_data;
|
||||
|
||||
$signature->setSignatureData($signature_data);
|
||||
$signature->setSignatureType($document->getSignatureType());
|
||||
$signature->setSignerName((string)idx($signature_data, 'name'));
|
||||
$signature->setSignerEmail((string)idx($signature_data, 'email'));
|
||||
$signature->setSignatureData($signature_data);
|
||||
|
||||
$agree = $request->getExists('agree');
|
||||
if (!$agree) {
|
||||
$errors[] = pht(
|
||||
'You must check "I agree to the terms laid forth above."');
|
||||
$e_agree = pht('Required');
|
||||
$field_errors['agree'] = pht('Required');
|
||||
}
|
||||
|
||||
if ($viewer->isLoggedIn()) {
|
||||
if ($viewer->isLoggedIn() && $is_individual) {
|
||||
$verified = LegalpadDocumentSignature::VERIFIED;
|
||||
} else {
|
||||
$verified = LegalpadDocumentSignature::UNVERIFIED;
|
||||
|
@ -195,9 +179,13 @@ final class LegalpadDocumentSignController extends LegalpadController {
|
|||
// If the viewer is logged in, send them to the document page, which
|
||||
// will show that they have signed the document. Otherwise, send them
|
||||
// to a completion page.
|
||||
if ($viewer->isLoggedIn()) {
|
||||
if ($viewer->isLoggedIn() && $is_individual) {
|
||||
$next_uri = '/'.$document->getMonogram();
|
||||
} else {
|
||||
$this->sendVerifySignatureEmail(
|
||||
$document,
|
||||
$signature);
|
||||
|
||||
$next_uri = $this->getApplicationURI('done/');
|
||||
}
|
||||
|
||||
|
@ -257,11 +245,9 @@ final class LegalpadDocumentSignController extends LegalpadController {
|
|||
}
|
||||
|
||||
$signature_form = $this->buildSignatureForm(
|
||||
$document_body,
|
||||
$document,
|
||||
$signature,
|
||||
$e_name,
|
||||
$e_email,
|
||||
$e_agree);
|
||||
$field_errors);
|
||||
|
||||
$subheader = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Agree and Sign Document'))
|
||||
|
@ -289,38 +275,96 @@ final class LegalpadDocumentSignController extends LegalpadController {
|
|||
));
|
||||
}
|
||||
|
||||
private function readSignerInformation(
|
||||
LegalpadDocument $document,
|
||||
AphrontRequest $request) {
|
||||
|
||||
$viewer = $request->getUser();
|
||||
$signer_phid = null;
|
||||
$signature_data = array();
|
||||
|
||||
switch ($document->getSignatureType()) {
|
||||
case LegalpadDocument::SIGNATURE_TYPE_INDIVIDUAL:
|
||||
if ($viewer->isLoggedIn()) {
|
||||
$signer_phid = $viewer->getPHID();
|
||||
$signature_data = array(
|
||||
'name' => $viewer->getRealName(),
|
||||
'email' => $viewer->loadPrimaryEmailAddress(),
|
||||
);
|
||||
} else if ($request->isFormPost()) {
|
||||
$email = new PhutilEmailAddress($request->getStr('email'));
|
||||
if (strlen($email->getDomainName())) {
|
||||
$email_obj = id(new PhabricatorUserEmail())
|
||||
->loadOneWhere('address = %s', $email->getAddress());
|
||||
if ($email_obj) {
|
||||
return $this->signInResponse();
|
||||
}
|
||||
$external_account = id(new PhabricatorExternalAccountQuery())
|
||||
->setViewer($viewer)
|
||||
->withAccountTypes(array('email'))
|
||||
->withAccountDomains(array($email->getDomainName()))
|
||||
->withAccountIDs(array($email->getAddress()))
|
||||
->loadOneOrCreate();
|
||||
if ($external_account->getUserPHID()) {
|
||||
return $this->signInResponse();
|
||||
}
|
||||
$signer_phid = $external_account->getPHID();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LegalpadDocument::SIGNATURE_TYPE_CORPORATION:
|
||||
$signer_phid = $viewer->getPHID();
|
||||
if ($signer_phid) {
|
||||
$signature_data = array(
|
||||
'contact.name' => $viewer->getRealName(),
|
||||
'email' => $viewer->loadPrimaryEmailAddress(),
|
||||
'actorPHID' => $viewer->getPHID(),
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return array($signer_phid, $signature_data);
|
||||
}
|
||||
|
||||
private function buildSignatureForm(
|
||||
LegalpadDocumentBody $body,
|
||||
LegalpadDocument $document,
|
||||
LegalpadDocumentSignature $signature,
|
||||
$e_name,
|
||||
$e_email,
|
||||
$e_agree) {
|
||||
array $errors) {
|
||||
|
||||
$viewer = $this->getRequest()->getUser();
|
||||
$data = $signature->getSignatureData();
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel(pht('Name'))
|
||||
->setValue(idx($data, 'name', ''))
|
||||
->setName('name')
|
||||
->setError($e_name));
|
||||
->setUser($viewer);
|
||||
|
||||
if (!$viewer->isLoggedIn()) {
|
||||
$form->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel(pht('Email'))
|
||||
->setValue(idx($data, 'email', ''))
|
||||
->setName('email')
|
||||
->setError($e_email));
|
||||
$signature_type = $document->getSignatureType();
|
||||
switch ($signature_type) {
|
||||
case LegalpadDocument::SIGNATURE_TYPE_INDIVIDUAL:
|
||||
$this->buildIndividualSignatureForm(
|
||||
$form,
|
||||
$document,
|
||||
$signature,
|
||||
$errors);
|
||||
break;
|
||||
case LegalpadDocument::SIGNATURE_TYPE_CORPORATION:
|
||||
$this->buildCorporateSignatureForm(
|
||||
$form,
|
||||
$document,
|
||||
$signature,
|
||||
$errors);
|
||||
break;
|
||||
default:
|
||||
throw new Exception(
|
||||
pht(
|
||||
'This document has an unknown signature type ("%s").',
|
||||
$signature_type));
|
||||
}
|
||||
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormCheckboxControl())
|
||||
->setError($e_agree)
|
||||
->setError(idx($errors, 'agree', null))
|
||||
->addCheckbox(
|
||||
'agree',
|
||||
'agree',
|
||||
|
@ -334,27 +378,240 @@ final class LegalpadDocumentSignController extends LegalpadController {
|
|||
return $form;
|
||||
}
|
||||
|
||||
private function buildIndividualSignatureForm(
|
||||
AphrontFormView $form,
|
||||
LegalpadDocument $document,
|
||||
LegalpadDocumentSignature $signature,
|
||||
array $errors) {
|
||||
|
||||
$data = $signature->getSignatureData();
|
||||
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel(pht('Name'))
|
||||
->setValue(idx($data, 'name', ''))
|
||||
->setName('name')
|
||||
->setError(idx($errors, 'name', null)));
|
||||
|
||||
$viewer = $this->getRequest()->getUser();
|
||||
if (!$viewer->isLoggedIn()) {
|
||||
$form->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel(pht('Email'))
|
||||
->setValue(idx($data, 'email', ''))
|
||||
->setName('email')
|
||||
->setError(idx($errors, 'email', null)));
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
private function buildCorporateSignatureForm(
|
||||
AphrontFormView $form,
|
||||
LegalpadDocument $document,
|
||||
LegalpadDocumentSignature $signature,
|
||||
array $errors) {
|
||||
|
||||
$data = $signature->getSignatureData();
|
||||
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel(pht('Company Name'))
|
||||
->setValue(idx($data, 'name', ''))
|
||||
->setName('name')
|
||||
->setError(idx($errors, 'name', null)))
|
||||
->appendChild(
|
||||
id(new AphrontFormTextAreaControl())
|
||||
->setLabel(pht('Company Address'))
|
||||
->setValue(idx($data, 'address', ''))
|
||||
->setName('address')
|
||||
->setError(idx($errors, 'address', null)))
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel(pht('Contact Name'))
|
||||
->setValue(idx($data, 'contact.name', ''))
|
||||
->setName('contact.name')
|
||||
->setError(idx($errors, 'contact.name', null)))
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel(pht('Contact Email'))
|
||||
->setValue(idx($data, 'email', ''))
|
||||
->setName('email')
|
||||
->setError(idx($errors, 'email', null)));
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
private function readSignatureForm(
|
||||
LegalpadDocument $document,
|
||||
AphrontRequest $request) {
|
||||
|
||||
$signature_type = $document->getSignatureType();
|
||||
switch ($signature_type) {
|
||||
case LegalpadDocument::SIGNATURE_TYPE_INDIVIDUAL:
|
||||
$result = $this->readIndividualSignatureForm(
|
||||
$document,
|
||||
$request);
|
||||
break;
|
||||
case LegalpadDocument::SIGNATURE_TYPE_CORPORATION:
|
||||
$result = $this->readCorporateSignatureForm(
|
||||
$document,
|
||||
$request);
|
||||
break;
|
||||
default:
|
||||
throw new Exception(
|
||||
pht(
|
||||
'This document has an unknown signature type ("%s").',
|
||||
$signature_type));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function readIndividualSignatureForm(
|
||||
LegalpadDocument $document,
|
||||
AphrontRequest $request) {
|
||||
|
||||
$signature_data = array();
|
||||
$errors = array();
|
||||
$field_errors = array();
|
||||
|
||||
|
||||
$name = $request->getStr('name');
|
||||
|
||||
if (!strlen($name)) {
|
||||
$field_errors['name'] = pht('Required');
|
||||
$errors[] = pht('Name field is required.');
|
||||
} else {
|
||||
$field_errors['name'] = null;
|
||||
}
|
||||
$signature_data['name'] = $name;
|
||||
|
||||
$viewer = $request->getUser();
|
||||
if ($viewer->isLoggedIn()) {
|
||||
$email = $viewer->loadPrimaryEmailAddress();
|
||||
} else {
|
||||
$email = $request->getStr('email');
|
||||
|
||||
$addr_obj = null;
|
||||
if (!strlen($email)) {
|
||||
$field_errors['email'] = pht('Required');
|
||||
$errors[] = pht('Email field is required.');
|
||||
} else {
|
||||
$addr_obj = new PhutilEmailAddress($email);
|
||||
$domain = $addr_obj->getDomainName();
|
||||
if (!$domain) {
|
||||
$field_errors['email'] = pht('Invalid');
|
||||
$errors[] = pht('A valid email is required.');
|
||||
} else {
|
||||
$field_errors['email'] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
$signature_data['email'] = $email;
|
||||
|
||||
return array($signature_data, $errors, $field_errors);
|
||||
}
|
||||
|
||||
private function readCorporateSignatureForm(
|
||||
LegalpadDocument $document,
|
||||
AphrontRequest $request) {
|
||||
|
||||
$viewer = $request->getUser();
|
||||
if (!$viewer->isLoggedIn()) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'You can not sign a document on behalf of a corporation unless '.
|
||||
'you are logged in.'));
|
||||
}
|
||||
|
||||
$signature_data = array();
|
||||
$errors = array();
|
||||
$field_errors = array();
|
||||
|
||||
$name = $request->getStr('name');
|
||||
|
||||
if (!strlen($name)) {
|
||||
$field_errors['name'] = pht('Required');
|
||||
$errors[] = pht('Company name is required.');
|
||||
} else {
|
||||
$field_errors['name'] = null;
|
||||
}
|
||||
$signature_data['name'] = $name;
|
||||
|
||||
$address = $request->getStr('address');
|
||||
if (!strlen($address)) {
|
||||
$field_errors['address'] = pht('Required');
|
||||
$errors[] = pht('Company address is required.');
|
||||
} else {
|
||||
$field_errors['address'] = null;
|
||||
}
|
||||
$signature_data['address'] = $address;
|
||||
|
||||
$contact_name = $request->getStr('contact.name');
|
||||
if (!strlen($contact_name)) {
|
||||
$field_errors['contact.name'] = pht('Required');
|
||||
$errors[] = pht('Contact name is required.');
|
||||
} else {
|
||||
$field_errors['contact.name'] = null;
|
||||
}
|
||||
$signature_data['contact.name'] = $contact_name;
|
||||
|
||||
$email = $request->getStr('email');
|
||||
$addr_obj = null;
|
||||
if (!strlen($email)) {
|
||||
$field_errors['email'] = pht('Required');
|
||||
$errors[] = pht('Contact email is required.');
|
||||
} else {
|
||||
$addr_obj = new PhutilEmailAddress($email);
|
||||
$domain = $addr_obj->getDomainName();
|
||||
if (!$domain) {
|
||||
$field_errors['email'] = pht('Invalid');
|
||||
$errors[] = pht('A valid email is required.');
|
||||
} else {
|
||||
$field_errors['email'] = null;
|
||||
}
|
||||
}
|
||||
$signature_data['email'] = $email;
|
||||
|
||||
return array($signature_data, $errors, $field_errors);
|
||||
}
|
||||
|
||||
private function sendVerifySignatureEmail(
|
||||
LegalpadDocument $doc,
|
||||
LegalpadDocumentSignature $signature) {
|
||||
|
||||
$signature_data = $signature->getSignatureData();
|
||||
$email = new PhutilEmailAddress($signature_data['email']);
|
||||
$doc_link = PhabricatorEnv::getProductionURI($doc->getMonogram());
|
||||
$doc_name = $doc->getTitle();
|
||||
$doc_link = PhabricatorEnv::getProductionURI('/'.$doc->getMonogram());
|
||||
$path = $this->getApplicationURI(sprintf(
|
||||
'/verify/%s/',
|
||||
$signature->getSecretKey()));
|
||||
$link = PhabricatorEnv::getProductionURI($path);
|
||||
|
||||
$body = <<<EOBODY
|
||||
Hi {$signature_data['name']},
|
||||
$name = idx($signature_data, 'name');
|
||||
|
||||
This email address was used to sign a Legalpad document ({$doc_link}).
|
||||
Please verify you own this email address by clicking this link:
|
||||
$body = <<<EOBODY
|
||||
{$name}:
|
||||
|
||||
This email address was used to sign a Legalpad document in Phabricator:
|
||||
|
||||
{$doc_name}
|
||||
|
||||
Please verify you own this email address and accept the agreement by clicking
|
||||
this link:
|
||||
|
||||
{$link}
|
||||
|
||||
Your signature is invalid until you verify you own the email.
|
||||
Your signature is not valid until you complete this verification step.
|
||||
|
||||
You can review the document here:
|
||||
|
||||
{$doc_link}
|
||||
|
||||
EOBODY;
|
||||
|
||||
id(new PhabricatorMetaMTAMail())
|
||||
|
|
|
@ -28,62 +28,90 @@ final class LegalpadDocumentSignatureAddController extends LegalpadController {
|
|||
|
||||
$next_uri = $this->getApplicationURI('signatures/'.$document->getID().'/');
|
||||
|
||||
$e_name = true;
|
||||
$e_user = true;
|
||||
$v_users = array();
|
||||
$v_notes = '';
|
||||
$v_name = '';
|
||||
$errors = array();
|
||||
|
||||
$type_individual = LegalpadDocument::SIGNATURE_TYPE_INDIVIDUAL;
|
||||
$is_individual = ($document->getSignatureType() == $type_individual);
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$v_notes = $request->getStr('notes');
|
||||
$v_users = array_slice($request->getArr('users'), 0, 1);
|
||||
$v_name = $request->getStr('name');
|
||||
|
||||
$user_phid = head($v_users);
|
||||
if (!$user_phid) {
|
||||
$e_user = pht('Required');
|
||||
$errors[] = pht('You must choose a user to exempt.');
|
||||
} else {
|
||||
$user = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($user_phid))
|
||||
->executeOne();
|
||||
|
||||
if (!$user) {
|
||||
$e_user = pht('Invalid');
|
||||
$errors[] = pht('That user does not exist.');
|
||||
if ($is_individual) {
|
||||
$user_phid = head($v_users);
|
||||
if (!$user_phid) {
|
||||
$e_user = pht('Required');
|
||||
$errors[] = pht('You must choose a user to exempt.');
|
||||
} else {
|
||||
$signature = id(new LegalpadDocumentSignatureQuery())
|
||||
$user = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($viewer)
|
||||
->withDocumentPHIDs(array($document->getPHID()))
|
||||
->withSignerPHIDs(array($user->getPHID()))
|
||||
->withPHIDs(array($user_phid))
|
||||
->executeOne();
|
||||
if ($signature) {
|
||||
$e_user = pht('Signed');
|
||||
$errors[] = pht('That user has already signed this document.');
|
||||
|
||||
if (!$user) {
|
||||
$e_user = pht('Invalid');
|
||||
$errors[] = pht('That user does not exist.');
|
||||
} else {
|
||||
$e_user = null;
|
||||
$signature = id(new LegalpadDocumentSignatureQuery())
|
||||
->setViewer($viewer)
|
||||
->withDocumentPHIDs(array($document->getPHID()))
|
||||
->withSignerPHIDs(array($user->getPHID()))
|
||||
->executeOne();
|
||||
if ($signature) {
|
||||
$e_user = pht('Signed');
|
||||
$errors[] = pht('That user has already signed this document.');
|
||||
} else {
|
||||
$e_user = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$company_name = $v_name;
|
||||
if (!strlen($company_name)) {
|
||||
$e_name = pht('Required');
|
||||
$errors[] = pht('You must choose a company to add an exemption for.');
|
||||
}
|
||||
}
|
||||
|
||||
if (!$errors) {
|
||||
$name = $user->getRealName();
|
||||
$email = $user->loadPrimaryEmailAddress();
|
||||
if ($is_individual) {
|
||||
$name = $user->getRealName();
|
||||
$email = $user->loadPrimaryEmailAddress();
|
||||
$signer_phid = $user->getPHID();
|
||||
$signature_data = array(
|
||||
'name' => $name,
|
||||
'email' => $email,
|
||||
'notes' => $v_notes,
|
||||
);
|
||||
} else {
|
||||
$name = $company_name;
|
||||
$email = '';
|
||||
$signer_phid = null;
|
||||
$signature_data = array(
|
||||
'name' => $name,
|
||||
'email' => null,
|
||||
'notes' => $v_notes,
|
||||
'actorPHID' => $viewer->getPHID(),
|
||||
);
|
||||
}
|
||||
|
||||
$signature = id(new LegalpadDocumentSignature())
|
||||
->setDocumentPHID($document->getPHID())
|
||||
->setDocumentVersion($document->getVersions())
|
||||
->setSignerPHID($user->getPHID())
|
||||
->setSignerPHID($signer_phid)
|
||||
->setSignerName($name)
|
||||
->setSignerEmail($email)
|
||||
->setSignatureType($document->getSignatureType())
|
||||
->setIsExemption(1)
|
||||
->setExemptionPHID($viewer->getPHID())
|
||||
->setVerified(LegalpadDocumentSignature::VERIFIED)
|
||||
->setSignatureData(
|
||||
array(
|
||||
'name' => $name,
|
||||
'email' => $email,
|
||||
'notes' => $v_notes,
|
||||
));
|
||||
->setSignatureData($signature_data);
|
||||
|
||||
$signature->save();
|
||||
|
||||
|
@ -91,18 +119,31 @@ final class LegalpadDocumentSignatureAddController extends LegalpadController {
|
|||
}
|
||||
}
|
||||
|
||||
$user_handles = $this->loadViewerHandles($v_users);
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->appendChild(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setLabel(pht('Exempt User'))
|
||||
->setName('users')
|
||||
->setLimit(1)
|
||||
->setDatasource('/typeahead/common/users/')
|
||||
->setValue($user_handles)
|
||||
->setError($e_user))
|
||||
->setUser($viewer);
|
||||
|
||||
if ($is_individual) {
|
||||
$user_handles = $this->loadViewerHandles($v_users);
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setLabel(pht('Exempt User'))
|
||||
->setName('users')
|
||||
->setLimit(1)
|
||||
->setDatasource('/typeahead/common/users/')
|
||||
->setValue($user_handles)
|
||||
->setError($e_user));
|
||||
} else {
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel(pht('Company Name'))
|
||||
->setName('name')
|
||||
->setError($e_name)
|
||||
->setValue($v_name));
|
||||
}
|
||||
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormTextAreaControl())
|
||||
->setLabel(pht('Notes'))
|
||||
|
|
|
@ -1,93 +1,99 @@
|
|||
<?php
|
||||
|
||||
final class LegalpadDocumentSignatureVerificationController
|
||||
extends LegalpadController {
|
||||
extends LegalpadController {
|
||||
|
||||
private $code;
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->code = $data['code'];
|
||||
}
|
||||
|
||||
public function shouldRequireEmailVerification() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function shouldRequireLogin() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
||||
// this page can be accessed by not logged in users to valid their
|
||||
// signatures. use the omnipotent user for these cases.
|
||||
if (!$user->isLoggedIn()) {
|
||||
$viewer = PhabricatorUser::getOmnipotentUser();
|
||||
} else {
|
||||
$viewer = $user;
|
||||
}
|
||||
$viewer = $request->getUser();
|
||||
|
||||
// NOTE: We're using the omnipotent user to handle logged-out signatures
|
||||
// and corporate signatures.
|
||||
$signature = id(new LegalpadDocumentSignatureQuery())
|
||||
->setViewer($viewer)
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withSecretKeys(array($this->code))
|
||||
->executeOne();
|
||||
|
||||
if (!$signature) {
|
||||
$title = pht('Unable to Verify Signature');
|
||||
$content = pht(
|
||||
'The verification code you provided is incorrect or the signature '.
|
||||
'has been removed. '.
|
||||
'Make sure you followed the link in the email correctly.');
|
||||
$uri = $this->getApplicationURI();
|
||||
$continue = pht('Rats!');
|
||||
} else {
|
||||
$document = id(new LegalpadDocumentQuery())
|
||||
->setViewer($user)
|
||||
->withPHIDs(array($signature->getDocumentPHID()))
|
||||
->executeOne();
|
||||
// the document could be deleted or have its permissions changed
|
||||
// 4oh4 time
|
||||
if (!$document) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$uri = '/'.$document->getMonogram();
|
||||
if ($signature->isVerified()) {
|
||||
$title = pht('Signature Already Verified');
|
||||
$content = pht(
|
||||
'This signature has already been verified.');
|
||||
$continue = pht('Continue to Legalpad Document');
|
||||
} else {
|
||||
$guard = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||
$signature
|
||||
->setVerified(LegalpadDocumentSignature::VERIFIED)
|
||||
->save();
|
||||
unset($guard);
|
||||
$title = pht('Signature Verified');
|
||||
$content = pht('The signature is now verified.');
|
||||
$continue = pht('Continue to Legalpad Document');
|
||||
}
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Unable to Verify Signature'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'The signature verification code is incorrect, or the signature '.
|
||||
'has been invalidated. Make sure you followed the link in the '.
|
||||
'email correctly.'))
|
||||
->addCancelButton('/', pht('Rats!'));
|
||||
}
|
||||
|
||||
$dialog = id(new AphrontDialogView())
|
||||
->setUser($user)
|
||||
->setTitle($title)
|
||||
->setMethod('GET')
|
||||
->addCancelButton($uri, $continue)
|
||||
->appendChild($content);
|
||||
if ($signature->isVerified()) {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Signature Already Verified'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'This signature has already been verified.'))
|
||||
->addCancelButton('/', pht('Okay'));
|
||||
}
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(pht('Verify Signature'));
|
||||
if ($request->isFormPost()) {
|
||||
$signature
|
||||
->setVerified(LegalpadDocumentSignature::VERIFIED)
|
||||
->save();
|
||||
|
||||
return $this->buildApplicationPage(
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Signature Verified'))
|
||||
->appendParagraph(pht('The signature is now verified.'))
|
||||
->addCancelButton('/', pht('Okay'));
|
||||
}
|
||||
|
||||
$document_link = phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
$crumbs,
|
||||
$dialog,
|
||||
'href' => '/'.$signature->getDocument()->getMonogram(),
|
||||
'target' => '_blank',
|
||||
),
|
||||
array(
|
||||
'title' => pht('Verify Signature'),
|
||||
));
|
||||
$signature->getDocument()->getTitle());
|
||||
|
||||
$signed_at = phabricator_datetime($signature->getDateCreated(), $viewer);
|
||||
|
||||
$name = $signature->getSignerName();
|
||||
$email = $signature->getSignerEmail();
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->appendRemarkupInstructions(
|
||||
pht('Please verify this document signature.'))
|
||||
->appendChild(
|
||||
id(new AphrontFormMarkupControl())
|
||||
->setLabel(pht('Document'))
|
||||
->setValue($document_link))
|
||||
->appendChild(
|
||||
id(new AphrontFormMarkupControl())
|
||||
->setLabel(pht('Signed At'))
|
||||
->setValue($signed_at))
|
||||
->appendChild(
|
||||
id(new AphrontFormMarkupControl())
|
||||
->setLabel(pht('Name'))
|
||||
->setValue($name))
|
||||
->appendChild(
|
||||
id(new AphrontFormMarkupControl())
|
||||
->setLabel(pht('Email'))
|
||||
->setValue($email));
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Verify Signature?'))
|
||||
->appendChild($form->buildLayoutView())
|
||||
->addCancelButton('/')
|
||||
->addSubmitButton(pht('Verify Signature'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -44,22 +44,63 @@ final class LegalpadDocumentSignatureViewController extends LegalpadController {
|
|||
$document_id = $signature->getDocument()->getID();
|
||||
$next_uri = $this->getApplicationURI('signatures/'.$document_id.'/');
|
||||
|
||||
$exemption_phid = $signature->getExemptionPHID();
|
||||
$handles = $this->loadViewerHandles(array($exemption_phid));
|
||||
$exemptor_handle = $handles[$exemption_phid];
|
||||
|
||||
$data = $signature->getSignatureData();
|
||||
|
||||
$exemption_phid = $signature->getExemptionPHID();
|
||||
$actor_phid = idx($data, 'actorPHID');
|
||||
$handles = $this->loadViewerHandles(
|
||||
array(
|
||||
$exemption_phid,
|
||||
$actor_phid,
|
||||
));
|
||||
$exemptor_handle = $handles[$exemption_phid];
|
||||
$actor_handle = $handles[$actor_phid];
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->appendChild(
|
||||
id(new AphrontFormMarkupControl())
|
||||
->setLabel(pht('Exemption By'))
|
||||
->setValue($exemptor_handle->renderLink()))
|
||||
->appendChild(
|
||||
id(new AphrontFormMarkupControl())
|
||||
->setLabel(pht('Notes'))
|
||||
->setValue(idx($data, 'notes')));
|
||||
->setUser($viewer);
|
||||
|
||||
if ($signature->getExemptionPHID()) {
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormMarkupControl())
|
||||
->setLabel(pht('Exemption By'))
|
||||
->setValue($exemptor_handle->renderLink()))
|
||||
->appendChild(
|
||||
id(new AphrontFormMarkupControl())
|
||||
->setLabel(pht('Notes'))
|
||||
->setValue(idx($data, 'notes')));
|
||||
}
|
||||
|
||||
$type_corporation = LegalpadDocument::SIGNATURE_TYPE_CORPORATION;
|
||||
if ($signature->getSignatureType() == $type_corporation) {
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormMarkupControl())
|
||||
->setLabel(pht('Signing User'))
|
||||
->setValue($actor_handle->renderLink()))
|
||||
->appendChild(
|
||||
id(new AphrontFormMarkupControl())
|
||||
->setLabel(pht('Company Name'))
|
||||
->setValue(idx($data, 'name')))
|
||||
->appendChild(
|
||||
id(new AphrontFormMarkupControl())
|
||||
->setLabel(pht('Address'))
|
||||
->setValue(phutil_escape_html_newlines(idx($data, 'address'))))
|
||||
->appendChild(
|
||||
id(new AphrontFormMarkupControl())
|
||||
->setLabel(pht('Contact Name'))
|
||||
->setValue(idx($data, 'contact.name')))
|
||||
->appendChild(
|
||||
id(new AphrontFormMarkupControl())
|
||||
->setLabel(pht('Contact Email'))
|
||||
->setValue(
|
||||
phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => 'mailto:'.idx($data, 'email'),
|
||||
),
|
||||
idx($data, 'email'))));
|
||||
}
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Signature Details'))
|
||||
|
|
|
@ -11,6 +11,7 @@ final class LegalpadDocumentEditor
|
|||
private function setIsContribution($is_contribution) {
|
||||
$this->isContribution = $is_contribution;
|
||||
}
|
||||
|
||||
private function isContribution() {
|
||||
return $this->isContribution;
|
||||
}
|
||||
|
@ -24,6 +25,8 @@ final class LegalpadDocumentEditor
|
|||
|
||||
$types[] = LegalpadTransactionType::TYPE_TITLE;
|
||||
$types[] = LegalpadTransactionType::TYPE_TEXT;
|
||||
$types[] = LegalpadTransactionType::TYPE_SIGNATURE_TYPE;
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
|
@ -36,6 +39,8 @@ final class LegalpadDocumentEditor
|
|||
return $object->getDocumentBody()->getTitle();
|
||||
case LegalpadTransactionType::TYPE_TEXT:
|
||||
return $object->getDocumentBody()->getText();
|
||||
case LegalpadTransactionType::TYPE_SIGNATURE_TYPE:
|
||||
return $object->getSignatureType();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,6 +51,7 @@ final class LegalpadDocumentEditor
|
|||
switch ($xaction->getTransactionType()) {
|
||||
case LegalpadTransactionType::TYPE_TITLE:
|
||||
case LegalpadTransactionType::TYPE_TEXT:
|
||||
case LegalpadTransactionType::TYPE_SIGNATURE_TYPE:
|
||||
return $xaction->getNewValue();
|
||||
}
|
||||
}
|
||||
|
@ -66,6 +72,9 @@ final class LegalpadDocumentEditor
|
|||
$body->setText($xaction->getNewValue());
|
||||
$this->setIsContribution(true);
|
||||
break;
|
||||
case LegalpadTransactionType::TYPE_SIGNATURE_TYPE:
|
||||
$object->setSignatureType($xaction->getNewValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,6 +125,7 @@ final class LegalpadDocumentEditor
|
|||
switch ($type) {
|
||||
case LegalpadTransactionType::TYPE_TITLE:
|
||||
case LegalpadTransactionType::TYPE_TEXT:
|
||||
case LegalpadTransactionType::TYPE_SIGNATURE_TYPE:
|
||||
return $v;
|
||||
}
|
||||
|
||||
|
|
|
@ -169,13 +169,18 @@ final class LegalpadDocumentSearchEngine
|
|||
|
||||
$title = $document->getTitle();
|
||||
|
||||
$type_name = $document->getSignatureTypeName();
|
||||
$type_icon = $document->getSignatureTypeIcon();
|
||||
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setObjectName($document->getMonogram())
|
||||
->setHeader($title)
|
||||
->setHref('/'.$document->getMonogram())
|
||||
->setObject($document)
|
||||
->addIcon('none', pht('Version %d', $document->getVersions()))
|
||||
->addIcon('none', pht('Updated %s', $last_updated));
|
||||
->addIcon($type_icon, $type_name)
|
||||
->addIcon(
|
||||
'fa-pencil grey',
|
||||
pht('Version %d (%s)', $document->getVersions(), $last_updated));
|
||||
|
||||
if ($viewer->getPHID()) {
|
||||
$signature = $document->getUserSignature($viewer->getPHID());
|
||||
|
|
|
@ -168,6 +168,11 @@ final class LegalpadDocumentSignatureSearchEngine
|
|||
null,
|
||||
pht('Verified, Current'));
|
||||
|
||||
$sig_corp = $this->renderIcon(
|
||||
'fa-building-o',
|
||||
null,
|
||||
pht('Verified, Corporate'));
|
||||
|
||||
$sig_old = $this->renderIcon(
|
||||
'fa-clock-o',
|
||||
'orange',
|
||||
|
@ -188,6 +193,8 @@ final class LegalpadDocumentSignatureSearchEngine
|
|||
->addSigil('has-tooltip')
|
||||
->setMetadata(array('tip' => pht('Unverified Email')));
|
||||
|
||||
$type_corporate = LegalpadDocument::SIGNATURE_TYPE_CORPORATION;
|
||||
|
||||
$rows = array();
|
||||
foreach ($signatures as $signature) {
|
||||
$name = $signature->getSignerName();
|
||||
|
@ -196,28 +203,36 @@ final class LegalpadDocumentSignatureSearchEngine
|
|||
$document = $signature->getDocument();
|
||||
|
||||
if ($signature->getIsExemption()) {
|
||||
$signature_href = $this->getApplicationURI(
|
||||
'signature/'.$signature->getID().'/');
|
||||
|
||||
$sig_icon = javelin_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $signature_href,
|
||||
'sigil' => 'workflow',
|
||||
),
|
||||
$sig_exemption);
|
||||
$sig_icon = $sig_exemption;
|
||||
} else if (!$signature->isVerified()) {
|
||||
$sig_icon = $sig_unverified;
|
||||
} else if ($signature->getDocumentVersion() != $document->getVersions()) {
|
||||
$sig_icon = $sig_old;
|
||||
} else if ($signature->getSignatureType() == $type_corporate) {
|
||||
$sig_icon = $sig_corp;
|
||||
} else {
|
||||
$sig_icon = $sig_good;
|
||||
}
|
||||
|
||||
$signature_href = $this->getApplicationURI(
|
||||
'signature/'.$signature->getID().'/');
|
||||
|
||||
$sig_icon = javelin_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $signature_href,
|
||||
'sigil' => 'workflow',
|
||||
),
|
||||
$sig_icon);
|
||||
|
||||
$signer_phid = $signature->getSignerPHID();
|
||||
|
||||
$rows[] = array(
|
||||
$sig_icon,
|
||||
$handles[$document->getPHID()]->renderLink(),
|
||||
$handles[$signature->getSignerPHID()]->renderLink(),
|
||||
$signer_phid
|
||||
? $handles[$signer_phid]->renderLink()
|
||||
: null,
|
||||
$name,
|
||||
phutil_tag(
|
||||
'a',
|
||||
|
|
|
@ -16,6 +16,10 @@ final class LegalpadDocument extends LegalpadDAO
|
|||
protected $viewPolicy;
|
||||
protected $editPolicy;
|
||||
protected $mailKey;
|
||||
protected $signatureType;
|
||||
|
||||
const SIGNATURE_TYPE_INDIVIDUAL = 'user';
|
||||
const SIGNATURE_TYPE_CORPORATION = 'corp';
|
||||
|
||||
private $documentBody = self::ATTACHABLE;
|
||||
private $contributors = self::ATTACHABLE;
|
||||
|
@ -37,6 +41,7 @@ final class LegalpadDocument extends LegalpadDAO
|
|||
->setContributorCount(0)
|
||||
->setRecentContributorPHIDs(array())
|
||||
->attachSignatures(array())
|
||||
->setSignatureType(self::SIGNATURE_TYPE_INDIVIDUAL)
|
||||
->setViewPolicy($view_policy)
|
||||
->setEditPolicy($edit_policy);
|
||||
}
|
||||
|
@ -104,6 +109,28 @@ final class LegalpadDocument extends LegalpadDAO
|
|||
return $this;
|
||||
}
|
||||
|
||||
public static function getSignatureTypeMap() {
|
||||
return array(
|
||||
self::SIGNATURE_TYPE_INDIVIDUAL => pht('Individuals'),
|
||||
self::SIGNATURE_TYPE_CORPORATION => pht('Corporations'),
|
||||
);
|
||||
}
|
||||
|
||||
public function getSignatureTypeName() {
|
||||
$type = $this->getSignatureType();
|
||||
return idx(self::getSignatureTypeMap(), $type, $type);
|
||||
}
|
||||
|
||||
public function getSignatureTypeIcon() {
|
||||
$type = $this->getSignatureType();
|
||||
$map = array(
|
||||
self::SIGNATURE_TYPE_INDIVIDUAL => 'fa-user grey',
|
||||
self::SIGNATURE_TYPE_CORPORATION => 'fa-building-o grey',
|
||||
);
|
||||
|
||||
return idx($map, $type, 'fa-user grey');
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorSubscribableInterface )----------------------------------- */
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ final class LegalpadDocumentSignature
|
|||
|
||||
protected $documentPHID;
|
||||
protected $documentVersion;
|
||||
protected $signatureType;
|
||||
protected $signerPHID;
|
||||
protected $signerName;
|
||||
protected $signerEmail;
|
||||
|
|
Loading…
Reference in a new issue