diff --git a/resources/sql/autopatches/20141013.phortunecartkey.sql b/resources/sql/autopatches/20141013.phortunecartkey.sql new file mode 100644 --- /dev/null +++ b/resources/sql/autopatches/20141013.phortunecartkey.sql @@ -0,0 +1,2 @@ +ALTER TABLE {$NAMESPACE}_phortune.phortune_cart + ADD mailKey BINARY(20) NOT NULL; 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 @@ -2568,6 +2568,7 @@ 'PhortuneCartListController' => 'applications/phortune/controller/PhortuneCartListController.php', 'PhortuneCartPHIDType' => 'applications/phortune/phid/PhortuneCartPHIDType.php', 'PhortuneCartQuery' => 'applications/phortune/query/PhortuneCartQuery.php', + 'PhortuneCartReplyHandler' => 'applications/phortune/mail/PhortuneCartReplyHandler.php', 'PhortuneCartSearchEngine' => 'applications/phortune/query/PhortuneCartSearchEngine.php', 'PhortuneCartTransaction' => 'applications/phortune/storage/PhortuneCartTransaction.php', 'PhortuneCartTransactionQuery' => 'applications/phortune/query/PhortuneCartTransactionQuery.php', @@ -5638,6 +5639,7 @@ 'PhortuneCartListController' => 'PhortuneController', 'PhortuneCartPHIDType' => 'PhabricatorPHIDType', 'PhortuneCartQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', + 'PhortuneCartReplyHandler' => 'PhabricatorMailReplyHandler', 'PhortuneCartSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PhortuneCartTransaction' => 'PhabricatorApplicationTransaction', 'PhortuneCartTransactionQuery' => 'PhabricatorApplicationTransactionQuery', diff --git a/src/applications/fund/editor/FundInitiativeEditor.php b/src/applications/fund/editor/FundInitiativeEditor.php --- a/src/applications/fund/editor/FundInitiativeEditor.php +++ b/src/applications/fund/editor/FundInitiativeEditor.php @@ -261,6 +261,18 @@ ->addHeader('Thread-Topic', $monogram); } + protected function buildMailBody( + PhabricatorLiskDAO $object, + array $xactions) { + + $body = parent::buildMailBody($object, $xactions); + + $body->addTextSection( + pht('INITIATIVE DETAIL'), + PhabricatorEnv::getProductionURI('/'.$object->getMonogram())); + + return $body; + } protected function getMailTo(PhabricatorLiskDAO $object) { return array($object->getOwnerPHID()); diff --git a/src/applications/phortune/editor/PhortuneCartEditor.php b/src/applications/phortune/editor/PhortuneCartEditor.php --- a/src/applications/phortune/editor/PhortuneCartEditor.php +++ b/src/applications/phortune/editor/PhortuneCartEditor.php @@ -92,4 +92,76 @@ return parent::applyCustomExternalTransaction($object, $xaction); } + protected function shouldSendMail( + PhabricatorLiskDAO $object, + array $xactions) { + return true; + } + + protected function buildMailTemplate(PhabricatorLiskDAO $object) { + $id = $object->getID(); + $name = $object->getName(); + + return id(new PhabricatorMetaMTAMail()) + ->setSubject(pht('Order %d: %s', $id, $name)) + ->addHeader('Thread-Topic', pht('Order %s', $id)); + } + + protected function buildMailBody( + PhabricatorLiskDAO $object, + array $xactions) { + + $body = parent::buildMailBody($object, $xactions); + + $items = array(); + foreach ($object->getPurchases() as $purchase) { + $name = $purchase->getFullDisplayName(); + $price = $purchase->getTotalPriceAsCurrency()->formatForDisplay(); + + $items[] = "{$name} {$price}"; + } + + $body->addTextSection(pht('ORDER CONTENTS'), implode("\n", $items)); + + $body->addTextSection( + pht('ORDER DETAIL'), + PhabricatorEnv::getProductionURI('/phortune/cart/'.$object->getID().'/')); + + return $body; + } + + protected function getMailTo(PhabricatorLiskDAO $object) { + $phids = array(); + + // Relaod the cart to pull merchant and account information, in case we + // just created the object. + $cart = id(new PhortuneCartQuery()) + ->setViewer($this->requireActor()) + ->withPHIDs(array($object->getPHID())) + ->executeOne(); + + foreach ($cart->getAccount()->getMemberPHIDs() as $account_member) { + $phids[] = $account_member; + } + + foreach ($cart->getMerchant()->getMemberPHIDs() as $merchant_member) { + $phids[] = $merchant_member; + } + + return $phids; + } + + protected function getMailCC(PhabricatorLiskDAO $object) { + return array(); + } + + protected function getMailSubjectPrefix() { + return 'Order'; + } + + protected function buildReplyHandler(PhabricatorLiskDAO $object) { + return id(new PhortuneCartReplyHandler()) + ->setMailReceiver($object); + } + } diff --git a/src/applications/phortune/editor/PhortuneMerchantEditor.php b/src/applications/phortune/editor/PhortuneMerchantEditor.php --- a/src/applications/phortune/editor/PhortuneMerchantEditor.php +++ b/src/applications/phortune/editor/PhortuneMerchantEditor.php @@ -111,5 +111,4 @@ return $errors; } - } diff --git a/src/applications/phortune/mail/PhortuneCartReplyHandler.php b/src/applications/phortune/mail/PhortuneCartReplyHandler.php new file mode 100644 --- /dev/null +++ b/src/applications/phortune/mail/PhortuneCartReplyHandler.php @@ -0,0 +1,38 @@ +getDefaultPrivateReplyHandlerEmailAddress($handle, 'CART'); + } + + public function getPublicReplyHandlerEmailAddress() { + return $this->getDefaultPublicReplyHandlerEmailAddress('CART'); + } + + public function getReplyHandlerDomain() { + return PhabricatorEnv::getEnvConfig('metamta.reply-handler-domain'); + } + + public function getReplyHandlerInstructions() { + if ($this->supportsReplies()) { + // TODO: Implement. + return null; + } else { + return null; + } + } + + protected function receiveEmail(PhabricatorMetaMTAReceivedMail $mail) { + // TODO: Implement. + return null; + } + +} 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 @@ -17,6 +17,7 @@ protected $cartClass; protected $status; protected $metadata = array(); + protected $mailKey; private $account = self::ATTACHABLE; private $purchases = self::ATTACHABLE; @@ -514,6 +515,7 @@ self::CONFIG_COLUMN_SCHEMA => array( 'status' => 'text32', 'cartClass' => 'text128', + 'mailKey' => 'bytes20', ), self::CONFIG_KEY_SCHEMA => array( 'key_account' => array( @@ -531,6 +533,13 @@ PhortuneCartPHIDType::TYPECONST); } + public function save() { + if (!$this->getMailKey()) { + $this->setMailKey(Filesystem::readRandomCharacters(20)); + } + return parent::save(); + } + public function attachPurchases(array $purchases) { assert_instances_of($purchases, 'PhortunePurchase'); $this->purchases = $purchases; diff --git a/src/applications/phortune/storage/PhortuneCartTransaction.php b/src/applications/phortune/storage/PhortuneCartTransaction.php --- a/src/applications/phortune/storage/PhortuneCartTransaction.php +++ b/src/applications/phortune/storage/PhortuneCartTransaction.php @@ -22,6 +22,15 @@ return null; } + public function shouldHideForMail(array $xactions) { + switch ($this->getTransactionType()) { + case self::TYPE_CREATED: + return true; + } + + return parent::shouldHideForMail($xactions); + } + public function getTitle() { $old = $this->getOldValue(); $new = $this->getNewValue();