Page MenuHomePhabricator

D20132.diff
No OneTemporary

D20132.diff

diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -9,7 +9,7 @@
'names' => array(
'conpherence.pkg.css' => '3c8a0668',
'conpherence.pkg.js' => '020aebcf',
- 'core.pkg.css' => 'eab5ccaf',
+ 'core.pkg.css' => '08baca0c',
'core.pkg.js' => '5c737607',
'differential.pkg.css' => 'b8df73d4',
'differential.pkg.js' => '67c9ea4c',
@@ -30,7 +30,7 @@
'rsrc/css/aphront/notification.css' => '30240bd2',
'rsrc/css/aphront/panel-view.css' => '46923d46',
'rsrc/css/aphront/phabricator-nav-view.css' => 'f8a0c1bf',
- 'rsrc/css/aphront/table-view.css' => '76eda3f8',
+ 'rsrc/css/aphront/table-view.css' => 'daa1f9df',
'rsrc/css/aphront/tokenizer.css' => 'b52d0668',
'rsrc/css/aphront/tooltip.css' => 'e3f2412f',
'rsrc/css/aphront/typeahead-browse.css' => 'b7ed02d2',
@@ -519,7 +519,7 @@
'aphront-list-filter-view-css' => 'feb64255',
'aphront-multi-column-view-css' => 'fbc00ba3',
'aphront-panel-view-css' => '46923d46',
- 'aphront-table-view-css' => '76eda3f8',
+ 'aphront-table-view-css' => 'daa1f9df',
'aphront-tokenizer-control-css' => 'b52d0668',
'aphront-tooltip-css' => 'e3f2412f',
'aphront-typeahead-control-css' => '8779483d',
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
@@ -5015,6 +5015,7 @@
'PhortuneCurrencySerializer' => 'applications/phortune/currency/PhortuneCurrencySerializer.php',
'PhortuneCurrencyTestCase' => 'applications/phortune/currency/__tests__/PhortuneCurrencyTestCase.php',
'PhortuneDAO' => 'applications/phortune/storage/PhortuneDAO.php',
+ 'PhortuneDisplayException' => 'applications/phortune/exception/PhortuneDisplayException.php',
'PhortuneErrCode' => 'applications/phortune/constants/PhortuneErrCode.php',
'PhortuneInvoiceView' => 'applications/phortune/view/PhortuneInvoiceView.php',
'PhortuneLandingController' => 'applications/phortune/controller/PhortuneLandingController.php',
@@ -11263,6 +11264,7 @@
'PhortuneCurrencySerializer' => 'PhabricatorLiskSerializer',
'PhortuneCurrencyTestCase' => 'PhabricatorTestCase',
'PhortuneDAO' => 'PhabricatorLiskDAO',
+ 'PhortuneDisplayException' => 'Exception',
'PhortuneErrCode' => 'PhortuneConstants',
'PhortuneInvoiceView' => 'AphrontTagView',
'PhortuneLandingController' => 'PhortuneController',
diff --git a/src/applications/fund/storage/FundBacker.php b/src/applications/fund/storage/FundBacker.php
--- a/src/applications/fund/storage/FundBacker.php
+++ b/src/applications/fund/storage/FundBacker.php
@@ -76,6 +76,7 @@
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
);
}
@@ -91,6 +92,8 @@
return $initiative->getPolicy($capability);
}
return PhabricatorPolicies::POLICY_NOONE;
+ case PhabricatorPolicyCapability::CAN_EDIT:
+ return PhabricatorPolicies::POLICY_NOONE;
}
}
diff --git a/src/applications/phortune/controller/payment/PhortunePaymentMethodCreateController.php b/src/applications/phortune/controller/payment/PhortunePaymentMethodCreateController.php
--- a/src/applications/phortune/controller/payment/PhortunePaymentMethodCreateController.php
+++ b/src/applications/phortune/controller/payment/PhortunePaymentMethodCreateController.php
@@ -73,6 +73,7 @@
$provider = $providers[$provider_id];
$errors = array();
+ $display_exception = null;
if ($request->isFormPost() && $request->getBool('isProviderForm')) {
$method = id(new PhortunePaymentMethod())
->setAccountPHID($account->getPHID())
@@ -107,14 +108,23 @@
}
if (!$errors) {
- $errors = $provider->createPaymentMethodFromRequest(
- $request,
- $method,
- $client_token);
+ try {
+ $provider->createPaymentMethodFromRequest(
+ $request,
+ $method,
+ $client_token);
+ } catch (PhortuneDisplayException $exception) {
+ $display_exception = $exception;
+ } catch (Exception $ex) {
+ $errors = array(
+ pht('There was an error adding this payment method:'),
+ $ex->getMessage(),
+ );
+ }
}
}
- if (!$errors) {
+ if (!$errors && !$display_exception) {
$method->save();
// If we added this method on a cart flow, return to the cart to
@@ -133,13 +143,17 @@
return id(new AphrontRedirectResponse())->setURI($next_uri);
} else {
- $dialog = id(new AphrontDialogView())
- ->setUser($viewer)
+ if ($display_exception) {
+ $dialog_body = $display_exception->getView();
+ } else {
+ $dialog_body = id(new PHUIInfoView())
+ ->setErrors($errors);
+ }
+
+ return $this->newDialog()
->setTitle(pht('Error Adding Payment Method'))
- ->appendChild(id(new PHUIInfoView())->setErrors($errors))
+ ->appendChild($dialog_body)
->addCancelButton($request->getRequestURI());
-
- return id(new AphrontDialogResponse())->setDialog($dialog);
}
}
diff --git a/src/applications/phortune/exception/PhortuneDisplayException.php b/src/applications/phortune/exception/PhortuneDisplayException.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/exception/PhortuneDisplayException.php
@@ -0,0 +1,15 @@
+<?php
+
+final class PhortuneDisplayException
+ extends Exception {
+
+ public function setView($view) {
+ $this->view = $view;
+ return $this;
+ }
+
+ public function getView() {
+ return $this->view;
+ }
+
+}
diff --git a/src/applications/phortune/provider/PhortuneStripePaymentProvider.php b/src/applications/phortune/provider/PhortuneStripePaymentProvider.php
--- a/src/applications/phortune/provider/PhortuneStripePaymentProvider.php
+++ b/src/applications/phortune/provider/PhortuneStripePaymentProvider.php
@@ -233,8 +233,6 @@
array $token) {
$this->loadStripeAPILibraries();
- $errors = array();
-
$secret_key = $this->getSecretKey();
$stripe_token = $token['stripeCardToken'];
@@ -253,7 +251,15 @@
// the card more than once. We create one Customer for each card;
// they do not map to PhortuneAccounts because we allow an account to
// have more than one active card.
- $customer = Stripe_Customer::create($params, $secret_key);
+ try {
+ $customer = Stripe_Customer::create($params, $secret_key);
+ } catch (Stripe_CardError $ex) {
+ $display_exception = $this->newDisplayExceptionFromCardError($ex);
+ if ($display_exception) {
+ throw $display_exception;
+ }
+ throw $ex;
+ }
$card = $info->card;
@@ -267,8 +273,6 @@
'stripe.customerID' => $customer->id,
'stripe.cardToken' => $stripe_token,
));
-
- return $errors;
}
public function renderCreatePaymentMethodForm(
@@ -383,4 +387,84 @@
require_once $root.'/externals/stripe-php/lib/Stripe.php';
}
+
+ private function newDisplayExceptionFromCardError(Stripe_CardError $ex) {
+ $body = $ex->getJSONBody();
+ if (!$body) {
+ return null;
+ }
+
+ $map = idx($body, 'error');
+ if (!$map) {
+ return null;
+ }
+
+ $view = array();
+
+ $message = idx($map, 'message');
+
+ $view[] = id(new PHUIInfoView())
+ ->setErrors(array($message));
+
+ $view[] = phutil_tag(
+ 'div',
+ array(
+ 'class' => 'mlt mlb',
+ ),
+ pht('Additional details about this error:'));
+
+ $rows = array();
+
+ $rows[] = array(
+ pht('Error Code'),
+ idx($map, 'code'),
+ );
+
+ $rows[] = array(
+ pht('Error Type'),
+ idx($map, 'type'),
+ );
+
+ $param = idx($map, 'param');
+ if (strlen($param)) {
+ $rows[] = array(
+ pht('Error Param'),
+ $param,
+ );
+ }
+
+ $decline_code = idx($map, 'decline_code');
+ if (strlen($decline_code)) {
+ $rows[] = array(
+ pht('Decline Code'),
+ $decline_code,
+ );
+ }
+
+ $doc_url = idx($map, 'doc_url');
+ if ($doc_url) {
+ $rows[] = array(
+ pht('Learn More'),
+ phutil_tag(
+ 'a',
+ array(
+ 'href' => $doc_url,
+ 'target' => '_blank',
+ ),
+ $doc_url),
+ );
+ }
+
+ $view[] = id(new AphrontTableView($rows))
+ ->setColumnClasses(
+ array(
+ 'header',
+ 'wide',
+ ));
+
+ return id(new PhortuneDisplayException(get_class($ex)))
+ ->setView($view);
+ }
+
+
}
diff --git a/src/applications/policy/filter/PhabricatorPolicyFilter.php b/src/applications/policy/filter/PhabricatorPolicyFilter.php
--- a/src/applications/policy/filter/PhabricatorPolicyFilter.php
+++ b/src/applications/policy/filter/PhabricatorPolicyFilter.php
@@ -175,9 +175,10 @@
if (!in_array($capability, $object_capabilities)) {
throw new Exception(
pht(
- "Testing for capability '%s' on an object which does ".
- "not have that capability!",
- $capability));
+ 'Testing for capability "%s" on an object ("%s") which does '.
+ 'not support that capability.',
+ $capability,
+ get_class($object)));
}
$policy = $this->getObjectPolicy($object, $capability);
diff --git a/webroot/rsrc/css/aphront/table-view.css b/webroot/rsrc/css/aphront/table-view.css
--- a/webroot/rsrc/css/aphront/table-view.css
+++ b/webroot/rsrc/css/aphront/table-view.css
@@ -45,16 +45,20 @@
background: inherit;
}
-.aphront-table-view th {
+.aphront-table-view th,
+.aphront-table-view td.header {
font-weight: bold;
white-space: nowrap;
color: {$bluetext};
- text-shadow: 0 1px 0 white;
font-weight: bold;
- border-bottom: 1px solid {$thinblueborder};
+ text-shadow: 0 1px 0 white;
background-color: {$lightbluebackground};
}
+.aphront-table-view th {
+ border-bottom: 1px solid {$thinblueborder};
+}
+
th.aphront-table-view-sortable-selected {
background-color: {$greybackground};
}
@@ -74,12 +78,8 @@
}
.aphront-table-view td.header {
- padding: 4px 8px;
- white-space: nowrap;
text-align: right;
- color: {$bluetext};
- font-weight: bold;
- vertical-align: top;
+ border-right: 1px solid {$thinblueborder};
}
.aphront-table-view td {

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 19, 7:53 PM (5 h, 8 m ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7709464
Default Alt Text
D20132.diff (10 KB)

Event Timeline