1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-23 05:50:55 +01:00

Update Fund for EditEngine

Summary: Ref T12685, updates fund for edit engine.

Test Plan: Create a Fund, Edit a Fund, wipe out Merchants, check errors for name and missing merchants, back Fund.

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin

Maniphest Tasks: T12685

Differential Revision: https://secure.phabricator.com/D17855
This commit is contained in:
Chad Little 2017-05-08 19:33:55 -07:00
parent f717e4b563
commit 86f9318052
5 changed files with 165 additions and 251 deletions

View file

@ -1141,6 +1141,7 @@ phutil_register_library_map(array(
'FundInitiativeCommentController' => 'applications/fund/controller/FundInitiativeCommentController.php',
'FundInitiativeDescriptionTransaction' => 'applications/fund/xaction/FundInitiativeDescriptionTransaction.php',
'FundInitiativeEditController' => 'applications/fund/controller/FundInitiativeEditController.php',
'FundInitiativeEditEngine' => 'applications/fund/editor/FundInitiativeEditEngine.php',
'FundInitiativeEditor' => 'applications/fund/editor/FundInitiativeEditor.php',
'FundInitiativeFulltextEngine' => 'applications/fund/search/FundInitiativeFulltextEngine.php',
'FundInitiativeListController' => 'applications/fund/controller/FundInitiativeListController.php',
@ -6105,6 +6106,7 @@ phutil_register_library_map(array(
'FundInitiativeCommentController' => 'FundController',
'FundInitiativeDescriptionTransaction' => 'FundInitiativeTransactionType',
'FundInitiativeEditController' => 'FundController',
'FundInitiativeEditEngine' => 'PhabricatorEditEngine',
'FundInitiativeEditor' => 'PhabricatorApplicationTransactionEditor',
'FundInitiativeFulltextEngine' => 'PhabricatorFulltextEngine',
'FundInitiativeListController' => 'FundController',

View file

@ -43,7 +43,8 @@ final class PhabricatorFundApplication extends PhabricatorApplication {
'(?:query/(?P<queryKey>[^/]+)/)?' => 'FundInitiativeListController',
'create/' => 'FundInitiativeEditController',
'comment/(?P<id>[1-9]\d*)/' => 'FundInitiativeCommentController',
'edit/(?:(?P<id>\d+)/)?' => 'FundInitiativeEditController',
$this->getEditRoutePattern('edit/')
=> 'FundInitiativeEditController',
'close/(?P<id>\d+)/' => 'FundInitiativeCloseController',
'back/(?P<id>\d+)/' => 'FundInitiativeBackController',
'backers/(?:(?P<id>\d+)/)?(?:query/(?P<queryKey>[^/]+)/)?'

View file

@ -1,256 +1,11 @@
<?php
final class FundInitiativeEditController
extends FundController {
final class FundInitiativeEditController extends
FundController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
if ($id) {
$initiative = id(new FundInitiativeQuery())
->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$initiative) {
return new Aphront404Response();
}
$is_new = false;
} else {
$initiative = FundInitiative::initializeNewInitiative($viewer);
$is_new = true;
}
if ($is_new) {
$title = pht('Create Initiative');
$button_text = pht('Create Initiative');
$cancel_uri = $this->getApplicationURI();
$header_icon = 'fa-plus-square';
} else {
$title = pht(
'Edit Initiative: %s',
$initiative->getName());
$button_text = pht('Save Changes');
$cancel_uri = '/'.$initiative->getMonogram();
$header_icon = 'fa-pencil';
}
$e_name = true;
$v_name = $initiative->getName();
$e_merchant = null;
$v_merchant = $initiative->getMerchantPHID();
$v_desc = $initiative->getDescription();
$v_risk = $initiative->getRisks();
if ($is_new) {
$v_projects = array();
} else {
$v_projects = PhabricatorEdgeQuery::loadDestinationPHIDs(
$initiative->getPHID(),
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
$v_projects = array_reverse($v_projects);
}
$validation_exception = null;
if ($request->isFormPost()) {
$v_name = $request->getStr('name');
$v_desc = $request->getStr('description');
$v_risk = $request->getStr('risks');
$v_view = $request->getStr('viewPolicy');
$v_edit = $request->getStr('editPolicy');
$v_merchant = $request->getStr('merchantPHID');
$v_projects = $request->getArr('projects');
$type_name = FundInitiativeNameTransaction::TRANSACTIONTYPE;
$type_desc = FundInitiativeDescriptionTransaction::TRANSACTIONTYPE;
$type_risk = FundInitiativeRisksTransaction::TRANSACTIONTYPE;
$type_merchant = FundInitiativeMerchantTransaction::TRANSACTIONTYPE;
$type_view = PhabricatorTransactions::TYPE_VIEW_POLICY;
$type_edit = PhabricatorTransactions::TYPE_EDIT_POLICY;
$xactions = array();
$xactions[] = id(new FundInitiativeTransaction())
->setTransactionType($type_name)
->setNewValue($v_name);
$xactions[] = id(new FundInitiativeTransaction())
->setTransactionType($type_desc)
->setNewValue($v_desc);
$xactions[] = id(new FundInitiativeTransaction())
->setTransactionType($type_risk)
->setNewValue($v_risk);
$xactions[] = id(new FundInitiativeTransaction())
->setTransactionType($type_merchant)
->setNewValue($v_merchant);
$xactions[] = id(new FundInitiativeTransaction())
->setTransactionType($type_view)
->setNewValue($v_view);
$xactions[] = id(new FundInitiativeTransaction())
->setTransactionType($type_edit)
->setNewValue($v_edit);
$proj_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
$xactions[] = id(new FundInitiativeTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
->setMetadataValue('edge:type', $proj_edge_type)
->setNewValue(array('=' => array_fuse($v_projects)));
$editor = id(new FundInitiativeEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true);
try {
$editor->applyTransactions($initiative, $xactions);
return id(new AphrontRedirectResponse())
->setURI('/'.$initiative->getMonogram());
} catch (PhabricatorApplicationTransactionValidationException $ex) {
$validation_exception = $ex;
$e_name = $ex->getShortMessage($type_name);
$e_merchant = $ex->getShortMessage($type_merchant);
$initiative->setViewPolicy($v_view);
$initiative->setEditPolicy($v_edit);
}
}
$policies = id(new PhabricatorPolicyQuery())
->setViewer($viewer)
->setObject($initiative)
->execute();
$merchants = id(new PhortuneMerchantQuery())
->setViewer($viewer)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->execute();
$merchant_options = array();
foreach ($merchants as $merchant) {
$merchant_options[$merchant->getPHID()] = pht(
'Merchant %d %s',
$merchant->getID(),
$merchant->getName());
}
if ($v_merchant && empty($merchant_options[$v_merchant])) {
$merchant_options = array(
$v_merchant => pht('(Restricted Merchant)'),
) + $merchant_options;
}
if (!$merchant_options) {
return $this->newDialog()
->setTitle(pht('No Valid Phortune Merchant Accounts'))
->appendParagraph(
pht(
'You do not control any merchant accounts which can receive '.
'payments from this initiative. When you create an initiative, '.
'you need to specify a merchant account where funds will be paid '.
'to.'))
->appendParagraph(
pht(
'Create a merchant account in the Phortune application before '.
'creating an initiative in Fund.'))
->addCancelButton($this->getApplicationURI());
}
$form = id(new AphrontFormView())
->setUser($viewer)
->appendChild(
id(new AphrontFormTextControl())
->setName('name')
->setLabel(pht('Name'))
->setValue($v_name)
->setError($e_name))
->appendChild(
id(new AphrontFormSelectControl())
->setName('merchantPHID')
->setLabel(pht('Pay To Merchant'))
->setValue($v_merchant)
->setError($e_merchant)
->setOptions($merchant_options))
->appendChild(
id(new PhabricatorRemarkupControl())
->setUser($viewer)
->setName('description')
->setLabel(pht('Description'))
->setValue($v_desc))
->appendChild(
id(new PhabricatorRemarkupControl())
->setUser($viewer)
->setName('risks')
->setLabel(pht('Risks/Challenges'))
->setValue($v_risk))
->appendControl(
id(new AphrontFormTokenizerControl())
->setLabel(pht('Tags'))
->setName('projects')
->setValue($v_projects)
->setDatasource(new PhabricatorProjectDatasource()))
->appendChild(
id(new AphrontFormPolicyControl())
->setName('viewPolicy')
->setPolicyObject($initiative)
->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
->setPolicies($policies))
->appendChild(
id(new AphrontFormPolicyControl())
->setName('editPolicy')
->setPolicyObject($initiative)
->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
->setPolicies($policies))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue($button_text)
->addCancelButton($cancel_uri));
$crumbs = $this->buildApplicationCrumbs();
if ($is_new) {
$crumbs->addTextCrumb(pht('Create Initiative'));
} else {
$crumbs->addTextCrumb(
$initiative->getMonogram(),
'/'.$initiative->getMonogram());
$crumbs->addTextCrumb(pht('Edit'));
}
$crumbs->setBorder(true);
$box = id(new PHUIObjectBoxView())
->setValidationException($validation_exception)
->setHeaderText(pht('Initiative'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->appendChild($form);
$header = id(new PHUIHeaderView())
->setHeader($title)
->setHeaderIcon($header_icon);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setFooter($box);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
return id(new FundInitiativeEditEngine())
->setController($this)
->buildResponse();
}
}

View file

@ -0,0 +1,152 @@
<?php
final class FundInitiativeEditEngine
extends PhabricatorEditEngine {
const ENGINECONST = 'fund.initiative';
public function getEngineName() {
return pht('Fund');
}
public function getEngineApplicationClass() {
return 'PhabricatorFundApplication';
}
public function getSummaryHeader() {
return pht('Configure Fund Forms');
}
public function getSummaryText() {
return pht('Configure creation and editing forms in Fund.');
}
public function isEngineConfigurable() {
return false;
}
protected function newEditableObject() {
return FundInitiative::initializeNewInitiative($this->getViewer());
}
protected function newObjectQuery() {
return new FundInitiativeQuery();
}
protected function getObjectCreateTitleText($object) {
return pht('Create New Initiative');
}
protected function getObjectEditTitleText($object) {
return pht('Edit Initiative: %s', $object->getName());
}
protected function getObjectEditShortText($object) {
return $object->getName();
}
protected function getObjectCreateShortText() {
return pht('Create Initiative');
}
protected function getObjectName() {
return pht('Initivative');
}
protected function getObjectCreateCancelURI($object) {
return $this->getApplication()->getApplicationURI('/');
}
protected function getEditorURI() {
return $this->getApplication()->getApplicationURI('edit/');
}
protected function getObjectViewURI($object) {
return $object->getViewURI();
}
protected function getCreateNewObjectPolicy() {
return $this->getApplication()->getPolicy(
FundCreateInitiativesCapability::CAPABILITY);
}
protected function buildCustomEditFields($object) {
$viewer = $this->getViewer();
$v_merchant = $object->getMerchantPHID();
$merchants = id(new PhortuneMerchantQuery())
->setViewer($viewer)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->execute();
$merchant_options = array();
foreach ($merchants as $merchant) {
$merchant_options[$merchant->getPHID()] = pht(
'Merchant %d %s',
$merchant->getID(),
$merchant->getName());
}
if ($v_merchant && empty($merchant_options[$v_merchant])) {
$merchant_options = array(
$v_merchant => pht('(Restricted Merchant)'),
) + $merchant_options;
}
$merchant_instructions = null;
if (!$merchant_options) {
$merchant_instructions = pht(
'NOTE: You do not control any merchant accounts which can receive '.
'payments from this initiative. When you create an initiative, '.
'you need to specify a merchant account where funds will be paid '.
'to. Create a merchant account in the Phortune application before '.
'creating an initiative in Fund.');
}
return array(
id(new PhabricatorTextEditField())
->setKey('name')
->setLabel(pht('Name'))
->setDescription(pht('Initiative name.'))
->setConduitTypeDescription(pht('New initiative name.'))
->setTransactionType(
FundInitiativeNameTransaction::TRANSACTIONTYPE)
->setValue($object->getName())
->setIsRequired(true),
id(new PhabricatorSelectEditField())
->setKey('merchantPHID')
->setLabel(pht('Merchant'))
->setDescription(pht('Merchant operating the initiative.'))
->setConduitTypeDescription(pht('New initiative merchant.'))
->setControlInstructions($merchant_instructions)
->setValue($object->getMerchantPHID())
->setTransactionType(
FundInitiativeMerchantTransaction::TRANSACTIONTYPE)
->setOptions($merchant_options)
->setIsRequired(true),
id(new PhabricatorRemarkupEditField())
->setKey('description')
->setLabel(pht('Description'))
->setDescription(pht('Initiative long description.'))
->setConduitTypeDescription(pht('New initiative description.'))
->setTransactionType(
FundInitiativeDescriptionTransaction::TRANSACTIONTYPE)
->setValue($object->getDescription()),
id(new PhabricatorRemarkupEditField())
->setKey('risks')
->setLabel(pht('Risks/Challenges'))
->setDescription(pht('Initiative risks and challenges.'))
->setConduitTypeDescription(pht('Initiative risks and challenges.'))
->setTransactionType(
FundInitiativeRisksTransaction::TRANSACTIONTYPE)
->setValue($object->getRisks()),
);
}
}

View file

@ -85,6 +85,10 @@ final class FundInitiative extends FundDAO
return 'I'.$this->getID();
}
public function getViewURI() {
return '/'.$this->getMonogram();
}
public function getProjectPHIDs() {
return $this->assertAttached($this->projectPHIDs);
}