1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-09-19 16:58:48 +02:00

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
This commit is contained in:
Chad Little 2016-10-28 13:55:55 -07:00
parent 09775279a9
commit c3809b0d59
11 changed files with 316 additions and 3 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_phortune.phortune_merchant
ADD profileImagePHID VARBINARY(64);

View file

@ -4185,6 +4185,7 @@ phutil_register_library_map(array(
'PhortuneMerchantInvoiceCreateController' => 'applications/phortune/controller/PhortuneMerchantInvoiceCreateController.php', 'PhortuneMerchantInvoiceCreateController' => 'applications/phortune/controller/PhortuneMerchantInvoiceCreateController.php',
'PhortuneMerchantListController' => 'applications/phortune/controller/PhortuneMerchantListController.php', 'PhortuneMerchantListController' => 'applications/phortune/controller/PhortuneMerchantListController.php',
'PhortuneMerchantPHIDType' => 'applications/phortune/phid/PhortuneMerchantPHIDType.php', 'PhortuneMerchantPHIDType' => 'applications/phortune/phid/PhortuneMerchantPHIDType.php',
'PhortuneMerchantPictureController' => 'applications/phortune/controller/PhortuneMerchantPictureController.php',
'PhortuneMerchantQuery' => 'applications/phortune/query/PhortuneMerchantQuery.php', 'PhortuneMerchantQuery' => 'applications/phortune/query/PhortuneMerchantQuery.php',
'PhortuneMerchantSearchEngine' => 'applications/phortune/query/PhortuneMerchantSearchEngine.php', 'PhortuneMerchantSearchEngine' => 'applications/phortune/query/PhortuneMerchantSearchEngine.php',
'PhortuneMerchantTransaction' => 'applications/phortune/storage/PhortuneMerchantTransaction.php', 'PhortuneMerchantTransaction' => 'applications/phortune/storage/PhortuneMerchantTransaction.php',
@ -9434,6 +9435,7 @@ phutil_register_library_map(array(
'PhortuneMerchantInvoiceCreateController' => 'PhortuneMerchantController', 'PhortuneMerchantInvoiceCreateController' => 'PhortuneMerchantController',
'PhortuneMerchantListController' => 'PhortuneMerchantController', 'PhortuneMerchantListController' => 'PhortuneMerchantController',
'PhortuneMerchantPHIDType' => 'PhabricatorPHIDType', 'PhortuneMerchantPHIDType' => 'PhabricatorPHIDType',
'PhortuneMerchantPictureController' => 'PhortuneMerchantController',
'PhortuneMerchantQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhortuneMerchantQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhortuneMerchantSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PhortuneMerchantSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhortuneMerchantTransaction' => 'PhabricatorApplicationTransaction', 'PhortuneMerchantTransaction' => 'PhabricatorApplicationTransaction',

View file

@ -81,6 +81,7 @@ final class PhabricatorPhortuneApplication extends PhabricatorApplication {
), ),
'merchant/' => array( 'merchant/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PhortuneMerchantListController', '(?:query/(?P<queryKey>[^/]+)/)?' => 'PhortuneMerchantListController',
'picture/(?:(?P<id>\d+)/)?' => 'PhortuneMerchantPictureController',
'edit/(?:(?P<id>\d+)/)?' => 'PhortuneMerchantEditController', 'edit/(?:(?P<id>\d+)/)?' => 'PhortuneMerchantEditController',
'orders/(?P<merchantID>\d+)/(?:query/(?P<queryKey>[^/]+)/)?' 'orders/(?P<merchantID>\d+)/(?:query/(?P<queryKey>[^/]+)/)?'
=> 'PhortuneCartListController', => 'PhortuneCartListController',

View file

@ -0,0 +1,234 @@
<?php
final class PhortuneMerchantPictureController
extends PhortuneMerchantController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
$merchant = id(new PhortuneMerchantQuery())
->setViewer($viewer)
->withIDs(array($id))
->needProfileImage(true)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$merchant) {
return new Aphront404Response();
}
$uri = $merchant->getViewURI();
$supported_formats = PhabricatorFile::getTransformableImageFormats();
$e_file = true;
$errors = array();
if ($request->isFormPost()) {
$phid = $request->getStr('phid');
$is_default = false;
if ($phid == PhabricatorPHIDConstants::PHID_VOID) {
$phid = null;
$is_default = true;
} else if ($phid) {
$file = id(new PhabricatorFileQuery())
->setViewer($viewer)
->withPHIDs(array($phid))
->executeOne();
} else {
if ($request->getFileExists('picture')) {
$file = PhabricatorFile::newFromPHPUpload(
$_FILES['picture'],
array(
'authorPHID' => $viewer->getPHID(),
'canCDN' => true,
));
} else {
$e_file = pht('Required');
$errors[] = pht(
'You must choose a file when uploading a merchant logo.');
}
}
if (!$errors && !$is_default) {
if (!$file->isTransformableImage()) {
$e_file = pht('Not Supported');
$errors[] = pht(
'This server only supports these image formats: %s.',
implode(', ', $supported_formats));
} else {
$xform = PhabricatorFileTransform::getTransformByKey(
PhabricatorFileThumbnailTransform::TRANSFORM_PROFILE);
$xformed = $xform->executeTransform($file);
}
}
if (!$errors) {
if ($is_default) {
$new_value = null;
} else {
$xformed->attachToObject($merchant->getPHID());
$new_value = $xformed->getPHID();
}
$xactions = array();
$xactions[] = id(new PhortuneMerchantTransaction())
->setTransactionType(PhortuneMerchantTransaction::TYPE_PICTURE)
->setNewValue($new_value);
$editor = id(new PhortuneMerchantEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnMissingFields(true)
->setContinueOnNoEffect(true);
$editor->applyTransactions($merchant, $xactions);
return id(new AphrontRedirectResponse())->setURI($uri);
}
}
$title = pht('Edit Merchant Picture');
$form = id(new PHUIFormLayoutView())
->setUser($viewer);
$default_image = PhabricatorFile::loadBuiltin($viewer, 'merchant.png');
$images = array();
$current = $merchant->getProfileImagePHID();
$has_current = false;
if ($current) {
$file = id(new PhabricatorFileQuery())
->setViewer($viewer)
->withPHIDs(array($current))
->executeOne();
if ($file) {
if ($file->isTransformableImage()) {
$has_current = true;
$images[$current] = array(
'uri' => $file->getBestURI(),
'tip' => pht('Current Picture'),
);
}
}
}
$images[PhabricatorPHIDConstants::PHID_VOID] = array(
'uri' => $default_image->getBestURI(),
'tip' => pht('Default Picture'),
);
require_celerity_resource('people-profile-css');
Javelin::initBehavior('phabricator-tooltips', array());
$buttons = array();
foreach ($images as $phid => $spec) {
$button = javelin_tag(
'button',
array(
'class' => 'grey profile-image-button',
'sigil' => 'has-tooltip',
'meta' => array(
'tip' => $spec['tip'],
'size' => 300,
),
),
phutil_tag(
'img',
array(
'height' => 50,
'width' => 50,
'src' => $spec['uri'],
)));
$button = array(
phutil_tag(
'input',
array(
'type' => 'hidden',
'name' => 'phid',
'value' => $phid,
)),
$button,
);
$button = phabricator_form(
$viewer,
array(
'class' => 'profile-image-form',
'method' => 'POST',
),
$button);
$buttons[] = $button;
}
if ($has_current) {
$form->appendChild(
id(new AphrontFormMarkupControl())
->setLabel(pht('Current Logo'))
->setValue(array_shift($buttons)));
}
$form->appendChild(
id(new AphrontFormMarkupControl())
->setLabel(pht('Use Logo'))
->setValue($buttons));
$form_box = id(new PHUIObjectBoxView())
->setHeaderText($title)
->setFormErrors($errors)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setForm($form);
$upload_form = id(new AphrontFormView())
->setUser($viewer)
->setEncType('multipart/form-data')
->appendChild(
id(new AphrontFormFileControl())
->setName('picture')
->setLabel(pht('Upload Logo'))
->setError($e_file)
->setCaption(
pht('Supported formats: %s', implode(', ', $supported_formats))))
->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton($uri)
->setValue(pht('Upload Logo')));
$upload_box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Upload New Logo'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setForm($upload_form);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($merchant->getName(), $uri);
$crumbs->addTextCrumb(pht('Merchant Logo'));
$crumbs->setBorder(true);
$header = id(new PHUIHeaderView())
->setHeader(pht('Edit Merchant Logo'))
->setHeaderIcon('fa-camera');
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setFooter(array(
$form_box,
$upload_box,
));
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild(
array(
$view,
));
}
}

View file

@ -10,6 +10,7 @@ final class PhortuneMerchantViewController
$merchant = id(new PhortuneMerchantQuery()) $merchant = id(new PhortuneMerchantQuery())
->setViewer($viewer) ->setViewer($viewer)
->withIDs(array($id)) ->withIDs(array($id))
->needProfileImage(true)
->executeOne(); ->executeOne();
if (!$merchant) { if (!$merchant) {
return new Aphront404Response(); return new Aphront404Response();
@ -28,7 +29,7 @@ final class PhortuneMerchantViewController
->setHeader($merchant->getName()) ->setHeader($merchant->getName())
->setUser($viewer) ->setUser($viewer)
->setPolicyObject($merchant) ->setPolicyObject($merchant)
->setHeaderIcon('fa-bank'); ->setImage($merchant->getProfileImageURI());
$providers = id(new PhortunePaymentProviderConfigQuery()) $providers = id(new PhortunePaymentProviderConfigQuery())
->setViewer($viewer) ->setViewer($viewer)
@ -171,6 +172,14 @@ final class PhortuneMerchantViewController
->setWorkflow(!$can_edit) ->setWorkflow(!$can_edit)
->setHref($this->getApplicationURI("merchant/edit/{$id}/"))); ->setHref($this->getApplicationURI("merchant/edit/{$id}/")));
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Edit Logo'))
->setIcon('fa-camera')
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit)
->setHref($this->getApplicationURI("merchant/picture/{$id}/")));
$curtain->addAction( $curtain->addAction(
id(new PhabricatorActionView()) id(new PhabricatorActionView())
->setName(pht('View Orders')) ->setName(pht('View Orders'))

View file

@ -17,6 +17,7 @@ final class PhortuneMerchantEditor
$types[] = PhortuneMerchantTransaction::TYPE_NAME; $types[] = PhortuneMerchantTransaction::TYPE_NAME;
$types[] = PhortuneMerchantTransaction::TYPE_DESCRIPTION; $types[] = PhortuneMerchantTransaction::TYPE_DESCRIPTION;
$types[] = PhortuneMerchantTransaction::TYPE_CONTACTINFO; $types[] = PhortuneMerchantTransaction::TYPE_CONTACTINFO;
$types[] = PhortuneMerchantTransaction::TYPE_PICTURE;
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
$types[] = PhabricatorTransactions::TYPE_EDGE; $types[] = PhabricatorTransactions::TYPE_EDGE;
@ -33,6 +34,8 @@ final class PhortuneMerchantEditor
return $object->getDescription(); return $object->getDescription();
case PhortuneMerchantTransaction::TYPE_CONTACTINFO: case PhortuneMerchantTransaction::TYPE_CONTACTINFO:
return $object->getContactInfo(); return $object->getContactInfo();
case PhortuneMerchantTransaction::TYPE_PICTURE:
return $object->getProfileImagePHID();
} }
return parent::getCustomTransactionOldValue($object, $xaction); return parent::getCustomTransactionOldValue($object, $xaction);
@ -46,6 +49,7 @@ final class PhortuneMerchantEditor
case PhortuneMerchantTransaction::TYPE_NAME: case PhortuneMerchantTransaction::TYPE_NAME:
case PhortuneMerchantTransaction::TYPE_DESCRIPTION: case PhortuneMerchantTransaction::TYPE_DESCRIPTION:
case PhortuneMerchantTransaction::TYPE_CONTACTINFO: case PhortuneMerchantTransaction::TYPE_CONTACTINFO:
case PhortuneMerchantTransaction::TYPE_PICTURE:
return $xaction->getNewValue(); return $xaction->getNewValue();
} }
@ -66,6 +70,9 @@ final class PhortuneMerchantEditor
case PhortuneMerchantTransaction::TYPE_CONTACTINFO: case PhortuneMerchantTransaction::TYPE_CONTACTINFO:
$object->setContactInfo($xaction->getNewValue()); $object->setContactInfo($xaction->getNewValue());
return; return;
case PhortuneMerchantTransaction::TYPE_PICTURE:
$object->setProfileImagePHID($xaction->getNewValue());
return;
} }
return parent::applyCustomInternalTransaction($object, $xaction); return parent::applyCustomInternalTransaction($object, $xaction);
@ -79,6 +86,7 @@ final class PhortuneMerchantEditor
case PhortuneMerchantTransaction::TYPE_NAME: case PhortuneMerchantTransaction::TYPE_NAME:
case PhortuneMerchantTransaction::TYPE_DESCRIPTION: case PhortuneMerchantTransaction::TYPE_DESCRIPTION:
case PhortuneMerchantTransaction::TYPE_CONTACTINFO: case PhortuneMerchantTransaction::TYPE_CONTACTINFO:
case PhortuneMerchantTransaction::TYPE_PICTURE:
return; return;
} }

