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

Provide a rudimentary "Attached Files" curtain UI panel

Summary: Ref T13682. Provide a basic UI element for showing file attached to an object.

Test Plan: Viewed objects with attached files in the UI.

Maniphest Tasks: T13682

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

+156
+4
src/__phutil_library_map__.php
··· 3508 3508 'PhabricatorFileTransformController' => 'applications/files/controller/PhabricatorFileTransformController.php', 3509 3509 'PhabricatorFileTransformListController' => 'applications/files/controller/PhabricatorFileTransformListController.php', 3510 3510 'PhabricatorFileTransformTestCase' => 'applications/files/transform/__tests__/PhabricatorFileTransformTestCase.php', 3511 + 'PhabricatorFileUICurtainListController' => 'applications/files/controller/PhabricatorFileUICurtainListController.php', 3511 3512 'PhabricatorFileUploadController' => 'applications/files/controller/PhabricatorFileUploadController.php', 3512 3513 'PhabricatorFileUploadDialogController' => 'applications/files/controller/PhabricatorFileUploadDialogController.php', 3513 3514 'PhabricatorFileUploadException' => 'applications/files/exception/PhabricatorFileUploadException.php', ··· 3521 3522 'PhabricatorFilesComposeAvatarBuiltinFile' => 'applications/files/builtin/PhabricatorFilesComposeAvatarBuiltinFile.php', 3522 3523 'PhabricatorFilesComposeIconBuiltinFile' => 'applications/files/builtin/PhabricatorFilesComposeIconBuiltinFile.php', 3523 3524 'PhabricatorFilesConfigOptions' => 'applications/files/config/PhabricatorFilesConfigOptions.php', 3525 + 'PhabricatorFilesCurtainExtension' => 'applications/files/engineextension/PhabricatorFilesCurtainExtension.php', 3524 3526 'PhabricatorFilesManagementCatWorkflow' => 'applications/files/management/PhabricatorFilesManagementCatWorkflow.php', 3525 3527 'PhabricatorFilesManagementCompactWorkflow' => 'applications/files/management/PhabricatorFilesManagementCompactWorkflow.php', 3526 3528 'PhabricatorFilesManagementCycleWorkflow' => 'applications/files/management/PhabricatorFilesManagementCycleWorkflow.php', ··· 9970 9972 'PhabricatorFileTransformController' => 'PhabricatorFileController', 9971 9973 'PhabricatorFileTransformListController' => 'PhabricatorFileController', 9972 9974 'PhabricatorFileTransformTestCase' => 'PhabricatorTestCase', 9975 + 'PhabricatorFileUICurtainListController' => 'PhabricatorFileController', 9973 9976 'PhabricatorFileUploadController' => 'PhabricatorFileController', 9974 9977 'PhabricatorFileUploadDialogController' => 'PhabricatorFileController', 9975 9978 'PhabricatorFileUploadException' => 'Exception', ··· 9983 9986 'PhabricatorFilesComposeAvatarBuiltinFile' => 'PhabricatorFilesBuiltinFile', 9984 9987 'PhabricatorFilesComposeIconBuiltinFile' => 'PhabricatorFilesBuiltinFile', 9985 9988 'PhabricatorFilesConfigOptions' => 'PhabricatorApplicationConfigOptions', 9989 + 'PhabricatorFilesCurtainExtension' => 'PHUICurtainExtension', 9986 9990 'PhabricatorFilesManagementCatWorkflow' => 'PhabricatorFilesManagementWorkflow', 9987 9991 'PhabricatorFilesManagementCompactWorkflow' => 'PhabricatorFilesManagementWorkflow', 9988 9992 'PhabricatorFilesManagementCycleWorkflow' => 'PhabricatorFilesManagementWorkflow',
+2
src/applications/files/application/PhabricatorFilesApplication.php
··· 95 95 ), 96 96 'document/(?P<engineKey>[^/]+)/(?P<phid>[^/]+)/' 97 97 => 'PhabricatorFileDocumentController', 98 + 'ui/curtainlist/(?P<phid>[^/]+)/' 99 + => 'PhabricatorFileUICurtainListController', 98 100 ) + $this->getResourceSubroutes(), 99 101 ); 100 102 }
+61
src/applications/files/controller/PhabricatorFileUICurtainListController.php
··· 1 + <?php 2 + 3 + final class PhabricatorFileUICurtainListController 4 + extends PhabricatorFileController { 5 + 6 + public function shouldAllowPublic() { 7 + return true; 8 + } 9 + 10 + public function handleRequest(AphrontRequest $request) { 11 + $viewer = $request->getViewer(); 12 + 13 + $object_phid = $request->getURIData('phid'); 14 + 15 + $object = id(new PhabricatorObjectQuery()) 16 + ->setViewer($viewer) 17 + ->withPHIDs(array($object_phid)) 18 + ->executeOne(); 19 + if (!$object) { 20 + return new Aphront404Response(); 21 + } 22 + 23 + $attachments = id(new PhabricatorFileAttachmentQuery()) 24 + ->setViewer($viewer) 25 + ->withObjectPHIDs(array($object->getPHID())) 26 + ->needFiles(true) 27 + ->execute(); 28 + 29 + $handles = $viewer->loadHandles(array($object_phid)); 30 + $object_handle = $handles[$object_phid]; 31 + 32 + $file_phids = mpull($attachments, 'getFilePHID'); 33 + $file_handles = $viewer->loadHandles($file_phids); 34 + 35 + $list = id(new PHUIObjectItemListView()) 36 + ->setUser($viewer); 37 + foreach ($attachments as $attachment) { 38 + $file_phid = $attachment->getFilePHID(); 39 + $handle = $file_handles[$file_phid]; 40 + 41 + $item = id(new PHUIObjectItemView()) 42 + ->setHeader($handle->getFullName()) 43 + ->setHref($handle->getURI()) 44 + ->setDisabled($handle->isDisabled()); 45 + 46 + if ($handle->getImageURI()) { 47 + $item->setImageURI($handle->getImageURI()); 48 + } 49 + 50 + $list->addItem($item); 51 + } 52 + 53 + return $this->newDialog() 54 + ->setViewer($viewer) 55 + ->setWidth(AphrontDialogView::WIDTH_FORM) 56 + ->setTitle(pht('Attached Files')) 57 + ->setObjectList($list) 58 + ->addCancelButton($object_handle->getURI(), pht('Close')); 59 + } 60 + 61 + }
+89
src/applications/files/engineextension/PhabricatorFilesCurtainExtension.php
··· 1 + <?php 2 + 3 + final class PhabricatorFilesCurtainExtension 4 + extends PHUICurtainExtension { 5 + 6 + const EXTENSIONKEY = 'files.files'; 7 + 8 + public function shouldEnableForObject($object) { 9 + return true; 10 + } 11 + 12 + public function getExtensionApplication() { 13 + return new PhabricatorFilesApplication(); 14 + } 15 + 16 + public function buildCurtainPanel($object) { 17 + $viewer = $this->getViewer(); 18 + 19 + $attachment_table = new PhabricatorFileAttachment(); 20 + $attachment_conn = $attachment_table->establishConnection('r'); 21 + 22 + $exact_limit = 100; 23 + $visible_limit = 8; 24 + 25 + $attachments = id(new PhabricatorFileAttachmentQuery()) 26 + ->setViewer($viewer) 27 + ->withObjectPHIDs(array($object->getPHID())) 28 + ->setLimit($exact_limit + 1) 29 + ->needFiles(true) 30 + ->execute(); 31 + 32 + $visible_attachments = array_slice($attachments, 0, $visible_limit, true); 33 + $visible_phids = mpull($visible_attachments, 'getFilePHID'); 34 + 35 + $handles = $viewer->loadHandles($visible_phids); 36 + 37 + PhabricatorPolicyFilterSet::loadHandleViewCapabilities( 38 + $viewer, 39 + $handles, 40 + array($object)); 41 + 42 + $ref_list = id(new PHUICurtainObjectRefListView()) 43 + ->setViewer($viewer) 44 + ->setEmptyMessage(pht('None')); 45 + 46 + foreach ($visible_attachments as $attachment) { 47 + $file_phid = $attachment->getFilePHID(); 48 + $handle = $handles[$file_phid]; 49 + 50 + $ref = $ref_list->newObjectRefView() 51 + ->setHandle($handle); 52 + 53 + if ($handle->hasCapabilities()) { 54 + if (!$handle->hasViewCapability($object)) { 55 + $ref->setExiled(true); 56 + } 57 + } 58 + 59 + $epoch = $attachment->getDateCreated(); 60 + $ref->setEpoch($epoch); 61 + } 62 + 63 + $show_all = (count($visible_attachments) < count($attachments)); 64 + if ($show_all) { 65 + $view_all_uri = urisprintf( 66 + '/file/ui/curtainlist/%s/', 67 + $object->getPHID()); 68 + 69 + $loaded_count = count($attachments); 70 + if ($loaded_count > $exact_limit) { 71 + $link_text = pht('View All Files'); 72 + } else { 73 + $link_text = pht('View All %d Files', new PhutilNumber($loaded_count)); 74 + } 75 + 76 + $ref_list->newTailLink() 77 + ->setURI($view_all_uri) 78 + ->setText($link_text) 79 + ->setWorkflow(true); 80 + } 81 + 82 + return $this->newPanel() 83 + ->setHeaderText(pht('Attached Files')) 84 + ->setOrder(15000) 85 + ->appendChild($ref_list); 86 + } 87 + 88 + 89 + }