mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-18 19:40:55 +01:00
Give applications control over Phortune cart logic
Summary: Ref T2787. Similar to D10634, give applications more control over the cart workflow. For now this just means they get to pick exit URIs, but in the future they can manage more details of cart behavior. Test Plan: Funded an initiative and got returned to the initiative instead of dead-ending in Phortune. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T2787 Differential Revision: https://secure.phabricator.com/D10638
This commit is contained in:
parent
ed0b23cb4d
commit
0beb8228da
9 changed files with 177 additions and 14 deletions
4
resources/sql/autopatches/20141006.phortunecart.sql
Normal file
4
resources/sql/autopatches/20141006.phortunecart.sql
Normal file
|
@ -0,0 +1,4 @@
|
|||
TRUNCATE TABLE {$NAMESPACE}_phortune.phortune_cart;
|
||||
|
||||
ALTER TABLE {$NAMESPACE}_phortune.phortune_cart
|
||||
ADD cartClass VARCHAR(128) NOT NULL COLLATE utf8_bin;
|
|
@ -666,6 +666,7 @@ phutil_register_library_map(array(
|
|||
'FlagEditConduitAPIMethod' => 'applications/flag/conduit/FlagEditConduitAPIMethod.php',
|
||||
'FlagQueryConduitAPIMethod' => 'applications/flag/conduit/FlagQueryConduitAPIMethod.php',
|
||||
'FundBacker' => 'applications/fund/storage/FundBacker.php',
|
||||
'FundBackerCart' => 'applications/fund/phortune/FundBackerCart.php',
|
||||
'FundBackerEditor' => 'applications/fund/editor/FundBackerEditor.php',
|
||||
'FundBackerListController' => 'applications/fund/controller/FundBackerListController.php',
|
||||
'FundBackerPHIDType' => 'applications/fund/phid/FundBackerPHIDType.php',
|
||||
|
@ -2555,6 +2556,7 @@ phutil_register_library_map(array(
|
|||
'PhortuneCart' => 'applications/phortune/storage/PhortuneCart.php',
|
||||
'PhortuneCartCheckoutController' => 'applications/phortune/controller/PhortuneCartCheckoutController.php',
|
||||
'PhortuneCartController' => 'applications/phortune/controller/PhortuneCartController.php',
|
||||
'PhortuneCartImplementation' => 'applications/phortune/cart/PhortuneCartImplementation.php',
|
||||
'PhortuneCartQuery' => 'applications/phortune/query/PhortuneCartQuery.php',
|
||||
'PhortuneCartViewController' => 'applications/phortune/controller/PhortuneCartViewController.php',
|
||||
'PhortuneCharge' => 'applications/phortune/storage/PhortuneCharge.php',
|
||||
|
@ -3514,6 +3516,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorApplicationTransactionInterface',
|
||||
),
|
||||
'FundBackerCart' => 'PhortuneCartImplementation',
|
||||
'FundBackerEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'FundBackerListController' => 'FundController',
|
||||
'FundBackerPHIDType' => 'PhabricatorPHIDType',
|
||||
|
|
|
@ -70,7 +70,10 @@ final class FundInitiativeBackController
|
|||
$viewer,
|
||||
PhabricatorContentSource::newFromRequest($request));
|
||||
|
||||
$cart = $account->newCart($viewer);
|
||||
$cart_implementation = id(new FundBackerCart())
|
||||
->setInitiative($initiative);
|
||||
|
||||
$cart = $account->newCart($viewer, $cart_implementation);
|
||||
|
||||
$purchase = $cart->newPurchase($viewer, $product);
|
||||
$purchase
|
||||
|
|
80
src/applications/fund/phortune/FundBackerCart.php
Normal file
80
src/applications/fund/phortune/FundBackerCart.php
Normal file
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
|
||||
final class FundBackerCart extends PhortuneCartImplementation {
|
||||
|
||||
private $initiativePHID;
|
||||
private $initiative;
|
||||
|
||||
public function setInitiativePHID($initiative_phid) {
|
||||
$this->initiativePHID = $initiative_phid;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getInitiativePHID() {
|
||||
return $this->initiativePHID;
|
||||
}
|
||||
|
||||
public function setInitiative(FundInitiative $initiative) {
|
||||
$this->initiative = $initiative;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getInitiative() {
|
||||
return $this->initiative;
|
||||
}
|
||||
|
||||
public function willCreateCart(
|
||||
PhabricatorUser $viewer,
|
||||
PhortuneCart $cart) {
|
||||
|
||||
$initiative = $this->getInitiative();
|
||||
if (!$initiative) {
|
||||
throw new Exception(
|
||||
pht('Call setInitiative() before building a cart!'));
|
||||
}
|
||||
|
||||
$cart->setMetadataValue('initiativePHID', $initiative->getPHID());
|
||||
}
|
||||
|
||||
public function loadImplementationsForCarts(
|
||||
PhabricatorUser $viewer,
|
||||
array $carts) {
|
||||
|
||||
$phids = array();
|
||||
foreach ($carts as $cart) {
|
||||
$phids[] = $cart->getMetadataValue('initiativePHID');
|
||||
}
|
||||
|
||||
$initiatives = id(new FundInitiativeQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs($phids)
|
||||
->execute();
|
||||
$initiatives = mpull($initiatives, null, 'getPHID');
|
||||
|
||||
$objects = array();
|
||||
foreach ($carts as $key => $cart) {
|
||||
$initiative_phid = $cart->getMetadataValue('initiativePHID');
|
||||
|
||||
$object = id(new FundBackerCart())
|
||||
->setInitiativePHID($initiative_phid);
|
||||
|
||||
$initiative = idx($initiatives, $initiative_phid);
|
||||
if ($initiative) {
|
||||
$object->setInitiative($initiative);
|
||||
}
|
||||
|
||||
$objects[$key] = $object;
|
||||
}
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function getCancelURI(PhortuneCart $cart) {
|
||||
return '/'.$this->getInitiative()->getMonogram();
|
||||
}
|
||||
|
||||
public function getDoneURI(PhortuneCart $cart) {
|
||||
return '/'.$this->getInitiative()->getMonogram();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
abstract class PhortuneCartImplementation {
|
||||
|
||||
/**
|
||||
* Load implementations for a given set of carts.
|
||||
*
|
||||
* Note that this method should return a map using the original keys to
|
||||
* identify which implementation corresponds to which cart.
|
||||
*/
|
||||
abstract public function loadImplementationsForCarts(
|
||||
PhabricatorUser $viewer,
|
||||
array $carts);
|
||||
|
||||
abstract public function getCancelURI(PhortuneCart $cart);
|
||||
abstract public function getDoneURI(PhortuneCart $cart);
|
||||
|
||||
abstract public function willCreateCart(
|
||||
PhabricatorUser $viewer,
|
||||
PhortuneCart $cart);
|
||||
|
||||
}
|
|
@ -162,11 +162,15 @@ final class PhortuneCartCheckoutController
|
|||
}
|
||||
|
||||
if ($methods || $add_providers) {
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
$submit = id(new AphrontFormSubmitControl())
|
||||
->setValue(pht('Submit Payment'))
|
||||
->setDisabled(!$methods));
|
||||
->setDisabled(!$methods);
|
||||
|
||||
if ($cart->getCancelURI() !== null) {
|
||||
$submit->addCancelButton($cart->getCancelURI());
|
||||
}
|
||||
|
||||
$form->appendChild($submit);
|
||||
}
|
||||
|
||||
$provider_form = null;
|
||||
|
|
|
@ -66,6 +66,24 @@ final class PhortuneCartQuery
|
|||
$cart->attachAccount($account);
|
||||
}
|
||||
|
||||
$implementations = array();
|
||||
|
||||
$cart_map = mgroup($carts, 'getCartClass');
|
||||
foreach ($cart_map as $class => $class_carts) {
|
||||
$implementations += newv($class, array())->loadImplementationsForCarts(
|
||||
$this->getViewer(),
|
||||
$class_carts);
|
||||
}
|
||||
|
||||
foreach ($carts as $key => $cart) {
|
||||
$implementation = idx($implementations, $key);
|
||||
if (!$implementation) {
|
||||
unset($carts[$key]);
|
||||
continue;
|
||||
}
|
||||
$cart->attachImplementation($implementation);
|
||||
}
|
||||
|
||||
return $carts;
|
||||
}
|
||||
|
||||
|
|
|
@ -56,9 +56,18 @@ final class PhortuneAccount extends PhortuneDAO
|
|||
return $account;
|
||||
}
|
||||
|
||||
public function newCart(PhabricatorUser $actor) {
|
||||
return PhortuneCart::initializeNewCart($actor, $this)
|
||||
->save();
|
||||
public function newCart(
|
||||
PhabricatorUser $actor,
|
||||
PhortuneCartImplementation $implementation) {
|
||||
|
||||
$cart = PhortuneCart::initializeNewCart($actor, $this);
|
||||
|
||||
$cart->setCartClass(get_class($implementation));
|
||||
$cart->attachImplementation($implementation);
|
||||
|
||||
$implementation->willCreateCart($actor, $cart);
|
||||
|
||||
return $cart->save();
|
||||
}
|
||||
|
||||
public function getConfiguration() {
|
||||
|
|
|
@ -11,11 +11,13 @@ final class PhortuneCart extends PhortuneDAO
|
|||
|
||||
protected $accountPHID;
|
||||
protected $authorPHID;
|
||||
protected $cartClass;
|
||||
protected $status;
|
||||
protected $metadata;
|
||||
protected $metadata = array();
|
||||
|
||||
private $account = self::ATTACHABLE;
|
||||
private $purchases = self::ATTACHABLE;
|
||||
private $implementation = self::ATTACHABLE;
|
||||
|
||||
public static function initializeNewCart(
|
||||
PhabricatorUser $actor,
|
||||
|
@ -73,13 +75,11 @@ final class PhortuneCart extends PhortuneDAO
|
|||
|
||||
|
||||
public function getDoneURI() {
|
||||
// TODO: Implement properly.
|
||||
return '/phortune/cart/'.$this->getID().'/';
|
||||
return $this->getImplementation()->getDoneURI($this);
|
||||
}
|
||||
|
||||
public function getCancelURI() {
|
||||
// TODO: Implement properly.
|
||||
return '/';
|
||||
return $this->getImplementation()->getCancelURI($this);
|
||||
}
|
||||
|
||||
public function getDetailURI() {
|
||||
|
@ -98,6 +98,7 @@ final class PhortuneCart extends PhortuneDAO
|
|||
),
|
||||
self::CONFIG_COLUMN_SCHEMA => array(
|
||||
'status' => 'text32',
|
||||
'cartClass' => 'text128',
|
||||
),
|
||||
self::CONFIG_KEY_SCHEMA => array(
|
||||
'key_account' => array(
|
||||
|
@ -131,6 +132,16 @@ final class PhortuneCart extends PhortuneDAO
|
|||
return $this->assertAttached($this->account);
|
||||
}
|
||||
|
||||
public function attachImplementation(
|
||||
PhortuneCartImplementation $implementation) {
|
||||
$this->implementation = $implementation;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getImplementation() {
|
||||
return $this->assertAttached($this->implementation);
|
||||
}
|
||||
|
||||
public function getTotalPriceAsCurrency() {
|
||||
$prices = array();
|
||||
foreach ($this->getPurchases() as $purchase) {
|
||||
|
@ -140,6 +151,15 @@ final class PhortuneCart extends PhortuneDAO
|
|||
return PhortuneCurrency::newFromList($prices);
|
||||
}
|
||||
|
||||
public function setMetadataValue($key, $value) {
|
||||
$this->metadata[$key] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMetadataValue($key, $default = null) {
|
||||
return idx($this->metadata, $key, $default);
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||
|
||||
|
|
Loading…
Reference in a new issue