Skip to content

Commit cced350

Browse files
committed
more twig work
1 parent 088092c commit cced350

12 files changed

+388
-321
lines changed

entities/ProjGroup.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -165,5 +165,5 @@ public function set_developers_manual($url) { $this->developers_manual = check_u
165165
public function set_testing_manual($url) { $this->testing_manual = check_url($url); }
166166
public function set_developers_mailing_list($url) { $this->developers_mailing_list = check_url($url); }
167167
public function set_patch_submission($url) { $this->patch_submission = check_url($url); }
168-
public function set_allow_modifications_date($time) { $this->allow_modifications_date = new DateTimeImmutable($time); }
168+
public function set_allow_modifications_date(DateTimeImmutable $time) { $this->allow_modifications_date = $time; }
169169
}

entities/RepositoryUser.php

+1-2
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ public function description() {
9696
if ($v)
9797
$extra .= " [$k: $v]";
9898
}
99-
return $this->platform() . ': <a href="' . $this->profileURL() . '">' .
100-
$this->username() . '</a>' . $extra;
99+
return $extra;
101100
}
102101
}

index.php

+14-5
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
$formFactory = Forms::createFormFactoryBuilder()
2222
->addExtension(new HttpFoundationExtension())
2323
->getFormFactory();
24+
$custom_header = null;
2425
$form = null;
2526
$select_form = null;
2627
$embed_file = null;
@@ -29,8 +30,10 @@
2930
$table = null;
3031
$lists = null;
3132
$deadline = null;
33+
$top_box = null;
3234
$info_box = null;
3335
$monospace = null;
36+
$bottom_links = null;
3437
$refresh_url = null;
3538

3639
$request = \Symfony\Component\HttpFoundation\Request::createFromGlobals();
@@ -48,11 +51,15 @@
4851
}
4952
} catch (ValidationException $ex) {
5053
terminate('Failed to validate all fields: ' . $ex->getMessage());
54+
} catch (DateMalformedStringException $ex) {
55+
terminate('Failed to parse date: ' . $ex->getMessage());
5156
}
5257

