Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion classes/output/email_certificate.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ public function export_for_template(\renderer_base $renderer) {
$info->certificatename = $this->certificatename;
$info->courseshortname = $this->courseshortname;
$info->coursefullname = $this->coursefullname;

if ($this->isstudent) {
$data->emailgreeting = get_string('emailstudentgreeting', 'customcert', $this->userfullname);
$data->emailbody = get_string('emailstudentbody', 'customcert', $info);
Expand Down
283 changes: 203 additions & 80 deletions classes/task/email_certificate_task.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ public function get_name() {
* Execute.
*/
public function execute() {
global $DB;
global $CFG, $DB;

// Force error_log output to a dedicated debug file for all executions.

require_once(__DIR__ . '/../../lib.php');

$customdata = $this->get_custom_data();
if (empty($customdata) || empty($customdata->issueid) || empty($customdata->customcertid)) {
Expand All @@ -56,8 +60,10 @@ public function execute() {

$issueid = (int)$customdata->issueid;
$customcertid = (int)$customdata->customcertid;

// Get certificate and course information
$sql = "SELECT c.*, ct.id as templateid, ct.name as templatename, ct.contextid, co.id as courseid,
co.fullname as coursefullname, co.shortname as courseshortname
co.fullname as coursefullname, co.shortname as courseshortname, co.lang as courselang
FROM {customcert} c
JOIN {customcert_templates} ct ON c.templateid = ct.id
JOIN {course} co ON c.course = co.id
Expand All @@ -68,120 +74,237 @@ public function execute() {
return;
}

// The renderers used for sending emails.
$page = new \moodle_page();
$htmlrenderer = $page->get_renderer('mod_customcert', 'email', 'htmlemail');
$textrenderer = $page->get_renderer('mod_customcert', 'email', 'textemail');

// Get the context.
$context = \context::instance_by_id($customcert->contextid);

// Get the person we are going to send this email on behalf of.
$userfrom = \core_user::get_noreply_user();

$courseshortname = format_string($customcert->courseshortname, true, ['context' => $context]);
$coursefullname = format_string($customcert->coursefullname, true, ['context' => $context]);
$certificatename = format_string($customcert->name, true, ['context' => $context]);

// Used to create the email subject.
$info = new \stdClass();
$info->coursename = $courseshortname; // Added for BC, so users who have edited the string don't lose this value.
$info->courseshortname = $courseshortname;
$info->coursefullname = $coursefullname;
$info->certificatename = $certificatename;

// Get the information about the user and the certificate issue.
// Get user and issue information
$userfields = helper::get_all_user_name_fields('u');
$sql = "SELECT u.id, u.username, $userfields, u.email, u.mailformat, ci.id as issueid, ci.emailed
$sql = "SELECT u.id, u.username, $userfields, u.email, u.mailformat, ci.id as issueid, ci.emailed, u.lang as lang
FROM {customcert_issues} ci
JOIN {user} u
ON ci.userid = u.id
WHERE ci.customcertid = :customcertid
AND ci.id = :issueid";
JOIN {user} u ON ci.userid = u.id
WHERE ci.customcertid = :customcertid AND ci.id = :issueid";
$user = $DB->get_record_sql($sql, ['customcertid' => $customcertid, 'issueid' => $issueid]);

if (!$user) {
return;
}

// Create a directory to store the PDF we will be sending.
$tempdir = make_temp_directory('certificate/attachment');
if (!$tempdir) {
return;
// Store original language to restore later
$originallang = current_language();

// --- LANGUAGE SELECTION LOGIC (same hierarchy as certificate view) ---
$lang = $this->resolve_certificate_language($customcert, $user);

// Force the resolved language
$activelangs = get_string_manager()->get_list_of_translations();
if (!empty($lang) && array_key_exists($lang, $activelangs)) {
force_current_language($lang);
get_string_manager()->reset_caches();

// Test string fetch after forcing language
$teststring = get_string('emailstudentsubject', 'customcert');
}

// Setup the user for the cron.
// Get the context
$context = \context::instance_by_id($customcert->contextid);

// Setup the user for the cron
\core\cron::setup_user($user);

$userfullname = fullname($user);
$info->userfullname = $userfullname;
// Create a directory to store the PDF
$tempdir = make_temp_directory('certificate/attachment');
if (!$tempdir) {
// Restore original language before returning
force_current_language($originallang);
return;
}

// Now, get the PDF.
// Generate PDF with the forced language
$template = new \stdClass();
$template->id = $customcert->templateid;
$template->name = $customcert->templatename;
$template->contextid = $customcert->contextid;
$template = new \mod_customcert\template($template);
$filecontents = $template->generate_pdf(false, $user->id, true);

// Set the name of the file we are going to send.
// Prepare file information
$courseshortname = format_string($customcert->courseshortname, true, ['context' => $context]);
$coursefullname = format_string($customcert->coursefullname, true, ['context' => $context]);
$certificatename = format_string($customcert->name, true, ['context' => $context]);
$userfullname = fullname($user);

// Set the name of the file we are going to send
$filename = $courseshortname . '_' . $certificatename;
$filename = \core_text::entities_to_utf8($filename);
$filename = strip_tags($filename);
$filename = rtrim($filename, '.');
$filename = str_replace('&', '_', $filename) . '.pdf';

// Create the file we will be sending.
// Create the file we will be sending
$tempfile = $tempdir . '/' . md5(microtime() . $user->id) . '.pdf';
file_put_contents($tempfile, $filecontents);

// Prepare email information object
$info = new \stdClass();
$info->coursename = $courseshortname; // Added for BC
$info->courseshortname = $courseshortname;
$info->coursefullname = $coursefullname;
$info->certificatename = $certificatename;
$info->userfullname = $userfullname;

// Get email renderers
$page = new \moodle_page();
$htmlrenderer = $page->get_renderer('mod_customcert', 'email', 'htmlemail');
$textrenderer = $page->get_renderer('mod_customcert', 'email', 'textemail');

// Get the person we are going to send this email on behalf of
$userfrom = \core_user::get_noreply_user();

// Send email to students
if ($customcert->emailstudents) {
$renderable = new \mod_customcert\output\email_certificate(true, $userfullname, $courseshortname,
$coursefullname, $certificatename, $context->instanceid);

$subject = get_string('emailstudentsubject', 'customcert', $info);
$message = $textrenderer->render($renderable);
$messagehtml = $htmlrenderer->render($renderable);
email_to_user($user, $userfrom, html_entity_decode($subject, ENT_COMPAT), $message,
$messagehtml, $tempfile, $filename);
$this->send_email_to_student($user, $userfrom, $info, $context, $htmlrenderer,
$textrenderer, $tempfile, $filename, $userfullname, $courseshortname,
$coursefullname, $certificatename);
}

// Send email to teachers
if ($customcert->emailteachers) {
$teachers = get_enrolled_users($context, 'moodle/course:update');

$renderable = new \mod_customcert\output\email_certificate(false, $userfullname, $courseshortname,
$coursefullname, $certificatename, $context->instanceid);

$subject = get_string('emailnonstudentsubject', 'customcert', $info);
$message = $textrenderer->render($renderable);
$messagehtml = $htmlrenderer->render($renderable);
foreach ($teachers as $teacher) {
email_to_user($teacher, $userfrom, html_entity_decode($subject, ENT_COMPAT),
$message, $messagehtml, $tempfile, $filename);
}
$this->send_email_to_teachers($context, $userfrom, $info, $htmlrenderer,
$textrenderer, $tempfile, $filename, $userfullname, $courseshortname,
$coursefullname, $certificatename);
}

// Send email to others
if (!empty($customcert->emailothers)) {
$others = explode(',', $customcert->emailothers);
foreach ($others as $email) {
$email = trim($email);
if (validate_email($email)) {
$renderable = new \mod_customcert\output\email_certificate(false, $userfullname,
$courseshortname, $coursefullname, $certificatename, $context->instanceid);

$subject = get_string('emailnonstudentsubject', 'customcert', $info);
$message = $textrenderer->render($renderable);
$messagehtml = $htmlrenderer->render($renderable);

$emailuser = new \stdClass();
$emailuser->id = -1;
$emailuser->email = $email;
email_to_user($emailuser, $userfrom, html_entity_decode($subject, ENT_COMPAT), $message,
$messagehtml, $tempfile, $filename);
}
}
$this->send_email_to_others($customcert->emailothers, $userfrom, $info,
$context, $htmlrenderer, $textrenderer, $tempfile, $filename,
$userfullname, $courseshortname, $coursefullname, $certificatename);
}

// Set the field so that it is emailed.
// Mark as emailed
$DB->set_field('customcert_issues', 'emailed', 1, ['id' => $issueid]);


// Restore original language
force_current_language($originallang);
get_string_manager()->reset_caches();
}

/**
* Resolve the certificate language using the same hierarchy as certificate view
*
* @param object $customcert The certificate record
* @param object $user The user record
* @return string The resolved language code
*/
private function resolve_certificate_language($customcert, $user) {
global $CFG;

$lang = null;

// 1. Certificate-specific language (if set)
if (!empty($customcert->force_language)) {
$lang = $customcert->force_language;
return $lang;
}

// 2. Course language (if set)
if (!empty($customcert->courselang)) {
$lang = $customcert->courselang;
return $lang;
}

// 3. User profile language (if set)
if (!empty($user->lang)) {
$lang = $user->lang;
return $lang;
}

// 4. Site default language
$lang = $CFG->lang;

return $lang;
}

/**
* Send email to student
*/
private function send_email_to_student($user, $userfrom, $info, $context, $htmlrenderer,
$textrenderer, $tempfile, $filename, $userfullname, $courseshortname,
$coursefullname, $certificatename) {

$renderable = new \mod_customcert\output\email_certificate(true, $userfullname,
$courseshortname, $coursefullname, $certificatename, $context->instanceid);

$subject = get_string('emailstudentsubject', 'customcert', $info);
$message = $textrenderer->render($renderable);
$messagehtml = $htmlrenderer->render($renderable);

// Apply multilang filter to all text content
$subject = format_text($subject, FORMAT_HTML, ['filter' => true, 'context' => $context]);
$message = format_text($message, FORMAT_HTML, ['filter' => true, 'context' => $context]);
$messagehtml = format_text($messagehtml, FORMAT_HTML, ['filter' => true, 'context' => $context]);


email_to_user($user, $userfrom, html_entity_decode($subject, ENT_COMPAT),
$message, $messagehtml, $tempfile, $filename);
}

/**
* Send email to teachers
*/
private function send_email_to_teachers($context, $userfrom, $info, $htmlrenderer,
$textrenderer, $tempfile, $filename, $userfullname, $courseshortname,
$coursefullname, $certificatename) {

$teachers = get_enrolled_users($context, 'moodle/course:update');

$renderable = new \mod_customcert\output\email_certificate(false, $userfullname,
$courseshortname, $coursefullname, $certificatename, $context->instanceid);

$subject = get_string('emailnonstudentsubject', 'customcert', $info);
$message = $textrenderer->render($renderable);
$messagehtml = $htmlrenderer->render($renderable);

// Apply multilang filter
$subject = format_text($subject, FORMAT_HTML, ['filter' => true, 'context' => $context]);
$message = format_text($message, FORMAT_HTML, ['filter' => true, 'context' => $context]);
$messagehtml = format_text($messagehtml, FORMAT_HTML, ['filter' => true, 'context' => $context]);

foreach ($teachers as $teacher) {
email_to_user($teacher, $userfrom, html_entity_decode($subject, ENT_COMPAT),
$message, $messagehtml, $tempfile, $filename);
}
}

/**
* Send email to other recipients
*/
private function send_email_to_others($emailothers, $userfrom, $info, $context,
$htmlrenderer, $textrenderer, $tempfile, $filename, $userfullname,
$courseshortname, $coursefullname, $certificatename) {

$others = explode(',', $emailothers);

foreach ($others as $email) {
$email = trim($email);
if (validate_email($email)) {
$renderable = new \mod_customcert\output\email_certificate(false, $userfullname,
$courseshortname, $coursefullname, $certificatename, $context->instanceid);

$subject = get_string('emailnonstudentsubject', 'customcert', $info);
$message = $textrenderer->render($renderable);
$messagehtml = $htmlrenderer->render($renderable);

// Apply multilang filter
$subject = format_text($subject, FORMAT_HTML, ['filter' => true, 'context' => $context]);
$message = format_text($message, FORMAT_HTML, ['filter' => true, 'context' => $context]);
$messagehtml = format_text($messagehtml, FORMAT_HTML, ['filter' => true, 'context' => $context]);

$emailuser = new \stdClass();
$emailuser->id = -1;
$emailuser->email = $email;

email_to_user($emailuser, $userfrom, html_entity_decode($subject, ENT_COMPAT),
$message, $messagehtml, $tempfile, $filename);
}
}
}
}
}
Loading