Skip to content

Optimize task email_certificate_task #634

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
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
21 changes: 21 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,27 @@ All notable changes to this project will be documented in this file.

Note - All hash comments refer to the issue number. Eg. #169 refers to https://github.com/mdjnelson/moodle-mod_customcert/issues/169.

## [4.1.6] - 2024-09-28

### Fixed

- Mobile app: Stop using deprecated module-description.
- Fixed auto-linking filters moving text element positions if reference point is center (#629).

### Changed

- Mobile app: Update Mobile template to Ionic 7.
- Mobile app: Remove Ionic 3 template.

### Added

- Optimise email certificate task by reducing database reads/writes and introducing
configurable settings for task efficiency (#531).
- New element `expiry` which when used will display the expiry date on the list of issued certificates
and the verification pages.<br />
Any Custom Certificates that are using the `date` element and selected the expiry dates will
automatically be upgraded to use this new element (#499).

## [4.1.5] - 2024-05-28

### Fixed
Expand Down
116 changes: 115 additions & 1 deletion classes/element_helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ public static function render_content($pdf, $element, $content) {
$y = $element->get_posy();
$w = $element->get_width();
$refpoint = $element->get_refpoint();
$actualwidth = $pdf->GetStringWidth($content);
$cleanedcontent = clean_param($content, PARAM_NOTAGS);
$actualwidth = $pdf->GetStringWidth($cleanedcontent);
$alignment = $element->get_alignment();

if ($w && $w < $actualwidth) {
Expand Down Expand Up @@ -685,4 +686,117 @@ public static function get_grade_item_info($gradeitemid, $gradeformat, $userid)
$grade->get_dategraded()
);
}

/**
* Helper function to return all the date formats.
*
* @return array the list of date formats
*/
public static function get_date_formats(): array {
// Hard-code date so users can see the difference between short dates with and without the leading zero.
// Eg. 06/07/18 vs 6/07/18.
$date = 1530849658;

$suffix = self::get_ordinal_number_suffix((int)userdate($date, '%d'));

$dateformats = [
1 => userdate($date, '%B %d, %Y'),
2 => userdate($date, '%B %d' . $suffix . ', %Y'),
];

$strdateformats = [
'strftimedate',
'strftimedatefullshort',
'strftimedatefullshortwleadingzero',
'strftimedateshort',
'strftimedatetime',
'strftimedatetimeshort',
'strftimedatetimeshortwleadingzero',
'strftimedaydate',
'strftimedaydatetime',
'strftimedayshort',
'strftimedaytime',
'strftimemonthyear',
'strftimerecent',
'strftimerecentfull',
'strftimetime',
];

foreach ($strdateformats as $strdateformat) {
if ($strdateformat == 'strftimedatefullshortwleadingzero') {
$dateformats[$strdateformat] = userdate($date, get_string('strftimedatefullshort', 'langconfig'), 99, false);
} else if ($strdateformat == 'strftimedatetimeshortwleadingzero') {
$dateformats[$strdateformat] = userdate($date, get_string('strftimedatetimeshort', 'langconfig'), 99, false);
} else {
$dateformats[$strdateformat] = userdate($date, get_string($strdateformat, 'langconfig'));
}
}

return $dateformats;
}

/**
* Returns the date in a readable format.
*
* @param int $date
* @param string $dateformat
* @return string
*/
public static function get_date_format_string(int $date, string $dateformat): string {
// Keeping for backwards compatibility.
if (is_number($dateformat)) {
switch ($dateformat) {
case 1:
$certificatedate = userdate($date, '%B %d, %Y');
break;
case 2:
$suffix = self::get_ordinal_number_suffix((int)userdate($date, '%d'));
$certificatedate = userdate($date, '%B %d' . $suffix . ', %Y');
break;
case 3:
$certificatedate = userdate($date, '%d %B %Y');
break;
case 4:
$certificatedate = userdate($date, '%B %Y');
break;
default:
$certificatedate = userdate($date, get_string('strftimedate', 'langconfig'));
}
}

// Ok, so we must have been passed the actual format in the lang file.
if (!isset($certificatedate)) {
if ($dateformat == 'strftimedatefullshortwleadingzero') {
$certificatedate = userdate($date, get_string('strftimedatefullshort', 'langconfig'), 99, false);
} else if ($dateformat == 'strftimedatetimeshortwleadingzero') {
$certificatedate = userdate($date, get_string('strftimedatetimeshort', 'langconfig'), 99, false);
} else {
$certificatedate = userdate($date, get_string($dateformat, 'langconfig'));
}
}

return $certificatedate;
}

/**
* Helper function to return the suffix of the day of
* the month, eg 'st' if it is the 1st of the month.
*
* @param int $day the day of the month
* @return string the suffix.
*/
private static function get_ordinal_number_suffix(int $day): string {
if (!in_array(($day % 100), [11, 12, 13])) {
switch ($day % 10) {
// Handle 1st, 2nd, 3rd.
case 1:
return get_string('numbersuffix_st_as_in_first', 'customcert');
case 2:
return get_string('numbersuffix_nd_as_in_second', 'customcert');
case 3:
return get_string('numbersuffix_rd_as_in_third', 'customcert');
}
}
return 'th';
}
}
2 changes: 1 addition & 1 deletion classes/output/mobile.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public static function mobile_view_activity($args) {
global $OUTPUT, $DB, $USER;

$args = (object) $args;
$versionname = $args->appversioncode >= 3950 ? 'latest' : 'ionic3';
$versionname = $args->appversioncode >= 44000 ? 'latest' : 'ionic5';

$cmid = $args->cmid;
$groupid = empty($args->group) ? 0 : (int) $args->group; // By default, group 0.
Expand Down
25 changes: 20 additions & 5 deletions classes/output/verify_certificate_result.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,27 +39,32 @@ class verify_certificate_result implements templatable, renderable {
/**
* @var string The URL to the user's profile.
*/
public $userprofileurl;
public string $userprofileurl;

/**
* @var string The user's fullname.
*/
public $userfullname;
public string $userfullname;

/**
* @var string The URL to the course page.
*/
public $courseurl;
public string $courseurl;

/**
* @var string The course's fullname.
*/
public $coursefullname;
public string $coursefullname;

/**
* @var string The certificate's name.
*/
public $certificatename;
public string $certificatename;

/**
* @var int|null The certificate's expiry date (optional).
*/
public ?int $expiry;

/**
* Constructor.
Expand All @@ -76,6 +81,12 @@ public function __construct($result) {
$this->courseurl = new \moodle_url('/course/view.php', ['id' => $result->courseid]);
$this->coursefullname = format_string($result->coursefullname, true, ['context' => $context]);
$this->certificatename = format_string($result->certificatename, true, ['context' => $context]);

if (property_exists($result, 'expiry')) {
$this->expiry = $result->expiry;
} else {
$this->expiry = null;
}
}

/**
Expand All @@ -92,6 +103,10 @@ public function export_for_template(\renderer_base $output) {
$result->courseurl = $this->courseurl;
$result->certificatename = $this->certificatename;

if (!empty($this->expiry)) {
$result->expiry = $this->expiry;
}

return $result;
}
}
32 changes: 31 additions & 1 deletion classes/report_table.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

namespace mod_customcert;

use customcertelement_expiry\element as expiry_element;

defined('MOODLE_INTERNAL') || die;

global $CFG;
Expand Down Expand Up @@ -67,13 +69,23 @@ public function __construct($customcertid, $cm, $groupmode, $download = null) {

$context = \context_module::instance($cm->id);
$extrafields = \core_user\fields::for_identity($context)->get_required_fields();
$showexpiry = false;

if (class_exists('\customcertelement_expiry\element')) {
$showexpiry = expiry_element::has_expiry($customcertid);
}

$columns = [];
$columns[] = 'fullname';
foreach ($extrafields as $extrafield) {
$columns[] = $extrafield;
}
$columns[] = 'timecreated';

if ($showexpiry) {
$columns[] = 'timeexpires';
}

$columns[] = 'code';

$headers = [];
Expand All @@ -82,6 +94,11 @@ public function __construct($customcertid, $cm, $groupmode, $download = null) {
$headers[] = \core_user\fields::get_display_name($extrafield);
}
$headers[] = get_string('receiveddate', 'customcert');

if ($showexpiry) {
$headers[] = get_string('expireson', 'customcertelement_expiry');
}

$headers[] = get_string('code', 'customcert');

// Check if we were passed a filename, which means we want to download it.
Expand Down Expand Up @@ -142,6 +159,20 @@ public function col_timecreated($user) {
return userdate($user->timecreated, $format);
}

/**
* Generate the optional certificate expires time column.
*
* @param \stdClass $user
* @return string
*/
public function col_timeexpires($user) {
if ($this->is_downloading() === '') {
return expiry_element::get_expiry_html($this->customcertid, $user->id);
}
$format = '%Y-%m-%d %H:%M';
return userdate(expiry_element::get_expiry_date($this->customcertid, $user->id), $format);
}

/**
* Generate the code column.
*
Expand Down Expand Up @@ -223,4 +254,3 @@ public function download() {
exit;
}
}

Loading