@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+165 -251
+2
src/__phutil_library_map__.php
··· 1141 1141 'FundInitiativeCommentController' => 'applications/fund/controller/FundInitiativeCommentController.php', 1142 1142 'FundInitiativeDescriptionTransaction' => 'applications/fund/xaction/FundInitiativeDescriptionTransaction.php', 1143 1143 'FundInitiativeEditController' => 'applications/fund/controller/FundInitiativeEditController.php', 1144 + 'FundInitiativeEditEngine' => 'applications/fund/editor/FundInitiativeEditEngine.php', 1144 1145 'FundInitiativeEditor' => 'applications/fund/editor/FundInitiativeEditor.php', 1145 1146 'FundInitiativeFulltextEngine' => 'applications/fund/search/FundInitiativeFulltextEngine.php', 1146 1147 'FundInitiativeListController' => 'applications/fund/controller/FundInitiativeListController.php', ··· 6105 6106 'FundInitiativeCommentController' => 'FundController', 6106 6107 'FundInitiativeDescriptionTransaction' => 'FundInitiativeTransactionType', 6107 6108 'FundInitiativeEditController' => 'FundController', 6109 + 'FundInitiativeEditEngine' => 'PhabricatorEditEngine', 6108 6110 'FundInitiativeEditor' => 'PhabricatorApplicationTransactionEditor', 6109 6111 'FundInitiativeFulltextEngine' => 'PhabricatorFulltextEngine', 6110 6112 'FundInitiativeListController' => 'FundController',
+2 -1
src/applications/fund/application/PhabricatorFundApplication.php
··· 43 43 '(?:query/(?P<queryKey>[^/]+)/)?' => 'FundInitiativeListController', 44 44 'create/' => 'FundInitiativeEditController', 45 45 'comment/(?P<id>[1-9]\d*)/' => 'FundInitiativeCommentController', 46 - 'edit/(?:(?P<id>\d+)/)?' => 'FundInitiativeEditController', 46 + $this->getEditRoutePattern('edit/') 47 + => 'FundInitiativeEditController', 47 48 'close/(?P<id>\d+)/' => 'FundInitiativeCloseController', 48 49 'back/(?P<id>\d+)/' => 'FundInitiativeBackController', 49 50 'backers/(?:(?P<id>\d+)/)?(?:query/(?P<queryKey>[^/]+)/)?'
+5 -250
src/applications/fund/controller/FundInitiativeEditController.php
··· 1 1 <?php 2 2 3 - final class FundInitiativeEditController 4 - extends FundController { 5 - 3 + final class FundInitiativeEditController extends 4 + FundController { 6 5 public function handleRequest(AphrontRequest $request) { 7 - $viewer = $request->getViewer(); 8 - $id = $request->getURIData('id'); 9 - 10 - if ($id) { 11 - $initiative = id(new FundInitiativeQuery()) 12 - ->setViewer($viewer) 13 - ->withIDs(array($id)) 14 - ->requireCapabilities( 15 - array( 16 - PhabricatorPolicyCapability::CAN_VIEW, 17 - PhabricatorPolicyCapability::CAN_EDIT, 18 - )) 19 - ->executeOne(); 20 - if (!$initiative) { 21 - return new Aphront404Response(); 22 - } 23 - $is_new = false; 24 - } else { 25 - $initiative = FundInitiative::initializeNewInitiative($viewer); 26 - $is_new = true; 27 - } 28 - 29 - if ($is_new) { 30 - $title = pht('Create Initiative'); 31 - $button_text = pht('Create Initiative'); 32 - $cancel_uri = $this->getApplicationURI(); 33 - $header_icon = 'fa-plus-square'; 34 - } else { 35 - $title = pht( 36 - 'Edit Initiative: %s', 37 - $initiative->getName()); 38 - $button_text = pht('Save Changes'); 39 - $cancel_uri = '/'.$initiative->getMonogram(); 40 - $header_icon = 'fa-pencil'; 41 - } 42 - 43 - $e_name = true; 44 - $v_name = $initiative->getName(); 45 - 46 - $e_merchant = null; 47 - $v_merchant = $initiative->getMerchantPHID(); 48 - 49 - $v_desc = $initiative->getDescription(); 50 - $v_risk = $initiative->getRisks(); 51 - 52 - if ($is_new) { 53 - $v_projects = array(); 54 - } else { 55 - $v_projects = PhabricatorEdgeQuery::loadDestinationPHIDs( 56 - $initiative->getPHID(), 57 - PhabricatorProjectObjectHasProjectEdgeType::EDGECONST); 58 - $v_projects = array_reverse($v_projects); 59 - } 60 - 61 - $validation_exception = null; 62 - if ($request->isFormPost()) { 63 - $v_name = $request->getStr('name'); 64 - $v_desc = $request->getStr('description'); 65 - $v_risk = $request->getStr('risks'); 66 - $v_view = $request->getStr('viewPolicy'); 67 - $v_edit = $request->getStr('editPolicy'); 68 - $v_merchant = $request->getStr('merchantPHID'); 69 - $v_projects = $request->getArr('projects'); 70 - 71 - $type_name = FundInitiativeNameTransaction::TRANSACTIONTYPE; 72 - $type_desc = FundInitiativeDescriptionTransaction::TRANSACTIONTYPE; 73 - $type_risk = FundInitiativeRisksTransaction::TRANSACTIONTYPE; 74 - $type_merchant = FundInitiativeMerchantTransaction::TRANSACTIONTYPE; 75 - $type_view = PhabricatorTransactions::TYPE_VIEW_POLICY; 76 - $type_edit = PhabricatorTransactions::TYPE_EDIT_POLICY; 77 - 78 - $xactions = array(); 79 - 80 - $xactions[] = id(new FundInitiativeTransaction()) 81 - ->setTransactionType($type_name) 82 - ->setNewValue($v_name); 83 - 84 - $xactions[] = id(new FundInitiativeTransaction()) 85 - ->setTransactionType($type_desc) 86 - ->setNewValue($v_desc); 87 - 88 - $xactions[] = id(new FundInitiativeTransaction()) 89 - ->setTransactionType($type_risk) 90 - ->setNewValue($v_risk); 91 - 92 - $xactions[] = id(new FundInitiativeTransaction()) 93 - ->setTransactionType($type_merchant) 94 - ->setNewValue($v_merchant); 95 - 96 - $xactions[] = id(new FundInitiativeTransaction()) 97 - ->setTransactionType($type_view) 98 - ->setNewValue($v_view); 99 - 100 - $xactions[] = id(new FundInitiativeTransaction()) 101 - ->setTransactionType($type_edit) 102 - ->setNewValue($v_edit); 103 - 104 - $proj_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST; 105 - $xactions[] = id(new FundInitiativeTransaction()) 106 - ->setTransactionType(PhabricatorTransactions::TYPE_EDGE) 107 - ->setMetadataValue('edge:type', $proj_edge_type) 108 - ->setNewValue(array('=' => array_fuse($v_projects))); 109 - 110 - $editor = id(new FundInitiativeEditor()) 111 - ->setActor($viewer) 112 - ->setContentSourceFromRequest($request) 113 - ->setContinueOnNoEffect(true); 114 - 115 - try { 116 - $editor->applyTransactions($initiative, $xactions); 117 - 118 - return id(new AphrontRedirectResponse()) 119 - ->setURI('/'.$initiative->getMonogram()); 120 - } catch (PhabricatorApplicationTransactionValidationException $ex) { 121 - $validation_exception = $ex; 122 - 123 - $e_name = $ex->getShortMessage($type_name); 124 - $e_merchant = $ex->getShortMessage($type_merchant); 125 - 126 - $initiative->setViewPolicy($v_view); 127 - $initiative->setEditPolicy($v_edit); 128 - } 129 - } 130 - 131 - $policies = id(new PhabricatorPolicyQuery()) 132 - ->setViewer($viewer) 133 - ->setObject($initiative) 134 - ->execute(); 135 - 136 - $merchants = id(new PhortuneMerchantQuery()) 137 - ->setViewer($viewer) 138 - ->requireCapabilities( 139 - array( 140 - PhabricatorPolicyCapability::CAN_VIEW, 141 - PhabricatorPolicyCapability::CAN_EDIT, 142 - )) 143 - ->execute(); 144 - 145 - $merchant_options = array(); 146 - foreach ($merchants as $merchant) { 147 - $merchant_options[$merchant->getPHID()] = pht( 148 - 'Merchant %d %s', 149 - $merchant->getID(), 150 - $merchant->getName()); 151 - } 152 - 153 - if ($v_merchant && empty($merchant_options[$v_merchant])) { 154 - $merchant_options = array( 155 - $v_merchant => pht('(Restricted Merchant)'), 156 - ) + $merchant_options; 157 - } 158 - 159 - if (!$merchant_options) { 160 - return $this->newDialog() 161 - ->setTitle(pht('No Valid Phortune Merchant Accounts')) 162 - ->appendParagraph( 163 - pht( 164 - 'You do not control any merchant accounts which can receive '. 165 - 'payments from this initiative. When you create an initiative, '. 166 - 'you need to specify a merchant account where funds will be paid '. 167 - 'to.')) 168 - ->appendParagraph( 169 - pht( 170 - 'Create a merchant account in the Phortune application before '. 171 - 'creating an initiative in Fund.')) 172 - ->addCancelButton($this->getApplicationURI()); 173 - } 174 - 175 - $form = id(new AphrontFormView()) 176 - ->setUser($viewer) 177 - ->appendChild( 178 - id(new AphrontFormTextControl()) 179 - ->setName('name') 180 - ->setLabel(pht('Name')) 181 - ->setValue($v_name) 182 - ->setError($e_name)) 183 - ->appendChild( 184 - id(new AphrontFormSelectControl()) 185 - ->setName('merchantPHID') 186 - ->setLabel(pht('Pay To Merchant')) 187 - ->setValue($v_merchant) 188 - ->setError($e_merchant) 189 - ->setOptions($merchant_options)) 190 - ->appendChild( 191 - id(new PhabricatorRemarkupControl()) 192 - ->setUser($viewer) 193 - ->setName('description') 194 - ->setLabel(pht('Description')) 195 - ->setValue($v_desc)) 196 - ->appendChild( 197 - id(new PhabricatorRemarkupControl()) 198 - ->setUser($viewer) 199 - ->setName('risks') 200 - ->setLabel(pht('Risks/Challenges')) 201 - ->setValue($v_risk)) 202 - ->appendControl( 203 - id(new AphrontFormTokenizerControl()) 204 - ->setLabel(pht('Tags')) 205 - ->setName('projects') 206 - ->setValue($v_projects) 207 - ->setDatasource(new PhabricatorProjectDatasource())) 208 - ->appendChild( 209 - id(new AphrontFormPolicyControl()) 210 - ->setName('viewPolicy') 211 - ->setPolicyObject($initiative) 212 - ->setCapability(PhabricatorPolicyCapability::CAN_VIEW) 213 - ->setPolicies($policies)) 214 - ->appendChild( 215 - id(new AphrontFormPolicyControl()) 216 - ->setName('editPolicy') 217 - ->setPolicyObject($initiative) 218 - ->setCapability(PhabricatorPolicyCapability::CAN_EDIT) 219 - ->setPolicies($policies)) 220 - ->appendChild( 221 - id(new AphrontFormSubmitControl()) 222 - ->setValue($button_text) 223 - ->addCancelButton($cancel_uri)); 224 - 225 - $crumbs = $this->buildApplicationCrumbs(); 226 - if ($is_new) { 227 - $crumbs->addTextCrumb(pht('Create Initiative')); 228 - } else { 229 - $crumbs->addTextCrumb( 230 - $initiative->getMonogram(), 231 - '/'.$initiative->getMonogram()); 232 - $crumbs->addTextCrumb(pht('Edit')); 233 - } 234 - $crumbs->setBorder(true); 235 - 236 - $box = id(new PHUIObjectBoxView()) 237 - ->setValidationException($validation_exception) 238 - ->setHeaderText(pht('Initiative')) 239 - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 240 - ->appendChild($form); 241 - 242 - $header = id(new PHUIHeaderView()) 243 - ->setHeader($title) 244 - ->setHeaderIcon($header_icon); 245 - 246 - $view = id(new PHUITwoColumnView()) 247 - ->setHeader($header) 248 - ->setFooter($box); 249 - 250 - return $this->newPage() 251 - ->setTitle($title) 252 - ->setCrumbs($crumbs) 253 - ->appendChild($view); 6 + return id(new FundInitiativeEditEngine()) 7 + ->setController($this) 8 + ->buildResponse(); 254 9 } 255 10 256 11 }
+152
src/applications/fund/editor/FundInitiativeEditEngine.php
··· 1 + <?php 2 + 3 + final class FundInitiativeEditEngine 4 + extends PhabricatorEditEngine { 5 + 6 + const ENGINECONST = 'fund.initiative'; 7 + 8 + public function getEngineName() { 9 + return pht('Fund'); 10 + } 11 + 12 + public function getEngineApplicationClass() { 13 + return 'PhabricatorFundApplication'; 14 + } 15 + 16 + public function getSummaryHeader() { 17 + return pht('Configure Fund Forms'); 18 + } 19 + 20 + public function getSummaryText() { 21 + return pht('Configure creation and editing forms in Fund.'); 22 + } 23 + 24 + public function isEngineConfigurable() { 25 + return false; 26 + } 27 + 28 + protected function newEditableObject() { 29 + return FundInitiative::initializeNewInitiative($this->getViewer()); 30 + } 31 + 32 + protected function newObjectQuery() { 33 + return new FundInitiativeQuery(); 34 + } 35 + 36 + protected function getObjectCreateTitleText($object) { 37 + return pht('Create New Initiative'); 38 + } 39 + 40 + protected function getObjectEditTitleText($object) { 41 + return pht('Edit Initiative: %s', $object->getName()); 42 + } 43 + 44 + protected function getObjectEditShortText($object) { 45 + return $object->getName(); 46 + } 47 + 48 + protected function getObjectCreateShortText() { 49 + return pht('Create Initiative'); 50 + } 51 + 52 + protected function getObjectName() { 53 + return pht('Initivative'); 54 + } 55 + 56 + protected function getObjectCreateCancelURI($object) { 57 + return $this->getApplication()->getApplicationURI('/'); 58 + } 59 + 60 + protected function getEditorURI() { 61 + return $this->getApplication()->getApplicationURI('edit/'); 62 + } 63 + 64 + protected function getObjectViewURI($object) { 65 + return $object->getViewURI(); 66 + } 67 + 68 + protected function getCreateNewObjectPolicy() { 69 + return $this->getApplication()->getPolicy( 70 + FundCreateInitiativesCapability::CAPABILITY); 71 + } 72 + 73 + protected function buildCustomEditFields($object) { 74 + $viewer = $this->getViewer(); 75 + $v_merchant = $object->getMerchantPHID(); 76 + 77 + $merchants = id(new PhortuneMerchantQuery()) 78 + ->setViewer($viewer) 79 + ->requireCapabilities( 80 + array( 81 + PhabricatorPolicyCapability::CAN_VIEW, 82 + PhabricatorPolicyCapability::CAN_EDIT, 83 + )) 84 + ->execute(); 85 + 86 + $merchant_options = array(); 87 + foreach ($merchants as $merchant) { 88 + $merchant_options[$merchant->getPHID()] = pht( 89 + 'Merchant %d %s', 90 + $merchant->getID(), 91 + $merchant->getName()); 92 + } 93 + 94 + if ($v_merchant && empty($merchant_options[$v_merchant])) { 95 + $merchant_options = array( 96 + $v_merchant => pht('(Restricted Merchant)'), 97 + ) + $merchant_options; 98 + } 99 + 100 + $merchant_instructions = null; 101 + if (!$merchant_options) { 102 + $merchant_instructions = pht( 103 + 'NOTE: You do not control any merchant accounts which can receive '. 104 + 'payments from this initiative. When you create an initiative, '. 105 + 'you need to specify a merchant account where funds will be paid '. 106 + 'to. Create a merchant account in the Phortune application before '. 107 + 'creating an initiative in Fund.'); 108 + } 109 + 110 + return array( 111 + id(new PhabricatorTextEditField()) 112 + ->setKey('name') 113 + ->setLabel(pht('Name')) 114 + ->setDescription(pht('Initiative name.')) 115 + ->setConduitTypeDescription(pht('New initiative name.')) 116 + ->setTransactionType( 117 + FundInitiativeNameTransaction::TRANSACTIONTYPE) 118 + ->setValue($object->getName()) 119 + ->setIsRequired(true), 120 + id(new PhabricatorSelectEditField()) 121 + ->setKey('merchantPHID') 122 + ->setLabel(pht('Merchant')) 123 + ->setDescription(pht('Merchant operating the initiative.')) 124 + ->setConduitTypeDescription(pht('New initiative merchant.')) 125 + ->setControlInstructions($merchant_instructions) 126 + ->setValue($object->getMerchantPHID()) 127 + ->setTransactionType( 128 + FundInitiativeMerchantTransaction::TRANSACTIONTYPE) 129 + ->setOptions($merchant_options) 130 + ->setIsRequired(true), 131 + id(new PhabricatorRemarkupEditField()) 132 + ->setKey('description') 133 + ->setLabel(pht('Description')) 134 + ->setDescription(pht('Initiative long description.')) 135 + ->setConduitTypeDescription(pht('New initiative description.')) 136 + ->setTransactionType( 137 + FundInitiativeDescriptionTransaction::TRANSACTIONTYPE) 138 + ->setValue($object->getDescription()), 139 + id(new PhabricatorRemarkupEditField()) 140 + ->setKey('risks') 141 + ->setLabel(pht('Risks/Challenges')) 142 + ->setDescription(pht('Initiative risks and challenges.')) 143 + ->setConduitTypeDescription(pht('Initiative risks and challenges.')) 144 + ->setTransactionType( 145 + FundInitiativeRisksTransaction::TRANSACTIONTYPE) 146 + ->setValue($object->getRisks()), 147 + 148 + ); 149 + 150 + } 151 + 152 + }
+4
src/applications/fund/storage/FundInitiative.php
··· 85 85 return 'I'.$this->getID(); 86 86 } 87 87 88 + public function getViewURI() { 89 + return '/'.$this->getMonogram(); 90 + } 91 + 88 92 public function getProjectPHIDs() { 89 93 return $this->assertAttached($this->projectPHIDs); 90 94 }