Skip to content

Commit b48c054

Browse files
Allow downloading a merged PDF of issued certificates
1 parent 48f0913 commit b48c054

File tree

4 files changed

+149
-1
lines changed

4 files changed

+149
-1
lines changed

certificates.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,14 @@
6363
$outputpage = new \tool_certificate\output\issues_page($template->get_id());
6464

6565
$data = $outputpage->export_for_template($PAGE->get_renderer('core'));
66+
67+
$downloadform = new \tool_certificate\download_issues_form($template->get_id());
68+
if ($downloadissues = $downloadform->get_data()) {
69+
$outputpage->output_issues_pdf($template, $downloadissues);
70+
die();
71+
}
72+
$data['content'] .= $downloadform->render();
73+
6674
$data += ['heading' => get_string('issuedcertificates', 'tool_certificate')];
6775
if ($template->can_issue_to_anybody()) {
6876
$data += ['addbutton' => true, 'addbuttontitle' => get_string('issuecertificates', 'tool_certificate'),

classes/download_issues_form.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
namespace tool_certificate;
4+
5+
class download_issues_form {
6+
public int $templateid;
7+
8+
public function __construct(int $templateid) {
9+
$this->templateid = $templateid;
10+
}
11+
12+
public function render(): string {
13+
return <<<HTML
14+
<form method="post" target="_blank" class="dataformatselector m-1">
15+
<div class="form-inline text-xs-right">
16+
<input type="hidden" name="templateid" value="$this->templateid">
17+
<label for="downloadissues_select" class="mr-1">Download issued PDFs as</label>
18+
<select name="downloadissues" id="downloadissues_select" class="form-control custom-select mr-1">
19+
<option value="pdf">Merged PDF</option>
20+
<option value="pdfdecollate">Merged PDF (De-collated)</option>
21+
</select>
22+
<button type="submit" class="btn btn-secondary">Download PDFs</button>
23+
</div>
24+
</form>
25+
HTML;
26+
}
27+
28+
public function get_data() {
29+
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
30+
return false;
31+
}
32+
33+
$downloadissues = required_param('downloadissues', PARAM_ALPHA);
34+
return $downloadissues;
35+
}
36+
37+
protected function definition(): void {
38+
$this->_form->setAttributes(['class' => 'form-inline']);
39+
40+
$templateid = $this->_customdata['templateid'];
41+
$this->_form->addElement('hidden', 'templateid', $templateid);
42+
$this->_form->setType('id', PARAM_INT);
43+
44+
$options =
45+
[
46+
'pdf' => 'Merged PDF',
47+
'pdfdecollate' => 'Merged PDF (De-collated)',
48+
];
49+
$this->_form->addElement('select', 'downloadissues', 'Download issued PDFs as', $options);
50+
$this->_form->setType('downloadissues', PARAM_TEXT);
51+
52+
$submit = $this->_form->addElement('submit', 'submit', 'Download PDFs');
53+
$submit->setAttributes(['class' => 'btn btn-secondary']);
54+
}
55+
}

classes/output/issues_page.php

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ class issues_page implements \templatable, \renderable {
3333
/** @var int */
3434
protected $templateid;
3535

36+
/**
37+
* @var \stdClass[] The rows that were displayed in the table
38+
*/
39+
public array $rows;
40+
3641
/**
3742
* templates_page constructor.
3843
*
@@ -53,6 +58,76 @@ public function export_for_template(renderer_base $output): array {
5358
$report = system_report_factory::create(issues::class, $context,
5459
'', '', 0, ['templateid' => $this->templateid]);
5560

56-
return ['content' => $report->output()];
61+
$result = ['content' => $report->output()];
62+
$this->rows = $report->rows;
63+
return $result;
64+
}
65+
66+
/**
67+
* @throws \InvalidArgumentException
68+
* @throws \setasign\Fpdi\PdfParser\PdfParserException
69+
* @throws \setasign\Fpdi\PdfParser\PdfParserException
70+
*/
71+
public function output_issues_pdf(template $template, string $type): void {
72+
global $CFG;
73+
$files = [];
74+
$handles = [];
75+
foreach ($this->rows as $row) {
76+
$file = $template->get_issue_file($row);
77+
$files[] = $file;
78+
$handles[$file->get_id()] = $file->get_content_file_handle();
79+
}
80+
81+
require_once($CFG->libdir . '/pdflib.php');
82+
require_once($CFG->dirroot . '/mod/assign/feedback/editpdf/fpdi/autoload.php');
83+
84+
try {
85+
$pdf = new \setasign\Fpdi\Tcpdf\Fpdi();
86+
87+
if ($type == 'pdf') {
88+
foreach ($files as $file) {
89+
$filePages = $pdf->setSourceFile($handles[$file->get_id()]);
90+
for ($pageNumber = 1; $pageNumber <= $filePages; $pageNumber++) {
91+
$sourcePage = $pdf->importPage($pageNumber);
92+
$size = $pdf->getTemplateSize($sourcePage);
93+
$pdf->AddPage($size['orientation'], array($size['width'], $size['height']));
94+
95+
$pdf->useTemplate($sourcePage);
96+
}
97+
}
98+
99+
$pdf->Output('certificates.pdf');
100+
}
101+
else if ($type == 'pdfdecollate') {
102+
$pageCount = 1;
103+
for ($pageNumber = 1; $pageNumber <= $pageCount; $pageNumber++) {
104+
foreach ($files as $file) {
105+
$filePages = $pdf->setSourceFile($handles[$file->get_id()]);
106+
if ($pageNumber > $filePages) {
107+
continue;
108+
}
109+
if ($filePages > $pageCount) {
110+
$pageCount = $filePages;
111+
}
112+
113+
$sourcePage = $pdf->importPage($pageNumber);
114+
$size = $pdf->getTemplateSize($sourcePage);
115+
$pdf->AddPage($size['orientation'], array($size['width'], $size['height']));
116+
117+
$pdf->useTemplate($sourcePage);
118+
}
119+
}
120+
121+
$pdf->Output('certificates - ordered.pdf');
122+
}
123+
else {
124+
throw new \InvalidArgumentException("Unknown download type: $type");
125+
}
126+
}
127+
finally {
128+
foreach ($handles as $handle) {
129+
fclose($handle);
130+
}
131+
}
57132
}
58133
}

classes/reportbuilder/local/systemreports/issues.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,18 @@ protected function add_actions(): void {
245245
*/
246246
public function row_callback(stdClass $row): void {
247247
$this->userid = (int) $row->userid;
248+
249+
if (!isset($this->rows)) {
250+
$this->rows = [];
251+
}
252+
$this->rows[] = $row;
248253
}
249254

255+
/**
256+
* @var stdClass[]
257+
*/
258+
public array $rows;
259+
250260
/**
251261
* Callback for the fullname to display badge for archived issues.
252262
*

0 commit comments

Comments
 (0)