Skip to content

Commit

Permalink
Fix pdf filenames and viewing, emailing and downloading
Browse files Browse the repository at this point in the history
  • Loading branch information
Petr Skoda committed Oct 30, 2014
1 parent ef7a3ec commit b79ab25
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 57 deletions.
2 changes: 1 addition & 1 deletion lang/en/certificate.php
Expand Up @@ -83,7 +83,7 @@
After a user receives their certificate, if they click on the certificate link from the course homepage, they will see the date they received their certificate and will be able to review their received certificate.';
$string['designoptions'] = 'Design Options';
$string['download'] = 'Force download';
$string['emailcertificate'] = 'Email (Must also choose save!)';
$string['emailcertificate'] = 'Email';
$string['emailothers'] = 'Email Others';
$string['emailothers_help'] = 'Enter the email addresses here, separated by a comma, of those who should be alerted with an email whenever students receive a certificate.';
$string['emailstudenttext'] = 'Attached is your certificate for {$a->course}.';
Expand Down
86 changes: 52 additions & 34 deletions locallib.php
Expand Up @@ -212,9 +212,11 @@ function certificate_email_teachers_html($info) {
* @param stdClass $certificate
* @param stdClass $certrecord
* @param stdClass $context
* @param string $filecontents the PDF file contents
* @param string $filename
* @return bool Returns true if mail was sent OK and false if there was an error.
*/
function certificate_email_student($course, $certificate, $certrecord, $context) {
function certificate_email_student($course, $certificate, $certrecord, $context, $filecontents, $filename) {
global $USER;

// Get teachers
Expand Down Expand Up @@ -247,36 +249,22 @@ function certificate_email_student($course, $certificate, $certrecord, $context)
// Make the HTML version more XHTML happy (&)
$messagehtml = text_to_html(get_string('emailstudenttext', 'certificate', $info));

// Remove full-stop at the end if it exists, to avoid "..pdf" being created and being filtered by clean_filename
$certname = rtrim($certificate->name, '.');
$filename = clean_filename("$certname.pdf");

// Get hashed pathname
$fs = get_file_storage();

$component = 'mod_certificate';
$filearea = 'issue';
$filepath = '/';
$files = $fs->get_area_files($context->id, $component, $filearea, $certrecord->id);
foreach ($files as $f) {
$filepathname = $f->get_contenthash();
$tempdir = make_temp_directory('certificate/attachment');
if (!$tempdir) {
return false;
}
$attachment = 'filedir/'.certificate_path_from_hash($filepathname).'/'.$filepathname;
$attachname = $filename;

return email_to_user($USER, $from, $subject, $message, $messagehtml, $attachment, $attachname);
}
$tempfile = $tempdir.'/'.md5(sesskey().microtime().$USER->id.'.pdf');
$fp = fopen($tempfile, 'w+');
fputs($fp, $filecontents);
fclose($fp);

/**
* Retrieve certificate path from hash
*
* @param array $contenthash
* @return string the path
*/
function certificate_path_from_hash($contenthash) {
$l1 = $contenthash[0].$contenthash[1];
$l2 = $contenthash[2].$contenthash[3];
return "$l1/$l2";
$prevabort = ignore_user_abort(true);
$result = email_to_user($USER, $from, $subject, $message, $messagehtml, $tempfile, $filename);
@unlink($tempfile);
ignore_user_abort($prevabort);

return $result;
}

/**
Expand Down Expand Up @@ -315,12 +303,9 @@ function certificate_save_pdf($pdf, $certrecordid, $filename, $contextid) {
'mimetype' => 'application/pdf', // any filename
'userid' => $USER->id);

// If the file exists, delete it and recreate it. This is to ensure that the
// latest certificate is saved on the server. For example, the student's grade
// may have been updated. This is a quick dirty hack.
if ($fs->file_exists($contextid, $component, $filearea, $certrecordid, $filepath, $filename)) {
$fs->delete_area_files($contextid, $component, $filearea, $certrecordid);
}
// We do not know the previous file name, better delete everything here,
// luckily there is supposed to be always only one certificate here.
$fs->delete_area_files($contextid, $component, $filearea, $certrecordid);

$fs->create_file_from_string($fileinfo, $pdf);

Expand Down Expand Up @@ -1228,3 +1213,36 @@ function certificate_scan_image_dir($path) {
}
return $options;
}

/**
* Get normalised certificate file name without file extension.
*
* @param stdClass $certificate
* @param stdClass $cm
* @param stdClass $course
* @return string file name without extension
*/
function certificate_get_certificate_filename($certificate, $cm, $course) {
$coursecontext = context_course::instance($course->id);
$coursename = format_string($course->shortname, true, array('context' => $coursecontext));

$context = context_module::instance($cm->id);
$name = format_string($certificate->name, true, array('context' => $context));

$filename = $coursename . '_' . $name;
$filename = core_text::entities_to_utf8($filename);
$filename = strip_tags($filename);
$filename = rtrim($filename, '.');

// Ampersand is not a valid filename char, let's replace it with something else.
$filename = str_replace('&', '_', $filename);

$filename = clean_filename($filename);

if (empty($filename)) {
// This is weird, but we need some file name.
$filename = 'certificate';
}

return $filename;
}
6 changes: 3 additions & 3 deletions report.php
Expand Up @@ -108,7 +108,7 @@
require_once("$CFG->libdir/odslib.class.php");

// Calculate file name
$filename = clean_filename("$course->shortname " . rtrim($certificate->name, '.') . '.ods');
$filename = certificate_get_certificate_filename($certificate, $cm, $course) . '.ods';
// Creating a workbook
$workbook = new MoodleODSWorkbook("-");
// Send HTTP headers
Expand Down Expand Up @@ -157,7 +157,7 @@
require_once("$CFG->libdir/excellib.class.php");

// Calculate file name
$filename = clean_filename("$course->shortname " . rtrim($certificate->name, '.') . '.xls');
$filename = certificate_get_certificate_filename($certificate, $cm, $course) . '.xls';
// Creating a workbook
$workbook = new MoodleExcelWorkbook("-");
// Send HTTP headers
Expand Down Expand Up @@ -203,7 +203,7 @@
}

if ($download == "txt") {
$filename = clean_filename("$course->shortname " . rtrim($certificate->name, '.') . '.txt');
$filename = certificate_get_certificate_filename($certificate, $cm, $course) . '.txt';

header("Content-Type: application/download\n");
header("Content-Disposition: attachment; filename=\"$filename\"");
Expand Down
8 changes: 4 additions & 4 deletions review.php
Expand Up @@ -67,10 +67,10 @@
require ("$CFG->dirroot/mod/certificate/type/$certificate->certificatetype/certificate.php");

if ($action) {
// Remove full-stop at the end if it exists, to avoid "..pdf" being created and being filtered by clean_filename
$certname = rtrim($certificate->name, '.');
$filename = clean_filename("$certname.pdf");
$pdf->Output($filename, 'I'); // open in browser
$filename = certificate_get_certificate_filename($certificate, $cm, $course) . '.pdf';
$filecontents = $pdf->Output('', 'S');
// Open in browser.
send_file($filecontents, $filename, 0, 0, true, false, 'application/pdf');
exit();
}

Expand Down
38 changes: 23 additions & 15 deletions view.php
Expand Up @@ -64,9 +64,6 @@
$PAGE->set_title(format_string($certificate->name));
$PAGE->set_heading(format_string($course->fullname));

// Set the context
$context = context_module::instance($cm->id);

if (($edit != -1) and $PAGE->user_allowed_editing()) {
$USER->editing = $edit;
}
Expand Down Expand Up @@ -131,27 +128,38 @@

$link = new moodle_url('/mod/certificate/view.php?id='.$cm->id.'&action=get');
$button = new single_button($link, $linkname);
$button->add_action(new popup_action('click', $link, 'view'.$cm->id, array('height' => 600, 'width' => 800)));
if ($certificate->delivery != 1) {
$button->add_action(new popup_action('click', $link, 'view' . $cm->id, array('height' => 600, 'width' => 800)));
}

echo html_writer::tag('div', $OUTPUT->render($button), array('style' => 'text-align:center'));
echo $OUTPUT->footer($course);
exit;
} else { // Output to pdf
// Remove full-stop at the end if it exists, to avoid "..pdf" being created and being filtered by clean_filename
$certname = rtrim($certificate->name, '.');
$filename = clean_filename("$certname.pdf");

// No debugging here, sorry.
$CFG->debugdisplay = 0;
@ini_set('display_errors', '0');
@ini_set('log_errors', '1');

$filename = certificate_get_certificate_filename($certificate, $cm, $course) . '.pdf';

// PDF contents are now in $file_contents as a string.
$filecontents = $pdf->Output('', 'S');

if ($certificate->savecert == 1) {
// PDF contents are now in $file_contents as a string
$file_contents = $pdf->Output('', 'S');
certificate_save_pdf($file_contents, $certrecord->id, $filename, $context->id);
certificate_save_pdf($filecontents, $certrecord->id, $filename, $context->id);
}

if ($certificate->delivery == 0) {
$pdf->Output($filename, 'I'); // open in browser
// Open in browser.
send_file($filecontents, $filename, 0, 0, true, false, 'application/pdf');
} elseif ($certificate->delivery == 1) {
$pdf->Output($filename, 'D'); // force download when create
// Force download.
send_file($filecontents, $filename, 0, 0, true, true, 'application/pdf');
} elseif ($certificate->delivery == 2) {
certificate_email_student($course, $certificate, $certrecord, $context);
$pdf->Output($filename, 'I'); // open in browser
$pdf->Output('', 'S'); // send
certificate_email_student($course, $certificate, $certrecord, $context, $filecontents, $filename);
// Open in browser after sending email.
send_file($filecontents, $filename, 0, 0, true, false, 'application/pdf');
}
}

0 comments on commit b79ab25

Please sign in to comment.