@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 PhabricatorConfigDatabaseIssueController
4 extends PhabricatorConfigDatabaseController {
5
6 public function handleRequest(AphrontRequest $request) {
7 $viewer = $request->getViewer();
8
9 $query = new PhabricatorConfigSchemaQuery();
10
11 $actual = $query->loadActualSchemata();
12 $expect = $query->loadExpectedSchemata();
13 $comp_servers = $query->buildComparisonSchemata($expect, $actual);
14
15 // Collect all open issues.
16 $issues = array();
17 foreach ($comp_servers as $ref_name => $comp) {
18 foreach ($comp->getDatabases() as $database_name => $database) {
19 foreach ($database->getLocalIssues() as $issue) {
20 $issues[] = array(
21 $ref_name,
22 $database_name,
23 null,
24 null,
25 null,
26 $issue,
27 );
28 }
29 foreach ($database->getTables() as $table_name => $table) {
30 foreach ($table->getLocalIssues() as $issue) {
31 $issues[] = array(
32 $ref_name,
33 $database_name,
34 $table_name,
35 null,
36 null,
37 $issue,
38 );
39 }
40 foreach ($table->getColumns() as $column_name => $column) {
41 foreach ($column->getLocalIssues() as $issue) {
42 $issues[] = array(
43 $ref_name,
44 $database_name,
45 $table_name,
46 'column',
47 $column_name,
48 $issue,
49 );
50 }
51 }
52 foreach ($table->getKeys() as $key_name => $key) {
53 foreach ($key->getLocalIssues() as $issue) {
54 $issues[] = array(
55 $ref_name,
56 $database_name,
57 $table_name,
58 'key',
59 $key_name,
60 $issue,
61 );
62 }
63 }
64 }
65 }
66 }
67
68 // Sort all open issues so that the most severe issues appear first.
69 $order = array();
70 $counts = array();
71 foreach ($issues as $key => $issue) {
72 $const = $issue[5];
73 $status = PhabricatorConfigStorageSchema::getIssueStatus($const);
74 $severity = PhabricatorConfigStorageSchema::getStatusSeverity($status);
75 $order[$key] = sprintf(
76 '~%d~%s%s%s',
77 9 - $severity,
78 $issue[1],
79 $issue[2],
80 $issue[4]);
81
82 if (empty($counts[$status])) {
83 $counts[$status] = 0;
84 }
85
86 $counts[$status]++;
87 }
88 asort($order);
89 $issues = array_select_keys($issues, array_keys($order));
90
91
92 // Render the issues.
93 $rows = array();
94 foreach ($issues as $issue) {
95 $const = $issue[5];
96
97 $uri = $this->getApplicationURI('/database/'.$issue[0].'/'.$issue[1].'/');
98
99 $database_link = phutil_tag(
100 'a',
101 array(
102 'href' => $uri,
103 ),
104 $issue[1]);
105
106 $rows[] = array(
107 $this->renderIcon(
108 PhabricatorConfigStorageSchema::getIssueStatus($const)),
109 $issue[0],
110 $database_link,
111 $issue[2],
112 $issue[3],
113 $issue[4],
114 PhabricatorConfigStorageSchema::getIssueDescription($const),
115 );
116 }
117
118 $table = id(new AphrontTableView($rows))
119 ->setNoDataString(
120 pht('No databases have any issues.'))
121 ->setHeaders(
122 array(
123 null,
124 pht('Server'),
125 pht('Database'),
126 pht('Table'),
127 pht('Type'),
128 pht('Column/Key'),
129 pht('Issue'),
130 ))
131 ->setColumnClasses(
132 array(
133 null,
134 null,
135 null,
136 null,
137 null,
138 null,
139 'wide',
140 ));
141
142 $errors = array();
143
144 if (isset($counts[PhabricatorConfigStorageSchema::STATUS_FAIL])) {
145 $errors[] = pht(
146 'Detected %s serious issue(s) with the schemata.',
147 new PhutilNumber($counts[PhabricatorConfigStorageSchema::STATUS_FAIL]));
148 }
149
150 if (isset($counts[PhabricatorConfigStorageSchema::STATUS_WARN])) {
151 $errors[] = pht(
152 'Detected %s warning(s) with the schemata.',
153 new PhutilNumber($counts[PhabricatorConfigStorageSchema::STATUS_WARN]));
154 }
155
156 $title = pht('Schemata Issues');
157 $header = $this->buildHeaderView($title);
158
159 $nav = $this->newNavigation('schemata-issues');
160
161 $view = $this->buildConfigBoxView(pht('Issues'), $table);
162
163 $crumbs = $this->newCrumbs()
164 ->addTextCrumb($title)
165 ->setBorder(true);
166
167 $content = id(new PHUITwoColumnView())
168 ->setHeader($header)
169 ->setFooter($view);
170
171 return $this->newPage()
172 ->setTitle($title)
173 ->setCrumbs($crumbs)
174 ->setNavigation($nav)
175 ->appendChild($content);
176 }
177
178}