mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-30 17:30:59 +01:00
Drag-drop file upload.
Summary: - have files be uploaded by drag+drop instead of browse. - Files are named by their uploaded filename, the user isn't given a chance to enter a file name. Is this bad? - Store author PHID now with files - Allow an ?author=<username> to limit the /files/ list by author. - If one file is uploaded, the user is taken to its info page. - If several are uploaded, they are taken to a list of their files. Test Plan: - Quickly tested everything and it still worked, I'd recommend some people try this out before it gets committed though. It's a rather huge revision. Reviewers: epriestley, Ttech CC: Differential Revision: 612
This commit is contained in:
parent
49310391e0
commit
420235f9c4
18 changed files with 112 additions and 34 deletions
3
resources/sql/patches/055.add_author_to_files.sql
Normal file
3
resources/sql/patches/055.add_author_to_files.sql
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
ALTER TABLE phabricator_file.file
|
||||||
|
ADD COLUMN authorPHID VARCHAR(64) BINARY,
|
||||||
|
ADD KEY (authorPHID);
|
|
@ -76,7 +76,8 @@ class PhabricatorOAuthDefaultRegistrationController
|
||||||
$file = PhabricatorFile::newFromFileData(
|
$file = PhabricatorFile::newFromFileData(
|
||||||
$image,
|
$image,
|
||||||
array(
|
array(
|
||||||
'name' => $provider->getProviderKey().'-profile.jpg'
|
'name' => $provider->getProviderKey().'-profile.jpg',
|
||||||
|
'authorPHID' => $user->getPHID(),
|
||||||
));
|
));
|
||||||
$user->setProfileImagePHID($file->getPHID());
|
$user->setProfileImagePHID($file->getPHID());
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,11 +45,13 @@ class ConduitAPI_file_upload_Method extends ConduitAPIMethod {
|
||||||
$data = $request->getValue('data_base64');
|
$data = $request->getValue('data_base64');
|
||||||
$name = $request->getValue('name');
|
$name = $request->getValue('name');
|
||||||
$data = base64_decode($data, $strict = true);
|
$data = base64_decode($data, $strict = true);
|
||||||
|
$user = $request->getUser();
|
||||||
|
|
||||||
$file = PhabricatorFile::newFromFileData(
|
$file = PhabricatorFile::newFromFileData(
|
||||||
$data,
|
$data,
|
||||||
array(
|
array(
|
||||||
'name' => $name
|
'name' => $name,
|
||||||
|
'authorPHID' => $user->getPHID(),
|
||||||
));
|
));
|
||||||
return $file->getPHID();
|
return $file->getPHID();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ class PhabricatorFileDropUploadController extends PhabricatorFileController {
|
||||||
|
|
||||||
public function processRequest() {
|
public function processRequest() {
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
|
$user = $request->getUser();
|
||||||
|
|
||||||
$data = file_get_contents('php://input');
|
$data = file_get_contents('php://input');
|
||||||
$name = $request->getStr('name');
|
$name = $request->getStr('name');
|
||||||
|
@ -28,6 +29,7 @@ class PhabricatorFileDropUploadController extends PhabricatorFileController {
|
||||||
$data,
|
$data,
|
||||||
array(
|
array(
|
||||||
'name' => $request->getStr('name'),
|
'name' => $request->getStr('name'),
|
||||||
|
'authorPHID' => $user->getPHID(),
|
||||||
));
|
));
|
||||||
|
|
||||||
$view = new AphrontAttachedFileView();
|
$view = new AphrontAttachedFileView();
|
||||||
|
|
|
@ -22,13 +22,32 @@ class PhabricatorFileListController extends PhabricatorFileController {
|
||||||
|
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
|
|
||||||
|
$author_username = $request->getStr('author');
|
||||||
|
if ($author_username) {
|
||||||
|
$author = id(new PhabricatorUser())->loadOneWhere(
|
||||||
|
'userName = %s',
|
||||||
|
$author_username);
|
||||||
|
|
||||||
|
if (!$author) {
|
||||||
|
return id(new Aphront404Response());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$pager = new AphrontPagerView();
|
$pager = new AphrontPagerView();
|
||||||
$pager->setOffset($request->getInt('page'));
|
$pager->setOffset($request->getInt('page'));
|
||||||
|
|
||||||
$files = id(new PhabricatorFile())->loadAllWhere(
|
if ($author) {
|
||||||
'1 = 1 ORDER BY id DESC LIMIT %d, %d',
|
$files = id(new PhabricatorFile())->loadAllWhere(
|
||||||
$pager->getOffset(),
|
'authorPHID = %s ORDER BY id DESC LIMIT %d, %d',
|
||||||
$pager->getPageSize() + 1);
|
$author->getPHID(),
|
||||||
|
$pager->getOffset(),
|
||||||
|
$pager->getPageSize() + 1);
|
||||||
|
} else {
|
||||||
|
$files = id(new PhabricatorFile())->loadAllWhere(
|
||||||
|
'1 = 1 ORDER BY id DESC LIMIT %d, %d',
|
||||||
|
$pager->getOffset(),
|
||||||
|
$pager->getPageSize() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
$files = $pager->sliceResults($files);
|
$files = $pager->sliceResults($files);
|
||||||
$pager->setURI($request->getRequestURI(), 'page');
|
$pager->setURI($request->getRequestURI(), 'page');
|
||||||
|
|
|
@ -6,8 +6,10 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'aphront/response/404');
|
||||||
phutil_require_module('phabricator', 'applications/files/controller/base');
|
phutil_require_module('phabricator', 'applications/files/controller/base');
|
||||||
phutil_require_module('phabricator', 'applications/files/storage/file');
|
phutil_require_module('phabricator', 'applications/files/storage/file');
|
||||||
|
phutil_require_module('phabricator', 'applications/people/storage/user');
|
||||||
phutil_require_module('phabricator', 'view/control/pager');
|
phutil_require_module('phabricator', 'view/control/pager');
|
||||||
phutil_require_module('phabricator', 'view/control/table');
|
phutil_require_module('phabricator', 'view/control/table');
|
||||||
phutil_require_module('phabricator', 'view/layout/panel');
|
phutil_require_module('phabricator', 'view/layout/panel');
|
||||||
|
|
|
@ -39,6 +39,7 @@ class PhabricatorFileMacroEditController extends PhabricatorFileController {
|
||||||
$e_name = true;
|
$e_name = true;
|
||||||
|
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
|
$user = $request->getUser();
|
||||||
if ($request->isFormPost()) {
|
if ($request->isFormPost()) {
|
||||||
|
|
||||||
$macro->setName($request->getStr('name'));
|
$macro->setName($request->getStr('name'));
|
||||||
|
@ -60,6 +61,7 @@ class PhabricatorFileMacroEditController extends PhabricatorFileController {
|
||||||
idx($_FILES, 'file'),
|
idx($_FILES, 'file'),
|
||||||
array(
|
array(
|
||||||
'name' => $request->getStr('name'),
|
'name' => $request->getStr('name'),
|
||||||
|
'authorPHID' => $user->getPHID(),
|
||||||
));
|
));
|
||||||
$macro->setFilePHID($file->getPHID());
|
$macro->setFilePHID($file->getPHID());
|
||||||
|
|
||||||
|
|
|
@ -21,43 +21,47 @@ class PhabricatorFileUploadController extends PhabricatorFileController {
|
||||||
public function processRequest() {
|
public function processRequest() {
|
||||||
|
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
if ($request->isFormPost()) {
|
$user = $request->getUser();
|
||||||
$file = PhabricatorFile::newFromPHPUpload(
|
|
||||||
idx($_FILES, 'file'),
|
|
||||||
array(
|
|
||||||
'name' => $request->getStr('name'),
|
|
||||||
));
|
|
||||||
|
|
||||||
return id(new AphrontRedirectResponse())
|
if ($request->isFormPost()) {
|
||||||
->setURI('/file/info/'.phutil_escape_uri($file->getPHID()).'/');
|
$files = $request->getArr('file');
|
||||||
|
|
||||||
|
if (count($files) > 1) {
|
||||||
|
return id(new AphrontRedirectResponse())
|
||||||
|
->setURI('/file/?author='.phutil_escape_uri($user->getUserName()));
|
||||||
|
} else {
|
||||||
|
return id(new AphrontRedirectResponse())
|
||||||
|
->setURI('/file/info/'.end($files).'/');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$panel_id = celerity_generate_unique_node_id();
|
||||||
|
|
||||||
$form = new AphrontFormView();
|
$form = new AphrontFormView();
|
||||||
$form->setAction('/file/upload/');
|
$form->setAction('/file/upload/');
|
||||||
$form->setUser($request->getUser());
|
$form->setUser($request->getUser());
|
||||||
|
|
||||||
$form
|
$form
|
||||||
->setEncType('multipart/form-data')
|
->setEncType('multipart/form-data')
|
||||||
|
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormFileControl())
|
id(new AphrontFormDragAndDropUploadControl())
|
||||||
->setLabel('File')
|
->setLabel('Files')
|
||||||
->setName('file')
|
->setName('file')
|
||||||
->setError(true))
|
->setError(true)
|
||||||
->appendChild(
|
->setDragAndDropTarget($panel_id)
|
||||||
id(new AphrontFormTextControl())
|
->setActivatedClass('aphront-panel-view-drag-and-drop'))
|
||||||
->setLabel('Name')
|
|
||||||
->setName('name')
|
|
||||||
->setCaption('Optional file display name.'))
|
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormSubmitControl())
|
id(new AphrontFormSubmitControl())
|
||||||
->setValue('Upload')
|
->setValue('Done here!'));
|
||||||
->addCancelButton('/file/'));
|
|
||||||
|
|
||||||
$panel = new AphrontPanelView();
|
$panel = new AphrontPanelView();
|
||||||
$panel->setHeader('Upload File');
|
$panel->setHeader('Upload File');
|
||||||
|
|
||||||
$panel->appendChild($form);
|
$panel->appendChild($form);
|
||||||
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
|
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
|
||||||
|
$panel->setID($panel_id);
|
||||||
|
|
||||||
return $this->buildStandardPageResponse(
|
return $this->buildStandardPageResponse(
|
||||||
array($panel),
|
array($panel),
|
||||||
|
|
|
@ -8,11 +8,10 @@
|
||||||
|
|
||||||
phutil_require_module('phabricator', 'aphront/response/redirect');
|
phutil_require_module('phabricator', 'aphront/response/redirect');
|
||||||
phutil_require_module('phabricator', 'applications/files/controller/base');
|
phutil_require_module('phabricator', 'applications/files/controller/base');
|
||||||
phutil_require_module('phabricator', 'applications/files/storage/file');
|
phutil_require_module('phabricator', 'infrastructure/celerity/api');
|
||||||
phutil_require_module('phabricator', 'view/form/base');
|
phutil_require_module('phabricator', 'view/form/base');
|
||||||
phutil_require_module('phabricator', 'view/form/control/file');
|
phutil_require_module('phabricator', 'view/form/control/draganddropupload');
|
||||||
phutil_require_module('phabricator', 'view/form/control/submit');
|
phutil_require_module('phabricator', 'view/form/control/submit');
|
||||||
phutil_require_module('phabricator', 'view/form/control/text');
|
|
||||||
phutil_require_module('phabricator', 'view/layout/panel');
|
phutil_require_module('phabricator', 'view/layout/panel');
|
||||||
|
|
||||||
phutil_require_module('phutil', 'markup');
|
phutil_require_module('phutil', 'markup');
|
||||||
|
|
|
@ -71,6 +71,20 @@ class PhabricatorFileViewController extends PhabricatorFileController {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$author_child = null;
|
||||||
|
if ($file->getAuthorPHID()) {
|
||||||
|
$author = id(new PhabricatorUser())->loadOneWhere(
|
||||||
|
'phid = %s',
|
||||||
|
$file->getAuthorPHID());
|
||||||
|
|
||||||
|
if ($author) {
|
||||||
|
$author_child = id(new AphrontFormStaticControl())
|
||||||
|
->setLabel('Author')
|
||||||
|
->setName('author')
|
||||||
|
->setValue($author->getUserName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$form = new AphrontFormView();
|
$form = new AphrontFormView();
|
||||||
|
|
||||||
if ($file->isViewableInBrowser()) {
|
if ($file->isViewableInBrowser()) {
|
||||||
|
@ -80,7 +94,7 @@ class PhabricatorFileViewController extends PhabricatorFileController {
|
||||||
$form->setAction('/file/download/'.$file->getPHID().'/');
|
$form->setAction('/file/download/'.$file->getPHID().'/');
|
||||||
$button_name = 'Download File';
|
$button_name = 'Download File';
|
||||||
}
|
}
|
||||||
$form->setUser($this->getRequest()->getUser());
|
$form->setUser($user);
|
||||||
$form
|
$form
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormStaticControl())
|
id(new AphrontFormStaticControl())
|
||||||
|
@ -92,6 +106,7 @@ class PhabricatorFileViewController extends PhabricatorFileController {
|
||||||
->setLabel('PHID')
|
->setLabel('PHID')
|
||||||
->setName('phid')
|
->setName('phid')
|
||||||
->setValue($file->getPHID()))
|
->setValue($file->getPHID()))
|
||||||
|
->appendChild($author_child)
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormStaticControl())
|
id(new AphrontFormStaticControl())
|
||||||
->setLabel('Created')
|
->setLabel('Created')
|
||||||
|
|
|
@ -13,6 +13,7 @@ phutil_require_module('phabricator', 'applications/files/controller/base');
|
||||||
phutil_require_module('phabricator', 'applications/files/storage/file');
|
phutil_require_module('phabricator', 'applications/files/storage/file');
|
||||||
phutil_require_module('phabricator', 'applications/files/storage/transformed');
|
phutil_require_module('phabricator', 'applications/files/storage/transformed');
|
||||||
phutil_require_module('phabricator', 'applications/files/uri');
|
phutil_require_module('phabricator', 'applications/files/uri');
|
||||||
|
phutil_require_module('phabricator', 'applications/people/storage/user');
|
||||||
phutil_require_module('phabricator', 'view/control/table');
|
phutil_require_module('phabricator', 'view/control/table');
|
||||||
phutil_require_module('phabricator', 'view/form/base');
|
phutil_require_module('phabricator', 'view/form/base');
|
||||||
phutil_require_module('phabricator', 'view/form/control/static');
|
phutil_require_module('phabricator', 'view/form/control/static');
|
||||||
|
|
|
@ -29,6 +29,7 @@ class PhabricatorFile extends PhabricatorFileDAO {
|
||||||
protected $name;
|
protected $name;
|
||||||
protected $mimeType;
|
protected $mimeType;
|
||||||
protected $byteSize;
|
protected $byteSize;
|
||||||
|
protected $authorPHID;
|
||||||
|
|
||||||
protected $storageEngine;
|
protected $storageEngine;
|
||||||
protected $storageFormat;
|
protected $storageFormat;
|
||||||
|
@ -88,9 +89,14 @@ class PhabricatorFile extends PhabricatorFileDAO {
|
||||||
$file_name = idx($params, 'name');
|
$file_name = idx($params, 'name');
|
||||||
$file_name = self::normalizeFileName($file_name);
|
$file_name = self::normalizeFileName($file_name);
|
||||||
|
|
||||||
|
// If for whatever reason, authorPHID isn't passed as a param
|
||||||
|
// (always the case with newFromFileDownload()), store a ''
|
||||||
|
$authorPHID = idx($params, 'authorPHID');
|
||||||
|
|
||||||
$file = new PhabricatorFile();
|
$file = new PhabricatorFile();
|
||||||
$file->setName($file_name);
|
$file->setName($file_name);
|
||||||
$file->setByteSize(strlen($data));
|
$file->setByteSize(strlen($data));
|
||||||
|
$file->setAuthorPHID($authorPHID);
|
||||||
|
|
||||||
$blob = new PhabricatorFileStorageBlob();
|
$blob = new PhabricatorFileStorageBlob();
|
||||||
$blob->setData($data);
|
$blob->setData($data);
|
||||||
|
|
|
@ -53,7 +53,11 @@ class ManiphestTransactionSaveController extends ManiphestController {
|
||||||
if (!empty($_FILES['file'])) {
|
if (!empty($_FILES['file'])) {
|
||||||
$err = idx($_FILES['file'], 'error');
|
$err = idx($_FILES['file'], 'error');
|
||||||
if ($err != UPLOAD_ERR_NO_FILE) {
|
if ($err != UPLOAD_ERR_NO_FILE) {
|
||||||
$file = PhabricatorFile::newFromPHPUpload($_FILES['file']);
|
$file = PhabricatorFile::newFromPHPUpload(
|
||||||
|
$_FILES['file'],
|
||||||
|
array(
|
||||||
|
'authorPHID' => $user->getPHID(),
|
||||||
|
));
|
||||||
$files[] = $file;
|
$files[] = $file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ class PhabricatorMetaMTASendGridReceiveController
|
||||||
public function processRequest() {
|
public function processRequest() {
|
||||||
|
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
|
$user = $request->getUser();
|
||||||
|
|
||||||
$raw_headers = $request->getStr('headers');
|
$raw_headers = $request->getStr('headers');
|
||||||
$raw_headers = explode("\n", rtrim($raw_headers));
|
$raw_headers = explode("\n", rtrim($raw_headers));
|
||||||
|
@ -51,7 +52,11 @@ class PhabricatorMetaMTASendGridReceiveController
|
||||||
$file_phids = array();
|
$file_phids = array();
|
||||||
foreach ($_FILES as $file_raw) {
|
foreach ($_FILES as $file_raw) {
|
||||||
try {
|
try {
|
||||||
$file = PhabricatorFile::newFromPHPUpload($file_raw);
|
$file = PhabricatorFile::newFromPHPUpload(
|
||||||
|
$file_raw,
|
||||||
|
array(
|
||||||
|
'authorPHID' => $user->getPHID(),
|
||||||
|
));
|
||||||
$file_phids[] = $file->getPHID();
|
$file_phids[] = $file->getPHID();
|
||||||
} catch (Exception $ex) {
|
} catch (Exception $ex) {
|
||||||
phlog($ex);
|
phlog($ex);
|
||||||
|
|
|
@ -59,6 +59,7 @@ class PhabricatorPasteCreateController extends PhabricatorPasteController {
|
||||||
array(
|
array(
|
||||||
'name' => $title,
|
'name' => $title,
|
||||||
'mime-type' => 'text/plain; charset=utf-8',
|
'mime-type' => 'text/plain; charset=utf-8',
|
||||||
|
'authorPHID' => $user->getPHID(),
|
||||||
));
|
));
|
||||||
$paste->setFilePHID($paste_file->getPHID());
|
$paste->setFilePHID($paste_file->getPHID());
|
||||||
$paste->setAuthorPHID($user->getPHID());
|
$paste->setAuthorPHID($user->getPHID());
|
||||||
|
|
|
@ -40,7 +40,11 @@ class PhabricatorPeopleProfileEditController
|
||||||
if (!empty($_FILES['image'])) {
|
if (!empty($_FILES['image'])) {
|
||||||
$err = idx($_FILES['image'], 'error');
|
$err = idx($_FILES['image'], 'error');
|
||||||
if ($err != UPLOAD_ERR_NO_FILE) {
|
if ($err != UPLOAD_ERR_NO_FILE) {
|
||||||
$file = PhabricatorFile::newFromPHPUpload($_FILES['image']);
|
$file = PhabricatorFile::newFromPHPUpload(
|
||||||
|
$_FILES['image'],
|
||||||
|
array(
|
||||||
|
'authorPHID' => $user->getPHID(),
|
||||||
|
));
|
||||||
$okay = $file->isTransformableImage();
|
$okay = $file->isTransformableImage();
|
||||||
if ($okay) {
|
if ($okay) {
|
||||||
$xformer = new PhabricatorImageTransformer();
|
$xformer = new PhabricatorImageTransformer();
|
||||||
|
|
|
@ -117,7 +117,11 @@ class PhabricatorUserSettingsController extends PhabricatorPeopleController {
|
||||||
if (!empty($_FILES['profile'])) {
|
if (!empty($_FILES['profile'])) {
|
||||||
$err = idx($_FILES['profile'], 'error');
|
$err = idx($_FILES['profile'], 'error');
|
||||||
if ($err != UPLOAD_ERR_NO_FILE) {
|
if ($err != UPLOAD_ERR_NO_FILE) {
|
||||||
$file = PhabricatorFile::newFromPHPUpload($_FILES['profile']);
|
$file = PhabricatorFile::newFromPHPUpload(
|
||||||
|
$_FILES['profile'],
|
||||||
|
array(
|
||||||
|
'authorPHID' => $user->getPHID(),
|
||||||
|
));
|
||||||
$okay = $file->isTransformableImage();
|
$okay = $file->isTransformableImage();
|
||||||
if ($okay) {
|
if ($okay) {
|
||||||
$xformer = new PhabricatorImageTransformer();
|
$xformer = new PhabricatorImageTransformer();
|
||||||
|
|
|
@ -57,7 +57,11 @@ class PhabricatorProjectProfileEditController
|
||||||
if (!empty($_FILES['image'])) {
|
if (!empty($_FILES['image'])) {
|
||||||
$err = idx($_FILES['image'], 'error');
|
$err = idx($_FILES['image'], 'error');
|
||||||
if ($err != UPLOAD_ERR_NO_FILE) {
|
if ($err != UPLOAD_ERR_NO_FILE) {
|
||||||
$file = PhabricatorFile::newFromPHPUpload($_FILES['image']);
|
$file = PhabricatorFile::newFromPHPUpload(
|
||||||
|
$_FILES['image'],
|
||||||
|
array(
|
||||||
|
'authorPHID' => $user->getPHID(),
|
||||||
|
));
|
||||||
$okay = $file->isTransformableImage();
|
$okay = $file->isTransformableImage();
|
||||||
if ($okay) {
|
if ($okay) {
|
||||||
$xformer = new PhabricatorImageTransformer();
|
$xformer = new PhabricatorImageTransformer();
|
||||||
|
|
Loading…
Reference in a new issue