53-
function terminate($error_message = null) {
54-
global $page, $deadline, $table, $lists, $info_box, $form, $select_form,
55-
$embed_file, $info_message, $success_message, $monospace, $refresh_url;
58+
function terminate($error_message = null, $template = 'main.html.twig',
59+
$extra_fields = []) {
60+
global $page, $deadline, $table, $lists, $info_box, $form, $select_form;
61+
global $embed_file, $info_message, $success_message, $monospace, $refresh_url;
62+
global $custom_header, $bottom_links, $top_box;
5663

5764
$appvar = new \ReflectionClass('\Symfony\Bridge\Twig\AppVariable');
5865
$loader = new \Twig\Loader\FilesystemLoader([
@@ -90,7 +97,7 @@ function terminate($error_message = null) {
9097
['phpinfo', 'PHP Info', ROLE_PROF],
9198
];
9299
$navbar = [];
93-
$title = 'Welcome';
100+
$title = $custom_header ?? 'Welcome';
94101

95102
foreach ($pages as $p) {
96103
if ($p[0] === $page)
@@ -119,9 +126,11 @@ function terminate($error_message = null) {
119126
'error_message' => $error_message,
120127
'table' => $table,
121128
'lists' => $lists,
129+
'top_box' => $top_box,
122130
'info_box' => $info_box,
123131
'monospace' => $monospace,
124132
'deadline' => $deadline ? $deadline->format('c') : null,
133+
'bottom_links' => $bottom_links,
125134
'refresh_url' => $refresh_url,
126135
];
127136

@@ -130,7 +139,7 @@ function terminate($error_message = null) {
130139
if ($select_form)
131140
$content['select_form'] = $select_form->createView();
132141

133-
echo $twig->render('main.html.twig', $content);
142+
echo $twig->render($template, $content + $extra_fields);
134143
db_flush();
135144
exit();
136145
}

pages/dashboard.php

+33-211
Original file line numberDiff line numberDiff line change
@@ -5,101 +5,26 @@
55
$selected_year = filter_by(['year']);
66

77
foreach (db_get_merged_patch_stats() as $entry) {
8-
$years[] = '"' . get_term_for($entry['year']) . '"';
8+
$years[] = get_term_for($entry['year']);
99
$patches[] = $entry['patches'];
1010
$lines_added[] = $entry['lines_added'];
1111
$lines_deleted[] = $entry['lines_deleted'];
1212
$files_modified[] = $entry['files_modified'];
1313
}
1414

15-
$max_y = round(max($patches) * 1.1);
16-
$max_y2 = round(max(max($lines_added),
17-
max($lines_deleted),
18-
max($files_modified)) * 1.1);
15+
$fields['max_y'] = round(max($patches) * 1.1);
16+
$fields['max_y2'] = round(max(max($lines_added),
17+
max($lines_deleted),
18+
max($files_modified)) * 1.1);
1919

20-
$years = implode(', ', $years);
21-
$patches = implode(', ', $patches);
22-
$lines_added = implode(', ', $lines_added);
23-
$lines_deleted = implode(', ', $lines_deleted);
24-
$files_modified = implode(', ', $files_modified);
20+
$fields['merged_prs_years'] = $years;
21+
$fields['merged_prs_patches'] = $patches;
22+
$fields['merged_prs_lines_added'] = $lines_added;
23+
$fields['merged_prs_lines_deleted'] = $lines_deleted;
24+
$fields['merged_prs_files_modified'] = $files_modified;
2525

26-
echo <<<HTML
27-
<script src='https://cdn.plot.ly/plotly-3.0.0.min.js'></script>
28-
<div id='plotdiv' style="max-width: 900px"></div>
29-
<script>
30-
xData = [$years];
31-
yData = [[$patches], [$lines_added], [$lines_deleted], [$files_modified]];
32-
var labels = ['Merged PRs', 'Lines added', 'Lines deleted', 'Files modified'];
33-
var lineSize = [3, 2, 2, 2];
34-
var yaxis = ['y', 'y2', 'y2', 'y2'];
3526

36-
var data = [];
37-
for (var i = 0 ; i < yData.length; ++i) {
38-
var result = {
39-
x: xData,
40-
y: yData[i],
41-
yaxis: yaxis[i],
42-
type: 'scatter',
43-
mode: 'lines',
44-
name: labels[i],
45-
line: {
46-
width: lineSize[i]
47-
}
48-
};
49-
data.push(result);
50-
}
51-
52-
var layout = {
53-
legend: {
54-
x: 1.1,
55-
y: 1.1
56-
},
57-
xaxis: {
58-
showline: true,
59-
showgrid: false,
60-
autotick: false
61-
},
62-
yaxis: {
63-
title: 'PR count',
64-
range: [0, $max_y]
65-
},
66-
yaxis2: {
67-
title: 'File/Line count',
68-
range: [0, $max_y2],
69-
showgrid: false,
70-
overlaying: 'y',
71-
side: 'right'
72-
},
73-
annotations: [
74-
{
75-
xref: 'paper',
76-
yref: 'paper',
77-
x: 0.0,
78-
y: 1.05,
79-
xanchor: 'left',
80-
yanchor: 'bottom',
81-
text: 'Merged PRs',
82-
font:{
83-
size: 24,
84-
color: 'rgb(37,37,37)'
85-
},
86-
showarrow: false
87-
}
88-
]
89-
};
90-
91-
config = {
92-
displayModeBar: false,
93-
responsive: true
94-
};
95-
96-
Plotly.newPlot('plotdiv', data, layout, config);
97-
</script>
98-
99-
HTML;
100-
101-
102-
// % of merged patches
27+
// 2nd plot: % of merged patches
10328
$merged = [];
10429
$total = [];
10530

@@ -128,50 +53,18 @@
12853
}
12954
ksort($total);
13055

131-
$pcmerged_x = [];
13256
$pcmerged_y = [];
13357
foreach ($total as $year => $data) {
134-
$pcmerged_x[] = '"' . get_term_for($year) . '"';
58+
$fields['pcmerged_x'][] = get_term_for($year);
13559
foreach ($data as $type => $n) {
13660
$pcmerged_y[$type][] = round(@$merged[$year][$type] / $n, 2);
13761
}
13862
}
139-
$pcmerged_x = implode(', ', $pcmerged_x);
140-
$pcmerged_bug = implode(', ', $pcmerged_y[PATCH_BUGFIX]);
141-
$pcmerged_feat = implode(', ', $pcmerged_y[PATCH_FEATURE]);
142-
143-
echo <<<HTML
144-
<div id='pcmergedplot' style="max-width: 500px"></div>
145-
<script>
146-
var bugs = {
147-
x: [$pcmerged_x],
148-
y: [$pcmerged_bug],
149-
name: 'Bug fixes',
150-
type: 'bar'
151-
};
152-
var features = {
153-
x: [$pcmerged_x],
154-
y: [$pcmerged_feat],
155-
name: 'Features',
156-
type: 'bar'
157-
};
158-
var data = [bugs, features];
159-
var layout = {
160-
title: {
161-
text: 'Percentage of Merged PRs'
162-
},
163-
barmode: 'group',
164-
yaxis: {
165-
tickformat: ',.0%'
166-
}
167-
};
168-
Plotly.newPlot('pcmergedplot', data, layout, config);
169-
</script>
170-
HTML;
171-
63+
$fields['pcmerged_bug'] = @$pcmerged_y[PATCH_BUGFIX];
64+
$fields['pcmerged_feat'] = @$pcmerged_y[PATCH_FEATURE];
17265

173-
// stats of projects selected this year
17466

67+
// 3rd plot: stats of projects selected this year
17568
foreach (db_fetch_groups($selected_year) as $group) {
17669
if ($repo = $group->getValidRepository()) {
17770
if ($lang = $repo->language()) {
@@ -197,102 +90,31 @@
19790
arsort($projs);
19891
ksort($prs_per_project, SORT_NATURAL | SORT_FLAG_CASE);
19992

200-
$lang_x = implode(', ', array_map('quote', array_keys($langs)));
201-
$lang_y = implode(', ', $langs);
93+
$fields['lang_x'] = array_keys($langs);
94+
$fields['lang_y'] = $langs;
20295

203-
$proj_x = implode(', ', array_map('quote', array_keys($projs)));
204-
$proj_y = implode(', ', $projs);
205-
206-
echo <<<HTML
207-
<div id='langsplot' style="max-width: 800px"></div>
208-
<script>
209-
var data = [
210-
{
211-
x: [$lang_x],
212-
y: [$lang_y],
213-
type: 'bar'
214-
}
215-
];
216-
var layout = {
217-
title: {
218-
text: 'Project Languages'
219-
}
220-
};
221-
Plotly.newPlot('langsplot', data, layout, config);
222-
</script>
223-
224-
<div id='projsplot' style="max-width: 900px; max-height: 500px"></div>
225-
<script>
226-
var data = [
227-
{
228-
x: [$proj_x],
229-
y: [$proj_y],
230-
type: 'bar'
231-
}
232-
];
233-
var layout = {
234-
title: {
235-
text: 'Most Frequent Projects'
236-
},
237-
xaxis: {
238-
tickangle: 45
239-
},
240-
margin: {
241-
b: 150
242-
}
243-
};
244-
Plotly.newPlot('projsplot', data, layout, config);
245-
</script>
246-
247-
HTML;
96+
$fields['proj_x'] = array_keys($projs);
97+
$fields['proj_y'] = $projs;
24898

24999

250100
// Now a table with all projects
251-
echo <<<HTML
252-
<link href="https://unpkg.com/tabulator-tables/dist/css/tabulator.min.css" rel="stylesheet">
253-
<script type="text/javascript" src="https://unpkg.com/tabulator-tables/dist/js/tabulator.js"></script>
254-
<p>&nbsp;</p>
255-
<h2>All projects</h2>
256-
<div id="projects-table" style="max-width: 999px"></div>
257-
<script>
258-
var tabledata = [
259-
260-
HTML;
261-
262101
$id = 0;
263102
foreach ($prs_per_project as $name => $stats) {
264-
$total_bugs = @array_sum($stats[PATCH_BUGFIX]);
265-
$total_feat = @array_sum($stats[PATCH_FEATURE]);
103+
$total_bugs = array_sum($stats[PATCH_BUGFIX] ?? array());
104+
$total_feat = array_sum($stats[PATCH_FEATURE] ?? array());
266105
$bugs = $stats[PATCH_BUGFIX][1] ?? 0;
267106
$feat = $stats[PATCH_FEATURE][1] ?? 0;
268-
$bugs_pc = $total_bugs ? round(($bugs / $total_bugs) * 100.0, 0) : 0;
269-
$feat_pc = $total_feat ? round(($feat / $total_feat) * 100.0, 0) : 0;
270-
$url = $stats['url'];
271-
echo <<<HTML
272-
{id: $id, name: "$name", url: "$url", bugs: $bugs, bugs_pc: "$bugs_pc%",
273-
features: $feat, features_pc: "$feat_pc%"},
274-
275-
HTML;
276-
++$id;
107+
$fields['table'][] = [
108+
'id' => $id++,
109+
'name' => $name,
110+
'total_bugs' => $total_bugs,
111+
'total_feat' => $total_feat,
112+
'bugs' => $bugs,
113+
'feat' => $feat,
114+
'bugs_pc' => $total_bugs ? round(($bugs / $total_bugs) * 100.0, 0) : 0,
115+
'feat_pc' => $total_feat ? round(($feat / $total_feat) * 100.0, 0) : 0,
116+
'url' => $stats['url'],
117+
];
277118
}
278119

279-
echo <<<HTML
280-
];
281-
var table = new Tabulator("#projects-table", {
282-
height: 250,
283-
data: tabledata,
284-
layout: "fitColumns",
285-
columns: [
286-
{title: "Project", field:"name", formatter:"link", formatterParams:{
287-
labelField: "name",
288-
urlField: "url"
289-
}},
290-
{title: "Merged PRs bug fixes", field: "bugs"},
291-
{title: "Merged PRs bug fixes %", field: "bugs_pc", sorter:"number"},
292-
{title: "Merged PRs features", field: "features"},
293-
{title: "Merged PRs features %", field: "features_pc", sorter:"number"},
294-
],
295-
});
296-
</script>
297-
298-
HTML;
120+
terminate(null, 'dashboard.html.twig', $fields);

pages/editpatch.php

-2
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@
7070
</tr>
7171
HTML;
7272
}
73-
echo "</table>\n";
7473

7574
$ci_failures = [];
7675
foreach ($patch->ci_failures as $ci) {
@@ -90,7 +89,6 @@
9089
nl2br(htmlspecialchars(implode("\n", $names))),
9190
"</td></tr>\n";
9291
}
93-
echo "</table>\n";
9492
}
9593

9694
// Add approve/reject buttons to simplify the life of TAs

0 commit comments

Comments
 (0)