View file

@ -6,6 +6,7 @@ final class PhortuneMerchantQuery
private $ids; private $ids;
private $phids; private $phids;
private $memberPHIDs; private $memberPHIDs;
private $needProfileImage;
public function withIDs(array $ids) { public function withIDs(array $ids) {
$this->ids = $ids; $this->ids = $ids;
@ -22,6 +23,11 @@ final class PhortuneMerchantQuery
return $this; return $this;
} }
public function needProfileImage($need) {
$this->needProfileImage = $need;
return $this;
}
protected function loadPage() { protected function loadPage() {
$table = new PhortuneMerchant(); $table = new PhortuneMerchant();
$conn = $table->establishConnection('r'); $conn = $table->establishConnection('r');
@ -50,6 +56,35 @@ final class PhortuneMerchantQuery
$merchant->attachMemberPHIDs($member_phids); $merchant->attachMemberPHIDs($member_phids);
} }
if ($this->needProfileImage) {
$default = null;
$file_phids = mpull($merchants, 'getProfileImagePHID');
$file_phids = array_filter($file_phids);
if ($file_phids) {
$files = id(new PhabricatorFileQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($file_phids)
->execute();
$files = mpull($files, null, 'getPHID');
} else {
$files = array();
}
foreach ($merchants as $merchant) {
$file = idx($files, $merchant->getProfileImagePHID());
if (!$file) {
if (!$default) {
$default = PhabricatorFile::loadBuiltin(
$this->getViewer(),
'merchant.png');
}
$file = $default;
}
$merchant->attachProfileImageFile($file);
}
}
return $merchants; return $merchants;
} }

