@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<?php
2
3final 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 $ref_list = id(new PHUICurtainObjectRefListView())
38 ->setViewer($viewer)
39 ->setEmptyMessage(pht('None'));
40
41 $view_capability = PhabricatorPolicyCapability::CAN_VIEW;
42 $object_policies = PhabricatorPolicyQuery::loadPolicies(
43 $viewer,
44 $object);
45 $object_policy = idx($object_policies, $view_capability);
46
47 foreach ($visible_attachments as $attachment) {
48 $file_phid = $attachment->getFilePHID();
49 $handle = $handles[$file_phid];
50
51 $ref = $ref_list->newObjectRefView()
52 ->setHandle($handle);
53
54 $file = $attachment->getFile();
55 if (!$file) {
56 // ...
57 } else {
58 if (!$attachment->isPolicyAttachment()) {
59 $file_policies = PhabricatorPolicyQuery::loadPolicies(
60 $viewer,
61 $file);
62 $file_policy = idx($file_policies, $view_capability);
63
64 if ($object_policy->isStrongerThanOrEqualTo($file_policy)) {
65 // The file is not attached to the object, but the file policy
66 // allows anyone who can see the object to see the file too, so
67 // there is no material problem with the file not being attached.
68 } else {
69 $attach_uri = urisprintf(
70 '/file/ui/curtain/attach/%s/%s/',
71 $object->getPHID(),
72 $file->getPHID());
73
74 $attached_link = javelin_tag(
75 'a',
76 array(
77 'href' => $attach_uri,
78 'sigil' => 'workflow',
79 ),
80 pht('File Not Attached'));
81
82 $ref->setExiled(
83 true,
84 $attached_link);
85 }
86 }
87 }
88
89 $epoch = $attachment->getDateCreated();
90 $ref->setEpoch($epoch);
91 }
92
93 $show_all = (count($visible_attachments) < count($attachments));
94 if ($show_all) {
95 $view_all_uri = urisprintf(
96 '/file/ui/curtain/list/%s/',
97 $object->getPHID());
98
99 $loaded_count = count($attachments);
100 if ($loaded_count > $exact_limit) {
101 $link_text = pht('View All Files');
102 } else {
103 $link_text = pht('View All %s Files', new PhutilNumber($loaded_count));
104 }
105
106 $ref_list->newTailLink()
107 ->setURI($view_all_uri)
108 ->setText($link_text)
109 ->setWorkflow(true);
110 }
111
112 return $this->newPanel()
113 ->setHeaderText(pht('Referenced Files'))
114 ->setOrder(15000)
115 ->appendChild($ref_list);
116 }
117
118
119}