From fd925c9ae0cd10fc61c8f206b9eee459e276cac7 Mon Sep 17 00:00:00 2001 From: Philipp Imhof <52650214+PhilippImhof@users.noreply.github.com> Date: Sat, 26 Oct 2024 11:21:39 +0200 Subject: [PATCH] add option for footer with page number --- classes/customTCPDF.php | 51 ++++++++++++++++++++++++++++++++++ essaydownload_form.php | 8 ++++++ essaydownload_options.php | 6 ++++ lang/en/quiz_essaydownload.php | 3 ++ report.php | 18 ++++++++---- tests/behat/form.feature | 1 + 6 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 classes/customTCPDF.php diff --git a/classes/customTCPDF.php b/classes/customTCPDF.php new file mode 100644 index 0000000..615a7e9 --- /dev/null +++ b/classes/customTCPDF.php @@ -0,0 +1,51 @@ +. + +namespace quiz_essaydownload; + +use \pdf; + +defined('MOODLE_INTERNAL') || die(); +require_once($CFG->libdir . '/pdflib.php'); + +/** + * Override TCPDF in order to have a custom footer that includes the page number. + * + * @package quiz_essaydownload + * @copyright 2024 Philipp Imhof + * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +class customTCPDF extends pdf { + + // @codingStandardsIgnoreLine + public function Footer() { + // We place the footer 15 mm away from the bottom. + $this->SetY(-15); + + // We cannot use getAliasNumPage(), because there seems to be a bug in TCPDF that will cause the + // footer to be badly centered. The same is true for getAliasNbPages(), but we don't need that + // here. + if (empty($this->pagegroups)) { + $pageno = $this->PageNo(); + } else { + $pageno = $this->getGroupPageNo(); + } + + $this->Cell(0, 10, get_string('pagenumber', 'quiz_essaydownload', $pageno), 0, 0, 'C'); + } + +} diff --git a/essaydownload_form.php b/essaydownload_form.php index 5f2fd1a..1bd7224 100644 --- a/essaydownload_form.php +++ b/essaydownload_form.php @@ -172,6 +172,14 @@ protected function pdf_layout_fields(MoodleQuickForm $mform) { $mform->addGroup($margingroup, 'margingroup', get_string('margins', 'quiz_essaydownload'), ' ', false); $mform->disabledIf('margingroup', 'fileformat', 'neq', 'pdf'); + $mform->addElement( + 'advcheckbox', + 'includefooter', + get_string('footer', 'quiz_essaydownload'), + get_string('includefooter', 'quiz_essaydownload') + ); + $mform->disabledIf('includefooter', 'fileformat', 'neq', 'pdf'); + $mform->addElement('select', 'linespacing', get_string('linespacing', 'quiz_essaydownload'), [ '1' => get_string('linesingle', 'quiz_essaydownload'), '1.5' => get_string('lineoneandhalf', 'quiz_essaydownload'), diff --git a/essaydownload_options.php b/essaydownload_options.php index 3061aa1..a82a45d 100644 --- a/essaydownload_options.php +++ b/essaydownload_options.php @@ -61,6 +61,9 @@ class quiz_essaydownload_options extends quiz_essaydownload_options_parent_class /** @var string how to organise the sub folders in the archive (by question or by attempt) */ public $groupby = 'byattempt'; + /** @var bool whether a footer containing the page number should be added to PDFs */ + public $includefooter = false; + /** @var float line spacing for PDF export */ public $linespacing = 1; @@ -118,6 +121,7 @@ public function get_initial_form_data() { $toform->font = $this->font; $toform->fontsize = $this->fontsize; $toform->groupby = $this->groupby; + $toform->includefooter = $this->includefooter; $toform->linespacing = $this->linespacing; $toform->marginbottom = $this->marginbottom; $toform->marginleft = $this->marginleft; @@ -144,6 +148,7 @@ public function setup_from_form_data($fromform): void { $this->font = $fromform->font ?? ''; $this->fontsize = $fromform->fontsize ?? ''; $this->groupby = $fromform->groupby; + $this->includefooter = $fromform->includefooter; $this->linespacing = $fromform->linespacing ?? ''; $this->marginbottom = $fromform->marginbottom ?? ''; $this->marginleft = $fromform->marginleft ?? ''; @@ -166,6 +171,7 @@ public function setup_from_params() { $this->font = optional_param('font', $this->font, PARAM_ALPHA); $this->fontsize = optional_param('fontsize', $this->fontsize, PARAM_INT); $this->groupby = optional_param('groupby', $this->groupby, PARAM_ALPHA); + $this->includefooter = optional_param('includefooter', $this->includefooter, PARAM_BOOL); $this->linespacing = optional_param('linespacing', $this->linespacing, PARAM_FLOAT); $this->marginbottom = optional_param('marginbottom', $this->marginbottom, PARAM_INT); $this->marginleft = optional_param('marginleft', $this->marginleft, PARAM_INT); diff --git a/lang/en/quiz_essaydownload.php b/lang/en/quiz_essaydownload.php index c092902..366cbcf 100644 --- a/lang/en/quiz_essaydownload.php +++ b/lang/en/quiz_essaydownload.php @@ -45,11 +45,13 @@ $string['fontserif'] = 'Serif'; $string['fontsize'] = 'Font size (points)'; $string['fontsize_help'] = 'Note that when using the original HTML formatted text, the actual font size may still be different, according to the formatting'; +$string['footer'] = 'Footer'; $string['generaloptions'] = 'General options'; $string['groupby'] = 'Group by'; $string['groupby_help'] = 'The archive can be structured by question or by attempt:'; $string['includeattachments'] = 'Also download possible attachments included in a student\'s answer.'; $string['includeattachments_help'] = 'Any attachment is provided as-is. Please note that attachments might contain malware.'; +$string['includefooter'] = 'Add footer with page number to each page.'; $string['includequestiontext'] = 'Also include question text.'; $string['includequestiontext_help'] = 'Including the question text might be useful if your quiz uses random questions.'; $string['lastfirst'] = 'Last name - First name'; @@ -64,6 +66,7 @@ $string['page'] = 'Page format'; $string['pagea4'] = 'A4'; $string['pageletter'] = 'Letter'; +$string['pagenumber'] = 'Page {$a}'; $string['pdfoptions'] = 'PDF settings'; $string['plugindescription'] = 'Download text answers and attachment files submitted in response to essay questions in a quiz.'; $string['pluginname'] = 'Essay responses downloader plugin (quiz_essaydownload)'; diff --git a/report.php b/report.php index e4c9cb2..f36def9 100644 --- a/report.php +++ b/report.php @@ -25,6 +25,7 @@ use core_files\archive_writer; use core\dml\sql_join; +use quiz_essaydownload\customTCPDF; defined('MOODLE_INTERNAL') || die(); @@ -40,6 +41,7 @@ class_alias('\quiz_attempts_report', '\quiz_essaydownload_report_parent_alias'); class_alias('\quiz_attempt', '\quiz_essaydownload_quiz_attempt_alias'); } +require_once($CFG->dirroot . '/mod/quiz/report/essaydownload/classes/customTCPDF.php'); require_once($CFG->dirroot . '/mod/quiz/report/essaydownload/essaydownload_form.php'); require_once($CFG->dirroot . '/mod/quiz/report/essaydownload/essaydownload_options.php'); require_once($CFG->libdir . '/pdflib.php'); @@ -505,7 +507,7 @@ protected function generate_pdf(string $text, string $header = '', string $subhe $text = $this->workaround_atto_font_size_issue($text); } - $doc = new pdf('P', 'mm', $this->options->pageformat); + $doc = new customTCPDF('P', 'mm', $this->options->pageformat); $doc->SetCreator('quiz_essaydownload plugin for Moodle LMS'); $doc->SetAuthor($author); @@ -523,7 +525,6 @@ protected function generate_pdf(string $text, string $header = '', string $subhe $this->options->margintop + $this->options->linespacing * $this->options->fontsize, $this->options->marginright ); - $doc->setPrintFooter(false); if ($this->options->font === 'serif') { $fontname = 'freeserif'; @@ -534,10 +535,17 @@ protected function generate_pdf(string $text, string $header = '', string $subhe } $doc->SetFont($fontname, '', $this->options->fontsize); $doc->setHeaderFont([$fontname, '', $this->options->fontsize]); - $doc->setHeaderData('', 0, $header, $subheader); - $doc->setFooterData(); - $doc->SetAutoPageBreak(true, $this->options->marginbottom); + + // The user may choose to add a footer to each page, by default, there is none. + $doc->setPrintFooter(false); + if ($this->options->includefooter) { + $doc->setPrintFooter(true); + // We add 20 mm to the bottom margin in order to accomodate the footer. + $doc->SetAutoPageBreak(true, $this->options->marginbottom + 20); + // Using 80% of the base font size seems good. + $doc->setFooterFont([$fontname, '', round(0.8 * $this->options->fontsize)]); + } $doc->AddPage(); $linespacebase = 1.25; diff --git a/tests/behat/form.feature b/tests/behat/form.feature index e56b4c6..6a2f7ab 100644 --- a/tests/behat/form.feature +++ b/tests/behat/form.feature @@ -59,6 +59,7 @@ Feature: Validation and display of the form And the "marginright" "field" should be disabled And the "margintop" "field" should be disabled And the "marginbottom" "field" should be disabled + And the "includefooter" "field" should be disabled And the "linespacing" "select" should be disabled And the "font" "select" should be disabled And the "fontsize" "field" should be disabled