diff --git a/resources/sql/autopatches/20140911.fund.4.backer.sql b/resources/sql/autopatches/20140911.fund.4.backer.sql new file mode 100644 index 0000000000..1dd6815192 --- /dev/null +++ b/resources/sql/autopatches/20140911.fund.4.backer.sql @@ -0,0 +1,14 @@ +CREATE TABLE {$NAMESPACE}_fund.fund_backer ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + phid VARCHAR(64) NOT NULL COLLATE utf8_bin, + initiativePHID VARCHAR(64) NOT NULL COLLATE utf8_bin, + backerPHID VARCHAR(64) NOT NULL COLLATE utf8_bin, + status VARCHAR(32) NOT NULL COLLATE utf8_bin, + amountInCents INT UNSIGNED NOT NULL, + properties LONGTEXT NOT NULL COLLATE utf8_bin, + dateCreated INT UNSIGNED NOT NULL, + dateModified INT UNSIGNED NOT NULL, + UNIQUE KEY `key_phid` (phid), + KEY `key_initiative` (initiativePHID), + KEY `key_backer` (backerPHID) +) ENGINE=InnoDB, COLLATE utf8_general_ci; diff --git a/resources/sql/autopatches/20140911.fund.5.backxaction.sql b/resources/sql/autopatches/20140911.fund.5.backxaction.sql new file mode 100644 index 0000000000..e9b5acbc0c --- /dev/null +++ b/resources/sql/autopatches/20140911.fund.5.backxaction.sql @@ -0,0 +1,19 @@ +CREATE TABLE {$NAMESPACE}_fund.fund_backertransaction ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + phid VARCHAR(64) COLLATE utf8_bin NOT NULL, + authorPHID VARCHAR(64) COLLATE utf8_bin NOT NULL, + objectPHID VARCHAR(64) COLLATE utf8_bin NOT NULL, + viewPolicy VARCHAR(64) COLLATE utf8_bin NOT NULL, + editPolicy VARCHAR(64) COLLATE utf8_bin NOT NULL, + commentPHID VARCHAR(64) COLLATE utf8_bin DEFAULT NULL, + commentVersion INT UNSIGNED NOT NULL, + transactionType VARCHAR(32) COLLATE utf8_bin NOT NULL, + oldValue LONGTEXT COLLATE utf8_bin NOT NULL, + newValue LONGTEXT COLLATE utf8_bin NOT NULL, + contentSource LONGTEXT COLLATE utf8_bin NOT NULL, + metadata LONGTEXT COLLATE utf8_bin NOT NULL, + dateCreated INT UNSIGNED NOT NULL, + dateModified INT UNSIGNED NOT NULL, + UNIQUE KEY `key_phid` (`phid`), + KEY `key_object` (`objectPHID`) +) ENGINE=InnoDB, COLLATE utf8_general_ci; diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 5be56d262c..f7039595d4 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -654,17 +654,20 @@ phutil_register_library_map(array( 'FlagDeleteConduitAPIMethod' => 'applications/flag/conduit/FlagDeleteConduitAPIMethod.php', 'FlagEditConduitAPIMethod' => 'applications/flag/conduit/FlagEditConduitAPIMethod.php', 'FlagQueryConduitAPIMethod' => 'applications/flag/conduit/FlagQueryConduitAPIMethod.php', - 'FundBacking' => 'applications/fund/storage/FundBacking.php', - 'FundBackingEditor' => 'applications/fund/editor/FundBackingEditor.php', - 'FundBackingPHIDType' => 'applications/fund/phid/FundBackingPHIDType.php', - 'FundBackingQuery' => 'applications/fund/query/FundBackingQuery.php', - 'FundBackingTransaction' => 'applications/fund/storage/FundBackingTransaction.php', - 'FundBackingTransactionQuery' => 'applications/fund/query/FundBackingTransactionQuery.php', + 'FundBacker' => 'applications/fund/storage/FundBacker.php', + 'FundBackerEditor' => 'applications/fund/editor/FundBackerEditor.php', + 'FundBackerListController' => 'applications/fund/controller/FundBackerListController.php', + 'FundBackerPHIDType' => 'applications/fund/phid/FundBackerPHIDType.php', + 'FundBackerQuery' => 'applications/fund/query/FundBackerQuery.php', + 'FundBackerSearchEngine' => 'applications/fund/query/FundBackerSearchEngine.php', + 'FundBackerTransaction' => 'applications/fund/storage/FundBackerTransaction.php', + 'FundBackerTransactionQuery' => 'applications/fund/query/FundBackerTransactionQuery.php', 'FundController' => 'applications/fund/controller/FundController.php', 'FundCreateInitiativesCapability' => 'applications/fund/capability/FundCreateInitiativesCapability.php', 'FundDAO' => 'applications/fund/storage/FundDAO.php', 'FundDefaultViewCapability' => 'applications/fund/capability/FundDefaultViewCapability.php', 'FundInitiative' => 'applications/fund/storage/FundInitiative.php', + 'FundInitiativeBackController' => 'applications/fund/controller/FundInitiativeBackController.php', 'FundInitiativeCloseController' => 'applications/fund/controller/FundInitiativeCloseController.php', 'FundInitiativeEditController' => 'applications/fund/controller/FundInitiativeEditController.php', 'FundInitiativeEditor' => 'applications/fund/editor/FundInitiativeEditor.php', @@ -3445,16 +3448,18 @@ phutil_register_library_map(array( 'FlagDeleteConduitAPIMethod' => 'FlagConduitAPIMethod', 'FlagEditConduitAPIMethod' => 'FlagConduitAPIMethod', 'FlagQueryConduitAPIMethod' => 'FlagConduitAPIMethod', - 'FundBacking' => array( + 'FundBacker' => array( 'FundDAO', 'PhabricatorPolicyInterface', 'PhabricatorApplicationTransactionInterface', ), - 'FundBackingEditor' => 'PhabricatorApplicationTransactionEditor', - 'FundBackingPHIDType' => 'PhabricatorPHIDType', - 'FundBackingQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', - 'FundBackingTransaction' => 'PhabricatorApplicationTransaction', - 'FundBackingTransactionQuery' => 'PhabricatorApplicationTransactionQuery', + 'FundBackerEditor' => 'PhabricatorApplicationTransactionEditor', + 'FundBackerListController' => 'FundController', + 'FundBackerPHIDType' => 'PhabricatorPHIDType', + 'FundBackerQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', + 'FundBackerSearchEngine' => 'PhabricatorApplicationSearchEngine', + 'FundBackerTransaction' => 'PhabricatorApplicationTransaction', + 'FundBackerTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'FundController' => 'PhabricatorController', 'FundCreateInitiativesCapability' => 'PhabricatorPolicyCapability', 'FundDAO' => 'PhabricatorLiskDAO', @@ -3470,6 +3475,7 @@ phutil_register_library_map(array( 'PhabricatorTokenReceiverInterface', 'PhabricatorDestructibleInterface', ), + 'FundInitiativeBackController' => 'FundController', 'FundInitiativeCloseController' => 'FundController', 'FundInitiativeEditController' => 'FundController', 'FundInitiativeEditor' => 'PhabricatorApplicationTransactionEditor', diff --git a/src/applications/fund/application/PhabricatorFundApplication.php b/src/applications/fund/application/PhabricatorFundApplication.php index 38da9b812a..e1a04520b8 100644 --- a/src/applications/fund/application/PhabricatorFundApplication.php +++ b/src/applications/fund/application/PhabricatorFundApplication.php @@ -42,8 +42,11 @@ final class PhabricatorFundApplication extends PhabricatorApplication { '/fund/' => array( '(?:query/(?P[^/]+)/)?' => 'FundInitiativeListController', 'create/' => 'FundInitiativeEditController', - 'edit/(?:(?P[^/]+)/)?' => 'FundInitiativeEditController', - 'close/(?P[^/]+)/' => 'FundInitiativeCloseController', + 'edit/(?:(?P\d+)/)?' => 'FundInitiativeEditController', + 'close/(?P\d+)/' => 'FundInitiativeCloseController', + 'back/(?P\d+)/' => 'FundInitiativeBackController', + 'backers/(?:(?P\d+)/)?(?:query/(?P[^/]+)/)?' + => 'FundBackerListController', ), ); } diff --git a/src/applications/fund/controller/FundBackerListController.php b/src/applications/fund/controller/FundBackerListController.php new file mode 100644 index 0000000000..157e1be4b0 --- /dev/null +++ b/src/applications/fund/controller/FundBackerListController.php @@ -0,0 +1,78 @@ +id = idx($data, 'id'); + $this->queryKey = idx($data, 'queryKey'); + } + + public function processRequest() { + $request = $this->getRequest(); + + if ($this->id) { + $this->initiative = id(new FundInitiativeQuery()) + ->setViewer($request->getUser()) + ->withIDs(array($this->id)) + ->executeOne(); + if (!$this->initiative) { + return new Aphront404Response(); + } + } + + $controller = id(new PhabricatorApplicationSearchController($request)) + ->setQueryKey($this->queryKey) + ->setSearchEngine($this->getEngine()) + ->setNavigation($this->buildSideNavView()); + + return $this->delegateToController($controller); + } + + public function buildSideNavView() { + $user = $this->getRequest()->getUser(); + + $nav = new AphrontSideNavFilterView(); + $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); + + $this->getEngine()->addNavigationItems($nav->getMenu()); + + $nav->selectFilter(null); + + return $nav; + } + + protected function buildApplicationCrumbs() { + $crumbs = parent::buildApplicationCrumbs(); + $crumbs->addTextCrumb( + pht('Backers'), + $this->getApplicationURI('backers/')); + + if ($this->initiative) { + $crumbs->addTextCrumb( + $this->initiative->getMonogram(), + '/'.$this->initiative->getMonogram()); + } + + return $crumbs; + } + + private function getEngine() { + $request = $this->getRequest(); + $viewer = $request->getUser(); + + $engine = id(new FundBackerSearchEngine()) + ->setViewer($viewer); + + if ($this->initiative) { + $engine->setInitiative($this->initiative); + } + + return $engine; + } + +} diff --git a/src/applications/fund/controller/FundInitiativeBackController.php b/src/applications/fund/controller/FundInitiativeBackController.php new file mode 100644 index 0000000000..042cf2eb0a --- /dev/null +++ b/src/applications/fund/controller/FundInitiativeBackController.php @@ -0,0 +1,100 @@ +id = $data['id']; + } + + public function processRequest() { + $request = $this->getRequest(); + $viewer = $request->getUser(); + + $initiative = id(new FundInitiativeQuery()) + ->setViewer($viewer) + ->withIDs(array($this->id)) + ->executeOne(); + if (!$initiative) { + return new Aphront404Response(); + } + + $initiative_uri = '/'.$initiative->getMonogram(); + + if ($initiative->isClosed()) { + return $this->newDialog() + ->setTitle(pht('Initiative Closed')) + ->appendParagraph( + pht('You can not back a closed initiative.')) + ->addCancelButton($initiative_uri); + } + + $v_amount = null; + $e_amount = true; + $errors = array(); + if ($request->isFormPost()) { + $v_amount = $request->getStr('amount'); + + if (!strlen($v_amount)) { + $errors[] = pht( + 'You must specify how much money you want to contribute to the '. + 'initiative.'); + $e_amount = pht('Required'); + } else { + try { + $currency = PhortuneCurrency::newFromUserInput( + $viewer, + $v_amount); + } catch (Exception $ex) { + $errors[] = $ex->getMessage(); + $e_amount = pht('Invalid'); + } + } + + if (!$errors) { + $backer = FundBacker::initializeNewBacker($viewer) + ->setInitiativePHID($initiative->getPHID()) + ->attachInitiative($initiative) + ->setAmountInCents($currency->getValue()) + ->save(); + + // TODO: Here, we'd create a purchase and cart. + + $xactions = array(); + + $xactions[] = id(new FundBackerTransaction()) + ->setTransactionType(FundBackerTransaction::TYPE_STATUS) + ->setNewValue(FundBacker::STATUS_IN_CART); + + $editor = id(new FundBackerEditor()) + ->setActor($viewer) + ->setContentSourceFromRequest($request); + + $editor->applyTransactions($backer, $xactions); + + // TODO: Here, we'd ship the user into Phortune. + + return id(new AphrontRedirectResponse())->setURI($initiative_uri); + } + } + + $form = id(new AphrontFormView()) + ->setUser($viewer) + ->appendChild( + id(new AphrontFormTextControl()) + ->setName('amount') + ->setLabel(pht('Amount')) + ->setValue($v_amount) + ->setError($e_amount)); + + return $this->newDialog() + ->setTitle(pht('Back Initiative')) + ->setErrors($errors) + ->appendChild($form->buildLayoutView()) + ->addCancelButton($initiative_uri) + ->addSubmitButton(pht('Continue')); + } + +} diff --git a/src/applications/fund/controller/FundInitiativeCloseController.php b/src/applications/fund/controller/FundInitiativeCloseController.php index 860f52707b..803b6242cf 100644 --- a/src/applications/fund/controller/FundInitiativeCloseController.php +++ b/src/applications/fund/controller/FundInitiativeCloseController.php @@ -55,7 +55,9 @@ final class FundInitiativeCloseController if ($is_close) { $title = pht('Close Initiative?'); - $body = pht('Really close this initiative?'); + $body = pht( + 'Really close this initiative? Users will no longer be able to '. + 'back it.'); $button_text = pht('Close Initiative'); } else { $title = pht('Reopen Initiative?'); diff --git a/src/applications/fund/controller/FundInitiativeListController.php b/src/applications/fund/controller/FundInitiativeListController.php index c14bf986cc..ad7fd1cf97 100644 --- a/src/applications/fund/controller/FundInitiativeListController.php +++ b/src/applications/fund/controller/FundInitiativeListController.php @@ -28,6 +28,10 @@ final class FundInitiativeListController id(new FundInitiativeSearchEngine()) ->setViewer($user) ->addNavigationItems($nav->getMenu()); + + $nav->addLabel(pht('Backers')); + $nav->addFilter('backers/', pht('Find Backers')); + $nav->selectFilter(null); return $nav; diff --git a/src/applications/fund/controller/FundInitiativeViewController.php b/src/applications/fund/controller/FundInitiativeViewController.php index 794380e409..ad2f8bf471 100644 --- a/src/applications/fund/controller/FundInitiativeViewController.php +++ b/src/applications/fund/controller/FundInitiativeViewController.php @@ -143,6 +143,20 @@ final class FundInitiativeViewController ->setWorkflow(true) ->setHref($this->getApplicationURI("/close/{$id}/"))); + $view->addAction( + id(new PhabricatorActionView()) + ->setName(pht('Back Initiative')) + ->setIcon('fa-money') + ->setDisabled($initiative->isClosed()) + ->setWorkflow(true) + ->setHref($this->getApplicationURI("/back/{$id}/"))); + + $view->addAction( + id(new PhabricatorActionView()) + ->setName(pht('View Backers')) + ->setIcon('fa-bank') + ->setHref($this->getApplicationURI("/backers/{$id}/"))); + return $view; } diff --git a/src/applications/fund/editor/FundBackerEditor.php b/src/applications/fund/editor/FundBackerEditor.php new file mode 100644 index 0000000000..067f9ce64c --- /dev/null +++ b/src/applications/fund/editor/FundBackerEditor.php @@ -0,0 +1,69 @@ +getTransactionType()) { + case FundBackerTransaction::TYPE_STATUS: + return $object->getStatus(); + } + + return parent::getCustomTransactionOldValue($object, $xaction); + } + + protected function getCustomTransactionNewValue( + PhabricatorLiskDAO $object, + PhabricatorApplicationTransaction $xaction) { + + switch ($xaction->getTransactionType()) { + case FundBackerTransaction::TYPE_STATUS: + return $xaction->getNewValue(); + } + + return parent::getCustomTransactionNewValue($object, $xaction); + } + + protected function applyCustomInternalTransaction( + PhabricatorLiskDAO $object, + PhabricatorApplicationTransaction $xaction) { + + switch ($xaction->getTransactionType()) { + case FundBackerTransaction::TYPE_STATUS: + $object->setStatus($xaction->getNewValue()); + return; + } + + return parent::applyCustomInternalTransaction($object, $xaction); + } + + protected function applyCustomExternalTransaction( + PhabricatorLiskDAO $object, + PhabricatorApplicationTransaction $xaction) { + + switch ($xaction->getTransactionType()) { + case FundBackerTransaction::TYPE_STATUS: + return; + } + + return parent::applyCustomExternalTransaction($object, $xaction); + } + +} diff --git a/src/applications/fund/editor/FundBackingEditor.php b/src/applications/fund/editor/FundBackingEditor.php deleted file mode 100644 index bd34e0a8d5..0000000000 --- a/src/applications/fund/editor/FundBackingEditor.php +++ /dev/null @@ -1,13 +0,0 @@ -ids = $ids; + return $this; + } + + public function withPHIDs(array $phids) { + $this->phids = $phids; + return $this; + } + + public function withInitiativePHIDs(array $phids) { + $this->initiativePHIDs = $phids; + return $this; + } + + public function withBackerPHIDs(array $phids) { + $this->backerPHIDs = $phids; + return $this; + } + + protected function loadPage() { + $table = new FundBacker(); + $conn_r = $table->establishConnection('r'); + + $rows = queryfx_all( + $conn_r, + 'SELECT * FROM %T %Q %Q %Q', + $table->getTableName(), + $this->buildWhereClause($conn_r), + $this->buildOrderClause($conn_r), + $this->buildLimitClause($conn_r)); + + return $table->loadAllFromArray($rows); + } + + protected function willFilterPage(array $backers) { + $initiative_phids = mpull($backers, 'getInitiativePHID'); + $initiatives = id(new PhabricatorObjectQuery()) + ->setParentQuery($this) + ->setViewer($this->getViewer()) + ->withPHIDs($initiative_phids) + ->execute(); + $initiatives = mpull($initiatives, null, 'getPHID'); + + foreach ($backers as $backer) { + $initiative_phid = $backer->getInitiativePHID(); + $initiative = idx($initiatives, $initiative_phid); + $backer->attachInitiative($initiative); + } + + return $backers; + } + + private function buildWhereClause(AphrontDatabaseConnection $conn_r) { + $where = array(); + + $where[] = $this->buildPagingClause($conn_r); + + if ($this->ids !== null) { + $where[] = qsprintf( + $conn_r, + 'id IN (%Ld)', + $this->ids); + } + + if ($this->phids !== null) { + $where[] = qsprintf( + $conn_r, + 'phid IN (%Ls)', + $this->phids); + } + + if ($this->initiativePHIDs !== null) { + $where[] = qsprintf( + $conn_r, + 'initiativePHID IN (%Ls)', + $this->initiativePHIDs); + } + + if ($this->backerPHIDs !== null) { + $where[] = qsprintf( + $conn_r, + 'backerPHID IN (%Ls)', + $this->backerPHIDs); + } + + return $this->formatWhereClause($where); + } + + public function getQueryApplicationClass() { + return 'PhabricatorFundApplication'; + } + +} diff --git a/src/applications/fund/query/FundBackerSearchEngine.php b/src/applications/fund/query/FundBackerSearchEngine.php new file mode 100644 index 0000000000..6c3469afff --- /dev/null +++ b/src/applications/fund/query/FundBackerSearchEngine.php @@ -0,0 +1,153 @@ +initiative = $initiative; + return $this; + } + + public function getInitiative() { + return $this->initiative; + } + + public function getResultTypeDescription() { + return pht('Fund Backers'); + } + + public function getApplicationClassName() { + return 'PhabricatorFundApplication'; + } + + public function buildSavedQueryFromRequest(AphrontRequest $request) { + $saved = new PhabricatorSavedQuery(); + + $saved->setParameter( + 'backerPHIDs', + $this->readUsersFromRequest($request, 'backers')); + + return $saved; + } + + public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { + $query = id(new FundBackerQuery()); + + if ($this->getInitiative()) { + $query->withInitiativePHIDs( + array( + $this->getInitiative()->getPHID(), + )); + } + + $backer_phids = $saved->getParameter('backerPHIDs'); + if ($backer_phids) { + $query->withBackerPHIDs($backer_phids); + } + + return $query; + } + + public function buildSearchForm( + AphrontFormView $form, + PhabricatorSavedQuery $saved) { + + + $backer_phids = $saved->getParameter('backerPHIDs', array()); + + $all_phids = array_mergev( + array( + $backer_phids, + )); + + $handles = id(new PhabricatorHandleQuery()) + ->setViewer($this->requireViewer()) + ->withPHIDs($all_phids) + ->execute(); + + $form + ->appendChild( + id(new AphrontFormTokenizerControl()) + ->setLabel(pht('Backers')) + ->setName('backers') + ->setDatasource(new PhabricatorPeopleDatasource()) + ->setValue(array_select_keys($handles, $backer_phids))); + } + + protected function getURI($path) { + if ($this->getInitiative()) { + return '/fund/backers/'.$this->getInitiative()->getID().'/'.$path; + } else { + return '/fund/backers/'.$path; + } + } + + public function getBuiltinQueryNames() { + $names = array(); + $names['all'] = pht('All Backers'); + + return $names; + } + + public function buildSavedQueryFromBuiltin($query_key) { + $query = $this->newSavedQuery(); + $query->setQueryKey($query_key); + + switch ($query_key) { + case 'all': + return $query; + } + + return parent::buildSavedQueryFromBuiltin($query_key); + } + + protected function getRequiredHandlePHIDsForResultList( + array $backers, + PhabricatorSavedQuery $query) { + + $phids = array(); + foreach ($backers as $backer) { + $phids[] = $backer->getBackerPHID(); + $phids[] = $backer->getInitiativePHID(); + } + + return $phids; + } + + protected function renderResultList( + array $backers, + PhabricatorSavedQuery $query, + array $handles) { + assert_instances_of($backers, 'FundBacker'); + + $viewer = $this->requireViewer(); + + $list = id(new PHUIObjectItemListView()); + foreach ($backers as $backer) { + $backer_handle = $handles[$backer->getBackerPHID()]; + + $currency = PhortuneCurrency::newFromUSDCents( + $backer->getAmountInCents()); + + $header = pht( + '%s for %s', + $currency->formatForDisplay(), + $handles[$backer->getInitiativePHID()]->renderLink()); + + $item = id(new PHUIObjectItemView()) + ->setHeader($header) + ->addIcon( + 'none', + phabricator_datetime($backer->getDateCreated(), $viewer)) + ->addByline(pht('Backer: %s', $backer_handle->renderLink())); + + $list->addItem($item); + } + + + return $list; + } + +} diff --git a/src/applications/fund/query/FundBackingTransactionQuery.php b/src/applications/fund/query/FundBackerTransactionQuery.php similarity index 60% rename from src/applications/fund/query/FundBackingTransactionQuery.php rename to src/applications/fund/query/FundBackerTransactionQuery.php index 34ad3ea647..9ba1506add 100644 --- a/src/applications/fund/query/FundBackingTransactionQuery.php +++ b/src/applications/fund/query/FundBackerTransactionQuery.php @@ -1,10 +1,10 @@ ids = $ids; - return $this; - } - - public function withPHIDs(array $phids) { - $this->phids = $phids; - return $this; - } - - protected function loadPage() { - $table = new FundBacking(); - $conn_r = $table->establishConnection('r'); - - $rows = queryfx_all( - $conn_r, - 'SELECT * FROM %T %Q %Q %Q', - $table->getTableName(), - $this->buildWhereClause($conn_r), - $this->buildOrderClause($conn_r), - $this->buildLimitClause($conn_r)); - - return $table->loadAllFromArray($rows); - } - - private function buildWhereClause(AphrontDatabaseConnection $conn_r) { - $where = array(); - - $where[] = $this->buildPagingClause($conn_r); - - if ($this->ids !== null) { - $where[] = qsprintf( - $conn_r, - 'id IN (%Ld)', - $this->ids); - } - - if ($this->phids !== null) { - $where[] = qsprintf( - $conn_r, - 'phid IN (%Ls)', - $this->phids); - } - - return $this->formatWhereClause($where); - } - - public function getQueryApplicationClass() { - return 'PhabricatorFundApplication'; - } - -} diff --git a/src/applications/fund/storage/FundBacking.php b/src/applications/fund/storage/FundBacker.php similarity index 65% rename from src/applications/fund/storage/FundBacking.php rename to src/applications/fund/storage/FundBacker.php index 31104bf2ed..4cdaafb9bd 100644 --- a/src/applications/fund/storage/FundBacking.php +++ b/src/applications/fund/storage/FundBacker.php @@ -1,27 +1,43 @@ setBackerPHID($actor->getPHID()) + ->setStatus(self::STATUS_NEW); + } + public function getConfiguration() { return array( self::CONFIG_AUX_PHID => true, + self::CONFIG_SERIALIZATION => array( + 'properties' => self::SERIALIZATION_JSON, + ), ) + parent::getConfiguration(); } public function generatePHID() { - return PhabricatorPHID::generateNewPHID(FundBackingPHIDType::TYPECONST); + return PhabricatorPHID::generateNewPHID(FundBackerPHIDType::TYPECONST); + } + + protected function didReadData() { + // The payment processing code is strict about types. + $this->amountInCents = (int)$this->amountInCents; } public function getProperty($key, $default = null) { @@ -33,6 +49,15 @@ final class FundBacking extends FundDAO return $this; } + public function getInitiative() { + return $this->assertAttached($this->initiative); + } + + public function attachInitiative(FundInitiative $initiative = null) { + $this->initiative = $initiative; + return $this; + } + /* -( PhabricatorPolicyInterface )----------------------------------------- */ @@ -48,7 +73,7 @@ final class FundBacking extends FundDAO case PhabricatorPolicyCapability::CAN_VIEW: // If we have the initiative, use the initiative's policy. // Otherwise, return NOONE. This allows the backer to continue seeing - // a backing even if they're no longer allowed to see the initiative. + // a backer even if they're no longer allowed to see the initiative. $initiative = $this->getInitiative(); if ($initiative) { @@ -71,7 +96,7 @@ final class FundBacking extends FundDAO public function getApplicationTransactionEditor() { - return new FundBackingEditor(); + return new FundBackerEditor(); } public function getApplicationTransactionObject() { @@ -79,7 +104,7 @@ final class FundBacking extends FundDAO } public function getApplicationTransactionTemplate() { - return new FundBackingTransaction(); + return new FundBackerTransaction(); } } diff --git a/src/applications/fund/storage/FundBackingTransaction.php b/src/applications/fund/storage/FundBackerTransaction.php similarity index 68% rename from src/applications/fund/storage/FundBackingTransaction.php rename to src/applications/fund/storage/FundBackerTransaction.php index 79fd55f0bd..28aed38d29 100644 --- a/src/applications/fund/storage/FundBackingTransaction.php +++ b/src/applications/fund/storage/FundBackerTransaction.php @@ -1,14 +1,16 @@ getPHID() == $this->getOwnerPHID()); } public function describeAutomaticCapability($capability) { - return null; + return pht( + 'The owner of an initiative can always view and edit it.'); }