1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-09-19 16:58:48 +02: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:
epriestley 2014-10-06 14:19:08 -07:00
parent ed0b23cb4d
commit 0beb8228da
9 changed files with 177 additions and 14 deletions

View 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;

View file

@ -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',

View file

@ -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

View 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();
}
}

View file

@ -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);
}

View file

@ -162,11 +162,15 @@ final class PhortuneCartCheckoutController
}
if ($methods || $add_providers) {
$form
->appendChild(
id(new AphrontFormSubmitControl())
->setValue(pht('Submit Payment'))
->setDisabled(!$methods));
$submit = id(new AphrontFormSubmitControl())
->setValue(pht('Submit Payment'))
->setDisabled(!$methods);
if ($cart->getCancelURI() !== null) {
$submit->addCancelButton($cart->getCancelURI());
}
$form->appendChild($submit);
}
$provider_form = null;

View file

@ -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;
}

View file

@ -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() {

View file

@ -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 )----------------------------------------- */