Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15441138
D9735.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
19 KB
Referenced Files
None
Subscribers
None
D9735.diff
View Options
diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -7,7 +7,7 @@
return array(
'names' =>
array(
- 'core.pkg.css' => 'e428441c',
+ 'core.pkg.css' => '3f0f5da2',
'core.pkg.js' => '8c184823',
'darkconsole.pkg.js' => 'df001cab',
'differential.pkg.css' => '4a93db37',
@@ -20,7 +20,7 @@
'rsrc/css/aphront/context-bar.css' => '1c3b0529',
'rsrc/css/aphront/dark-console.css' => '6378ef3d',
'rsrc/css/aphront/dialog-view.css' => '4dbbe3bb',
- 'rsrc/css/aphront/error-view.css' => '9f1d5518',
+ 'rsrc/css/aphront/error-view.css' => '3462dbee',
'rsrc/css/aphront/lightbox-attachment.css' => '7acac05d',
'rsrc/css/aphront/list-filter-view.css' => '2ae43867',
'rsrc/css/aphront/multi-column.css' => '1b95ab2e',
@@ -499,7 +499,7 @@
'aphront-contextbar-view-css' => '1c3b0529',
'aphront-dark-console-css' => '6378ef3d',
'aphront-dialog-view-css' => '4dbbe3bb',
- 'aphront-error-view-css' => '9f1d5518',
+ 'aphront-error-view-css' => '3462dbee',
'aphront-list-filter-view-css' => '2ae43867',
'aphront-multi-column-view-css' => '1b95ab2e',
'aphront-pager-view-css' => '2e3539af',
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -860,6 +860,7 @@
'LegalpadDocument' => 'applications/legalpad/storage/LegalpadDocument.php',
'LegalpadDocumentBody' => 'applications/legalpad/storage/LegalpadDocumentBody.php',
'LegalpadDocumentCommentController' => 'applications/legalpad/controller/LegalpadDocumentCommentController.php',
+ 'LegalpadDocumentDoneController' => 'applications/legalpad/controller/LegalpadDocumentDoneController.php',
'LegalpadDocumentEditController' => 'applications/legalpad/controller/LegalpadDocumentEditController.php',
'LegalpadDocumentEditor' => 'applications/legalpad/editor/LegalpadDocumentEditor.php',
'LegalpadDocumentListController' => 'applications/legalpad/controller/LegalpadDocumentListController.php',
@@ -3613,6 +3614,7 @@
1 => 'PhabricatorMarkupInterface',
),
'LegalpadDocumentCommentController' => 'LegalpadController',
+ 'LegalpadDocumentDoneController' => 'LegalpadController',
'LegalpadDocumentEditController' => 'LegalpadController',
'LegalpadDocumentEditor' => 'PhabricatorApplicationTransactionEditor',
'LegalpadDocumentListController' => 'LegalpadController',
diff --git a/src/applications/legalpad/application/PhabricatorApplicationLegalpad.php b/src/applications/legalpad/application/PhabricatorApplicationLegalpad.php
--- a/src/applications/legalpad/application/PhabricatorApplicationLegalpad.php
+++ b/src/applications/legalpad/application/PhabricatorApplicationLegalpad.php
@@ -46,6 +46,7 @@
'edit/(?P<id>\d+)/' => 'LegalpadDocumentEditController',
'comment/(?P<id>\d+)/' => 'LegalpadDocumentCommentController',
'view/(?P<id>\d+)/' => 'LegalpadDocumentManageController',
+ 'done/' => 'LegalpadDocumentDoneController',
'verify/(?P<code>[^/]+)/' =>
'LegalpadDocumentSignatureVerificationController',
'signatures/(?P<id>\d+)/' => 'LegalpadDocumentSignatureListController',
diff --git a/src/applications/legalpad/controller/LegalpadDocumentDoneController.php b/src/applications/legalpad/controller/LegalpadDocumentDoneController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/legalpad/controller/LegalpadDocumentDoneController.php
@@ -0,0 +1,22 @@
+<?php
+
+final class LegalpadDocumentDoneController extends LegalpadController {
+
+ public function shouldRequireLogin() {
+ return false;
+ }
+
+ public function processRequest() {
+ $request = $this->getRequest();
+ $viewer = $request->getUser();
+
+ return $this->newDialog()
+ ->setTitle(pht('Verify Signature'))
+ ->appendParagraph(
+ pht(
+ 'Thank you for signing this document. Please check your email '.
+ 'to verify your signature and complete the process.'))
+ ->addCancelButton('/', pht('Okay'));
+ }
+
+}
diff --git a/src/applications/legalpad/controller/LegalpadDocumentListController.php b/src/applications/legalpad/controller/LegalpadDocumentListController.php
--- a/src/applications/legalpad/controller/LegalpadDocumentListController.php
+++ b/src/applications/legalpad/controller/LegalpadDocumentListController.php
@@ -4,6 +4,10 @@
private $queryKey;
+ public function shouldAllowPublic() {
+ return true;
+ }
+
public function willProcessRequest(array $data) {
$this->queryKey = idx($data, 'queryKey');
}
diff --git a/src/applications/legalpad/controller/LegalpadDocumentSignController.php b/src/applications/legalpad/controller/LegalpadDocumentSignController.php
--- a/src/applications/legalpad/controller/LegalpadDocumentSignController.php
+++ b/src/applications/legalpad/controller/LegalpadDocumentSignController.php
@@ -21,145 +21,162 @@
->withIDs(array($this->id))
->needDocumentBodies(true)
->executeOne();
-
if (!$document) {
return new Aphront404Response();
}
$signer_phid = null;
- $signature = null;
$signature_data = array();
if ($viewer->isLoggedIn()) {
$signer_phid = $viewer->getPHID();
$signature_data = array(
- 'email' => $viewer->loadPrimaryEmailAddress());
+ 'name' => $viewer->getRealName(),
+ 'email' => $viewer->loadPrimaryEmailAddress(),
+ );
} else if ($request->isFormPost()) {
$email = new PhutilEmailAddress($request->getStr('email'));
- $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();
+ 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();
}
- $signer_phid = $external_account->getPHID();
}
+ $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($viewer)
+ ->setViewer(PhabricatorUser::getOmnipotentUser())
->withDocumentPHIDs(array($document->getPHID()))
->withSignerPHIDs(array($signer_phid))
->withDocumentVersions(array($document->getVersions()))
->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;
- $error_view = null;
$signature = id(new LegalpadDocumentSignature())
->setSignerPHID($signer_phid)
->setDocumentPHID($document->getPHID())
->setDocumentVersion($document->getVersions())
->setSignatureData($signature_data);
+
+ // 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;
- if ($signature->isVerified()) {
- $title = pht('Already Signed');
- $body = $this->getVerifiedSignatureBlurb();
- } else {
- $title = pht('Already Signed but...');
- $body = $this->getUnverifiedSignatureBlurb();
- }
- $error_view = id(new AphrontErrorView())
- ->setSeverity(AphrontErrorView::SEVERITY_NOTICE)
- ->setTitle($title)
- ->appendChild($body);
$signature_data = $signature->getSignatureData();
+
+ // In this case, we know they've signed.
+ $signed_at = $signature->getDateCreated();
+ $signed_status = id(new AphrontErrorView())
+ ->setSeverity(AphrontErrorView::SEVERITY_NOTICE)
+ ->setErrors(
+ array(
+ pht(
+ 'You signed this document on %s.',
+ phabricator_datetime($signed_at, $viewer)),
+ ));
}
$e_name = true;
$e_email = true;
- $e_address_1 = true;
+ $e_agree = null;
+
$errors = array();
if ($request->isFormPost() && !$has_signed) {
$name = $request->getStr('name');
- $email = $request->getStr('email');
- $address_1 = $request->getStr('address_1');
- $address_2 = $request->getStr('address_2');
- $phone = $request->getStr('phone');
$agree = $request->getExists('agree');
- if (!$name) {
+ if (!strlen($name)) {
$e_name = pht('Required');
$errors[] = pht('Name field is required.');
+ } else {
+ $e_name = null;
}
$signature_data['name'] = $name;
- $addr_obj = null;
- if (!$email) {
- $e_email = pht('Required');
- $errors[] = pht('Email field is required.');
+ if ($viewer->isLoggedIn()) {
+ $email = $viewer->loadPrimaryEmailAddress();
} else {
- $addr_obj = new PhutilEmailAddress($email);
- $domain = $addr_obj->getDomainName();
- if (!$domain) {
- $e_email = pht('Invalid');
- $errors[] = pht('A valid email is required.');
+ $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;
- if (!$address_1) {
- $e_address_1 = pht('Required');
- $errors[] = pht('Address line 1 field is required.');
- }
- $signature_data['address_1'] = $address_1;
- $signature_data['address_2'] = $address_2;
- $signature_data['phone'] = $phone;
$signature->setSignatureData($signature_data);
if (!$agree) {
$errors[] = pht(
'You must check "I agree to the terms laid forth above."');
+ $e_agree = pht('Required');
}
- $verified = LegalpadDocumentSignature::UNVERIFIED;
- if ($viewer->isLoggedIn() && $addr_obj) {
- $email_obj = id(new PhabricatorUserEmail())
- ->loadOneWhere('address = %s', $addr_obj->getAddress());
- if ($email_obj && $email_obj->getUserPHID() == $viewer->getPHID()) {
- $verified = LegalpadDocumentSignature::VERIFIED;
- }
+ if ($viewer->isLoggedIn()) {
+ $verified = LegalpadDocumentSignature::VERIFIED;
+ } else {
+ $verified = LegalpadDocumentSignature::UNVERIFIED;
}
$signature->setVerified($verified);
if (!$errors) {
$signature->save();
- $has_signed = true;
- if ($signature->isVerified()) {
- $body = $this->getVerifiedSignatureBlurb();
+
+ // 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()) {
+ $next_uri = '/'.$document->getMonogram();
} else {
- $body = $this->getUnverifiedSignatureBlurb();
- $this->sendVerifySignatureEmail(
- $document,
- $signature);
+ $next_uri = $this->getApplicationURI('done/');
}
- $error_view = id(new AphrontErrorView())
- ->setSeverity(AphrontErrorView::SEVERITY_NOTICE)
- ->setTitle(pht('Signature Successful'))
- ->appendChild($body);
- } else {
- $error_view = id(new AphrontErrorView())
- ->setTitle(pht('Error in submission.'))
- ->setErrors($errors);
+
+ return id(new AphrontRedirectResponse())->setURI($next_uri);
}
}
@@ -171,6 +188,10 @@
LegalpadDocumentBody::MARKUP_FIELD_TEXT);
$engine->process();
+ $document_markup = $engine->getOutput(
+ $document_body,
+ LegalpadDocumentBody::MARKUP_FIELD_TEXT);
+
$title = $document_body->getTitle();
$manage_uri = $this->getApplicationURI('view/'.$document->getID().'/');
@@ -193,25 +214,36 @@
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
- $signature_form = $this->buildSignatureForm(
- $document_body,
- $signature,
- $has_signed,
- $e_name,
- $e_email,
- $e_address_1);
-
- $content = $this->buildDocument(
- $header,
- $engine,
- $document_body);
-
- $content->appendChild(
- array(
- id(new PHUIHeaderView())->setHeader(pht('Agree and Sign Document')),
- $error_view,
- $signature_form,
- ));
+ $content = id(new PHUIDocumentView())
+ ->addClass('legalpad')
+ ->setHeader($header)
+ ->appendChild(
+ array(
+ $signed_status,
+ $document_markup,
+ ));
+
+ if (!$has_signed) {
+ $error_view = null;
+ if ($errors) {
+ $error_view = id(new AphrontErrorView())
+ ->setErrors($errors);
+ }
+
+ $signature_form = $this->buildSignatureForm(
+ $document_body,
+ $signature,
+ $e_name,
+ $e_email,
+ $e_agree);
+
+ $content->appendChild(
+ array(
+ id(new PHUIHeaderView())->setHeader(pht('Agree and Sign Document')),
+ $error_view,
+ $signature_form,
+ ));
+ }
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($document->getMonogram());
@@ -227,35 +259,16 @@
));
}
- private function buildDocument(
- PHUIHeaderView $header,
- PhabricatorMarkupEngine $engine,
- LegalpadDocumentBody $body) {
-
- return id(new PHUIDocumentView())
- ->addClass('legalpad')
- ->setHeader($header)
- ->appendChild($engine->getOutput(
- $body,
- LegalpadDocumentBody::MARKUP_FIELD_TEXT));
- }
-
private function buildSignatureForm(
LegalpadDocumentBody $body,
LegalpadDocumentSignature $signature,
- $has_signed = false,
- $e_name = true,
- $e_email = true,
- $e_address_1 = true) {
+ $e_name,
+ $e_email,
+ $e_agree) {
$viewer = $this->getRequest()->getUser();
- if ($has_signed) {
- $instructions = pht('Thank you for signing and agreeing.');
- } else {
- $instructions = pht('Please enter the following information.');
- }
-
$data = $signature->getSignatureData();
+
$form = id(new AphrontFormView())
->setUser($viewer)
->appendChild(
@@ -263,61 +276,34 @@
->setLabel(pht('Name'))
->setValue(idx($data, 'name', ''))
->setName('name')
- ->setError($e_name)
- ->setDisabled($has_signed))
- ->appendChild(
- id(new AphrontFormTextControl())
- ->setLabel(pht('Email'))
- ->setValue(idx($data, 'email', ''))
- ->setName('email')
- ->setError($e_email)
- ->setDisabled($has_signed))
- ->appendChild(
- id(new AphrontFormTextControl())
- ->setLabel(pht('Address line 1'))
- ->setValue(idx($data, 'address_1', ''))
- ->setName('address_1')
- ->setError($e_address_1)
- ->setDisabled($has_signed))
- ->appendChild(
- id(new AphrontFormTextControl())
- ->setLabel(pht('Address line 2'))
- ->setValue(idx($data, 'address_2', ''))
- ->setName('address_2')
- ->setDisabled($has_signed))
- ->appendChild(
+ ->setError($e_name));
+
+ if (!$viewer->isLoggedIn()) {
+ $form->appendChild(
id(new AphrontFormTextControl())
- ->setLabel(pht('Phone'))
- ->setValue(idx($data, 'phone', ''))
- ->setName('phone')
- ->setDisabled($has_signed))
+ ->setLabel(pht('Email'))
+ ->setValue(idx($data, 'email', ''))
+ ->setName('email')
+ ->setError($e_email));
+ }
+
+ $form
->appendChild(
id(new AphrontFormCheckboxControl())
- ->addCheckbox(
- 'agree',
- 'agree',
- pht('I agree to the terms laid forth above.'),
- $has_signed)
- ->setDisabled($has_signed))
+ ->setError($e_agree)
+ ->addCheckbox(
+ 'agree',
+ 'agree',
+ pht('I agree to the terms laid forth above.'),
+ false))
->appendChild(
id(new AphrontFormSubmitControl())
- ->setValue(pht('Sign and Agree'))
- ->setDisabled($has_signed)
- ->addCancelButton($this->getApplicationURI()));
+ ->setValue(pht('Sign Document'))
+ ->addCancelButton($this->getApplicationURI()));
return $form;
}
- private function getVerifiedSignatureBlurb() {
- return pht('Thank you for signing and agreeing.');
- }
-
- private function getUnverifiedSignatureBlurb() {
- return pht('Thank you for signing and agreeing. However, you must '.
- 'verify your email address. Please check your email '.
- 'and follow the instructions.');
- }
-
private function sendVerifySignatureEmail(
LegalpadDocument $doc,
LegalpadDocumentSignature $signature) {
diff --git a/webroot/rsrc/css/aphront/error-view.css b/webroot/rsrc/css/aphront/error-view.css
--- a/webroot/rsrc/css/aphront/error-view.css
+++ b/webroot/rsrc/css/aphront/error-view.css
@@ -77,6 +77,12 @@
background-color: #fff;
}
+.legalpad .aphront-error-view {
+ margin: 0;
+ border-width: 0 0 1px 0;
+ border-bottom: 1px solid {$lightblueborder};
+}
+
.aphront-dialog-body .aphront-error-view {
margin: -16px -16px 16px -16px;
border-width: 0 0 1px 0;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Mar 27, 4:40 PM (3 w, 5 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7530041
Default Alt Text
D9735.diff (19 KB)
Attached To
Mode
D9735: Streamline Legalpad signature workflow
Attached
Detach File
Event Timeline
Log In to Comment