@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 upstream/main 120 lines 3.4 kB view raw
1<?php 2 3final class PhabricatorFileDetachController 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 $handles = $viewer->loadHandles( 21 array( 22 $object_phid, 23 $file_phid, 24 )); 25 26 $object_handle = $handles[$object_phid]; 27 $file_handle = $handles[$file_phid]; 28 $cancel_uri = $file_handle->getURI(); 29 30 $dialog = $this->newDialog() 31 ->setViewer($viewer) 32 ->setTitle(pht('Detach File')) 33 ->addCancelButton($cancel_uri, pht('Close')); 34 35 $file_link = phutil_tag('strong', array(), $file_handle->renderLink()); 36 $object_link = phutil_tag('strong', array(), $object_handle->renderLink()); 37 38 $attachment = id(new PhabricatorFileAttachmentQuery()) 39 ->setViewer($viewer) 40 ->withObjectPHIDs(array($object->getPHID())) 41 ->withFilePHIDs(array($file_phid)) 42 ->needFiles(true) 43 ->withVisibleFiles(true) 44 ->executeOne(); 45 if (!$attachment) { 46 $body = pht( 47 'The file %s is not attached to the object %s.', 48 $file_link, 49 $object_link); 50 51 return $dialog->appendParagraph($body); 52 } 53 54 $mode_reference = PhabricatorFileAttachment::MODE_REFERENCE; 55 if ($attachment->getAttachmentMode() === $mode_reference) { 56 $body = pht( 57 'The file %s is referenced by the object %s, but not attached to '. 58 'it, so it can not be detached.', 59 $file_link, 60 $object_link); 61 62 return $dialog->appendParagraph($body); 63 } 64 65 if (!$attachment->canDetach()) { 66 $body = pht( 67 'The file %s can not be detached from the object %s.', 68 $file_link, 69 $object_link); 70 71 return $dialog->appendParagraph($body); 72 } 73 74 if (!$request->isDialogFormPost()) { 75 $dialog->appendParagraph( 76 pht( 77 'Detach the file %s from the object %s?', 78 $file_link, 79 $object_link)); 80 81 $dialog->addSubmitButton(pht('Detach File')); 82 83 return $dialog; 84 } 85 86 if (!($object instanceof PhabricatorApplicationTransactionInterface)) { 87 $dialog->appendParagraph( 88 pht( 89 'This object (of class "%s") does not implement the required '. 90 'interface ("%s"), so files can not be manually detached from it.', 91 get_class($object), 92 'PhabricatorApplicationTransactionInterface')); 93 94 return $dialog; 95 } 96 97 $editor = $object->getApplicationTransactionEditor() 98 ->setActor($viewer) 99 ->setContentSourceFromRequest($request) 100 ->setContinueOnNoEffect(true) 101 ->setContinueOnMissingFields(true); 102 103 $template = $object->getApplicationTransactionTemplate(); 104 105 $xactions = array(); 106 107 $xactions[] = id(clone $template) 108 ->setTransactionType(PhabricatorTransactions::TYPE_FILE) 109 ->setNewValue( 110 array( 111 $file_phid => PhabricatorFileAttachment::MODE_DETACH, 112 )); 113 114 $editor->applyTransactions($object, $xactions); 115 116 return $this->newRedirect() 117 ->setURI($cancel_uri); 118 } 119 120}