@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 Phortune Merchant UI

Summary: Builds out Phortune Merchant pages to have a sidenav and sub-pages for further expansion. For now this links Orders and Subscriptions to the query engine pages, but could be split out to be more informative (unpaid, upcoming, etc).

Test Plan:
Create a new merchant, edit some information, add a manager in new UI, edit logo, click through to subscriptions, orders.

{F4883013}

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin

Differential Revision: https://secure.phabricator.com/D17655

+292 -37
+9 -3
src/__phutil_library_map__.php
··· 4369 4369 'PhortuneMemberHasAccountEdgeType' => 'applications/phortune/edge/PhortuneMemberHasAccountEdgeType.php', 4370 4370 'PhortuneMemberHasMerchantEdgeType' => 'applications/phortune/edge/PhortuneMemberHasMerchantEdgeType.php', 4371 4371 'PhortuneMerchant' => 'applications/phortune/storage/PhortuneMerchant.php', 4372 + 'PhortuneMerchantAddManagerController' => 'applications/phortune/controller/merchant/PhortuneMerchantAddManagerController.php', 4372 4373 'PhortuneMerchantCapability' => 'applications/phortune/capability/PhortuneMerchantCapability.php', 4373 4374 'PhortuneMerchantContactInfoTransaction' => 'applications/phortune/xaction/PhortuneMerchantContactInfoTransaction.php', 4374 4375 'PhortuneMerchantController' => 'applications/phortune/controller/merchant/PhortuneMerchantController.php', ··· 4381 4382 'PhortuneMerchantInvoiceEmailTransaction' => 'applications/phortune/xaction/PhortuneMerchantInvoiceEmailTransaction.php', 4382 4383 'PhortuneMerchantInvoiceFooterTransaction' => 'applications/phortune/xaction/PhortuneMerchantInvoiceFooterTransaction.php', 4383 4384 'PhortuneMerchantListController' => 'applications/phortune/controller/merchant/PhortuneMerchantListController.php', 4385 + 'PhortuneMerchantManagerController' => 'applications/phortune/controller/merchant/PhortuneMerchantManagerController.php', 4384 4386 'PhortuneMerchantNameTransaction' => 'applications/phortune/xaction/PhortuneMerchantNameTransaction.php', 4385 4387 'PhortuneMerchantPHIDType' => 'applications/phortune/phid/PhortuneMerchantPHIDType.php', 4386 4388 'PhortuneMerchantPictureController' => 'applications/phortune/controller/merchant/PhortuneMerchantPictureController.php', 4387 4389 'PhortuneMerchantPictureTransaction' => 'applications/phortune/xaction/PhortuneMerchantPictureTransaction.php', 4390 + 'PhortuneMerchantProfileController' => 'applications/phortune/controller/merchant/PhortuneMerchantProfileController.php', 4388 4391 'PhortuneMerchantQuery' => 'applications/phortune/query/PhortuneMerchantQuery.php', 4389 4392 'PhortuneMerchantSearchEngine' => 'applications/phortune/query/PhortuneMerchantSearchEngine.php', 4390 4393 'PhortuneMerchantTransaction' => 'applications/phortune/storage/PhortuneMerchantTransaction.php', ··· 9832 9835 'PhabricatorApplicationTransactionInterface', 9833 9836 'PhabricatorPolicyInterface', 9834 9837 ), 9838 + 'PhortuneMerchantAddManagerController' => 'PhortuneController', 9835 9839 'PhortuneMerchantCapability' => 'PhabricatorPolicyCapability', 9836 9840 'PhortuneMerchantContactInfoTransaction' => 'PhortuneMerchantTransactionType', 9837 9841 'PhortuneMerchantController' => 'PhortuneController', ··· 9840 9844 'PhortuneMerchantEditEngine' => 'PhabricatorEditEngine', 9841 9845 'PhortuneMerchantEditor' => 'PhabricatorApplicationTransactionEditor', 9842 9846 'PhortuneMerchantHasMemberEdgeType' => 'PhabricatorEdgeType', 9843 - 'PhortuneMerchantInvoiceCreateController' => 'PhortuneMerchantController', 9847 + 'PhortuneMerchantInvoiceCreateController' => 'PhortuneMerchantProfileController', 9844 9848 'PhortuneMerchantInvoiceEmailTransaction' => 'PhortuneMerchantTransactionType', 9845 9849 'PhortuneMerchantInvoiceFooterTransaction' => 'PhortuneMerchantTransactionType', 9846 9850 'PhortuneMerchantListController' => 'PhortuneMerchantController', 9851 + 'PhortuneMerchantManagerController' => 'PhortuneMerchantProfileController', 9847 9852 'PhortuneMerchantNameTransaction' => 'PhortuneMerchantTransactionType', 9848 9853 'PhortuneMerchantPHIDType' => 'PhabricatorPHIDType', 9849 - 'PhortuneMerchantPictureController' => 'PhortuneMerchantController', 9854 + 'PhortuneMerchantPictureController' => 'PhortuneMerchantProfileController', 9850 9855 'PhortuneMerchantPictureTransaction' => 'PhortuneMerchantTransactionType', 9856 + 'PhortuneMerchantProfileController' => 'PhortuneController', 9851 9857 'PhortuneMerchantQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 9852 9858 'PhortuneMerchantSearchEngine' => 'PhabricatorApplicationSearchEngine', 9853 9859 'PhortuneMerchantTransaction' => 'PhabricatorModularTransaction', 9854 9860 'PhortuneMerchantTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 9855 9861 'PhortuneMerchantTransactionType' => 'PhabricatorModularTransactionType', 9856 - 'PhortuneMerchantViewController' => 'PhortuneMerchantController', 9862 + 'PhortuneMerchantViewController' => 'PhortuneMerchantProfileController', 9857 9863 'PhortuneMonthYearExpiryControl' => 'AphrontFormControl', 9858 9864 'PhortuneOrderTableView' => 'AphrontView', 9859 9865 'PhortunePayPalPaymentProvider' => 'PhortunePaymentProvider',
+4
src/applications/phortune/application/PhabricatorPhortuneApplication.php
··· 88 88 => 'PhortuneMerchantEditController', 89 89 'orders/(?P<merchantID>\d+)/(?:query/(?P<queryKey>[^/]+)/)?' 90 90 => 'PhortuneCartListController', 91 + 'manager/' => array( 92 + '(?:(?P<id>\d+)/)?' => 'PhortuneMerchantManagerController', 93 + 'add/(?:(?P<id>\d+)/)?' => 'PhortuneMerchantAddManagerController', 94 + ), 91 95 '(?P<merchantID>\d+)/' => array( 92 96 'cart/(?P<id>\d+)/' => array( 93 97 '' => 'PhortuneCartViewController',
+76
src/applications/phortune/controller/merchant/PhortuneMerchantAddManagerController.php
··· 1 + <?php 2 + 3 + final class PhortuneMerchantAddManagerController extends PhortuneController { 4 + 5 + public function handleRequest(AphrontRequest $request) { 6 + $viewer = $request->getViewer(); 7 + $id = $request->getURIData('id'); 8 + 9 + $merchant = id(new PhortuneMerchantQuery()) 10 + ->setViewer($viewer) 11 + ->withIDs(array($id)) 12 + ->needProfileImage(true) 13 + ->requireCapabilities( 14 + array( 15 + PhabricatorPolicyCapability::CAN_VIEW, 16 + PhabricatorPolicyCapability::CAN_EDIT, 17 + )) 18 + ->executeOne(); 19 + if (!$merchant) { 20 + return new Aphront404Response(); 21 + } 22 + 23 + $v_members = array(); 24 + $e_members = null; 25 + $merchant_uri = $this->getApplicationURI("/merchant/manager/{$id}/"); 26 + 27 + if ($request->isFormPost()) { 28 + $xactions = array(); 29 + $v_members = $request->getArr('memberPHIDs'); 30 + $type_edge = PhabricatorTransactions::TYPE_EDGE; 31 + 32 + $xactions[] = id(new PhortuneMerchantTransaction()) 33 + ->setTransactionType($type_edge) 34 + ->setMetadataValue( 35 + 'edge:type', 36 + PhortuneMerchantHasMemberEdgeType::EDGECONST) 37 + ->setNewValue( 38 + array( 39 + '+' => array_fuse($v_members), 40 + )); 41 + 42 + $editor = id(new PhortuneMerchantEditor()) 43 + ->setActor($viewer) 44 + ->setContentSourceFromRequest($request) 45 + ->setContinueOnNoEffect(true); 46 + 47 + try { 48 + $editor->applyTransactions($merchant, $xactions); 49 + 50 + return id(new AphrontRedirectResponse())->setURI($merchant_uri); 51 + } catch (PhabricatorApplicationTransactionValidationException $ex) { 52 + $validation_exception = $ex; 53 + $e_members = $ex->getShortMessage($type_edge); 54 + } 55 + } 56 + 57 + $form = id(new AphrontFormView()) 58 + ->setUser($viewer) 59 + ->appendControl( 60 + id(new AphrontFormTokenizerControl()) 61 + ->setDatasource(new PhabricatorPeopleDatasource()) 62 + ->setLabel(pht('Members')) 63 + ->setName('memberPHIDs') 64 + ->setValue($v_members) 65 + ->setError($e_members)); 66 + 67 + return $this->newDialog() 68 + ->setTitle(pht('Add New Manager')) 69 + ->appendForm($form) 70 + ->setWidth(AphrontDialogView::WIDTH_FORM) 71 + ->addCancelButton($merchant_uri) 72 + ->addSubmitButton(pht('Add Manager')); 73 + 74 + } 75 + 76 + }
+6 -3
src/applications/phortune/controller/merchant/PhortuneMerchantInvoiceCreateController.php
··· 1 1 <?php 2 2 3 3 final class PhortuneMerchantInvoiceCreateController 4 - extends PhortuneMerchantController { 4 + extends PhortuneMerchantProfileController { 5 5 6 6 public function handleRequest(AphrontRequest $request) { 7 7 $viewer = $request->getUser(); ··· 11 11 return new Aphront404Response(); 12 12 } 13 13 14 + $this->setMerchant($merchant); 14 15 $merchant_id = $merchant->getID(); 15 16 $cancel_uri = $this->getApplicationURI("/merchant/{$merchant_id}/"); 16 17 ··· 88 89 $title = pht('New Invoice'); 89 90 90 91 $crumbs = $this->buildApplicationCrumbs(); 91 - $crumbs->addTextCrumb($merchant->getName()); 92 - $crumbs->setBorder(true); 92 + $crumbs->addTextCrumb($title); 93 93 94 94 $v_title = $request->getStr('title'); 95 95 $e_title = true; ··· 245 245 $box, 246 246 )); 247 247 248 + $navigation = $this->buildSideNavView('orders'); 249 + 248 250 return $this->newPage() 249 251 ->setTitle($title) 250 252 ->setCrumbs($crumbs) 253 + ->setNavigation($navigation) 251 254 ->appendChild($view); 252 255 } 253 256
+91
src/applications/phortune/controller/merchant/PhortuneMerchantManagerController.php
··· 1 + <?php 2 + 3 + final class PhortuneMerchantManagerController 4 + extends PhortuneMerchantProfileController { 5 + 6 + public function handleRequest(AphrontRequest $request) { 7 + $viewer = $request->getViewer(); 8 + $id = $request->getURIData('id'); 9 + 10 + $merchant = id(new PhortuneMerchantQuery()) 11 + ->setViewer($viewer) 12 + ->withIDs(array($id)) 13 + ->needProfileImage(true) 14 + ->executeOne(); 15 + if (!$merchant) { 16 + return new Aphront404Response(); 17 + } 18 + 19 + $this->setMerchant($merchant); 20 + $header = $this->buildHeaderView(); 21 + 22 + $crumbs = $this->buildApplicationCrumbs(); 23 + $crumbs->addTextCrumb(pht('Managers')); 24 + 25 + $header = $this->buildHeaderView(); 26 + $members = $this->buildMembersSection($merchant); 27 + 28 + $view = id(new PHUITwoColumnView()) 29 + ->setHeader($header) 30 + ->setFooter(array( 31 + $members, 32 + )); 33 + 34 + $navigation = $this->buildSideNavView('managers'); 35 + 36 + return $this->newPage() 37 + ->setTitle(pht('Managers')) 38 + ->setCrumbs($crumbs) 39 + ->setNavigation($navigation) 40 + ->appendChild($view); 41 + 42 + } 43 + 44 + private function buildMembersSection(PhortuneMerchant $merchant) { 45 + $viewer = $this->getViewer(); 46 + 47 + $can_edit = PhabricatorPolicyFilter::hasCapability( 48 + $viewer, 49 + $merchant, 50 + PhabricatorPolicyCapability::CAN_EDIT); 51 + 52 + $id = $merchant->getID(); 53 + 54 + $add = id(new PHUIButtonView()) 55 + ->setTag('a') 56 + ->setText(pht('New Manager')) 57 + ->setIcon('fa-plus') 58 + ->setWorkflow(true) 59 + ->setHref("/phortune/merchant/manager/add/{$id}/"); 60 + 61 + $header = id(new PHUIHeaderView()) 62 + ->setHeader(pht('Merchant Account Managers')) 63 + ->addActionLink($add); 64 + 65 + $list = id(new PHUIObjectItemListView()) 66 + ->setUser($viewer); 67 + 68 + $member_phids = $merchant->getMemberPHIDs(); 69 + $handles = $viewer->loadHandles($member_phids); 70 + 71 + foreach ($member_phids as $member_phid) { 72 + $image_uri = $handles[$member_phid]->getImageURI(); 73 + $image_href = $handles[$member_phid]->getURI(); 74 + $person = $handles[$member_phid]; 75 + 76 + $member = id(new PHUIObjectItemView()) 77 + ->setImageURI($image_uri) 78 + ->setHref($image_href) 79 + ->setHeader($person->getFullName()) 80 + ->addAttribute(pht('Merchant Manager')); 81 + 82 + $list->addItem($member); 83 + } 84 + 85 + return id(new PHUIObjectBoxView()) 86 + ->setHeader($header) 87 + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 88 + ->setObjectList($list); 89 + } 90 + 91 + }
+8 -6
src/applications/phortune/controller/merchant/PhortuneMerchantPictureController.php
··· 1 1 <?php 2 2 3 3 final class PhortuneMerchantPictureController 4 - extends PhortuneMerchantController { 4 + extends PhortuneMerchantProfileController { 5 5 6 6 public function handleRequest(AphrontRequest $request) { 7 7 $viewer = $request->getViewer(); ··· 21 21 return new Aphront404Response(); 22 22 } 23 23 24 + $this->setMerchant($merchant); 24 25 $uri = $merchant->getURI(); 25 26 26 27 $supported_formats = PhabricatorFile::getTransformableImageFormats(); ··· 92 93 } 93 94 } 94 95 95 - $title = pht('Edit Merchant Picture'); 96 + $title = pht('Edit Logo'); 96 97 97 98 $form = id(new PHUIFormLayoutView()) 98 99 ->setUser($viewer); ··· 208 209 ->setForm($upload_form); 209 210 210 211 $crumbs = $this->buildApplicationCrumbs(); 211 - $crumbs->addTextCrumb($merchant->getName(), $uri); 212 - $crumbs->addTextCrumb(pht('Merchant Logo')); 213 - $crumbs->setBorder(true); 212 + $crumbs->addTextCrumb(pht('Edit Logo')); 214 213 215 214 $header = id(new PHUIHeaderView()) 216 - ->setHeader(pht('Edit Merchant Logo')) 215 + ->setHeader(pht('Edit Logo')) 217 216 ->setHeaderIcon('fa-camera'); 218 217 219 218 $view = id(new PHUITwoColumnView()) ··· 223 222 $upload_box, 224 223 )); 225 224 225 + $navigation = $this->buildSideNavView(); 226 + 226 227 return $this->newPage() 227 228 ->setTitle($title) 228 229 ->setCrumbs($crumbs) 230 + ->setNavigation($navigation) 229 231 ->appendChild( 230 232 array( 231 233 $view,
+92
src/applications/phortune/controller/merchant/PhortuneMerchantProfileController.php
··· 1 + <?php 2 + 3 + abstract class PhortuneMerchantProfileController 4 + extends PhortuneController { 5 + 6 + private $merchant; 7 + 8 + public function setMerchant(PhortuneMerchant $merchant) { 9 + $this->merchant = $merchant; 10 + return $this; 11 + } 12 + 13 + public function getMerchant() { 14 + return $this->merchant; 15 + } 16 + 17 + public function buildApplicationMenu() { 18 + return $this->buildSideNavView()->getMenu(); 19 + } 20 + 21 + protected function buildHeaderView() { 22 + $viewer = $this->getViewer(); 23 + $merchant = $this->getMerchant(); 24 + $title = $merchant->getName(); 25 + 26 + $header = id(new PHUIHeaderView()) 27 + ->setHeader($title) 28 + ->setUser($viewer) 29 + ->setPolicyObject($merchant) 30 + ->setImage($merchant->getProfileImageURI()); 31 + 32 + return $header; 33 + } 34 + 35 + protected function buildApplicationCrumbs() { 36 + $merchant = $this->getMerchant(); 37 + $id = $merchant->getID(); 38 + $merchant_uri = $this->getApplicationURI("/merchant/{$id}/"); 39 + 40 + $crumbs = parent::buildApplicationCrumbs(); 41 + $crumbs->addTextCrumb($merchant->getName(), $merchant_uri); 42 + $crumbs->setBorder(true); 43 + return $crumbs; 44 + } 45 + 46 + protected function buildSideNavView($filter = null) { 47 + $viewer = $this->getViewer(); 48 + $merchant = $this->getMerchant(); 49 + $id = $merchant->getID(); 50 + 51 + $can_edit = PhabricatorPolicyFilter::hasCapability( 52 + $viewer, 53 + $merchant, 54 + PhabricatorPolicyCapability::CAN_EDIT); 55 + 56 + $nav = id(new AphrontSideNavFilterView()) 57 + ->setBaseURI(new PhutilURI($this->getApplicationURI())); 58 + 59 + $nav->addLabel(pht('Merchant')); 60 + 61 + $nav->addFilter( 62 + 'overview', 63 + pht('Overview'), 64 + $this->getApplicationURI("/merchant/{$id}/"), 65 + 'fa-building-o'); 66 + 67 + if ($can_edit) { 68 + $nav->addFilter( 69 + 'orders', 70 + pht('Orders'), 71 + $this->getApplicationURI("merchant/orders/{$id}/"), 72 + 'fa-retweet'); 73 + 74 + $nav->addFilter( 75 + 'subscriptions', 76 + pht('Subscriptions'), 77 + $this->getApplicationURI("merchant/{$id}/subscription/"), 78 + 'fa-shopping-cart'); 79 + 80 + $nav->addFilter( 81 + 'managers', 82 + pht('Managers'), 83 + $this->getApplicationURI("/merchant/manager/{$id}/"), 84 + 'fa-group'); 85 + } 86 + 87 + $nav->selectFilter($filter); 88 + 89 + return $nav; 90 + } 91 + 92 + }
+6 -25
src/applications/phortune/controller/merchant/PhortuneMerchantViewController.php
··· 1 1 <?php 2 2 3 3 final class PhortuneMerchantViewController 4 - extends PhortuneMerchantController { 4 + extends PhortuneMerchantProfileController { 5 5 6 6 public function handleRequest(AphrontRequest $request) { 7 7 $viewer = $request->getViewer(); ··· 16 16 return new Aphront404Response(); 17 17 } 18 18 19 + $this->setMerchant($merchant); 19 20 $crumbs = $this->buildApplicationCrumbs(); 20 - $crumbs->addTextCrumb($merchant->getName()); 21 - $crumbs->setBorder(true); 21 + $header = $this->buildHeaderView(); 22 22 23 23 $title = pht( 24 24 'Merchant %d %s', 25 25 $merchant->getID(), 26 26 $merchant->getName()); 27 27 28 - $header = id(new PHUIHeaderView()) 29 - ->setHeader($merchant->getName()) 30 - ->setUser($viewer) 31 - ->setPolicyObject($merchant) 32 - ->setImage($merchant->getProfileImageURI()); 33 - 34 28 $providers = id(new PhortunePaymentProviderConfigQuery()) 35 29 ->setViewer($viewer) 36 30 ->withMerchantPHIDs(array($merchant->getPHID())) ··· 48 42 new PhortuneMerchantTransactionQuery()); 49 43 $timeline->setShouldTerminate(true); 50 44 45 + $navigation = $this->buildSideNavView('overview'); 46 + 51 47 $view = id(new PHUITwoColumnView()) 52 48 ->setHeader($header) 53 49 ->setCurtain($curtain) ··· 60 56 return $this->newPage() 61 57 ->setTitle($title) 62 58 ->setCrumbs($crumbs) 59 + ->setNavigation($navigation) 63 60 ->appendChild($view); 64 61 } 65 62 ··· 195 192 ->setDisabled(!$can_edit) 196 193 ->setWorkflow(!$can_edit) 197 194 ->setHref($this->getApplicationURI("merchant/picture/{$id}/"))); 198 - 199 - $curtain->addAction( 200 - id(new PhabricatorActionView()) 201 - ->setName(pht('View Orders')) 202 - ->setIcon('fa-shopping-cart') 203 - ->setHref($this->getApplicationURI("merchant/orders/{$id}/")) 204 - ->setDisabled(!$can_edit) 205 - ->setWorkflow(!$can_edit)); 206 - 207 - $curtain->addAction( 208 - id(new PhabricatorActionView()) 209 - ->setName(pht('View Subscriptions')) 210 - ->setIcon('fa-moon-o') 211 - ->setHref($this->getApplicationURI("merchant/{$id}/subscription/")) 212 - ->setDisabled(!$can_edit) 213 - ->setWorkflow(!$can_edit)); 214 195 215 196 $curtain->addAction( 216 197 id(new PhabricatorActionView())