@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 PhabricatorApplicationDetailViewController
4 extends PhabricatorApplicationsController {
5
6
7 public function shouldAllowPublic() {
8 return true;
9 }
10
11 public function handleRequest(AphrontRequest $request) {
12 $viewer = $this->getViewer();
13 $application = $request->getURIData('application');
14
15 $selected = id(new PhabricatorApplicationQuery())
16 ->setViewer($viewer)
17 ->withClasses(array($application))
18 ->executeOne();
19 if (!$selected) {
20 return new Aphront404Response();
21 }
22
23 $title = $selected->getName();
24
25 $crumbs = $this->buildApplicationCrumbs();
26 $crumbs->addTextCrumb($selected->getName());
27 $crumbs->setBorder(true);
28
29 $header = id(new PHUIHeaderView())
30 ->setHeader($title)
31 ->setViewer($viewer)
32 ->setPolicyObject($selected)
33 ->setHeaderIcon($selected->getIcon());
34
35 if ($selected->isInstalled()) {
36 $header->setStatus('fa-check', 'bluegrey', pht('Enabled'));
37 } else {
38 $header->setStatus('fa-ban', 'dark', pht('Disabled'));
39 }
40
41 if (!$selected->isFirstParty()) {
42 $header->addTag(id(new PHUITagView())
43 ->setName('Extension')
44 ->setIcon('fa-plug')
45 ->setColor(PHUITagView::COLOR_INDIGO)
46 ->setType(PHUITagView::TYPE_SHADE));
47 }
48
49 if ($selected->isPrototype()) {
50 $header->addTag(id(new PHUITagView())
51 ->setName('Prototype')
52 ->setIcon('fa-exclamation-circle')
53 ->setColor(PHUITagView::COLOR_ORANGE)
54 ->setType(PHUITagView::TYPE_SHADE));
55 }
56
57 if ($selected->isDeprecated()) {
58 $header->addTag(id(new PHUITagView())
59 ->setName('Deprecated')
60 ->setIcon('fa-exclamation-triangle')
61 ->setColor(PHUITagView::COLOR_RED)
62 ->setType(PHUITagView::TYPE_SHADE));
63 }
64
65 $timeline = $this->buildTransactionTimeline(
66 $selected,
67 new PhabricatorApplicationApplicationTransactionQuery());
68 $timeline->setShouldTerminate(true);
69
70 $curtain = $this->buildCurtain($selected);
71 $details = $this->buildPropertySectionView($selected);
72 $policies = $this->buildPolicyView($selected);
73
74 $configs =
75 PhabricatorApplicationConfigurationPanel::loadAllPanelsForApplication(
76 $selected);
77
78 $panels = array();
79 foreach ($configs as $config) {
80 $config->setViewer($viewer);
81 $config->setApplication($selected);
82 $panel = $config->buildConfigurationPagePanel();
83 $panel->setBackground(PHUIObjectBoxView::BLUE_PROPERTY);
84 $panels[] = $panel;
85 }
86
87 $view = id(new PHUITwoColumnView())
88 ->setHeader($header)
89 ->setCurtain($curtain)
90 ->setMainColumn(array(
91 $policies,
92 $panels,
93 $timeline,
94 ))
95 ->addPropertySection(pht('Details'), $details);
96
97 return $this->newPage()
98 ->setTitle($title)
99 ->setCrumbs($crumbs)
100 ->appendChild(
101 array(
102 $view,
103 ));
104 }
105
106 private function buildPropertySectionView(
107 PhabricatorApplication $application) {
108
109 $viewer = $this->getViewer();
110 $properties = new PHUIPropertyListView();
111
112 $properties->addProperty(
113 pht('Description'),
114 $application->getShortDescription());
115
116 if ($application->getFlavorText()) {
117 $properties->addProperty(
118 null,
119 phutil_tag('em', array(), $application->getFlavorText()));
120 }
121
122 $phids = PhabricatorPHIDType::getAllTypesForApplication(
123 get_class($application));
124
125 $user_friendly_phids = array();
126 foreach ($phids as $phid => $type) {
127 $user_friendly_phids[] = "PHID-{$phid} ({$type->getTypeName()})";
128 }
129
130 if ($user_friendly_phids) {
131 $properties->addProperty(
132 'PHIDs',
133 phutil_implode_html(phutil_tag('br'), $user_friendly_phids));
134 }
135
136 $monograms = $application->getMonograms();
137 if ($monograms) {
138 $properties->addProperty(
139 'Monograms',
140 phutil_implode_html(', ', $monograms));
141 }
142
143 if ($application->isPrototype()) {
144 $proto_href = PhabricatorEnv::getDoclink(
145 'User Guide: Prototype Applications');
146 $learn_more = phutil_tag(
147 'a',
148 array(
149 'href' => $proto_href,
150 'target' => '_blank',
151 ),
152 pht('Learn More'));
153
154 $properties->addProperty(
155 pht('Prototype'),
156 pht(
157 'This application is a prototype. %s',
158 $learn_more));
159 }
160
161 $overview = $application->getOverview();
162 if (phutil_nonempty_string($overview)) {
163 $overview = new PHUIRemarkupView($viewer, $overview);
164 $properties->addSectionHeader(
165 pht('Overview'), PHUIPropertyListView::ICON_SUMMARY);
166 $properties->addTextContent($overview);
167 }
168
169 return $properties;
170 }
171
172 private function buildPolicyView(
173 PhabricatorApplication $application) {
174
175 $viewer = $this->getViewer();
176 $properties = new PHUIPropertyListView();
177
178 $header = id(new PHUIHeaderView())
179 ->setHeader(pht('Policies'));
180
181 $descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions(
182 $viewer,
183 $application);
184
185 foreach ($application->getCapabilities() as $capability) {
186 $properties->addProperty(
187 $application->getCapabilityLabel($capability),
188 idx($descriptions, $capability));
189 }
190
191 return id(new PHUIObjectBoxView())
192 ->setHeader($header)
193 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
194 ->appendChild($properties);
195
196 }
197
198 private function buildCurtain(PhabricatorApplication $application) {
199 $viewer = $this->getViewer();
200
201 $can_edit = PhabricatorPolicyFilter::hasCapability(
202 $viewer,
203 $application,
204 PhabricatorPolicyCapability::CAN_EDIT);
205
206 $key = get_class($application);
207 $edit_uri = $this->getApplicationURI("edit/{$key}/");
208 $install_uri = $this->getApplicationURI("{$key}/install/");
209 $uninstall_uri = $this->getApplicationURI("{$key}/uninstall/");
210
211 $curtain = $this->newCurtainView($application);
212
213 $curtain->addAction(
214 id(new PhabricatorActionView())
215 ->setName(pht('Edit Policies'))
216 ->setIcon('fa-pencil')
217 ->setDisabled(!$can_edit)
218 ->setWorkflow(!$can_edit)
219 ->setHref($edit_uri));
220
221 if ($application->canUninstall()) {
222 if ($application->isInstalled()) {
223 $curtain->addAction(
224 id(new PhabricatorActionView())
225 ->setName(pht('Disable'))
226 ->setIcon('fa-times')
227 ->setDisabled(!$can_edit)
228 ->setWorkflow(true)
229 ->setHref($uninstall_uri));
230 } else {
231 $action = id(new PhabricatorActionView())
232 ->setName(pht('Enable'))
233 ->setIcon('fa-plus')
234 ->setDisabled(!$can_edit)
235 ->setWorkflow(true)
236 ->setHref($install_uri);
237
238 $prototypes_enabled = PhabricatorEnv::getEnvConfig(
239 'phabricator.show-prototypes');
240 if ($application->isPrototype() && !$prototypes_enabled) {
241 $action->setDisabled(true);
242 }
243
244 $curtain->addAction($action);
245 }
246 } else {
247 $curtain->addAction(
248 id(new PhabricatorActionView())
249 ->setName(pht('Disable'))
250 ->setIcon('fa-times')
251 ->setWorkflow(true)
252 ->setDisabled(true)
253 ->setHref($uninstall_uri));
254 }
255
256 return $curtain;
257 }
258
259}