@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
at recaptime-dev/main 133 lines 3.8 kB view raw
1<?php 2 3final class PhabricatorFileUICurtainAttachController 4 extends PhabricatorFileController { 5 6 public function handleRequest(AphrontRequest $request) { 7 $viewer = $request->getViewer(); 8 9 $object_phid = $request->getURIData('objectPHID'); 10 $file_phid = $request->getURIData('filePHID'); 11 12 $object = id(new PhabricatorObjectQuery()) 13 ->setViewer($viewer) 14 ->withPHIDs(array($object_phid)) 15 ->executeOne(); 16 if (!$object) { 17 return new Aphront404Response(); 18 } 19 20 $attachment = id(new PhabricatorFileAttachmentQuery()) 21 ->setViewer($viewer) 22 ->withObjectPHIDs(array($object->getPHID())) 23 ->withFilePHIDs(array($file_phid)) 24 ->needFiles(true) 25 ->withVisibleFiles(true) 26 ->executeOne(); 27 if (!$attachment) { 28 return new Aphront404Response(); 29 } 30 31 $handles = $viewer->loadHandles( 32 array( 33 $object_phid, 34 $file_phid, 35 )); 36 37 $object_handle = $handles[$object_phid]; 38 $file_handle = $handles[$file_phid]; 39 $cancel_uri = $object_handle->getURI(); 40 41 $dialog = $this->newDialog() 42 ->setViewer($viewer) 43 ->setTitle(pht('Attach File')) 44 ->addCancelButton($cancel_uri, pht('Close')); 45 46 $file_link = phutil_tag('strong', array(), $file_handle->renderLink()); 47 $object_link = phutil_tag('strong', array(), $object_handle->renderLink()); 48 49 if ($attachment->isPolicyAttachment()) { 50 $body = pht( 51 'The file %s is already attached to the object %s.', 52 $file_link, 53 $object_link); 54 55 return $dialog->appendParagraph($body); 56 } 57 58 if (!$request->isDialogFormPost()) { 59 $dialog->appendRemarkup( 60 pht( 61 '(WARNING) This file is referenced by this object, but '. 62 'not formally attached to it. Users who can see the object may '. 63 'not be able to see the file.')); 64 65 $dialog->appendParagraph( 66 pht( 67 'Do you want to attach the file %s to the object %s?', 68 $file_link, 69 $object_link)); 70 71 $dialog->addSubmitButton(pht('Attach File')); 72 73 return $dialog; 74 } 75 76 if (!$request->getBool('confirm')) { 77 $dialog->setTitle(pht('Confirm File Attachment')); 78 79 $dialog->addHiddenInput('confirm', 1); 80 81 $dialog->appendRemarkup( 82 pht( 83 '(IMPORTANT) If you attach this file to this object, any user who '. 84 'has permission to view the object will be able to view and '. 85 'download the file!')); 86 87 $dialog->appendParagraph( 88 pht( 89 'Really attach the file %s to the object %s, allowing any user '. 90 'who can view the object to view and download the file?', 91 $file_link, 92 $object_link)); 93 94 $dialog->addSubmitButton(pht('Grant Permission')); 95 96 return $dialog; 97 } 98 99 if (!($object instanceof PhabricatorApplicationTransactionInterface)) { 100 $dialog->appendParagraph( 101 pht( 102 'This object (of class "%s") does not implement the required '. 103 'interface ("%s"), so files can not be manually attached to it.', 104 get_class($object), 105 'PhabricatorApplicationTransactionInterface')); 106 107 return $dialog; 108 } 109 110 $editor = $object->getApplicationTransactionEditor() 111 ->setActor($viewer) 112 ->setContentSourceFromRequest($request) 113 ->setContinueOnNoEffect(true) 114 ->setContinueOnMissingFields(true); 115 116 $template = $object->getApplicationTransactionTemplate(); 117 118 $xactions = array(); 119 120 $xactions[] = id(clone $template) 121 ->setTransactionType(PhabricatorTransactions::TYPE_FILE) 122 ->setNewValue( 123 array( 124 $file_phid => PhabricatorFileAttachment::MODE_ATTACH, 125 )); 126 127 $editor->applyTransactions($object, $xactions); 128 129 return $this->newRedirect() 130 ->setURI($cancel_uri); 131 } 132 133}