View file

@ -18,7 +18,8 @@ final class PhortuneMerchantSearchEngine
} }
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
$query = id(new PhortuneMerchantQuery()); $query = id(new PhortuneMerchantQuery())
->needProfileImage(true);
return $query; return $query;
} }
@ -74,7 +75,7 @@ final class PhortuneMerchantSearchEngine
->setHeader($merchant->getName()) ->setHeader($merchant->getName())
->setHref('/phortune/merchant/'.$merchant->getID().'/') ->setHref('/phortune/merchant/'.$merchant->getID().'/')
->setObject($merchant) ->setObject($merchant)
->setImageIcon('fa-bank'); ->setImageURI($merchant->getProfileImageURI());
$list->addItem($item); $list->addItem($item);
} }

View file

@ -9,8 +9,10 @@ final class PhortuneMerchant extends PhortuneDAO
protected $viewPolicy; protected $viewPolicy;
protected $description; protected $description;
protected $contactInfo; protected $contactInfo;
protected $profileImagePHID;
private $memberPHIDs = self::ATTACHABLE; private $memberPHIDs = self::ATTACHABLE;
private $profileImageFile = self::ATTACHABLE;
public static function initializeNewMerchant(PhabricatorUser $actor) { public static function initializeNewMerchant(PhabricatorUser $actor) {
return id(new PhortuneMerchant()) return id(new PhortuneMerchant())
@ -25,6 +27,7 @@ final class PhortuneMerchant extends PhortuneDAO
'name' => 'text255', 'name' => 'text255',
'description' => 'text', 'description' => 'text',
'contactInfo' => 'text', 'contactInfo' => 'text',
'profileImagePHID' => 'phid?',
), ),
) + parent::getConfiguration(); ) + parent::getConfiguration();
} }
@ -43,6 +46,23 @@ final class PhortuneMerchant extends PhortuneDAO
return $this; return $this;
} }
public function getViewURI() {
return '/phortune/merchant/'.$this->getID().'/';
}
public function getProfileImageURI() {
return $this->getProfileImageFile()->getBestURI();
}
public function attachProfileImageFile(PhabricatorFile $file) {
$this->profileImageFile = $file;
return $this;
}
public function getProfileImageFile() {
return $this->assertAttached($this->profileImageFile);
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */ /* -( PhabricatorApplicationTransactionInterface )------------------------- */

View file

@ -6,6 +6,7 @@ final class PhortuneMerchantTransaction
const TYPE_NAME = 'merchant:name'; const TYPE_NAME = 'merchant:name';
const TYPE_DESCRIPTION = 'merchant:description'; const TYPE_DESCRIPTION = 'merchant:description';
const TYPE_CONTACTINFO = 'merchant:contactinfo'; const TYPE_CONTACTINFO = 'merchant:contactinfo';
const TYPE_PICTURE = 'merchant:picture';
public function getApplicationName() { public function getApplicationName() {
return 'phortune'; return 'phortune';