@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.

Add a Merchant logo to Phortune

Summary: Is a logo. For merchants.

Test Plan: Set a new logo, remove it. See on list.

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin

Maniphest Tasks: T7607

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

+316 -3
resources/builtin/merchant.png

This is a binary file and will not be displayed.

+2
resources/sql/autopatches/20161025.phortune.merchant.image.1.sql
··· 1 + ALTER TABLE {$NAMESPACE}_phortune.phortune_merchant 2 + ADD profileImagePHID VARBINARY(64);
+2
src/__phutil_library_map__.php
··· 4185 4185 'PhortuneMerchantInvoiceCreateController' => 'applications/phortune/controller/PhortuneMerchantInvoiceCreateController.php', 4186 4186 'PhortuneMerchantListController' => 'applications/phortune/controller/PhortuneMerchantListController.php', 4187 4187 'PhortuneMerchantPHIDType' => 'applications/phortune/phid/PhortuneMerchantPHIDType.php', 4188 + 'PhortuneMerchantPictureController' => 'applications/phortune/controller/PhortuneMerchantPictureController.php', 4188 4189 'PhortuneMerchantQuery' => 'applications/phortune/query/PhortuneMerchantQuery.php', 4189 4190 'PhortuneMerchantSearchEngine' => 'applications/phortune/query/PhortuneMerchantSearchEngine.php', 4190 4191 'PhortuneMerchantTransaction' => 'applications/phortune/storage/PhortuneMerchantTransaction.php', ··· 9434 9435 'PhortuneMerchantInvoiceCreateController' => 'PhortuneMerchantController', 9435 9436 'PhortuneMerchantListController' => 'PhortuneMerchantController', 9436 9437 'PhortuneMerchantPHIDType' => 'PhabricatorPHIDType', 9438 + 'PhortuneMerchantPictureController' => 'PhortuneMerchantController', 9437 9439 'PhortuneMerchantQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 9438 9440 'PhortuneMerchantSearchEngine' => 'PhabricatorApplicationSearchEngine', 9439 9441 'PhortuneMerchantTransaction' => 'PhabricatorApplicationTransaction',
+1
src/applications/phortune/application/PhabricatorPhortuneApplication.php
··· 81 81 ), 82 82 'merchant/' => array( 83 83 '(?:query/(?P<queryKey>[^/]+)/)?' => 'PhortuneMerchantListController', 84 + 'picture/(?:(?P<id>\d+)/)?' => 'PhortuneMerchantPictureController', 84 85 'edit/(?:(?P<id>\d+)/)?' => 'PhortuneMerchantEditController', 85 86 'orders/(?P<merchantID>\d+)/(?:query/(?P<queryKey>[^/]+)/)?' 86 87 => 'PhortuneCartListController',
+234
src/applications/phortune/controller/PhortuneMerchantPictureController.php
··· 1 + <?php 2 + 3 + final class PhortuneMerchantPictureController 4 + extends PhortuneMerchantController { 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 + ->requireCapabilities( 15 + array( 16 + PhabricatorPolicyCapability::CAN_VIEW, 17 + PhabricatorPolicyCapability::CAN_EDIT, 18 + )) 19 + ->executeOne(); 20 + if (!$merchant) { 21 + return new Aphront404Response(); 22 + } 23 + 24 + $uri = $merchant->getViewURI(); 25 + 26 + $supported_formats = PhabricatorFile::getTransformableImageFormats(); 27 + $e_file = true; 28 + $errors = array(); 29 + 30 + if ($request->isFormPost()) { 31 + $phid = $request->getStr('phid'); 32 + $is_default = false; 33 + if ($phid == PhabricatorPHIDConstants::PHID_VOID) { 34 + $phid = null; 35 + $is_default = true; 36 + } else if ($phid) { 37 + $file = id(new PhabricatorFileQuery()) 38 + ->setViewer($viewer) 39 + ->withPHIDs(array($phid)) 40 + ->executeOne(); 41 + } else { 42 + if ($request->getFileExists('picture')) { 43 + $file = PhabricatorFile::newFromPHPUpload( 44 + $_FILES['picture'], 45 + array( 46 + 'authorPHID' => $viewer->getPHID(), 47 + 'canCDN' => true, 48 + )); 49 + } else { 50 + $e_file = pht('Required'); 51 + $errors[] = pht( 52 + 'You must choose a file when uploading a merchant logo.'); 53 + } 54 + } 55 + 56 + if (!$errors && !$is_default) { 57 + if (!$file->isTransformableImage()) { 58 + $e_file = pht('Not Supported'); 59 + $errors[] = pht( 60 + 'This server only supports these image formats: %s.', 61 + implode(', ', $supported_formats)); 62 + } else { 63 + $xform = PhabricatorFileTransform::getTransformByKey( 64 + PhabricatorFileThumbnailTransform::TRANSFORM_PROFILE); 65 + $xformed = $xform->executeTransform($file); 66 + } 67 + } 68 + 69 + if (!$errors) { 70 + if ($is_default) { 71 + $new_value = null; 72 + } else { 73 + $xformed->attachToObject($merchant->getPHID()); 74 + $new_value = $xformed->getPHID(); 75 + } 76 + 77 + $xactions = array(); 78 + $xactions[] = id(new PhortuneMerchantTransaction()) 79 + ->setTransactionType(PhortuneMerchantTransaction::TYPE_PICTURE) 80 + ->setNewValue($new_value); 81 + 82 + $editor = id(new PhortuneMerchantEditor()) 83 + ->setActor($viewer) 84 + ->setContentSourceFromRequest($request) 85 + ->setContinueOnMissingFields(true) 86 + ->setContinueOnNoEffect(true); 87 + 88 + $editor->applyTransactions($merchant, $xactions); 89 + 90 + return id(new AphrontRedirectResponse())->setURI($uri); 91 + } 92 + } 93 + 94 + $title = pht('Edit Merchant Picture'); 95 + 96 + $form = id(new PHUIFormLayoutView()) 97 + ->setUser($viewer); 98 + 99 + $default_image = PhabricatorFile::loadBuiltin($viewer, 'merchant.png'); 100 + 101 + $images = array(); 102 + 103 + $current = $merchant->getProfileImagePHID(); 104 + $has_current = false; 105 + if ($current) { 106 + $file = id(new PhabricatorFileQuery()) 107 + ->setViewer($viewer) 108 + ->withPHIDs(array($current)) 109 + ->executeOne(); 110 + if ($file) { 111 + if ($file->isTransformableImage()) { 112 + $has_current = true; 113 + $images[$current] = array( 114 + 'uri' => $file->getBestURI(), 115 + 'tip' => pht('Current Picture'), 116 + ); 117 + } 118 + } 119 + } 120 + 121 + $images[PhabricatorPHIDConstants::PHID_VOID] = array( 122 + 'uri' => $default_image->getBestURI(), 123 + 'tip' => pht('Default Picture'), 124 + ); 125 + 126 + require_celerity_resource('people-profile-css'); 127 + Javelin::initBehavior('phabricator-tooltips', array()); 128 + 129 + $buttons = array(); 130 + foreach ($images as $phid => $spec) { 131 + $button = javelin_tag( 132 + 'button', 133 + array( 134 + 'class' => 'grey profile-image-button', 135 + 'sigil' => 'has-tooltip', 136 + 'meta' => array( 137 + 'tip' => $spec['tip'], 138 + 'size' => 300, 139 + ), 140 + ), 141 + phutil_tag( 142 + 'img', 143 + array( 144 + 'height' => 50, 145 + 'width' => 50, 146 + 'src' => $spec['uri'], 147 + ))); 148 + 149 + $button = array( 150 + phutil_tag( 151 + 'input', 152 + array( 153 + 'type' => 'hidden', 154 + 'name' => 'phid', 155 + 'value' => $phid, 156 + )), 157 + $button, 158 + ); 159 + 160 + $button = phabricator_form( 161 + $viewer, 162 + array( 163 + 'class' => 'profile-image-form', 164 + 'method' => 'POST', 165 + ), 166 + $button); 167 + 168 + $buttons[] = $button; 169 + } 170 + 171 + if ($has_current) { 172 + $form->appendChild( 173 + id(new AphrontFormMarkupControl()) 174 + ->setLabel(pht('Current Logo')) 175 + ->setValue(array_shift($buttons))); 176 + } 177 + 178 + $form->appendChild( 179 + id(new AphrontFormMarkupControl()) 180 + ->setLabel(pht('Use Logo')) 181 + ->setValue($buttons)); 182 + 183 + $form_box = id(new PHUIObjectBoxView()) 184 + ->setHeaderText($title) 185 + ->setFormErrors($errors) 186 + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 187 + ->setForm($form); 188 + 189 + $upload_form = id(new AphrontFormView()) 190 + ->setUser($viewer) 191 + ->setEncType('multipart/form-data') 192 + ->appendChild( 193 + id(new AphrontFormFileControl()) 194 + ->setName('picture') 195 + ->setLabel(pht('Upload Logo')) 196 + ->setError($e_file) 197 + ->setCaption( 198 + pht('Supported formats: %s', implode(', ', $supported_formats)))) 199 + ->appendChild( 200 + id(new AphrontFormSubmitControl()) 201 + ->addCancelButton($uri) 202 + ->setValue(pht('Upload Logo'))); 203 + 204 + $upload_box = id(new PHUIObjectBoxView()) 205 + ->setHeaderText(pht('Upload New Logo')) 206 + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 207 + ->setForm($upload_form); 208 + 209 + $crumbs = $this->buildApplicationCrumbs(); 210 + $crumbs->addTextCrumb($merchant->getName(), $uri); 211 + $crumbs->addTextCrumb(pht('Merchant Logo')); 212 + $crumbs->setBorder(true); 213 + 214 + $header = id(new PHUIHeaderView()) 215 + ->setHeader(pht('Edit Merchant Logo')) 216 + ->setHeaderIcon('fa-camera'); 217 + 218 + $view = id(new PHUITwoColumnView()) 219 + ->setHeader($header) 220 + ->setFooter(array( 221 + $form_box, 222 + $upload_box, 223 + )); 224 + 225 + return $this->newPage() 226 + ->setTitle($title) 227 + ->setCrumbs($crumbs) 228 + ->appendChild( 229 + array( 230 + $view, 231 + )); 232 + 233 + } 234 + }
+10 -1
src/applications/phortune/controller/PhortuneMerchantViewController.php
··· 10 10 $merchant = id(new PhortuneMerchantQuery()) 11 11 ->setViewer($viewer) 12 12 ->withIDs(array($id)) 13 + ->needProfileImage(true) 13 14 ->executeOne(); 14 15 if (!$merchant) { 15 16 return new Aphront404Response(); ··· 28 29 ->setHeader($merchant->getName()) 29 30 ->setUser($viewer) 30 31 ->setPolicyObject($merchant) 31 - ->setHeaderIcon('fa-bank'); 32 + ->setImage($merchant->getProfileImageURI()); 32 33 33 34 $providers = id(new PhortunePaymentProviderConfigQuery()) 34 35 ->setViewer($viewer) ··· 170 171 ->setDisabled(!$can_edit) 171 172 ->setWorkflow(!$can_edit) 172 173 ->setHref($this->getApplicationURI("merchant/edit/{$id}/"))); 174 + 175 + $curtain->addAction( 176 + id(new PhabricatorActionView()) 177 + ->setName(pht('Edit Logo')) 178 + ->setIcon('fa-camera') 179 + ->setDisabled(!$can_edit) 180 + ->setWorkflow(!$can_edit) 181 + ->setHref($this->getApplicationURI("merchant/picture/{$id}/"))); 173 182 174 183 $curtain->addAction( 175 184 id(new PhabricatorActionView())
+8
src/applications/phortune/editor/PhortuneMerchantEditor.php
··· 17 17 $types[] = PhortuneMerchantTransaction::TYPE_NAME; 18 18 $types[] = PhortuneMerchantTransaction::TYPE_DESCRIPTION; 19 19 $types[] = PhortuneMerchantTransaction::TYPE_CONTACTINFO; 20 + $types[] = PhortuneMerchantTransaction::TYPE_PICTURE; 20 21 $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; 21 22 $types[] = PhabricatorTransactions::TYPE_EDGE; 22 23 ··· 33 34 return $object->getDescription(); 34 35 case PhortuneMerchantTransaction::TYPE_CONTACTINFO: 35 36 return $object->getContactInfo(); 37 + case PhortuneMerchantTransaction::TYPE_PICTURE: 38 + return $object->getProfileImagePHID(); 36 39 } 37 40 38 41 return parent::getCustomTransactionOldValue($object, $xaction); ··· 46 49 case PhortuneMerchantTransaction::TYPE_NAME: 47 50 case PhortuneMerchantTransaction::TYPE_DESCRIPTION: 48 51 case PhortuneMerchantTransaction::TYPE_CONTACTINFO: 52 + case PhortuneMerchantTransaction::TYPE_PICTURE: 49 53 return $xaction->getNewValue(); 50 54 } 51 55 ··· 66 70 case PhortuneMerchantTransaction::TYPE_CONTACTINFO: 67 71 $object->setContactInfo($xaction->getNewValue()); 68 72 return; 73 + case PhortuneMerchantTransaction::TYPE_PICTURE: 74 + $object->setProfileImagePHID($xaction->getNewValue()); 75 + return; 69 76 } 70 77 71 78 return parent::applyCustomInternalTransaction($object, $xaction); ··· 79 86 case PhortuneMerchantTransaction::TYPE_NAME: 80 87 case PhortuneMerchantTransaction::TYPE_DESCRIPTION: 81 88 case PhortuneMerchantTransaction::TYPE_CONTACTINFO: 89 + case PhortuneMerchantTransaction::TYPE_PICTURE: 82 90 return; 83 91 } 84 92
+35
src/applications/phortune/query/PhortuneMerchantQuery.php
··· 6 6 private $ids; 7 7 private $phids; 8 8 private $memberPHIDs; 9 + private $needProfileImage; 9 10 10 11 public function withIDs(array $ids) { 11 12 $this->ids = $ids; ··· 19 20 20 21 public function withMemberPHIDs(array $member_phids) { 21 22 $this->memberPHIDs = $member_phids; 23 + return $this; 24 + } 25 + 26 + public function needProfileImage($need) { 27 + $this->needProfileImage = $need; 22 28 return $this; 23 29 } 24 30 ··· 48 54 $member_phids = $query->getDestinationPHIDs(array($merchant->getPHID())); 49 55 $member_phids = array_reverse($member_phids); 50 56 $merchant->attachMemberPHIDs($member_phids); 57 + } 58 + 59 + if ($this->needProfileImage) { 60 + $default = null; 61 + $file_phids = mpull($merchants, 'getProfileImagePHID'); 62 + $file_phids = array_filter($file_phids); 63 + if ($file_phids) { 64 + $files = id(new PhabricatorFileQuery()) 65 + ->setParentQuery($this) 66 + ->setViewer($this->getViewer()) 67 + ->withPHIDs($file_phids) 68 + ->execute(); 69 + $files = mpull($files, null, 'getPHID'); 70 + } else { 71 + $files = array(); 72 + } 73 + 74 + foreach ($merchants as $merchant) { 75 + $file = idx($files, $merchant->getProfileImagePHID()); 76 + if (!$file) { 77 + if (!$default) { 78 + $default = PhabricatorFile::loadBuiltin( 79 + $this->getViewer(), 80 + 'merchant.png'); 81 + } 82 + $file = $default; 83 + } 84 + $merchant->attachProfileImageFile($file); 85 + } 51 86 } 52 87 53 88 return $merchants;
+3 -2
src/applications/phortune/query/PhortuneMerchantSearchEngine.php
··· 18 18 } 19 19 20 20 public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { 21 - $query = id(new PhortuneMerchantQuery()); 21 + $query = id(new PhortuneMerchantQuery()) 22 + ->needProfileImage(true); 22 23 23 24 return $query; 24 25 } ··· 74 75 ->setHeader($merchant->getName()) 75 76 ->setHref('/phortune/merchant/'.$merchant->getID().'/') 76 77 ->setObject($merchant) 77 - ->setImageIcon('fa-bank'); 78 + ->setImageURI($merchant->getProfileImageURI()); 78 79 79 80 $list->addItem($item); 80 81 }
+20
src/applications/phortune/storage/PhortuneMerchant.php
··· 9 9 protected $viewPolicy; 10 10 protected $description; 11 11 protected $contactInfo; 12 + protected $profileImagePHID; 12 13 13 14 private $memberPHIDs = self::ATTACHABLE; 15 + private $profileImageFile = self::ATTACHABLE; 14 16 15 17 public static function initializeNewMerchant(PhabricatorUser $actor) { 16 18 return id(new PhortuneMerchant()) ··· 25 27 'name' => 'text255', 26 28 'description' => 'text', 27 29 'contactInfo' => 'text', 30 + 'profileImagePHID' => 'phid?', 28 31 ), 29 32 ) + parent::getConfiguration(); 30 33 } ··· 41 44 public function attachMemberPHIDs(array $member_phids) { 42 45 $this->memberPHIDs = $member_phids; 43 46 return $this; 47 + } 48 + 49 + public function getViewURI() { 50 + return '/phortune/merchant/'.$this->getID().'/'; 51 + } 52 + 53 + public function getProfileImageURI() { 54 + return $this->getProfileImageFile()->getBestURI(); 55 + } 56 + 57 + public function attachProfileImageFile(PhabricatorFile $file) { 58 + $this->profileImageFile = $file; 59 + return $this; 60 + } 61 + 62 + public function getProfileImageFile() { 63 + return $this->assertAttached($this->profileImageFile); 44 64 } 45 65 46 66
+1
src/applications/phortune/storage/PhortuneMerchantTransaction.php
··· 6 6 const TYPE_NAME = 'merchant:name'; 7 7 const TYPE_DESCRIPTION = 'merchant:description'; 8 8 const TYPE_CONTACTINFO = 'merchant:contactinfo'; 9 + const TYPE_PICTURE = 'merchant:picture'; 9 10 10 11 public function getApplicationName() { 11 12 return 'phortune';