Page MenuHomePhabricator

D16751.id40345.diff
No OneTemporary

D16751.id40345.diff

diff --git a/resources/builtin/merchant.png b/resources/builtin/merchant.png
new file mode 100644
index 0000000000000000000000000000000000000000..c8381eb00fd59eff93fb0a28242ad81f360331d4
GIT binary patch
literal 5344
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
Jt&VH-{{jDmc#;4B
literal 0
Hc$@<O00001
diff --git a/resources/sql/autopatches/20161025.phortune.merchant.image.1.sql b/resources/sql/autopatches/20161025.phortune.merchant.image.1.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20161025.phortune.merchant.image.1.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_phortune.phortune_merchant
+ ADD profileImagePHID VARBINARY(64);
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -4179,6 +4179,7 @@
'PhortuneMerchantInvoiceCreateController' => 'applications/phortune/controller/PhortuneMerchantInvoiceCreateController.php',
'PhortuneMerchantListController' => 'applications/phortune/controller/PhortuneMerchantListController.php',
'PhortuneMerchantPHIDType' => 'applications/phortune/phid/PhortuneMerchantPHIDType.php',
+ 'PhortuneMerchantPictureController' => 'applications/phortune/controller/PhortuneMerchantPictureController.php',
'PhortuneMerchantQuery' => 'applications/phortune/query/PhortuneMerchantQuery.php',
'PhortuneMerchantSearchEngine' => 'applications/phortune/query/PhortuneMerchantSearchEngine.php',
'PhortuneMerchantTransaction' => 'applications/phortune/storage/PhortuneMerchantTransaction.php',
@@ -9419,6 +9420,7 @@
'PhortuneMerchantInvoiceCreateController' => 'PhortuneMerchantController',
'PhortuneMerchantListController' => 'PhortuneMerchantController',
'PhortuneMerchantPHIDType' => 'PhabricatorPHIDType',
+ 'PhortuneMerchantPictureController' => 'PhortuneMerchantController',
'PhortuneMerchantQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhortuneMerchantSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhortuneMerchantTransaction' => 'PhabricatorApplicationTransaction',
diff --git a/src/applications/files/transform/.PhabricatorFileThumbnailTransform.php.swp b/src/applications/files/transform/.PhabricatorFileThumbnailTransform.php.swp
new file mode 100644
index 0000000000000000000000000000000000000000..9e9f426fe07f2ea2aef7426a5b2d15152417467a
GIT binary patch
literal 1024
zc$`Zz$V<%2S1{5u)iY*50xP5$7?Lv*Qy7Q<1sRFSx+$q;dO7*Yi8;8{6&EGzCl(as
zWF{w;Waj4;>!)Srq!#O!6eZ>rr{x#r>IY;bCKZ8X^NZYoQXv_oxk-76nK>aa6?z33
P1;n^$6pVsVKnwr?TE8Z!
literal 0
Hc$@<O00001
diff --git a/src/applications/phortune/application/PhabricatorPhortuneApplication.php b/src/applications/phortune/application/PhabricatorPhortuneApplication.php
--- a/src/applications/phortune/application/PhabricatorPhortuneApplication.php
+++ b/src/applications/phortune/application/PhabricatorPhortuneApplication.php
@@ -81,6 +81,7 @@
),
'merchant/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PhortuneMerchantListController',
+ 'picture/(?:(?P<id>\d+)/)?' => 'PhortuneMerchantPictureController',
'edit/(?:(?P<id>\d+)/)?' => 'PhortuneMerchantEditController',
'orders/(?P<merchantID>\d+)/(?:query/(?P<queryKey>[^/]+)/)?'
=> 'PhortuneCartListController',
diff --git a/src/applications/phortune/controller/PhortuneMerchantPictureController.php b/src/applications/phortune/controller/PhortuneMerchantPictureController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/controller/PhortuneMerchantPictureController.php
@@ -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,
+ ));
+
+ }
+}
diff --git a/src/applications/phortune/controller/PhortuneMerchantViewController.php b/src/applications/phortune/controller/PhortuneMerchantViewController.php
--- a/src/applications/phortune/controller/PhortuneMerchantViewController.php
+++ b/src/applications/phortune/controller/PhortuneMerchantViewController.php
@@ -10,6 +10,7 @@
$merchant = id(new PhortuneMerchantQuery())
->setViewer($viewer)
->withIDs(array($id))
+ ->needProfileImage(true)
->executeOne();
if (!$merchant) {
return new Aphront404Response();
@@ -28,7 +29,7 @@
->setHeader($merchant->getName())
->setUser($viewer)
->setPolicyObject($merchant)
- ->setHeaderIcon('fa-bank');
+ ->setImage($merchant->getProfileImageURI());
$providers = id(new PhortunePaymentProviderConfigQuery())
->setViewer($viewer)
@@ -173,6 +174,14 @@
$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(
+ id(new PhabricatorActionView())
->setName(pht('View Orders'))
->setIcon('fa-shopping-cart')
->setHref($this->getApplicationURI("merchant/orders/{$id}/"))
diff --git a/src/applications/phortune/editor/PhortuneMerchantEditor.php b/src/applications/phortune/editor/PhortuneMerchantEditor.php
--- a/src/applications/phortune/editor/PhortuneMerchantEditor.php
+++ b/src/applications/phortune/editor/PhortuneMerchantEditor.php
@@ -17,6 +17,7 @@
$types[] = PhortuneMerchantTransaction::TYPE_NAME;
$types[] = PhortuneMerchantTransaction::TYPE_DESCRIPTION;
$types[] = PhortuneMerchantTransaction::TYPE_CONTACTINFO;
+ $types[] = PhortuneMerchantTransaction::TYPE_PICTURE;
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
$types[] = PhabricatorTransactions::TYPE_EDGE;
@@ -33,6 +34,8 @@
return $object->getDescription();
case PhortuneMerchantTransaction::TYPE_CONTACTINFO:
return $object->getContactInfo();
+ case PhortuneMerchantTransaction::TYPE_PICTURE:
+ return $object->getProfileImagePHID();
}
return parent::getCustomTransactionOldValue($object, $xaction);
@@ -46,6 +49,7 @@
case PhortuneMerchantTransaction::TYPE_NAME:
case PhortuneMerchantTransaction::TYPE_DESCRIPTION:
case PhortuneMerchantTransaction::TYPE_CONTACTINFO:
+ case PhortuneMerchantTransaction::TYPE_PICTURE:
return $xaction->getNewValue();
}
@@ -66,6 +70,9 @@
case PhortuneMerchantTransaction::TYPE_CONTACTINFO:
$object->setContactInfo($xaction->getNewValue());
return;
+ case PhortuneMerchantTransaction::TYPE_PICTURE:
+ $object->setProfileImagePHID($xaction->getNewValue());
+ return;
}
return parent::applyCustomInternalTransaction($object, $xaction);
@@ -79,6 +86,7 @@
case PhortuneMerchantTransaction::TYPE_NAME:
case PhortuneMerchantTransaction::TYPE_DESCRIPTION:
case PhortuneMerchantTransaction::TYPE_CONTACTINFO:
+ case PhortuneMerchantTransaction::TYPE_PICTURE:
return;
}
diff --git a/src/applications/phortune/query/PhortuneMerchantQuery.php b/src/applications/phortune/query/PhortuneMerchantQuery.php
--- a/src/applications/phortune/query/PhortuneMerchantQuery.php
+++ b/src/applications/phortune/query/PhortuneMerchantQuery.php
@@ -6,6 +6,7 @@
private $ids;
private $phids;
private $memberPHIDs;
+ private $needProfileImage;
public function withIDs(array $ids) {
$this->ids = $ids;
@@ -22,6 +23,11 @@
return $this;
}
+ public function needProfileImage($need) {
+ $this->needProfileImage = $need;
+ return $this;
+ }
+
protected function loadPage() {
$table = new PhortuneMerchant();
$conn = $table->establishConnection('r');
@@ -50,6 +56,35 @@
$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;
}
diff --git a/src/applications/phortune/query/PhortuneMerchantSearchEngine.php b/src/applications/phortune/query/PhortuneMerchantSearchEngine.php
--- a/src/applications/phortune/query/PhortuneMerchantSearchEngine.php
+++ b/src/applications/phortune/query/PhortuneMerchantSearchEngine.php
@@ -18,7 +18,8 @@
}
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
- $query = id(new PhortuneMerchantQuery());
+ $query = id(new PhortuneMerchantQuery())
+ ->needProfileImage(true);
return $query;
}
@@ -74,7 +75,7 @@
->setHeader($merchant->getName())
->setHref('/phortune/merchant/'.$merchant->getID().'/')
->setObject($merchant)
- ->setImageIcon('fa-bank');
+ ->setImageURI($merchant->getProfileImageURI());
$list->addItem($item);
}
diff --git a/src/applications/phortune/storage/PhortuneMerchant.php b/src/applications/phortune/storage/PhortuneMerchant.php
--- a/src/applications/phortune/storage/PhortuneMerchant.php
+++ b/src/applications/phortune/storage/PhortuneMerchant.php
@@ -9,8 +9,10 @@
protected $viewPolicy;
protected $description;
protected $contactInfo;
+ protected $profileImagePHID;
private $memberPHIDs = self::ATTACHABLE;
+ private $profileImageFile = self::ATTACHABLE;
public static function initializeNewMerchant(PhabricatorUser $actor) {
return id(new PhortuneMerchant())
@@ -25,6 +27,7 @@
'name' => 'text255',
'description' => 'text',
'contactInfo' => 'text',
+ 'profileImagePHID' => 'phid?',
),
) + parent::getConfiguration();
}
@@ -43,6 +46,23 @@
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 )------------------------- */
diff --git a/src/applications/phortune/storage/PhortuneMerchantTransaction.php b/src/applications/phortune/storage/PhortuneMerchantTransaction.php
--- a/src/applications/phortune/storage/PhortuneMerchantTransaction.php
+++ b/src/applications/phortune/storage/PhortuneMerchantTransaction.php
@@ -6,6 +6,7 @@
const TYPE_NAME = 'merchant:name';
const TYPE_DESCRIPTION = 'merchant:description';
const TYPE_CONTACTINFO = 'merchant:contactinfo';
+ const TYPE_PICTURE = 'merchant:picture';
public function getApplicationName() {
return 'phortune';

File Metadata

Mime Type
text/plain
Expires
Sat, May 11, 12:37 AM (3 w, 5 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6284586
Default Alt Text
D16751.id40345.diff (24 KB)

Event Timeline