MDL-45301 assign: Add font options for EditPDF

This commit is contained in:
Tomo Tsuyuki 2023-02-17 15:30:25 +11:00
parent 8503f2cfd8
commit 9e725bc168
19 changed files with 160 additions and 9 deletions

View File

@ -22,6 +22,10 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir . '/pdflib.php');
use core_admin\local\settings\filesize;
$capabilities = array(
@ -174,6 +178,19 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
$temp->add(new admin_setting_configselect('moodlecourse/maxbytes', new lang_string('maximumupload'),
new lang_string('coursehelpmaximumupload'), key($choices), $choices));
if (!empty($CFG->enablepdfexportfont)) {
$pdf = new \pdf;
$fontlist = $pdf->get_export_fontlist();
// Show the option if the font is defined more than one.
if (count($fontlist) > 1) {
$temp->add(new admin_setting_configselect('moodlecourse/pdfexportfont',
new lang_string('pdfexportfont', 'course'),
new lang_string('pdfexportfont_help', 'course'),
'freesans', $fontlist
));
}
}
// Completion tracking.
$temp->add(new admin_setting_heading('progress', new lang_string('completion','completion'), ''));
$temp->add(new admin_setting_configselect('moodlecourse/enablecompletion', new lang_string('completion', 'completion'),

View File

@ -18,6 +18,8 @@ if ($hassiteconfig) {
$temp->add(new admin_setting_configcheckbox('langstringcache', new lang_string('langstringcache', 'admin'), new lang_string('configlangstringcache', 'admin'), 1));
$temp->add(new admin_setting_configtext('locale', new lang_string('localetext', 'admin'), new lang_string('configlocale', 'admin'), '', PARAM_FILE));
$temp->add(new admin_setting_configselect('latinexcelexport', new lang_string('latinexcelexport', 'admin'), new lang_string('configlatinexcelexport', 'admin'), '0', array('0'=>'Unicode','1'=>'Latin')));
$temp->add(new admin_setting_configcheckbox('enablepdfexportfont', new lang_string('enablepdfexportfont', 'admin'),
new lang_string('enablepdfexportfont_desc', 'admin'), 0));
$temp->add(new setting_scheduled_task_status('langimporttaskstatus', '\tool_langimport\task\update_langpacks_task'));
$ADMIN->add('language', $temp);

View File

@ -459,7 +459,7 @@ class backup_course_structure_step extends backup_structure_step {
'timecreated', 'timemodified',
'requested',
'showactivitydates',
'showcompletionconditions',
'showcompletionconditions', 'pdfexportfont',
'enablecompletion', 'completionstartonenrol', 'completionnotify'));
$category = new backup_nested_element('category', array('id'), array(

View File

@ -1933,6 +1933,9 @@ class restore_course_structure_step extends restore_structure_step {
$showactivitydatesdefault = ($courseconfig->showactivitydates ?? null);
$data->showactivitydates = $data->showactivitydates ?? $showactivitydatesdefault;
$pdffontdefault = ($courseconfig->pdfexportfont ?? null);
$data->pdfexportfont = $data->pdfexportfont ?? $pdffontdefault;
$languages = get_string_manager()->get_list_of_translations(); // Get languages for quick search
if (isset($data->lang) && !array_key_exists($data->lang, $languages)) {
$data->lang = '';

View File

@ -655,8 +655,12 @@ $CFG->admin = 'admin';
// Font used in exported PDF files. When generating a PDF, Moodle embeds a subset of
// the font in the PDF file so it will be readable on the widest range of devices.
// The default font is 'freesans' which is part of the GNU FreeFont collection.
// The font used to export can be set per-course - a drop down list in the course
// settings shows all the options specified in the array here. The key must be the
// font name (e.g., "kozminproregular") and the value is a friendly name, (e.g.,
// "Kozmin Pro Regular").
//
// $CFG->pdfexportfont = 'freesans';
// $CFG->pdfexportfont = ['freesans' => 'FreeSans'];
//
// Use the following flag to enable messagingallusers and set the default preference
// value for existing users to allow them to be contacted by other site users.

View File

@ -117,6 +117,10 @@ class course_summary_exporter extends \core\external\exporter {
'type' => PARAM_BOOL,
'null' => NULL_ALLOWED
],
'pdfexportfont' => [
'type' => PARAM_TEXT,
'null' => NULL_ALLOWED
],
);
}

View File

@ -4,6 +4,7 @@ defined('MOODLE_INTERNAL') || die;
require_once($CFG->libdir.'/formslib.php');
require_once($CFG->libdir.'/completionlib.php');
require_once($CFG->libdir . '/pdflib.php');
/**
* The form for handling editing a course.
@ -318,6 +319,22 @@ class course_edit_form extends moodleform {
$mform->addHelpButton('maxbytes', 'maximumupload');
$mform->setDefault('maxbytes', $courseconfig->maxbytes);
// PDF font.
if (!empty($CFG->enablepdfexportfont)) {
$pdf = new \pdf;
$fontlist = $pdf->get_export_fontlist();
// Show the option if the font is defined more than one.
if (count($fontlist) > 1) {
$defaultfont = $courseconfig->pdfexportfont ?? 'freesans';
if (empty($fontlist[$defaultfont])) {
$defaultfont = current($fontlist);
}
$mform->addElement('select', 'pdfexportfont', get_string('pdfexportfont', 'course'), $fontlist);
$mform->addHelpButton('pdfexportfont', 'pdfexportfont', 'course');
$mform->setDefault('pdfexportfont', $defaultfont);
}
}
// Completion tracking.
if (completion_info::is_enabled_for_site()) {
$mform->addElement('header', 'completionhdr', get_string('completion', 'completion'));

View File

@ -621,6 +621,7 @@ class core_course_external extends external_api {
// For backward-compartibility
$courseinfo['numsections'] = $courseformatoptions['numsections'];
}
$courseinfo['pdfexportfont'] = $course->pdfexportfont;
$handler = core_course\customfield\course_handler::create();
if ($customfields = $handler->export_instance_data($course->id)) {

View File

@ -4747,7 +4747,7 @@ function course_get_recent_courses(int $userid = null, int $limit = 0, int $offs
$basefields = [
'id', 'idnumber', 'summary', 'summaryformat', 'startdate', 'enddate', 'category',
'shortname', 'fullname', 'timeaccess', 'component', 'visible',
'showactivitydates', 'showcompletionconditions',
'showactivitydates', 'showcompletionconditions', 'pdfexportfont'
];
if (empty($sort)) {

View File

@ -5751,7 +5751,7 @@ class courselib_test extends advanced_testcase {
'shortname DESC, xyz ASC',
'Invalid field in the sort parameter, allowed fields: id, idnumber, summary, summaryformat, ' .
'startdate, enddate, category, shortname, fullname, timeaccess, component, visible, ' .
'showactivitydates, showcompletionconditions.',
'showactivitydates, showcompletionconditions, pdfexportfont.',
],
'Sort uses invalid value for the sorting direction' =>
[

View File

@ -577,6 +577,8 @@ $string['enableglobalsearch_desc'] = 'If enabled, data will be indexed and synch
$string['enablegravatar'] = 'Enable Gravatar';
$string['enablegravatar_help'] = 'When enabled Moodle will attempt to fetch a user profile picture from Gravatar if the user has not uploaded an image.';
$string['enablemobilewebservice'] = 'Enable web services for mobile devices';
$string['enablepdfexportfont'] = 'Enable PDF fonts';
$string['enablepdfexportfont_desc'] = 'If your site has courses in different languages which need other fonts in generated PDF files, you can provide the option to set the font in the course settings. You need to specify available fonts in $CFG->pdfexportfont in config.php. If $CFG->pdfexportfont defines none or one font, the setting in the course is not shown.';
$string['enablerecordcache'] = 'Enable record cache';
$string['enablerssfeeds'] = 'Enable RSS feeds';
$string['enablesearchareas'] = 'Enable search areas';

View File

@ -108,6 +108,8 @@ $string['noteachinginfomessage'] = 'Hi {$a->userfirstname},
$string['participants:perpage'] = 'Number of participants per page';
$string['participants:perpage_help'] = 'The number of users shown per page on the participants page in each course.';
$string['participantsnavigation'] = 'Participants tertiary navigation.';
$string['pdfexportfont'] = 'PDF font';
$string['pdfexportfont_help'] = 'The font to be used for generated PDF files, such as assignment submissions.';
$string['privacy:perpage'] = 'The number of courses to show per page.';
$string['privacy:completionpath'] = 'Course completion';
$string['privacy:favouritespath'] = 'Course starred information';

View File

@ -105,6 +105,7 @@
<FIELD NAME="originalcourseid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="the id of the source course when a new course originates from a restore of another course on the same site."/>
<FIELD NAME="showactivitydates" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Whether to display activity dates to user. 0 = do not display, 1 = display activity dates"/>
<FIELD NAME="showcompletionconditions" TYPE="int" LENGTH="1" NOTNULL="false" SEQUENCE="false" COMMENT="Whether to display completion conditions to user. 0 = do not display, 1 = display conditions"/>
<FIELD NAME="pdfexportfont" TYPE="char" LENGTH="50" NOTNULL="false" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>

View File

@ -2984,5 +2984,19 @@ privatefiles,moodle|/user/files.php';
upgrade_main_savepoint(true, 2023020800.00);
}
if ($oldversion < 2023021700.01) {
// Define field pdfexportfont to be added to course.
$table = new xmldb_table('course');
$field = new xmldb_field('pdfexportfont', XMLDB_TYPE_CHAR, '50', null, false, false, null, 'showcompletionconditions');
// Conditionally launch add field pdfexportfont.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
// Main savepoint reached.
upgrade_main_savepoint(true, 2023021700.01);
}
return true;
}

View File

@ -250,4 +250,32 @@ class pdf extends TCPDF {
return $families;
}
/**
* Get font list from config.
* @return array|string[]
*/
public function get_export_fontlist(): array {
global $CFG;
$fontlist = [];
if (!empty($CFG->pdfexportfont)) {
if (is_array($CFG->pdfexportfont)) {
$fontlist = $CFG->pdfexportfont;
} else {
$fontlist[$CFG->pdfexportfont] = $CFG->pdfexportfont;
}
}
// Verify fonts.
$availablefonts = $this->get_font_families();
foreach ($fontlist as $key => $value) {
if (empty($availablefonts[$key])) {
unset($fontlist[$key]);
}
}
if (empty($fontlist)) {
// Default font if there is no value set in CFG.
$fontlist = ['freesans' => 'FreeSans'];
}
return $fontlist;
}
}

View File

@ -66,4 +66,35 @@ class pdflib_test extends \advanced_testcase {
$this->assertGreaterThan(100000, strlen($res));
$this->assertLessThan(120000, strlen($res));
}
/**
* Test get_export_fontlist function.
*
* @covers ::get_export_fontlist
*
* @return void
*/
public function test_get_export_fontlist(): void {
global $CFG;
require_once($CFG->libdir.'/pdflib.php');
$this->resetAfterTest();
$pdf = new \pdf();
$fontlist = $pdf->get_export_fontlist();
$this->assertCount(1, $fontlist);
$this->assertArrayHasKey('freesans', $fontlist);
$CFG->pdfexportfont = [
'kozminproregular' => 'Kozmin Pro Regular',
'stsongstdlight' => 'STSong stdlight',
'invalidfont' => 'Invalid'
];
$fontlist = $pdf->get_export_fontlist();
$this->assertCount(2, $fontlist);
$this->assertArrayNotHasKey('freesans', $fontlist);
$this->assertArrayHasKey('kozminproregular', $fontlist);
$this->assertArrayHasKey('stsongstdlight', $fontlist);
$this->assertArrayNotHasKey('invalidfont', $fontlist);
}
}

View File

@ -645,6 +645,7 @@ EOD;
* @return stored_file
*/
public static function generate_feedback_document($assignment, $userid, $attemptnumber) {
global $CFG;
$assignment = self::get_assignment_from_param($assignment);
@ -674,6 +675,20 @@ EOD;
$pdf = new pdf();
// Set fontname from course setting if it's enabled.
if (!empty($CFG->enablepdfexportfont)) {
$fontlist = $pdf->get_export_fontlist();
// Load font from course if it's more than 1.
if (count($fontlist) > 1) {
$course = $assignment->get_course();
if (!empty($course->pdfexportfont)) {
$pdf->set_export_font_name($course->pdfexportfont);
}
} else {
$pdf->set_export_font_name(current($fontlist));
}
}
$fs = get_file_storage();
$stamptmpdir = make_temp_directory('assignfeedback_editpdf/stamps/' . self::hash($assignment, $userid, $attemptnumber));
$grade = $assignment->get_user_grade($userid, true, $attemptnumber);

View File

@ -50,6 +50,8 @@ class pdf extends TcpdfFpdi {
protected $imagefolder = null;
/** @var string the path to the PDF currently being processed */
protected $filename = null;
/** @var string the fontname used when the PDF being processed */
protected $fontname = null;
/** No errors */
const GSPATH_OK = 'ok';
@ -81,15 +83,23 @@ class pdf extends TcpdfFpdi {
* @return string
*/
private function get_export_font_name() {
global $CFG;
$fontname = 'freesans';
if (!empty($CFG->pdfexportfont)) {
$fontname = $CFG->pdfexportfont;
if (!empty($this->fontname)) {
$fontname = $this->fontname;
}
return $fontname;
}
/**
* Set font name.
*
* @param string $fontname Font name which is
* @return void
*/
public function set_export_font_name($fontname): void {
$this->fontname = $fontname;
}
/**
* Combine the given PDF files into a single PDF. Optionally add a coversheet and coversheet fields.
* @param string[] $pdflist the filenames of the files to combine

View File

@ -29,7 +29,7 @@
defined('MOODLE_INTERNAL') || die();
$version = 2023021700.00; // YYYYMMDD = weekly release date of this DEV branch.
$version = 2023021700.01; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.
$release = '4.2dev (Build: 20230217)'; // Human-friendly version name