diff --git a/resources/sql/autopatches/20141006.phortunecart.sql b/resources/sql/autopatches/20141006.phortunecart.sql new file mode 100644 --- /dev/null +++ b/resources/sql/autopatches/20141006.phortunecart.sql @@ -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; 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 @@ -666,6 +666,7 @@ '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 @@ '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 @@ 'PhabricatorPolicyInterface', 'PhabricatorApplicationTransactionInterface', ), + 'FundBackerCart' => 'PhortuneCartImplementation', 'FundBackerEditor' => 'PhabricatorApplicationTransactionEditor', 'FundBackerListController' => 'FundController', 'FundBackerPHIDType' => 'PhabricatorPHIDType', diff --git a/src/applications/fund/controller/FundInitiativeBackController.php b/src/applications/fund/controller/FundInitiativeBackController.php --- a/src/applications/fund/controller/FundInitiativeBackController.php +++ b/src/applications/fund/controller/FundInitiativeBackController.php @@ -70,7 +70,10 @@ $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 diff --git a/src/applications/fund/phortune/FundBackerCart.php b/src/applications/fund/phortune/FundBackerCart.php new file mode 100644 --- /dev/null +++ b/src/applications/fund/phortune/FundBackerCart.php @@ -0,0 +1,80 @@ +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(); + } + +} diff --git a/src/applications/phortune/cart/PhortuneCartImplementation.php b/src/applications/phortune/cart/PhortuneCartImplementation.php new file mode 100644 --- /dev/null +++ b/src/applications/phortune/cart/PhortuneCartImplementation.php @@ -0,0 +1,22 @@ +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; diff --git a/src/applications/phortune/query/PhortuneCartQuery.php b/src/applications/phortune/query/PhortuneCartQuery.php --- a/src/applications/phortune/query/PhortuneCartQuery.php +++ b/src/applications/phortune/query/PhortuneCartQuery.php @@ -66,6 +66,24 @@ $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; } diff --git a/src/applications/phortune/storage/PhortuneAccount.php b/src/applications/phortune/storage/PhortuneAccount.php --- a/src/applications/phortune/storage/PhortuneAccount.php +++ b/src/applications/phortune/storage/PhortuneAccount.php @@ -56,9 +56,18 @@ 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() { diff --git a/src/applications/phortune/storage/PhortuneCart.php b/src/applications/phortune/storage/PhortuneCart.php --- a/src/applications/phortune/storage/PhortuneCart.php +++ b/src/applications/phortune/storage/PhortuneCart.php @@ -11,11 +11,13 @@ 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 @@ 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 @@ ), self::CONFIG_COLUMN_SCHEMA => array( 'status' => 'text32', + 'cartClass' => 'text128', ), self::CONFIG_KEY_SCHEMA => array( 'key_account' => array( @@ -131,6 +132,16 @@ 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 @@ 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 )----------------------------------------- */